4
votes

I'm trying to get information from an image using the function cvGet2D in OpenCV.

I created an array of 10 IplImage pointers:

IplImage *imageArray[10];  

and I'm saving 10 images from my webcam:

imageArray[numPicture] = cvQueryFrame(capture);  

when I call the function:

info = cvGet2D(imageArray[0], 250, 100);  

where info:

CvScalar info;  

I got the error:

OpenCV Error: Bad argument (unrecognized or unsupported array type) in cvPtr2D, file /build/buildd/opencv-2.1.0/src/cxcore/cxarray.cpp, line 1824
terminate called after throwing an instance of 'cv::Exception'
what(): /build/buildd/opencv-2.1.0/src/cxcore/cxarray.cpp:1824: error: (-5) unrecognized or unsupported array type in function cvPtr2D

If I use the function cvLoadImage to initialize an IplImage pointer and then I pass it to the cvGet2D function, the code works properly:

IplImage* imagen = cvLoadImage("test0.jpg");
info = cvGet2D(imagen, 250, 100);  

however, I want to use the information already stored in my array.

Do you know how can I solve it?

3
Are you sure ''imageArray[0]'' is a valid IplImage pointer? You can debug on it and inquire its members' value.Yantao Xie

3 Answers

9
votes

Yeah the message is correct.

If you want to store a pixel value you need to do something like this.

int value = 0;
value = ((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels +0];
cout << "pixel value for Blue Channel and (i,j) coordinates: " << value << endl;

Summarizing, to plot or store data you must create an integer value (pixel value varies between 0 and 255). But if you only want to test pixel value (like in an if closure or something similar) you can access directly to pixel value without using an integer value.

I think thats a little bit weird when you start but when you work with it 2 o 3 times you will work without difficulties.

12
votes

Even though its a very late response, but I guess someone might be still searching for the solution with CvGet2D. Here it is.

For CvGet2D, we need to pass the arguments in the order of Y first and then X.

Example:

CvScalar s = cvGet2D(img, Y, X);

Its not mentioned anywhere in the documentation, but you find it only inside core.h/ core_c.h. Try to go to the declaration of CvGet2D(), and above the function prototypes, there are few comments that explain this.

1
votes

Sorry, cvGet2D is not the best way to obtain pixel value. I know its the shortest and clear way because you in only one line of code and knowing coordinates obtain the pixel value.

I suggest you this option. When you see this code you you wiil think that is so complicated but is more effecient.

int main()
{
// Acquire the image (I'm reading it from a file);
IplImage* img = cvLoadImage("image.bmp",1);

int i,j,k;
// Variables to store image properties
int height,width,step,channels;
uchar *data;
// Variables to store the number of white pixels and a flag
int WhiteCount,bWhite;

// Acquire image unfo
height    = img->height;
width     = img->width;
step      = img->widthStep;
channels  = img->nChannels;
data      = (uchar *)img->imageData;

// Begin
WhiteCount = 0;
for(i=0;i<height;i++) 
{
  for(j=0;j<width;j++) 
  { // Go through each channel of the image (R,G, and B) to see if it's equal to 255
    bWhite = 0;
    for(k=0;k<channels;k++)
    {       // This checks if the pixel's kth channel is 255 - it can be faster.
            if (data[i*step+j*channels+k]==255) bWhite = 1;
            else 
            {
                    bWhite = 0;
                    break;
            }
    }
    if(bWhite == 1) WhiteCount++;
  }
}           

printf("Percentage: %f%%",100.0*WhiteCount/(height*width));

return 0;

This code count white pixels and gives you a percetage of white pixels in the image.