前言
java-opencv分水岭算法示例网上我是没找到java版本的教程。另外网上搜关于#基于分水岭算法的图像分割用法的教程基本都是官网基于那个有粘连的硬币分割图的。因为python语法简介灵活很多,移植到java的话稍不注意就会没那个效果的还不好排查,试了很多次才复现出示例的那个效果。教程很多我就不写明细了,说下例子了解的东西吧。理论我是不懂的想了解的网上找教程。
关键点在这个步骤上
- 联通函数返回物体个数和对应的掩码(ret个数,markers的坐标值其实的是个数的序号0,1,2,3最大值是ret;0算是背景)
- markers[unknown==255] = 0;这步是个关键只是python语法太简洁,unknown来源就是背景(膨胀)-前景(腐蚀)的到的,把得到的联通域中之前的未知部分变为分水岭的未知区域。
1 | ini复制代码 #Marker labelling` |
流程了解的东西也不知道对不对
- 图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果,二值化后的图片是单通道的。
1 | scss复制代码//背景黑色前景白色THRESH_OTSU自动二值化 |
2.形态学处理,二值化后由于图像存在一些噪声(即白色的点)。所以需要形态学的开运算:腐蚀与膨胀平滑边界消除一些白点。
1 | ini复制代码Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3,3)); |
3.得到背景、前景、未知区域。 膨胀是内容变大背景变小,物体边界增加到背景肯定是背景;腐蚀是内容变小,背景变大,这部分内容肯定是内容;然后膨胀后的图像-腐蚀后的=得到未知区域(如果物体不相连的话应该就是所谓的边界)。这个未知区域后面会用到
1 | ini复制代码Mat sure_bg=new Mat(); |
- 物体有相连接的部分需要用到距离变换,注意这里要使用第二次二值化处理。
1 | ini复制代码//上次开运算得到的 |
- 使用分水岭算法
markers = markers+1因为分水岭中0是未知区域
makrers在java中里面坐标表示的图像的个数
markers[unknown==255] = 0把上面得到的未知区域,在得到的连通域中表示为未知的地方
unknown是第一次得到的背景-第二次二值化的大前景
1 | css复制代码int count=Imgproc.connectedComponents(sure_fg2,mask); |
本文转载自: 掘金