本文首发于“小白学视觉”微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究!


经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《OpenCV 4开发详解》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社沟通,提前在公众号上连载部分内容,请持续关注小白。

漫水填充算法是根据像素灰度值之间的差值寻找相同区域实现分割。我们可以将图像的灰度值理解成像素点的高度,这样一张图像可以看成崎岖不平的地面或者山区,向地面上某一个低洼的地方倾倒一定量的水,水将会掩盖低于某个高度的区域。漫水填充法利用的就是这样的原理,其形式与注水相似,因此被称形象的称为“漫水”。

与向地面注水一致,漫水填充法也需要在图像选择一个注水像素,该像素被称为种子点,种子点按照一定规则不断向外扩散,从而形成具有相似特征的独立区域,进而实现图像分割。漫水填充分割法主要分为3以下三个步骤:

  • Step1:选择种子点(x,y)(x,y)(x,y);
  • Step2:以种子点为中心,判断4邻域或者8邻域的像素值与种子点像素值的差值,将差值小于阈值的像素点添加进区域内。
  • Step3:将新加入的像素点作为新的种子点,反复执行Step2,直到没有新的像素点被添加进该区域。

OpenCV 4提供了floodFill函数用于实现漫水填充法分割图像,该函数有两种函数原型,代码清单8-16中给出其中一种函数原型。

代码清单8-16 floodFill()函数原型1
1.  int cv::floodFill(InputOutputArray  image,
2.                        InputOutputArray  mask,
3.                        Point  seedPoint,
4.                        Scalar  newVal,
5.                        Rect *  rect = 0,
6.                        Scalar  loDiff = Scalar(),
7.                        Scalar  upDiff = Scalar(),
8.                        int  flags = 4
9.                        )
  • image:输入输出图像,图像数据类型可以为CV_8U或者CV_32F的单通道或者三通道图像。
  • mask:掩码矩阵,尺寸比如输入图像的宽和高各大2的单通道图像,用于标记漫水填充的区域。
  • seedPoint:种子点。
  • newVal:归入种子点区域内像素点的新像素值。
  • rect:种子点漫水填充区域的最小矩形边界,默认值为0,表示不输出边界。
  • loDiff:添加进种子点区域条件的下界差值,当邻域某像素点的像素值与种子点像素值的差值大于该值时,该像素点被添加进种子点所在的区域。
  • upDiff:添加进种子点区域条件的上界差值,当种子点像素值与邻域某像素点的像素值的差值小于该值时,该像素点被添加进种子点所在的区域。
  • flags:漫水填充方法的操作标志,其由三部分构成,分别表示邻域种类、掩码像素值和填充算法的规则,填充算法规则可选择的参数在表8-7给出。

表8-3 inpaint()函数修复图像算法可选择标志

标志参数 简记 含义
FLOODFILL_FIXED_RANGE 1<<16 如果设置该参数,则仅考虑当前像素值与初始种子点像素值之间的差值,否则考虑新种子点像素值与当前像素值之间的差异,即范围是否浮动的标志。
FLOODFILL_MASK_ONLY 1<<17 如果设置,该函数不会更改原始图像,即忽略第四个参数newVal,只生成掩码矩阵。

该函数可以根据给定像素点的像素值,寻找邻域内与其像素值接近的区域。该函数的第一个参数既是输入图像又是输出图像,可以是CV_8U或者CV_32F的单通道或者三通道图像。第二个参数是漫水填充的掩码矩阵,非0像素点表示在原图像中被填充的区域。掩码矩阵的宽和高要比原图像的宽和高大2,并且需要在函数之前将该矩阵初始化。函数第三个参数是种子点,可以是图像范围内任意一点。函数第四个参数是被填充像素点的新像素值,该值会直接作用在原图中,对原图进行修改。第五个参数是填充像素的最小矩形区域。第六个和第七个参数是像素点被填充的阈值条件,分别表示范围的下界和上界。最后一个参数是填充方法的操作标志,该标志由三部分组成,第一部分表示邻域的种类,可以选择值为4(表示4-邻域)和8(表示8-邻域);第二部分表示掩码矩阵中表示被填充像素点的像素值;第三部分是填充规则的标志,其可选择的参数在表8-7给出,这三部分可以通过“|”符号连接,例如“4|(255<<8)| FLOODFILL_FIXED_RANGE”。

