【问题标题】:Is there a simple method to highlight the mask?有没有简单的方法来突出面具?
【发布时间】:2018-02-16 15:03:56
【问题描述】:

如果我有类似的面具

我有一个图像(大小与面具相同),如

我想突出显示图像中的蒙版。如果我使用其他语言,我只是

如您所见,结果图像有一个透明红色显示蒙版。我希望在 OpenCV 中实现这一点。所以我写了这段代码

#include <opencv.hpp>

using namespace cv;
using namespace std;

int main() {
    Mat srcImg = imread("image.jpg");
    Mat mask = imread("mask.jpg", IMREAD_GRAYSCALE)>200;

    for(int i=0;i<srcImg.rows;i++)
        for(int j=0;j<srcImg.cols;j++)
            if(mask.at<uchar>(i, j)==255)
                circle(srcImg, Point(j,i), 3, Scalar(0, 0, 128,128));
    imshow("image",srcImg);

    waitKey();
    return 0;
}

但是如你所见,我在Scalar 中使用了一个alpha 值,但它不是透明红色

这可能是因为 srcImg 只有 3 个频道。我对此有两个问题

  1. 如何用透明红色高亮遮罩(即使图像只有 3 个通道)?
  2. 我必须逐个像素地绘制circle 才能做到这一点?

【问题讨论】:

    标签: c++ opencv image-processing


    【解决方案1】:
    #include<opencv2/core.hpp>
    #include<opencv2/imgproc.hpp>
    #include<opencv2/highgui.hpp>
    
    using namespace cv;
    
    int main(int argc, char** argv)
    {
        Mat srcImg = imread("image.png");
        Mat mask = imread("mask.png", IMREAD_GRAYSCALE) > 200;
    
        Mat red;
        cvtColor(mask, red, COLOR_GRAY2BGR);
        red = (red - Scalar(0, 0, 255)) / 2;
        srcImg = srcImg - red;
    
        imshow("image", srcImg);
    
        waitKey();
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      我已经用 python 编写了这个,但您可以轻松地将它移植到 C++。假设您的 sourcemask 图像是 CV_8UC3 图像:

      src = cv2.imread("source.png", -1)
      mask = cv2.imread("mask.png", -1)
      
      # convert mask to gray and then threshold it to convert it to binary
      gray = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
      ret, binary = cv2.threshold(gray, 40, 255, cv2.THRESH_BINARY)
      
      # find contours of two major blobs present in the mask
      im2,contours,hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
      
      # draw the found contours on to source image
      for contour in contours:
          cv2.drawContours(src, contour, -1, (255,0,0), thickness = 1)
      
      # split source to B,G,R channels
      b,g,r = cv2.split(src)
      
      # add a constant to R channel to highlight the selected area in reed
      r = cv2.add(b, 30, dst = b, mask = binary, dtype = cv2.CV_8U)
      
      # merge the channels back together
      cv2.merge((b,g,r), src)
      

      【讨论】:

      • 我认为 findContours 的返回签名已从 3 个变量变为 2 个 - 即去掉了 im2 部分。
      猜你喜欢
      • 2021-10-21
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-25
      • 2017-12-18
      • 1970-01-01
      相关资源
      最近更新 更多