带掩模的OpenCV floodfill

1''*_*1'' 19 opencv flood-fill

文档为OpenCV的的floodfill功能状态:

该函数使用并更新掩码,因此您负责初始化掩码内容.洪水填充不能跨越掩码中的非零像素.例如,边缘检测器输出可以用作掩模以停止在边缘处填充.可以在对函数的多次调用中使用相同的掩码,以确保填充区域不重叠.

该功能如何更新掩码?它是否将填充中的所有像素设置为某个非零值?

Aur*_*ius 26

与掩码的种子点相同的连接组件中的所有零值像素将替换为您指定的值.必须将此值添加到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));
Run Code Online (Sandbox Code Playgroud)

下面是一个简单但可能具有启发性的例子.像这样创建一个图像:

//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);
Run Code Online (Sandbox Code Playgroud)

结果在这张图片中:

原始图像

然后,创建一个掩码并填充它:

//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));
Run Code Online (Sandbox Code Playgroud)

给出这个结果:

充满洪水的面具

掩模中的白色像素是边缘检测的结果,而灰色像素是泛洪填充的结果.

更新: 响应于评论,标志值4指定用于比较颜色值差异的像素邻域.从文档:

较低位包含函数内使用的连接值4(默认值)或8.连通性确定考虑像素的哪些邻居.

cv::FLOODFILL_MASK_ONLY不通过标志,形象和面具被更新,但洪水填充将停止在任何非零掩码值.

  • @Aurelius感谢您指出掩码的像素必须为零值以便填充.这个提示救了我的一天...... (2认同)

Roy*_*rot 8

还有一个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)
Run Code Online (Sandbox Code Playgroud)

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

结果: 结果

  • 需要注意的一个特别重要的事情是,当指定一个点"x"和"y"时,与numpy索引相比,切换轴. (3认同)
  • 使用相同的图像和代码,我只得到边缘 - https://drive.google.com/open?id=17DhliW4OIy2iNPJkXglbNPdgaEgpGACf 您能告诉我为什么会出现这种情况吗? (2认同)