【问题标题】:How to Apply Mask to Image in OpenCV?如何在 OpenCV 中对图像应用蒙版?
【发布时间】:2011-11-20 17:04:19
【问题描述】:

我想将二进制蒙版应用于彩色图像。 请提供一个基本的代码示例,并正确解释代码的工作原理。

另外,是否有一些选项可以永久应用掩码,以便所有功能仅在掩码内运行?

【问题讨论】:

    标签: c++ image image-processing opencv mask


    【解决方案1】:

    虽然@perrejba 的答案是正确的,但它使用了遗留的 C 风格函数。由于问题标记为 C++,因此您可能希望使用一种方法:

    inputMat.copyTo(outputMat, maskMat);

    所有对象的类型都是cv::Mat

    请注意,屏蔽是二进制的。掩码中的任何非零值都被解释为“复制”。即使蒙版是灰度图像。

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

    如果您想永久更改原始图像,则必须进行额外的复制/克隆/分配。没有为重叠的输入/输出图像定义 copyTo() 函数。所以你不能使用相同的图像作为输入和输出。

    【讨论】:

    • copyTo 仅对于部分重叠的图像未定义,因此您应该能够使用它来应用蒙版而无需创建新矩阵。来自 docs.opencv.org/modules/core/doc/… :“虽然 m.copyTo(m); 完美运行,但该函数无法处理源矩阵和目标矩阵之间部分重叠的情况。”
    【解决方案2】:

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

    【讨论】:

    • 一些简单的例子会有帮助
    • @Vitovalov 我认为这适用于例如feature detection SIFT 或 SURF 等函数。
    【解决方案3】:

    好吧,这个问题出现在搜索结果的顶部,所以我相信我们需要这里的代码示例。这是 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);
    

    【讨论】:

      【解决方案4】:

      您可以使用蒙版仅将原始图像的感兴趣区域复制到目标区域:

      cvCopy(origImage,destImage,mask);
      

      其中mask 应该是一个 8 位单通道数组。

      OpenCV docs查看更多信息

      【讨论】:

      • 这使用 OpenCV 的旧式 C API。您应该改用并推荐 C++ API。
      • 你只需要 image.copyTo(dst, mask);
      【解决方案5】:

      下面是一些代码,用于在从网络摄像头获取的视频帧序列上应用二进制掩码。 注释并取消注释“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");
      
      }
      

      【讨论】:

      • 正如提问者所写,如果您提供“代码,请解释代码而不是仅仅发布它。”
      猜你喜欢
      • 1970-01-01
      • 2012-05-15
      • 2020-10-24
      • 1970-01-01
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多