有时我们并不需要使用掩码矩阵,输入掩码矩阵是对内存资源的浪费,因此OpenCV 4提供了floodFill()函数第二种原型,用于不输出掩码矩阵,代码清单8-17中给出了这种函数原型。

代码清单8-17 floodFill()函数原型2
1.  int cv::floodFill(InputOutputArray  image,
2.                        Point  seedPoint,
3.                        Scalar  newVal,
4.                        Rect *  rect = 0,
5.                        Scalar  loDiff = Scalar(),
6.                        Scalar  upDiff = Scalar(),
7.                        int  flags = 4
8.                        )

函数所有参数的含义与代码清单8-16中的相同,这里不再赘述,不过需要注意的是函数最后一个参数在可选值的范围上有些变换,由于函数不输出掩码矩阵,因此FLOODFILL_MASK_ONLY标志不起任何作用,因此该种函数原型中没有任何意义,甚至可以缺省表示掩码矩阵中被填充像素点的新像素值的第二部分。

为了了解该函数的使用方法以及漫水填充分割的效果,在代码清单8-18中给出了利用floodFill()函数对图像进行分割的示例程序。程序中每一次循环都会随机生成一个像素点,并对这个像素点进行漫水填充,图8-10给出了填充结果和掩码矩阵,同时输出每个像素点的坐标和填充像素点的数目,输出结果如图8-11所示。

代码清单8-18 myFloodfill.cpp漫水填充分割图像
1.  #include <opencv2\opencv.hpp>
2.  #include <iostream>
3.
4.  using namespace cv;
5.  using namespace std;
6.
7.  int main()
8.  {9.      system("color F0");  //将DOS界面调成白底黑字
10.     Mat img = imread("lena.png");
11.     if (!(img.data))
12.     {13.         cout << "读取图像错误,请确认图像文件是否正确" << endl;
14.         return -1;
15.     }
16.
17.     RNG rng(10086);//随机数,用于随机生成像素
18.
19.     //设置操作标志flags
20.     int connectivity = 4;  //连通邻域方式
21.     int maskVal = 255;  //掩码图像的数值
22.     int flags = connectivity|(maskVal<<8)| FLOODFILL_FIXED_RANGE;  //漫水填充操作方式标志
23.
24.     //设置与选中像素点的差值
25.     Scalar loDiff = Scalar(20, 20, 20);
26.     Scalar upDiff = Scalar(20, 20, 20);
27.
28.     //声明掩模矩阵变量
29.     Mat mask = Mat::zeros(img.rows + 2, img.cols + 2, CV_8UC1);
30.
31.     while (true)
32.     {33.         //随机产生图像中某一像素点
34.         int py = rng.uniform(0,img.rows-1);
35.         int px = rng.uniform(0, img.cols - 1);
36.         Point point = Point(px, py);
37.
38.         //彩色图像中填充的像素值
39.         Scalar newVal = Scalar(rng.uniform(0, 255), rng.uniform(0, 255),
40.                                       rng.uniform(0, 255));
41.
42.         //漫水填充函数
43.         int area = floodFill(img, mask, point, newVal, &Rect(),loDiff,upDiff,flags);
44.
45.         //输出像素点和填充的像素数目
46.         cout << "像素点x:" << point.x << "  y:" << point.y
47.             << "     填充像数数目:" << area << endl;
48.
49.         //输出填充的图像结果
50.         imshow("填充的彩色图像", img);
51.         imshow("掩模图像", mask);
52.
53.         //判断是否结束程序
54.         int c = waitKey(0);
55.         if ((c&255)==27)
56.         {57.             break;
58.         }
59.     }
60.     return 0;
61. }

图8-10 myFloodfill.cpp程序填充结果

