一、漫水填充定义
漫水填充(Flood Fill)法是用特定的颜色填充联通区域,通过设置可联通像素的上下限以及联通方式来达到不同的填充效果的方法。主要用来标记和分离图像的一部分以便对其进一步处理和分析。也可以用来从输入图像获取掩码区域,掩码会加快处理过程,或只处理掩码指定的像素点。
所谓漫水填充,简单来说,就是自动选中了和种子点相连的区域,接着将该区域替换成指定的颜色,这是个非常有用的功能,经常用来标记或者分离图像的一部分进行处理或分析.漫水填充也可以用来从输入图像获取掩码区域,掩码会加速处理过程,或者只处理掩码指定的像素点.
在OpenCV中,漫水填充是填充算法中最通用的方法。且在OpenCV 2.X中,使用C++重写过的FloodFill函数有两个版本。一个不带掩膜mask的版本,和一个带mask的版本。这个掩膜mask,就是用于进一步控制哪些区域将被填充颜色(比如说当对同一图像进行多次填充时)。这两个版本的FloodFill,都必须在图像中选择一个种子点,然后把临近区域所有相似点填充上同样的颜色,不同的是,不一定将所有的邻近像素点都染上同一颜色,漫水填充操作的结果总是某个连续的区域。当邻近像素点位于给定的范围(从loDiff到upDiff)内或在原始seedPoint像素值范围内时,FloodFill函数就会为这个点涂上颜色。
来自 https://blog.csdn.net/poem_qianmo/article/details/28261997
二、floodFill函数详解
Opencv中有两个版本的floodFill函数,如下所示:
Python:
retval, image, mask, rect = cv.floodFill( image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]] )
retval, image, mask, rect = cv.floodFill( image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]] )
image:InputOutputArray类型的image, 输入/输出1通道或3通道,8位或浮点图 像,具体参数由之后的参数具体指明。
mask:InputOutputArray类型的mask,这是第二个版本的floodFill独享的参数, 表示操作掩模,。它应该为单通道、8位、长和宽上都比输入图像 image 大两个像素点的图像。第二个版本的floodFill需要使用以及更新掩膜,所以这个mask参数我们一定要将其准备好并填在此处。需要注意的是,漫水填充不会填充掩膜mask的非零像素区域。例如,一个边缘检测算子的输出可以用来作为掩膜,以防止填充到边缘。同样的,也可以在多次的函数调用中使用同一个掩膜,以保证填充的区域不会重叠。另外需要注意的是,掩膜mask会比需填充的图像大,所以 mask 中与输入图像(x,y)像素点相对应的点的坐标为(x+1,y+1)。
seedPoint:Point类型的seedPoint,漫水填充算法的起始点。
newVal:Scalar类型的newVal,像素点被染色的值,即在重绘区域像素的新值。
loDiff:Rect*类型的rect,有默认值0,一个可选的参数,用于设置floodFill函数将要重绘区域的最小边界矩形区域。
upDiff:Scalar类型的loDiff,有默认值Scalar( ),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之负差(lower brightness/color difference)的最大值。
rect Scalar类型的upDiff,有默认值Scalar( ),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之正差(lower brightness/color difference)的最大值。
flags:int类型的flags,操作标志符,此参数包含三个部分
• FLOODFILL_FIXED_RANGE - 如果设置为这个标识符的话,就会考虑当前像素与种子像素之间的差,否则就考虑当前像素与其相邻像素的差。也就是说,这个范围是浮动的。
• FLOODFILL_MASK_ONLY - 如果设置为这个标识符的话,函数不会去填充改变原始图像 (也就是忽略第三个参数newVal), 而是去填充掩模图像(mask)。这个标识符只对第二个版本的floodFill有用,因第一个版本里面压根就没有mask参数。
• 中间八位部分,上面关于高八位FLOODFILL_MASK_ONLY标识符中已经说的很明显,需要输入符合要求的掩码。Floodfill的flags参数的中间八位的值就是用于指定填充掩码图像的值的。但如果flags中间八位的值为0,则掩码会用1来填充。
来自 https://blog.csdn.net/poem_qianmo/article/details/28261997
import cv2
import matplotlib.pyplot as plt
import numpy as np
img1 = cv2.imread('C:\\Work\\application\\test\camera8\\STC-MBS500U3V(17JE353).bmp')
copyIma = img1.copy()
h, w = img1.shape[:2]
print(h, w)
mask = np.zeros([h+2, w+2], np.uint8)
plt.subplot(2, 1, 1)
plt.imshow(img1, cmap='gray')
retval, image, mask, rect = cv2.floodFill(img1, mask, (1480, 1443),
(0, 0, 0), (4, 4, 4), (20, 20, 20))
plt.subplot(2, 1, 2)
plt.imshow(image, cmap='gray')
plt.show()