qcustomplot清除已绘制图像_【图像处理】OpenCV系列二十四 --- 漫水填充(floodFill)详解...

上一节我们学习了用如何用findContours函数对图像查找轮廓,以及用drawContours函数对查找的轮廓进行绘制,相信大家学习之后,对图像轮廓已经有了基本的认识,本节呢,我们对漫水填充算法(floodFill)进行详细的理解!

一、漫水填充函数详解

1、函数原型

int floodFill(InputOutputArray image, Point seedPoint,  Scalar newVal,  CV_OUT Rect* rect = 0, Scalar loDiff = Scalar(),  Scalar upDiff = Scalar(), int flags = 4);int floodFill(InputOutputArray image,  InputOutputArray mask, Point seedPoint,  Scalar newVal,  CV_OUT Rect* rect = 0, Scalar loDiff = Scalar(),  Scalar upDiff = Scalar(), int flags = 4);

2、函数功能

用指定的颜色从种子点(参数中 seedPoint 为种子点)开始填充连通的元素;

在以下情况下,(x,y) 处的像素被视为重新绘制的区域:

(1)在灰度图像和浮动范围的情况下

1a517245c2ed54f25c514b6e8dfc22d7.png

在灰度图像和浮动范围的情况下

(2)在灰度图像和固定范围的情况下

a1c4304f6df33ed287daf1efda662724.png

在灰度图像和固定范围的情况下

(3)在彩色图像和浮动范围的情况下

8b76e5aadab7db7ccb7022de9d800a13.png

在彩色图像和浮动范围的情况下

(4)在彩色图像和固定范围的情况下

50140fbf7f6d91716d3eb8cbd79917bd.png

在彩色图像和固定范围的情况下

其中 src(x′,y′) 已知属于该元素的像素邻域之一的值 。也就是说,要添加到连接的元素中,像素的颜色/亮度应该足够接近于:

(1)在浮动范围内,已属于已连接元素的邻域之一的颜色/亮度;

(2)在固定范围内种子点的颜色/亮度。

使用这些函数标记具有指定颜色的连接要素,或构建掩码,然后提取轮廓,或将区域复制到其他图像,以此类推。

3、参数详解

  • 第一个参数,InputOutputArray image,输入/输出图像,这个图像可以是单通道或者三通道图像,也可以是8位或者32位浮点图像;图像会被函数修改,如果在重载的函数中设置FLOODFILL_MASK_ONLY标志,图像不会被修改;
  • 第二个参数,InputOutputArray mask,操作的掩码图像,一般为8位单通道图像,比图像(image)宽两个像素,高两个像素;由于这个mask输一个输入/输出参数,所以必须对这个参数进行初始化,即必须创建一个掩码图像;漫水填充不能跨越输入掩码中的非零像素;例如,边缘检测器输出可以用作掩码,以停止边缘填充;在输出时,对应于图像中填充像素的掩码中的像素设置为1或设置为在标志中指定的值;此外,该函数填充掩码的边框,以简化内部处理;因此,可以在函数的多次调用中使用相同的掩码,以确保填充的区域不重叠;
  • 第三个参数,Point seedPoint,漫水填充的种子点;
  • 第四个参数,Scalar newVal,重新绘制漫水填充区域所用的颜色;
  • 第五个参数,CV_OUT Rect* rect = 0,函数将可选输出参数设置为重绘域的最小边界矩形;
  • 第六个参数,Scalar loDiff = Scalar(),当前选定像素与其连通区中相邻像素中的一个像素,或者与加入该连通区的一个seedPoint像素,二者之间的最大下行差异值;
  • 第七个参数,Scalar upDiff = Scalar(),当前选定像素与其连通区中相邻像素中的一个像素,或者与加入该连通区的一个seedPoint像素,二者之间的最大上行差异值;
  • 第八个参数,int flags = 4,操作标记,前8位包含一个连通的值;默认值4意味着只考虑四个最近邻像素(共享边缘的像素);连通的值为8意味着将考虑8个最近的相邻像素(共享一个角的像素);接下来的8位(8-16)包含一个介于1到255之间的值,用来填充掩码(默认值是1);例如,4 |(255<8)将考虑4个最近的邻居,并填充值为255的掩码。以下附加选项占用较高的位,因此可能会进一步结合使用按位进行填充的连接和掩码填充值。

floodfill填充模式

1、FLOODFILL_FIXED_RANGE ,如果设置,则考虑当前像素与种子像素之间的差异;否则,考虑相邻像素之间的差异(即范围是浮动的)。

2、FLOODFILL_MASK_ONLY ,如果设置,函数不会更改图像(忽略newVal),并且只使用上面描述的标志位8-16中指定的值填充掩码;此选项仅在具有掩码参数的函数变体中才有意义。

二、综合实例

1、实验案例

#include #include #include #include #include using namespace cv;using namespace std;static void help(){ cout << "键盘: " "ESC - 退出程序" "c - 切换彩色与灰度图像" "m - 切换掩码图像" "r - 恢复为原始图像" "s - 不使用" "f - 绝对梯度" "g - 相对梯度" "4 - 4连通域" "8 - 8连通域" << endl;}// 图像Mat image0, image, gray, mask;// 漫水填充的模式int ffillMode = 1;int loDiff = 20, upDiff = 20;// 连通域int connectivity = 4;// 是否是彩色图像int isColor = true;// 是否使用掩码图像bool useMask = false;// 掩码值int newMaskVal = 255;static void onMouse( int event, int x, int y, int, void* ){ // 如果不是左键按下事件,则不处理 if( event != EVENT_LBUTTONDOWN ) return;  // 获取鼠标点击位置的坐标 Point seed = Point(x,y);  int lo = ffillMode == 0 ? 0 : loDiff; int up = ffillMode == 0 ? 0 : upDiff;  // 判断使用哪种方式进行漫水填充 int flags = connectivity + (newMaskVal << 8) + (ffillMode == 1 ? FLOODFILL_FIXED_RANGE : 0);   // 随机取值&255,使得值在0-255之间 int b = (unsigned)theRNG() & 255; int g = (unsigned)theRNG() & 255; int r = (unsigned)theRNG() & 255;  // 图像的颜色,彩色还是灰色 Scalar newVal = isColor ? Scalar(b, g, r) : Scalar(r*0.299 + g*0.587 + b*0.114);  // 彩色图像还是灰度图像 Mat dst = isColor ? image : gray;  int area; Rect ccomp;  // 是否使用掩码图像 if( useMask ) { threshold(mask, mask, 1, 128, THRESH_BINARY);  // 进行漫水填充 area = floodFill(dst, mask, seed, newVal, &ccomp, Scalar(lo, lo, lo), Scalar(up, up, up), flags);  // 显示掩码图像 imshow( "mask
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值