Create mask from color Image in C++(叠加彩色图像蒙版)

Create mask from color Image in C++ (Superimposing a colored image mask)

我编写了一个代码,可以实时检测正方形(白色)并在其周围绘制一个框。正方形的每条边长l被分成7份。然后我在从垂直于三角形边(蓝色)的偏差演变而来的六个点中的每一个处绘制一条长度为 h=l/7 的线。角落用红色标记。它看起来像这样:

为了绘制蓝线和圆圈,我有一个 3 通道 (CV_8UC3) 矩阵 drawing,除了红线、蓝线和白线的位置外,它在任何地方都是零。然后我使用 opencv 的 addWeighted 函数将这个矩阵放在我的网络摄像头图像上。 addWeighted( drawing, 1, webcam_img, 1, 0.0, dst); (Description for addWeighted here)。 但是,正如您所看到的,我得到的效果是我的破折号和圆圈的颜色在黑色区域之外是错误的(可能在黑色区域内也不正确,但在那里更好)。它发生的原因完全有道理,因为它只是给矩阵加上一个权重。

我希望矩阵 drawing 在我的图像上具有正确的颜色。问题是,我不知道如何修复它。我不知何故需要一个遮罩 drawing_mask,其中我的破折号有点叠加到我的相机图像上。在 Matlab 中类似于 dst=webcam_img; dst(drawing>0)=drawing(drawing>0);

有人知道如何在 C++ 中执行此操作吗?

1。自定义版本

我会明确地写出来:

const int cols = drawing.cols;
const int rows = drawing.rows;

for (int j = 0; j < rows; j++) {
    const uint8_t* p_draw = drawing.ptr(j); //Take a pointer to j-th row of the image to be drawn
    uint8_t* p_dest = webcam_img.ptr(j);  //Take a pointer to j-th row of the destination image
    for (int i = 0; i < cols; i++) {
        //Check all three channels BGR
        if(p_draw[0] | p_draw[1] | p_draw[2]) { //Using binary OR should ease the optimization work for the compiler
            p_dest[0] = p_draw[0]; //If the pixel is not zero, 
            p_dest[1] = p_draw[1]; //copy it (overwrite) in the destination image
            p_dest[2] = p_draw[2];
        }
        p_dest += 3; //Move to the next pixel
        p_draw += 3; 
    }
}

当然,您可以将此代码移动到带有参数 (const cv::Mat& drawing, cv::Mat& webcam_img) 的函数中。

2。 OpenCV“纯粹”版本

但纯 OpenCV 方式如下:

cv::Mat mask;
//Create a single channel image where each pixel != 0 if it is colored in your "drawing" image
cv::cvtColor(drawing, mask, CV_BGR2GRAY);
 //Copy to destination image only pixels that are != 0 in the mask
drawing.copyTo(webcam_img, mask);

效率较低(创建遮罩的颜色转换在某种程度上很昂贵),但肯定更紧凑。小提示:如果你有一种非常深的颜色,它不会起作用,比如 (0,0,1) 在灰度中将被转换为 0.


另请注意,在目标图像中重新绘制相同的叠加层(线条、圆圈)可能会更便宜,基本上调用与创建 drawing 图像相同的绘制操作。