8

I am using Ubuntu 12.04 and OpenCV 2

I have written 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 I am getting negative values and very large values in the data variable. I think I have made some mistake somewhere. Can you please point it out.
I have been reading the documentation (I have not finished it fully.. it is quite large. ) But from what I have read, this should work. But it isnt. What is going wrong here?

Georgy
  • 12,464
  • 7
  • 65
  • 73
Chani
  • 5,055
  • 15
  • 57
  • 92

3 Answers3

13

Img_mat is a 3 channeled image. Each channel consists of pixel values uchar in data type. So with split(Img_mat, BGR) the Img_mat is split into 3 planes of blue, green and red which are collectively stored in a vector BGR. So BGR[0] is the first (blue) plane with uchar data type pixels...hence it will be

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

so on...

CerebralFart
  • 3,336
  • 5
  • 26
  • 29
rotating_image
  • 3,046
  • 4
  • 28
  • 46
2

You have to specify the correct type for cv::Mat::at(i,j). You are accessing the pixel as int, while it should be a vector of uchar. 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
}
flowfree
  • 16,356
  • 12
  • 52
  • 76
1

Why are you loading an IplImage first? You are mixing the C and C++ interfaces. Loading a cv::Mat with imread directly would be more straight-forward.

This way you can also specify the type and use the according type in your at call.

aLu
  • 47
  • 1
  • 6