作者:RayChiu_Labloy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
定义:
泛洪填充算法又称洪水填充算法是在很多图形绘制软件中常用的填充算法,最熟悉不过就是windows paint的油漆桶功能。算法的原理很简单,就是从一个点开始附近像素点,填充成新的颜色,直到封闭区域内的所有像素点都被填充新颜色为止。因为其思路类似洪水从一个区域扩散到所有能到达的区域而得名。在围棋(Go)和扫雷中,Flood Fill算法被用来计算需要被清除的区域。
分类
泛红填充实现根据是否考虑在连接角落处接触的节点最常见有四邻域像素填充法,八邻域像素填充法和基于扫描线的像素填充方法。
根据实现又可以分为递归与非递归(基于栈)。
四邻域泛洪
寻找像素点(x, y)的上下左右四个临近像素点,如果没有被填充,则填充它们,并且继续寻找它们的四邻域像素,直到封闭区域完全被新颜色填充。
八邻域泛洪
在四邻域的基础上增加了左上,左下,右上,右下四个相邻像素。并递归寻找它们的八邻域像素填充,直到区域完全被新颜色填充。
描绘线算法(Scanline Fill)
利用填充线来加速算法, 它不是在堆栈上推动每个潜在的未来像素坐标,而是检查相邻线(前一个和下一个)以找到可能在未来通过中填充的相邻段, 线段的坐标(开始或结束)被推到堆栈上。 在大多数情况下,该扫描线算法至少比每像素算法快一个数量级。
该算法的过程是:先将一条线上的像素点进行着色,然后依次向上下扩张,直到着色完成。
相关函数:floodFill()
OpenCV中有两个版本的漫水填充函数:一个不带mask的版本,和一个带mask的版本。这个掩膜mask,就是用于进一步控制哪些区域被填充颜色(比如对同一图像进行多次填充时)。这两个版本的相同点是:都必须在图像中选择一个种子点,然后把邻近区域所有相似点填充上同样的颜色。不同的是,不一定将所有的临近像素点都染上同一颜色。漫水填充操作的结果总是某个连续的区域。当临近像素点位于给定的范围(从loDiff到uoDiff)内或者在原始种子点像素值范围内时,就会涂上颜色。
看下带掩膜的:
int floodFill(InputArray image, InputArray mask, Point seedPoint, Scalar newVal, Rect* rect=0,Scalar ioDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4)
关于参数解释:
- 第一个参数:输入图像,1个或3个通道的8位或浮点图像。
- 第二个参数:InputArray类型的mask,只有第二个版本才有该参数,表示作为掩膜。它应该是单通道,8位,长和宽都比输入图像大两个点的图像。因为漫水填充需要使用以及更细掩膜,所以对这个mask参数,我们一定要将其准本好并填在此处。需要注意的是,漫水填充不会填充mask的非零像素区域。例如,一个边缘检测算子的输出可以用来作为掩膜,以防止填充到边缘。同样的,也可以在多次的函数调用中使用同一个掩膜,以保证填充的区域不会重叠。需要注意的是,mask会比需填充的图像大,所以mask与输入图像(x, y)像素点对应的坐标为(x,+1 y+1)。
- 第三个参数:Point类型的seedPoint,漫水填充算法的起始点。
- 第四个参数:Scalar类型的newVal,像素被染色的值。
- 第五个参数:Rect*类型的rect,默认值是0,可选参数,用于设置floodFill函数将要重绘区域的最小边界矩形区域。
- 第六个参数:Scalar类型loDiff,默认值是Scalar(),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之负差的最大值。
- 第七个参数:Scalar类型upDiff,默认值是Scalar(),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之正差的最大值。
- 第八个参数:int类型的flags,操作标志符。
测试
测试图片:
C++测试代码:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>using namespace std;
using namespace cv;int main() {Mat srcImage;srcImage = imread("/Users/dwz/Desktop/cpp/b.jpg");Rect ccomp;floodFill(srcImage,Point(150, 150), Scalar(0, 0, 255), &ccomp, Scalar(20, 20, 20),Scalar(20, 20, 20));imwrite("floodfill.jpg", srcImage);return 0;
}
效果:
本文参考:图像分割经典算法--《泛洪算法》(Flood Fill)_mmm_jsw的博客-CSDN博客
【如果对您有帮助,交个朋友给个一键三连吧,您的肯定是我博客高质量维护的动力!!!】