OpenCV 4开发详解
往期推荐
【OpenCV 4开发详解】直方图应用
【OpenCV 4开发详解】图像模板匹配
【OpenCV 4开发详解】图像卷积
【OpenCV 4开发详解】图像噪声的种类与生成
【OpenCV 4开发详解】均值滤波
【OpenCV 4开发详解】方框滤波
【OpenCV 4开发详解】高斯滤波
【OpenCV 4开发详解】可分离滤波
【OpenCV 4开发详解】中值滤波
【OpenCV 4开发详解】边缘检测原理
【OpenCV 4开发详解】Scharr算子
【OpenCV 4开发详解】Laplacian算子
【OpenCV 4开发详解】Canny算法
【OpenCV 4开发详解】图像距离变换
【OpenCV 4开发详解】图像连通域分析
【OpenCV 4开发详解】图像腐蚀
【OpenCV 4开发详解】图像膨胀
【OpenCV 4开发详解】形态学应用
【OpenCV 4开发详解】检测直线
【OpenCV 4开发详解】直线拟合
【OpenCV 4开发详解】直线检测
【OpenCV 4开发详解】轮廓发现与绘制
【OpenCV 4开发详解】轮廓面积与长度
【OpenCV 4开发详解】图像矩的计算与应用
【OpenCV 4开发详解】点集拟合
【OpenCV 4开发详解】QR二维码检测
经过几个月的努力,市面上第一本OpenCV 4入门书籍《OpenCV 4开发详解》将春节后由人民邮电出版社发行。如果小伙伴觉得内容有帮助,希望到时候多多支持!
关注小白的小伙伴可以提前看到书中的内容,我们创建了学习交流群,欢迎各位小伙伴添加小白微信加入交流群,添加小白时请备注“学习OpenCV 4”。

【OpenCV 4开发详解】漫水填充法相关推荐

  1. 【OpenCV 4开发详解】分割图像——分水岭法

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  2. 【OpenCV 4开发详解】深度神经网络应用实例

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  3. 【OpenCV 4开发详解】图像修复

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  4. 【OpenCV 4开发详解】分割图像——Mean-Shift分割算法

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  5. 【OpenCV 4开发详解】分割图像——Grabcut图像分割

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  6. 【OpenCV 4开发详解】形态学应用

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  7. 【OpenCV 4开发详解】图像膨胀

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  8. 【OpenCV 4开发详解】图像腐蚀

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  9. 【OpenCV 4开发详解】图像连通域分析

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

最新文章

  1. highcharts图表组件常见问题:highcharts图表组件错误集合分析大放送
  2. ThinkPHP多应用/多模块配置
  3. Linux 升级 Python 至 3.x
  4. contentwindow无法搜索对象_面试官:讲一下Jvm中如何判断对象的生死?
  5. linux下启动solr命令,如何自动启动Solr?
  6. -bash: id: command not found -bash: tty: command not found
  7. 电机的入门之路系列3--直流电机的工作原理
  8. Dom4j SAXReader Constructors
  9. 如何突破网吧禁止下载的限制~?
  10. python有道-Python爬去有道翻译
  11. 开源多云技术平台——Choerodon猪齿鱼发布0.23版本
  12. 计算机的时钟设置错误,谷歌浏览器用不了显示电脑时钟错误解决方法
  13. 莫斯科的年轻人(一)
  14. 每日一狗 · 比利牛斯山犬
  15. 使用电脑时经常遇到问题?来试试这四款小众的实用软件吧
  16. 历届上海电影节获奖名单
  17. 计算机网络-基本概念
  18. frustum pointnets训练代码学习笔记——kitti_object.py
  19. c++里面的protect和public、private有什么区别?
  20. 使用Java实现矩形 平行四边形 等腰三角形 菱形 倒三角

热门文章

  1. AI一分钟 | 华米发布全球首款可穿戴AI芯片;亚马逊年底上线至少8款Alexa设备
  2. 开源用于寻找系外行星的代码
  3. 从AlexNet到DenseNet,再到SENet,一文看懂图像分类领域的突破性进展
  4. Redis 实现限流的三种方式
  5. IDEA 这样配置注释模板,让你高出一个逼格
  6. 用了这么久配置中心,还不知道长轮询是什么?
  7. RabbitMQ 七种队列模式应用场景案例分析(通俗易懂)
  8. JDK1.8源码分析:线程安全的CopyOnWriteArrayList与CopyOnWriteArraySet
  9. 为什么SpringBoot的 jar 可以直接运行?
  10. Spring MVC 到 Spring BOOT 的简化之路