如何在OpenCV中对图像应用蒙版

How to Apply Mask to Image in OpenCV?

本文关键字:图像 应用 OpenCV      更新时间:2023-10-16

我想应用二进制蒙版到彩色图像。请提供一个基本的代码示例,并适当地解释代码是如何工作的。

还有,是否有一些选项可以永久地应用掩码,以便所有函数仅在掩码内操作?

虽然@perrejba的答案是正确的,但它使用了遗留的c风格函数。由于问题被标记为c++,您可能想要使用方法来代替:

inputMat.copyTo(outputMat, maskMat);

所有对象类型为cv::Mat

请注意,掩码是二进制的。掩码中的任何非零值都被解释为'do copy'。即使蒙版是灰度图像

还要注意,. copyto()函数在复制之前不会清除输出。

如果你想永久地改变原始图像,你必须做一个额外的复制/克隆/分配。copyTo()函数没有为重叠的输入/输出图像定义。因此,您不能使用相同的图像作为输入和输出。

不能对图像应用二进制掩码。您(可选地)在处理函数调用中使用二进制掩码来告诉函数要处理图像的哪些像素。如果我完全误解了你的问题,你应该补充更多的细节来澄清。

嗯,这个问题出现在搜索结果的顶部,所以我认为我们需要这里的代码示例。下面是Python代码:

import cv2
def apply_mask(frame, mask):
    """Apply binary mask to frame, return in-place masked image."""
    return cv2.bitwise_and(frame, frame, mask=mask)

掩码和帧必须是相同的大小,所以像素保持原样,掩码是1,设置为零,掩码像素是0

对于C++则略有不同:

cv::Mat inFrame; // Original (non-empty) image
cv::Mat mask; // Original (non-empty) mask
// ...
cv::Mat outFrame;  // Result output
inFrame.copyTo(outFrame, mask);

您可以使用掩码将原始图像中感兴趣的区域复制到目标图像:

cvCopy(origImage,destImage,mask);

其中mask应为8位单通道数组。

参见OpenCV文档

下面是对从网络摄像头获取的视频帧序列应用二进制掩码的一些代码。注释和取消注释"bitwise_not(Mon_mask,Mon_mask);行,看看效果。

最好,艾哈迈德。

#include "cv.h"      // include it to used Main OpenCV functions.
#include "highgui.h" //include it to use GUI functions.
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
    int c;
int radius=100;
      CvPoint2D32f center;
    //IplImage* color_img;
      Mat image, image0,image1; 
        IplImage *tmp;
    CvCapture* cv_cap = cvCaptureFromCAM(0);
    while(1)  {
        tmp = cvQueryFrame(cv_cap); // get frame
          // IplImage to Mat
            Mat imgMat(tmp);
            image =tmp; 

    center.x = tmp->width/2;
    center.y = tmp->height/2;
         Mat Mon_mask(image.size(), CV_8UC1, Scalar(0,0,0));

        circle(Mon_mask, center, radius, Scalar(255,255,255), -1, 8, 0 ); //-1 means filled
        bitwise_not(Mon_mask,Mon_mask);// commenté ou pas = RP ou DMLA 


        if(tmp != 0)
           imshow("Glaucom", image); // show frame
     c = cvWaitKey(10); // wait 10 ms or for key stroke
    if(c == 27)
        break; // if ESC, break and quit
    }
    /* clean up */
    cvReleaseCapture( &cv_cap );
    cvDestroyWindow("Glaucom");
}

使用蒙版复制

代码示例:

Mat img1 = imread(path); // Load your image
Mat mask(img1 .size(),img1 .type()); // Create your mask
mask.setTo(0);
Point center(img1.cols/2, img1.rows / 2); 
const int radius = img1.cols / 5; // Circle radio
circle(mask, center, radius, 255, FILLED);// Draw a circle in the image center
Mat img2(img1 .size(),img1 .type()); // Outimage
img2.setTo(0); // Clear data
img1.copyTo(img2, mask); // Only values at mask > 0 will be copied.