在cv::Mat中,cv::Point的OpenCV RGB值是什么?

4
我已经在StackOverflow上看过不同的问题,但没有一个能帮助我。 我想做的很简单:我有一个cv::Point,我需要获取在cv::Mat中该点的像素RGB值,以便我可以将其与存储的RGB值进行比较。
现在这应该非常容易,但我尝试了1001种不同的方法,它就是不起作用。
请有人帮帮我摆脱我的痛苦!
编辑: 下面的两个答案都可以工作! 我对C++还比较新,不知道通过cout输出unsigned char会得到一个问号! 当然,printf可以给出正确的值!
2个回答

9
这很简单。然而,OpenCV的文档擅长隐藏简单的答案。
以下是示例代码:
cv::Mat3b image = imread(filename);
cv::Point point(23, 42);
cv::Vec3b template;
template[0] = 128; template[1] = 12; template[2] = 64;

const cv::Vec3b& bgr = image(point);
if (bgr[0] == template[0] && bgr[1] == template[1] && bgr[2] == template[2])
   std::cout << "Colors match!" << std::endl;

处理cv::Vec可能有更好的方法,但我忘了。 还请参考OpenCV速查表


谢谢回答,明天会尝试一下。但是cv::Mat和cv::Mat3b有什么区别呢? - user458753
我有一个名为oldImage的cv::Mat,而不是cv::Mat3b,所以我首先将其复制到cv::Mat3b中:cv::Mat3b image = oldImage; 然后我按照您在示例中的方式进行操作,但当我尝试输出它时:std::cout << bgr[0] << std::endl; 我得到了一个问号.. - user458753
谢谢,它起作用了,但我仍然想知道cv::Mat和cv::Mat3b之间的区别是什么。 - user458753
Mat3b是Mat_<Vec_<uchar,3>>的typedef。基本上它是一个带有模板类型的Mat。当您在编译时知道类型时,访问元素更容易/更优雅。Mat是所有Mat_*类的超类,这就是为什么您也可以在Mat_<*>上使用每个cv函数的原因。 - ypnos

0

这取决于图像/矩阵的类型。如果图像只是每个像素的普通1字节RGB,则可以通过以下方式访问它。这种方法相当高效,但不是最安全的方法:

// The RGB values are stored in reverse order (i don't know why)
struct RGB { unsigned char b, g, r; };

// Assumes 1 byte for r,g,b
RGB& GetRGB(cv::Mat &mat, cv::Point p)
{
  assert((mat.step/mat.cols) == sizeof(RGB));
  RGB *data = (RGB*)mat.data;
  data += p.y * mat.cols + p.x;
  return *data;
}

如果Mat是不同类型的,则只需更改RGB结构以匹配所需内容。
尝试使用以下代码将读取的图像类型更改为普通的RGB图像:
Mat in, out;
cvtColor(in, out, CV_8UC3);

OpenCV和图像对我来说都比较新,所以我不太清楚这是什么类型的图像(听起来很傻,我知道),但它是在Mac上制作的png截图。 - user458753
它可能只是一个RGB图像。请尝试上面的代码,它对您有效吗? - Nick Banks
@user458753,我能看一下你用来加载图像的代码吗?你知道这张图片是否有alpha值吗? - Nick Banks
输出 mat.cols 和 mat.rows,你得到了什么? - Nick Banks
感谢您的所有努力,但我仍然在处理我的图像方面遇到了一些问题。不过,现在我已经成功地在全白色的图像上运行了它,所以我会解决其余的问题! - user458753
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接