Wednesday, December 19, 2007

OpenCV: access pixel values

We may use ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1] = 255; to access the pixel value. Using the following template may make it easier:
template <class T> class Image
{
private:
IplImage *imgp;
public:
Image(IplImage *img = 0) {imgp = img;}
~Image() {imgp = 0;}
void operator = (IplImage *img){imgp = img;}
inline T* operator[](const int rowIndx){
return ((T*)(imgp->imageData + rowIndx *imgp ->widthStep));}
};
typedef struct{
unsigned char b, g, r;
}RgbPixel;

typedef struct{
float b, g, r;
}RgbPixelFloat;

typedef Image<RgbPixel> RgbImage;
typedef Image<RgbPixelFloat> RgbImageFloat;
typedef Image<unsigned char> BwImage;
typedef Image<float> BwImageFloat;

To access a single channel image:
BwImage img(pImg);img[i][j] = 255;

The following codes show an example to access multi-channel image:

IplImage* pImg = cvLoadImage ("lena.jpg", 1); 
cvNamedWindow( "Image", 1 );

RgbImage img(pImg);
for (i = 0; i < 20; i++)
{
for (j = 20; j < 40; j++)
{
img[i][j].r = 10;
img[i][j].g = 10;
img[i][j].b = 10;
}
}
cvShowImage( "Image", pImg );
-online source.

5 comments:

  1. OpenCV also offers several macros to make it easier (and safer) to access the pixels than using the pointers, while being significantly faster than the class based method. These include:
    * CV_MAT_ELEM_PTR
    * CV_MAT_ELEM

    I've also just posted some notes at http://neurov.is/on/OpenCV_cheat_sheet for further (and updated) information.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. OpenCV C++ interface:
    cv:Mat matrix =...
    float f = matrix.at(1,1);
    etc.

    ReplyDelete
  4. Anonymous11:50 PM

    Hey.... Thanks for the post.... But any idea why during compilation it says - 'BwImage' was not declared in this scope.
    I've included the following libraries -
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    Thanks again.

    ReplyDelete
  5. Anonymous2:51 AM

    Nice work with that class the cv::mat object of opencv does similar things but this is a really elegant solution. Calling this class image is maybe wrong, maybe this could be an imageItarator that could adress image pixels using rows and cols. It would also be funny to add some other methods like:

    gotorow(row) save that in a variable
    {tmprow = return ((T*)(imgp->imageData + rowIndx *imgp ->widthStep))
    and
    row(int)
    return tmprow

    I don t understand why the classic opencv macros should be fuster than this solution

    ReplyDelete