泛洪填充简单理解就是将指定颜色从指定位置开始填充一个连通区域,此时的连通性由像素值的接近程度来衡量。OpenCV中提供两种泛洪填充方式:
下面先来看看在OpenCV中泛洪填充的函数。
01
OpenCV中泛洪填充函数
OpenCV提供了floodFill函数进行泛洪填充,函数的完整定义:
floodFill(image, mask, seedPoint, newVal, loDiff, upDiff, flags)具体参数如下:
1. image,需要进行泛洪填充的原始图像;
2. msak,一个二值矩阵也就是说里面元素值要不为0要不为1;
3. seedPoint,种子像素,填充的起始点像素;
4. newVal,要填充的颜色;
5. loDiff,规定像素值的下限;
6. upDiff,规定像素值的上限;
7. flags,填充的方法。
这里需要说明一点,在图像上会被填充的像素值的范围是[seedPoind.BGR - lowDiff, seedPoint.BGR + upDiff]。
有了函数定义,接下来就看一看这两种泛洪填充方式吧。
02
填充彩色图像
对于填充彩色图像,我们需要使用像素值的接近程度来决定是否进行填充,此时需要指定一个起始点,规定像素值的上下限,只要与起始点连接并且其像素值在定义的范围之内,则会被填充,然后这个被填充的点连接的点,哪一个点的像素值在上面定义的范围之内,也会被填充,如此往复,由此可以看出位置被填充的条件:
使用"my_love.jpg"的图片:
具体代码如下:
效果如下:
此时需要注意两点:
而且必须要比原始图像的宽高上加两个像素,这是OpenCV强制的,如果不这样指定会抛出异常;
前面说到在此模式下,mask二值掩码(只能取0或1)能够锁定被图片不被填充,比如在上面的填充图片中,我们想保留头部分不被填充,在提取ROI的时候我们已经提取过这一范围了,具体的只需要将这一区域mask值设置为1即可:
# 锁定不被填充的区域mask[151:501, 161:551] = 1
此时需要注意mask掩码的比原始图片长宽都大了两个像素,因此如果选择指定范围,需要加上1即可。具体效果如下:
从上图也可以看出,阻断了像素的连通性,也是不会被填充的。
03
填充掩码图像
掩码就是前面所说的mask二值,前面说的填充图像,mask只起到锁定图像的作用,而在填充掩码图像的模式下,不直接对图像进行填充,而是对掩码进行填充。当设置这种填充掩码图像的模式的时候(cv.FLOODFILL_MASK_ONLY),loDiff,规定像素值的下限,upDiff,规定像素值的上限,自动会失效。此时为了效果明显使用纯色进行试验,因为此时填充没有了像素范围,也就是当设置cv.FLOODFILL_MASK_ONLY的时候,原始图片起始点周边只能是完全相同的像素值才能被填充。
执行效果如下:
下面来具体分析,原始图像如下图所示:
此时mask二值掩码都为0,也就是说整张图片都可以进行填充。此时seedPoint值为(0, 0),也就是左上角,因为左上角对于原始图像来说,有一个范围都是白色,因此就会把这些具有相同像素值的白色进行填充。接下来再来看一个例子:
执行效果如下所示:
接下来具体分析一下,原始图像和上面一样:
此时的mask二值掩码就有很大的不同,此时为了表示方便,将可以填充区域,即值为0的区域用绿色进行显示,当然这并不是mask的真实效果,mask是拥有单通道的0,1值,如果将其显示是黑色的图像。
此时将原始图片和mask结合:
此时设置seedPoint为(0, 0),即左上角,左上角相同颜色就是白色,但是此时二值图像只有绿色区域可以被填充,因此最终的效果:
也就是说,如果使用填充掩码的方式,要被填充必须具备两个条件: