在 OpenCV 中应用蒙版

Posted

技术标签:

【中文标题】在 OpenCV 中应用蒙版【英文标题】:Apply Mask in OpenCV 【发布时间】:2019-10-28 11:26:36 【问题描述】:

我从这张图片开始:

我想直接在车辆前方的车道标记上着色(是的,这是针对 Udacity 在线课程,但他们希望我在 python 中执行此操作,但我宁愿在 C++ 中执行此操作)

找到正确的标记很容易:

这适用于为标记着色:

  cv::MatIterator_<cv::Vec3b> output_pix_it = output.begin<cv::Vec3b>(); 
  cv::MatIterator_<cv::Vec3b> output_end = output.end<cv::Vec3b>();

  cv::MatIterator_<cv::Vec3b> mask_pix_it = lane_markers.begin<cv::Vec3b>(); 

  //auto t1 = std::chrono::high_resolution_clock::now();

  while (output_pix_it != output_end)
  
    if((*mask_pix_it)[0] == 255)
    
      (*output_pix_it)[0] = 0;
      (*output_pix_it)[1] = 0;
      (*output_pix_it)[2] = 255;
    

    ++output_pix_it;
    ++mask_pix_it;
  

正确生产

但我有点惊讶,它似乎有点慢,需要 1-2 毫秒(在核心 i7-7700HQ 上 w/16gb ram,使用 -O3 编译)用于 960 x 540 的图像

在此处遵循“有效方式”:https://docs.opencv.org/2.4/doc/tutorials/core/how_to_scan_images/how_to_scan_images.html#howtoscanimagesopencv

我想出了:

    unsigned char *o; // pointer to first element in output Mat
    unsigned char *m; //pointer to first element in mask Mat
    o = output.data;
    m = lane_markers.data;
    size_t pixel_elements = output.rows * output.cols * output.channels();

    for( size_t i=0; i < pixel_elements; i+=3 )
    
      if(m[i] == 255)
      
        o[i] = 0;
        o[i+1] = 0;
        o[i+2] = 255;
      
    

这大约快 3 倍......但不会产生正确的结果:

所有 cv::Mat 对象都是 8UC3 类型(标准 BGR 像素格式)。 据我所知,Mat 对象的基础数据应该是长度像素宽度 * 像素高度 * 通道数的 unsigned chars 数组。但似乎我错过了一些东西。 isContinuous() 对于输出矩阵和掩码矩阵都为真。我在 Ubuntu 18.04 上使用 openCV 3.4.4。我错过了什么?

【问题讨论】:

为什么你认为 1-2 ms 很慢? 你到底在问什么? “我错过了什么”太宽泛了 @nada 来自经验,对于正在执行的操作,它似乎应该比原来更快。使用答案中提到的setTo() 函数以大约 45 us 或大约 25 到 40 倍的速度应用掩码。在这种情况下,看起来他们可能会在后台使用 CUDA 和 GPU 来获得这种速度。在诸如此类的视觉管道中,最小化延迟对于拥有响应式控制系统至关重要。我的 hack 不起作用,这仍然让我有点发疯,但我想哦,好吧。给出的答案是一个更好的解决方案。 【参考方案1】:

Mat 的屏蔽区域设置为特定值的典型方法是使用Mat::setTo 函数:

cv::Mat mask;
cv::cvtColor(lane_markers, mask, cv::COLOR_BGR2GRAY); //mask Mat has to be 8UC1
output.setTo(cv::Scalar(0, 0, 255), mask);

【讨论】:

我知道必须有一个函数可以做到这一点,但我就是不知道它是什么。那太棒了。而且速度明显加快(25x - 40x)——大约 45us。

以上是关于在 OpenCV 中应用蒙版的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV:创建一个透明蒙版?

Opencv检测边界和ROI掩码

在opencv中屏蔽图像

通过 openCV 创建矩形蒙版的更好方法

使用 OpenCV 在图像上创建矩形区域蒙版

带有opencv的三角形蒙版