通过Mat::at获取像素值

4

我正在尝试从Mat对象获取像素。为了测试,我试图在一个正方形上画一条对角线,并期望获得一条完美的线,从左上角到右下角的顶点穿过。

for (int i =0; i<500; i++){
     //I just hard-coded the width (or height) to make the problem more obvious

  (image2.at<int>(i, i)) = 0xffffff;
     //Draw a white dot at pixels that have equal x and y position.
}

然而,结果并不如预期。 这是在彩色图片上画的一条对角线。 enter image description here 这是在灰度图片上的效果。 enter image description here 有人看出问题了吗?

噢,是的,大家都看到了问题。 - qPCR4vir
@qPCR4vir 这张图片不是500x500吗? - Min Lin
它是700x700的,但结果无论数字是多少都保持不变。 - Max
你能否提供一个模板成员函数 .at<type>(int,int) 的文档链接? - qPCR4vir
是的,我确实阅读了参考文献,但它并没有提供太多帮助: http://opencv.willowgarage.com/documentation/cpp/basic_structures.html 而且对于 Mat::at<template T>(int, int) 没有具体的解释。 不管怎样,现在我知道问题出在哪里了。谢谢大家。 - Max
我发现模板参数必须像image2.type()(或Mat :: type())这样,因为“真实”数据存储为原始无符号字符,并且函数 at() 需要知道类型以根据传递的整数计算“真实”坐标(数组索引)。 - qPCR4vir
2个回答

6
问题在于你试图将每个像素作为int访问(32位每像素图像),而你的图像是一个3通道的unsigned char(24位每像素图像)或一个1通道的unsigned char(8位每像素灰度图像)。 对于灰度图像,可以尝试像这样访问每个像素。
for (int i =0; i<image2.width; i++){
  image2.at<unsigned char>(i, i) = 255;
}

或者像这样进行颜色设置

for (int i =0; i<image2.width; i++){     
      image2.at<Vec3b>(i, i)[0] = 255;
      image2.at<Vec3b>(i, i)[1] = 255;
      image2.at<Vec3b>(i, i)[2] = 255;
}

很酷,谢谢。 我以为可以通过使用“int”一次性设置所有通道来加快速度。 - Max

3
(image2.at<int>(i, i)) = 0xffffff;

看起来你的彩色图像是24位的,但是你用int来表示像素,而int似乎是32位的。


这也是为什么当您切换到8位黑白模式时,错误会增加的原因。 - sean3k
哦,我真傻。那么,没有办法直接设置像素的值而不经过所有红、绿和蓝色通道吗?(我相信这比仅设置一个值要慢3倍) - Max
2
也许 image2.at<Vec3b>(i,i) |= 0xffffff00 是你想要的快速方法。如果可以,请告诉我,我很好奇。我认为我上面的答案可能有效,但不会比分别设置三个分量更快。你可能需要进行类型转换。 - sean3k
尝试过 0xffffff00、0xffffff、0xffffff00 >> 2,现在代码是正确的,但颜色不对了,变成了蓝色 (0xff0000)... 我猜编译器仍将这些值视为32位整数,所以这里没有快速的解决方法。 感谢快速响应的答复。 - Max
这是一个非常棒的想法,使用位运算,但不幸的是Vec3b不支持位运算符。 - Max
显示剩余2条评论

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