在opencv中使用Mat :: at(i,j)表示2-D Mat对象

时间:2013-01-13 11:41:15

标签: c++ opencv image-processing

我正在使用Ubuntu 12.04和OpenCV 2

我写了以下代码:

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*/ 
}

问题是我在数据变量中得到负值和非常大的值。我想我在某个地方犯了一些错误。你能指出来吗。
我一直在阅读文档(我还没有完全完成它...它非常大。)但是根据我的阅读,这应该可行。但它不是。这里出了什么问题?

3 个答案:

答案 0 :(得分:11)

Img_mat是一个3通道图像。每个通道由数据类型中的像素值uchar组成。 因此,对于split(Img_mat, BGR)Img_mat被分为3个蓝色,绿色和红色的平面,这些平面共同存储在向量BGR中。所以BGR[0]是第一个(蓝色)平面,uchar数据类型像素...因此它将是

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

等......

答案 1 :(得分:2)

您必须为cv::Mat::at(i,j)指定正确的类型。您正在访问int像素,而它应该是uchar的向量。您的代码应如下所示:

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 :(得分:1)

为什么要先加载IplImage?您正在混合使用C和C ++接口。 直接加载带有imread的cv :: Mat会更直截了当。

通过这种方式,您还可以指定类型并在通话中使用相应的类型。