在opencv中屏蔽图像

Posted

技术标签:

【中文标题】在opencv中屏蔽图像【英文标题】:Mask an image in opencv 【发布时间】:2014-04-27 23:13:20 【问题描述】:

我正在尝试沿接缝拆分两个图像,然后将它们混合在一起。在这个过程中,我需要通过应用蒙版沿接缝剪切每个图像。我该如何敷面膜?我尝试了bitwise_andmultiplying 蒙版和图像,但都没有成功。

int pano_width = left_template_width + right_template_width - roi_width;  
// add zeros to the right of the left template
Mat full_left = Mat::zeros(roi_height, pano_width, CV_32FC3);
Mat tmp_l = full_left(Rect(0,0, left_template_width, roi_height));
imshow("Scene mask", mask0f3);
imshow("Cropped scene", cropped_scene);
Mat left_masked;
//bitwise_and(cropped_scene, mask0f3, left_masked); // full_left looks all black
multiply(cropped_scene, mask0f3, left_masked); // full_left looks like the scene mask, but with an extra black rectangle on the right side
left_masked.copyTo(tmp_l);
imshow("Full left", full_left);

我采用了一种非常高效但有效的破解方法:

void apply_mask(Mat& img, Mat mask) 
    CV_Assert(img.rows == mask.rows);
    CV_Assert(img.cols == mask.cols);
    print_mat_type(img);
    print_mat_type(mask);
    for (int r = 0; r < mask.rows; r++) 
        for (int c = 0; c < mask.cols; c++) 
            if (mask.at<uchar>(r, c) == 0) 
                img.at<Vec3f>(r, c) = Vec3f(0, 0, 0);
            
        
    

【问题讨论】:

使用Mat::copyTo 使用上面的掩码,另请参阅答案here 可能会有所帮助。 你可能会觉得this answer很有趣。 【参考方案1】:

这里有可以使用 bitwise_and 工作的 sn-p(看看 docs 这个方法是如何工作的)

    Mat img = imread("lena.jpg");
    Mat mask = Mat::zeros(img.rows, img.cols, CV_8UC1);
    Mat halfMask = mask(cv::Rect(0,0,img.rows/2, img.cols/2));
    halfMask.setTo(cv::Scalar(255));
    Mat left_masked;
    bitwise_and(img, cv::Scalar(255,255,255), left_masked, mask);

所以你可以使用类似的东西:

bitwise_and(cropped_scene, cv::Scalar(255,255,255), left_masked, mask); // mask must be CV_8UC1!

但是你必须改变类型,或者创建一个类型为 CV_8UC1 的新掩码。

编辑:您的函数 apply_mask 可能如下所示:

void apply_mask(Mat& img, Mat &mask, Mat &result) 
    CV_Assert(img.rows == mask.rows);
    CV_Assert(img.cols == mask.cols);
    CV_Assert(img.type() == CV_32FC3);
    bitwise_and(img, cv::Scalar(1.0f,1.0f,1.0f), result, mask);

不幸的是,如果您将输入图像作为输出图像在 bitwise_and 中传递,您将得到全黑输出。但是传递另一个参数可以正常工作。

【讨论】:

我想使用不规则形状作为遮罩——而不仅仅是矩形。你可以在上面的评论中看到我尝试使用bitwise_and

以上是关于在opencv中屏蔽图像的主要内容,如果未能解决你的问题,请参考以下文章

Opencv - 蒙版图像导致黑色图像

将灰度图像中的像素转换为黑色(OpenCV)会导致意外结果?

在 OpenCV 中打开和保存图像会使图像变大(ruby-opencv)

在 Opencv 中映射 2 图像

Qt-OpenCV:如何在 Qt 中显示灰度图像(opencv)

[OpenCV实战]19 使用OpenCV实现基于特征的图像对齐