C++ OpenCV基于距离变换与分水岭的图像分割

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

图像分割

图像分割,英文名image segmentation,就是把图像分成若干个特定的、具有独特性质的区域并提出感兴趣目标的技术和过程。它是由图像处理到图像分析的关键步骤。现有的图像分割方法主要分以下几类:

  • 基于阈值的分割方法

  • 基于区域的分割方法

  • 基于边缘的分割方法以及基于特定理论的分割方法

从数学角度来看,图像分割是将数字图像划分成互不相交的区域的过程。图像分割的过程也是一个标记过程,即把属于同一区域的像索赋予相同的编号。

a4d919f2e61a574b2ed640050f04ffa2.jpeg

  • 图像分割的目标是将图像中像素根据一定的规则分为若干个(N)个cluster集合,I每个集合包含一类像素。

  • 根据算法分为监督学习算法和无监督学习算法,图像分割的算法多数都是无监督学习算法。---KMeans

距离变换与分水岭介绍

距离变换

08aea47c32a39a04675424d53b5b556c.jpeg

距离变换常见算法有两种

  • 不断膨胀/ 腐蚀得到

  • 基于倒角距离

分水岭变换

9a68ea5e16a06fac3ceb006a391179f4.jpeg

分水岭变换常见的算法

基于浸泡理论实现

相关API

        cv::distanceTransform(

                InputArray  src, 

                OutputArray dst,  

                OutputArray  labels,  

                int  distanceType,  

                int maskSize,  

                int labelType = DIST_LABEL_CCOMP

        )

distanceType = DIST_L1/DIST_L2,

maskSize = 3x3,最新的支持5x5,推荐3x3、

labels离散维诺图输出,

dst输出8位或者32位的浮点数,单一通道,大小与输入图像一致

        cv::watershed(

                InputArray image, 

                InputOutputArray  markers

        )

操作步骤

  1. 将白色背景变成黑色-目的是为后面的变换做准备

  2. 使用filter2D与拉普拉斯算子实现图像对比度提高,sharp

  3. 转为二值图像通过threshold

  4. 距离变换

  5. 对距离变换结果进行归一化到[0~1]之间

  6. 使用阈值,再次二值化,得到标记

  7. 腐蚀得到每个Peak - erode

  8. 发现轮廓 – findContours

  9. 绘制轮廓- drawContours

  10. 分水岭变换 watershed

  11. 对每个分割区域着色输出结果

代码演示

新建一个项目opencv-0027,配置属性(VS2017配置OpenCV通用属性),然后在源文件写入#include和main方法

这次我们用opencv里面自带的一张图像来实个这个方法

1032ff170ec989d7e944f614b1c2b050.jpeg

运行显示的图像为

6758b03946d4b9e118d77e2073feece9.jpeg

1.将白色背景变成黑色

bfae6a7c8e0417946a029a6e4f97cd1b.jpeg

我们运行看一下

60ee7fed60be8275ad41c799fcc75a77.jpeg

可以看到右边的已经把背景都换为黑色了。

2.使用filter2D与拉普拉斯算子实现图像对比度提高,sharp

be5cf8445eceb4d5d78fa5c6752bb6b6.jpeg

我们再运行看一下,左边的就是生成的结果图,可以看出左边的清晰度更高了一些

fa16c4830c24b3ebc6a56992358d9f53.jpeg3.转为二值图像通过threshold

173e7c49060c1dc348d898fde348c632.jpeg

我们再运行看一下,左边的图像已经让我们转换为二值图像了,也比较清晰

fd295d366046d17b161ebbef47122631.jpeg

4.距离变换

5.对距离变换结果进行归一化到[0~1]之间

因为距离变换看不出任何效果,所以我们把4和5两步放在一起显示

4a8569be2664cff9319282586826ad29.jpeg

我们再运行一下看看执行结果

222ec325bb0722b40b787b42ff188d30.jpeg

6.使用阈值,再次二值化,得到标记

1ca5f8814a96d87fc46897d3e794c13e.png

显示效果为

178ed3a45f81bfb136130cf0a8261b8b.jpeg

7.腐蚀得到每个Peak

效果不太好看,我们需要再进行二值的腐蚀,把上面的代码再修改一下

38a2e5783ef25381df9f1f044cef6fbb.jpeg

我们再看一下运行效果,可以看出来比刚才的效果好很多了

4b6247043a0409d56cfe17badc545012.jpeg

8.标记并且开始查找轮廓

edb255812ebb6e097f90c22ff4c7294d.jpeg

这一步只是查找轮廓,我们接下来绘制查找的轮廓再一起显示出来

9.绘制轮廓

64a2d7aa7cb22afd578807148517cf98.jpeg

上面drawContours和circle最后一个参数都是用了-1,代表着画的轮廓里面进行颜色填充

我们再显示一下看看效果

3d7d26e81dd9704be50f5940c589b7aa.jpeg

看到好像什么也没有,这是因为我们画的轮廓太小了, 我们改一下显示效果

8beaf7c029e281352dece45ed6a22555.png

把最后显示cv::imshow(imgdst,makers*5000)再乘5000,重新看一下显示效果

45c29020b3987a4b952b65f5e5ab8f6a.jpeg

这会儿就可以看到绘制的轮廓出来了

10.分水岭变换

1991630b831691ed52ccc4633c1e9fb2.jpeg

我们看看显示的效果

64afcf3eda9acab76c0dc1489cabab80.jpeg

可以看出,每个轮廓都有明显的区分开了。

11.对每个分割区域着色输出结果

ff16b7d66c45ef1a5a8e7cd9cbcfcfd8.jpeg

3808cd7c351fdbeb369a2ea91dfcb1f4.jpeg

然后我们再运行看到最后结果

a1ea3dec837f0f4b4734c9b9ac1750fb.jpeg

 
 

好消息!

小白学视觉知识星球

开始面向外开放啦👇👇👇

 
 

3c7b946a48226b7b496a3a6d4ee0fb82.jpeg

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。


下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。


下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。


交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值