【问题标题】:Why OpenCV return strange value for pixel intensity?为什么 OpenCV 返回像素强度的奇怪值?
【发布时间】:2025-11-27 23:25:01
【问题描述】:

我有 c++ 和 OpenCV 3.1,我用这些代码分隔了 RGB 三个通道:

Mat src = imread("original_image.jpg",CV_LOAD_IMAGE_COLOR);
Mat bgr[3] , bluemat ;
split(src,bgr);
bluemat = bgr[0];
std::cout << "bluemat.at<int>(0,1); : " << bluemat.at<int>(0,1) << '\n';

奇怪的是它打印出一个大数字:1415208581,这是为什么呢?

不是应该在 0-255 范围内吗?为什么不是?

【问题讨论】:

  • 您要求 c++ 从该像素开始打印 int(32/64 位)的值,而不是无符号字符
  • @MartinBeckett,我如何打印实际数字?
  • .at

标签: c++ opencv


【解决方案1】:

(扩展搜索评论)

openCV 的一个特点cv::Mat 图像类型是一个基于原始C 版本库的非常简单的对象。

cv::Mat 包含一个给出像素类型的字段,但数据仅作为内存字节块存储。您可以根据需要使用此内存块来存储和访问像素。它使与其他库的链接变得非常灵活和容易,但意味着您需要手动跟踪数据是什么。

所以data.at&lt;int&gt;(0,0) 将提取第一个像素,就好像数据是 int(无论您的平台上的 int 是什么),data.at&lt;uchar&gt; (0,0) 会将第一个像素作为一个字节(这通常是您想要的)。

【讨论】:

  • 感谢您的回答,但它(uchar 或 unsigned char)返回空值,并且什么也不打印。如果我将其更改为 (0,0) 它会返回其中一个神秘字符(如矩形中的问号)。
  • 我找到了答案,但是,将字节转换为 uchar 然后转换为 int !为什么 ?你能解释一下吗?为什么不直接 int 工作?
  • @komoboji,你混淆了两件事。你需要 cv::Mat "at" 的 参数来告诉它一个像素在内存中有多大,但是你需要一个 "cout" 的 int 参数来告诉它以数字而不是作为数字打印结果一个可打印的字符。所以像 cout (0,0)
【解决方案2】:

这里的主要区别是将内存字节转换为 uchar 与 int。您拥有的数据形式取决于您如何读取它。CV_LOAD_IMAGE_COLOR 将图像读取为 16 位/32 位值。我无法编译您给我的代码,因为将数据转换为 int 会产生内存问题。

现在,如果您使用uchar,这将得到解决。然而,cout 打印字符的问题与&lt;&lt; 的重载函数有关

Mat src = imread("1.jpg", CV_LOAD_IMAGE_COLOR);

Mat bgr[3], bluemat;
split(src, bgr);
bluemat = bgr[0];
std::cout << "bluemat.at<uchar>(0,1); : " << (int)bluemat.at<uchar>(0, 1) << '\n';

我所做的只是插入类型转换 int。这个问题扩展了here,但告诉输出流这是一个数字,而不是一个字符。

【讨论】: