C++和OpenCV如何在Mat中获取和设置像素颜色

54

我想要将某些像素的颜色值设置为一个新值,这些像素在cv::Mat图像中。以下是我的代码:

    Mat image = img;
    for(int y=0;y<img.rows;y++)
    {
        for(int x=0;x<img.cols;x++)
        {
        Vec3b color = image.at<Vec3b>(Point(x,y));
        if(color[0] > 150 && color[1] > 150 && color[2] > 150)
        {
            color[0] = 0;
            color[1] = 0;
            color[2] = 0;
            cout << "Pixel >200 :" << x << "," << y << endl;
        }
        else
        {
            color.val[0] = 255;
            color.val[1] = 255;
            color.val[2] = 255;
        }
    }
    imwrite("../images/imgopti"+to_string(i)+".tiff",image);

使用cout输出时,好像可以得到正确的像素,但使用imwrite输出图像时,受影响的像素未被修改。我已经尝试过color.val[0]...,但仍然无法弄清楚为什么输出图像中的像素颜色没有改变。

3个回答

90

除了将新像素值复制回图像之外,您已经完成了所有操作。

此行将像素复制到本地变量中:

Vec3b color = image.at<Vec3b>(Point(x,y));

所以,在按您要求更改颜色后,只需将其像这样设置回来:color
image.at<Vec3b>(Point(x,y)) = color;

因此,完整的翻译可能会是这样:

Mat image = img;
for(int y=0;y<img.rows;y++)
{
    for(int x=0;x<img.cols;x++)
    {
        // get pixel
        Vec3b & color = image.at<Vec3b>(y,x);

        // ... do something to the color ....
        color[0] = 13;
        color[1] = 13;
        color[2] = 13;

        // set pixel
        //image.at<Vec3b>(Point(x,y)) = color;
        //if you copy value
    }
}

21

只需使用参考文献:

Vec3b & color = image.at<Vec3b>(y,x);
color[2] = 13;

2
因为问题涉及到颜色矩阵,所以在uchar情况下,当然要使用uchar& c = image.at<uchar>(y,x) - berak

17

基于性能原因,我不会使用 .at。

定义一个结构体:

//#pragma pack(push, 2) //not useful (see comments below)
struct BGR {
    uchar blue;
    uchar green;
    uchar red;  };

然后在 cv::Mat 图像上使用它,如下所示:

BGR& bgr = image.ptr<BGR>(y)[x];

image.ptr(y) 给您提供了指向扫描线 y 的指针。使用 x 和 y 循环迭代像素。


如果uchar的大小为1,设置pack值为2有什么意义? - Antony Hatchkins
1
编译器会向结构体添加填充字节。pack设置更改这些填充,以便数据以另一种方式对齐。编辑:请参见此帖子https://dev59.com/2nA75IYBdhLWcg3wZ4Fr - Flocke
3
pragma对仅由uchar组成的结构体没有影响。详情请阅读这里提供的简明解释(链接已提供)。 - Antony Hatchkins
谢谢,好链接。看起来在这种情况下,pragma 确实是无用的 :) 谢谢! - Flocke
不客气 :) 很好的回答:少些魔法,多些效率。 - Antony Hatchkins
显示剩余2条评论

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