Using Mat :: at (i, j) in opencv for a 2-D Mat object

I am using Ubuntu 12.04 and OpenCV 2

I wrote the following code:

IplImage* img =0; img = cvLoadImage("nature.jpg"); if(img != 0) { Mat Img_mat(img); std::vector<Mat> RGB; split(Img_mat, RGB); int data = (RGB[0]).at<int>(i,j)); /*Where i, j are inside the bounds of the matrix size .. i have checked this*/ } 

The problem is that I get negative values ​​and very large values ​​in the data variable. I think I made a mistake somewhere. Can you point it out.
I read the documentation (I haven't finished it completely yet ... it's pretty big). But from what I read, this should work. But this is not so. What is wrong here?

+7
source share
3 answers

Img_mat is a 3-channel image. Each channel consists of uchar pixel uchar in a data type. Thus, using split(Img_mat, BGR) Img_mat divided into 3 planes: blue, green and red, which are stored together in the BGR vector. Thus, BGR[0] is the first (blue) plane with uchar data uchar ... therefore, it will be

 int dataB = (int)BGR[0].at<uchar>(i,j); int dataG = (int)BGR[1].at<uchar>(i,j); 

soon...

+11
source

You must specify the correct type for cv::Mat::at(i,j) . You access the pixel as an int , whereas it must be a uchar vector. Your code should look something like this:

 IplImage* img = 0; img = cvLoadImage("nature.jpg"); if(img != 0) { Mat Img_mat(img); std::vector<Mat> BGR; split(Img_mat, BGR); Vec3b data = BGR[0].at<Vec3b>(i,j); // data[0] -> blue // data[1] -> green // data[2] -> red } 
+2
source

Why do you download IplImage first? You mix C and C ++ interfaces. Loading cv :: Mat with imread directly will be more direct.

This way you can also specify the type and use the appropriate type during your call.

+1
source

All Articles