C++ OpenCV图像分割之分水岭分割

前言

前面我们说了两种分割方法,这一章我们说图像的分水岭分割。分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特征。

API介绍

void watershed( InputArray image, InputOutputArray markers );

参数说明:

image:   必须是一个8bit 3通道彩色图像矩阵序列

markers: 在执行分水岭函数watershed之前,必须对第二个参数markers进行处理,它应该包含不同区域的轮廓,每个轮廓有一个自己唯一的编号,轮廓的定位可以通过Opencv中findContours方法实现,这个是执行分水岭之前的要求。算法会根据markers传入的轮廓作为种子(也就是所谓的注水点),对图像上其他的像素点根据分水岭算法规则进行判断,并对每个像素点的区域归属进行划定,直到处理完图像上所有像素点。而区域与区域之间的分界处的值被置为“-1”,以做区分。


上面的API函数非常简单,但是参数里面第二个说了在需要进行轮廓的提取,所以说在做分水岭操作之前,我们要结合以前学过的知识对图像进行先一步的处理如   均值滤波----变成灰度图---二值化---形态学操作---查找轮廓等

代码演示

我们再新建一个项目名为opencv--Matting,按照配置属性(VS2017配置OpenCV通用属性),然后在源文件写入#include和main方法.

C++ OpenCV图像分割之分水岭分割_第1张图片

运行一下看我们的源图

C++ OpenCV图像分割之分水岭分割_第2张图片

上面就是我们的源图,然后我们开始进行图像分割

1.均值漂移算法

C++ OpenCV图像分割之分水岭分割_第3张图片

我们看一下结果,右图上变化不大,就是相当于做了一个简单的模糊

C++ OpenCV图像分割之分水岭分割_第4张图片

2.把图像转为灰度图并进行二值化操作

再运行看一下效果

C++ OpenCV图像分割之分水岭分割_第5张图片

3.图二值化图像进行距离变化并归一化显示出来

C++ OpenCV图像分割之分水岭分割_第6张图片

运行效果

C++ OpenCV图像分割之分水岭分割_第7张图片

4.将变换后的重新二值化显示出来

运行效果

C++ OpenCV图像分割之分水岭分割_第8张图片

5.定义markers并划到新的Mat里面

C++ OpenCV图像分割之分水岭分割_第9张图片

6.对源图进行形态学操作,去掉干扰,让效果更好

7.将生成的markers进行分水岭转换

C++ OpenCV图像分割之分水岭分割_第10张图片

8.生成随机颜色,并填充颜色,在新的图像中画出来后看一下分割的效果

C++ OpenCV图像分割之分水岭分割_第11张图片

C++ OpenCV图像分割之分水岭分割_第12张图片

9.显示最后填充的图片并打印出一共多少个

C++ OpenCV图像分割之分水岭分割_第13张图片


我们来看一下运行效果

C++ OpenCV图像分割之分水岭分割_第14张图片

可以看到上面已经把所有的颜色都区分开了,我们再看一下输入的轮廓数,下面打印出来的就是14个,也和我们图片中是一样的。

C++ OpenCV图像分割之分水岭分割_第15张图片


-END-

长按下方二维码关注微卡智享

你可能感兴趣的:(算法,opencv,计算机视觉,python,js)