【问题标题】:OpenCV floodfill with mask带掩码的 OpenCV 泛洪填充
【发布时间】:2013-05-23 04:33:50
【问题描述】:

OpenCV 的洪水填充功能的documentation 声明:

函数使用和更新掩码,所以你负责 初始化掩码内容。洪水填充不能跨越非零 掩码中的像素。例如,可以使用边缘检测器输出 作为停止在边缘填充的遮罩。可以使用相同的 在对函数的多次调用中进行掩码以确保填充区域 不重叠。

函数如何更新掩码?它是否将 Floodfill 中的所有像素设置为某个非零值?

【问题讨论】:

    标签: opencv flood-fill


    【解决方案1】:

    与掩码的种子点相同的连通分量中的所有零值像素都将替换为您指定的值。这个值必须加到flags参数中,左移8位:

    uchar fillValue = 128;
    cv::floodFill(img, mask, seed, cv::Scalar(255) ,0, cv::Scalar(), cv::Scalar(), 4 | cv::FLOODFILL_MASK_ONLY | (fillValue << 8));
    

    下面是一个简单但也许很有启发性的例子。像这样创建图像:

    //Create simple input image
    cv::Point seed(4,4);
    cv::Mat img = cv::Mat::zeros(100,100,CV_8UC1);
    cv::circle(img, seed, 20, cv::Scalar(128),3);
    

    此图像中的结果:

    然后,创建一个蒙版并填充它:

    //Create a mask from edges in the original image
    cv::Mat mask;
    cv::Canny(img, mask, 100, 200);
    cv::copyMakeBorder(mask, mask, 1, 1, 1, 1, cv::BORDER_REPLICATE);
    
    //Fill mask with value 128
    uchar fillValue = 128;
    cv::floodFill(img, mask, seed, cv::Scalar(255) ,0, cv::Scalar(), cv::Scalar(), 4 | cv::FLOODFILL_MASK_ONLY | (fillValue << 8));
    

    给出这个结果:

    mask中的白色像素是边缘检测的结果,而灰色像素是flood-fill的结果。

    更新: 作为对评论的回应,标志值4 指定了用于比较颜色值差异的像素邻域。来自文档:

    低位包含函数中使用的连接值,4(默认)或 8。连通性决定了考虑像素的哪些邻居。

    cv::FLOODFILL_MASK_ONLY 标志未通过时,图像和蒙版都会更新,但洪水填充将在任何非零蒙版值处停止。

    【讨论】:

    • 有人会在java的答案中重写这个和平的代码吗?
    • @Aurelius 感谢您指出蒙版的像素必须为零值才能被填充。这个提示拯救了我的一天....
    • python 用户提示:工作方式完全相同,语法如下:flood_value = 128 cv.floodFill(img, mask, seed, 255, 5, 5, flags=cv.FLOODFILL_MASK_ONLY | (flood_value &lt;&lt; 8))
    【解决方案2】:

    还有一个python版本

    im = cv2.imread("seagull.jpg")
    h,w,chn = im.shape
    seed = (w/2,h/2)
    
    mask = np.zeros((h+2,w+2),np.uint8)
    
    floodflags = 4
    floodflags |= cv2.FLOODFILL_MASK_ONLY
    floodflags |= (255 << 8)
    
    num,im,mask,rect = cv2.floodFill(im, mask, seed, (255,0,0), (10,)*3, (10,)*3, floodflags)
    
    cv2.imwrite("seagull_flood.png", mask)
    

    (来自维基媒体的海鸥图片:https://commons.wikimedia.org/wiki/Commons:Quality_images#/media/File:Gull_portrait_ca_usa.jpg

    结果:

    【讨论】:

    【解决方案3】:

    根据 Aurelius 的回答,面具需要归零。

    检查源中的评论,它指出

    由于这既是输入参数又是输出参数,你必须负责 初始化它。填充不能跨越输入掩码中的非零像素。

    蒙版会影响结果,因此需要在使用前归零:

    cv::Mat mask;
    mask = cv::Mat::zeros(img.rows + 2, img.cols + 2, CV_8UC1);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-07
      • 2018-12-06
      • 2021-10-24
      相关资源
      最近更新 更多