在opencv中使用Mat::at(i,j)用于二维Mat对象

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

本文关键字:Mat 用于 opencv 对象 二维 at      更新时间:2023-10-16

我使用的是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*/ 
}

问题是我在数据变量中得到负值和非常大的值。我想我在什么地方犯了错误。你能指出来吗?
我一直在看文档(我还没有完全看完)。它相当大。)但据我所知,这应该行得通。但事实并非如此。这里出了什么问题?

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);

等等…

必须为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
}

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

这样,您还可以指定类型,并在调用中使用相应的类型。