3-3-使用分水岭算法对图像进行分割_第1页
3-3-使用分水岭算法对图像进行分割_第2页
3-3-使用分水岭算法对图像进行分割_第3页
3-3-使用分水岭算法对图像进行分割_第4页
3-3-使用分水岭算法对图像进行分割_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

图像分割使用分水岭算法对图像进行分割目录CONTENTS分水岭算法的核心思想分水岭算法对应的函数使用分水岭算法实现图像分割01分水岭算法的核心思想分水岭算法的核心思想(1)分水岭把图像中每一点像素的灰度值理解为该点的海拔高度,每一个局部极小值及其影响区域称为集水盆,而集水盆的边界则形成分水岭。分水岭的概念和形成可以通过模拟浸入过程来说明。在每一个局部极小值位置,刺穿一个小孔,然后把整个模型慢慢浸入水中,随着浸入的加深,每一个局部极小值的影响域慢慢向外扩展,在两个集水盆汇合处构筑大坝,即形成分水岭。分水岭算法的核心思想(2)分水岭计算过程分水岭计算分两个过程:先排序,然后淹没。首先对每个像素的灰度级进行从低到高排序,然后在从低到高实现淹没过程,在该过程中,对每一个局部极小值在h阶高度的影响域采用先进先出(FIFO)结构进行判断及标注。02分水岭算法对应的函数分水岭算法对应的函数函数markerswatershed(img,markers)其中img是需要分割的图像,必须是一个8位的3通道彩色图像,第二个参数是markers,markers是对图相中区域的标记,图像中可能包含不同的区域,每个区域有一个自己唯一的编号,区域的定位可以通过findContours方法实现,在使用分水岭算法之前需要初始化这个markers。分水岭算法对应的函数函数功能算法会根据markers传入的区域作为种子(也就是所谓的注水点),对图像上其它的像素点根据分水岭算法规则进行判断,并对每个像素点的区域归属进行划定,直到处理完所有的像素点。而区域和区域之间的分界处的值被置为-1,以做区分。参数中的markers必须包含种子点信息,可以通过手工方式标记。分水岭算法执行之后,会返回markers,这里包含了使用-1表示的分界信息。之后可以根据该信息对图像进行分割。03使用分水岭算法实现图像分割使用分水岭算法实现图像分割(1)引入相关包importcv2importnumpyasnp使用分水岭算法实现图像分割(2)加载图片如果图片位置与当前程序在相同的位置,则可以使用下面的相对路径,如果图片不在当前位置,则需要写出来图片的绝对地址。img=cv2.imread('images/mourse.jpg')加载图像之后需要转换为灰度图像:gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)使用分水岭算法实现图像分割(3)转换为二值图像ret,thresh=cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)参数THRESH_BINARY_INV表示大于阈值的像素的值被设置为0,小于阈值的像素的值被设置为255,也就是把亮的部分变成黑的,把暗的部分变成白的,所以适合的场景是目标接近黑色、背景接近白色的场景。THRESH_OTSU表示根据图像的直方图自动计算二值化的阈值,这时候threshold方法中第二个参数使用0。如果自己明确知道使用什么阈值合适,也可以直接指定阈值。使用分水岭算法实现图像分割(4)对图像进行开运算对图像进行开运算,先腐蚀再膨胀,能够去除图像中的部分噪音数据,卷积核kernel的大小和迭代次数iterations都会影响去噪的效果。下面的代码完成了对图像的开运算操作:kernel=np.ones((3,3),np.uint8)opening=cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,iterations=2)上面的开运算使用的核是3*3大小,值都被初始化为1,迭代次数是2,可以根据图像本身的情况调整这些参数来得到更好的效果。二值化图像中右上角的白色区域经过开运算已经不存在了。使用分水岭算法实现图像分割(5)对图像进行闭运算对图像进行闭运算,先膨胀再腐蚀,能够去除图像中的目标中包含的部分噪音数据,卷积核kernel的大小和迭代次数iterations都会影响去噪的效果。closing=cv2.morphologyEx(opening,cv2.MORPH_CLOSE,kernel,iterations=20)开运算使用的核是3*3大小,值都被初始化为1,迭代次数是20,因为前景中包含的黑色区域比较大。可以根据图像本身的情况调整这些参数来得到更好的效果。图是进行闭运算之后的效果。从图中可以看出经过开运算之后目标内部的黑色区域已经不存在了。使用分水岭算法实现图像分割(6)得到背景区域对闭运算的结果进行膨胀,这样就增加了前景(白色)占用的空间,剩下的黑色部分大部分就应该是背景了。sure_bg=cv2.dilate(opening,kernel,iterations=3)这里使用的核还是前面进行开运算的核,迭代次数为3。运行的效果,黑色区域就是背景部分了。使用分水岭算法实现图像分割(7)获取前景区域通过distanceTransform获取前景区域,先介绍一下该函数的用法。函数distanceTransform()用于计算图像中每一个非零点像素与其最近的零点像素之间的距离,输出的是保存每一个非零点与最近零点的距离信息。这样,越靠近背景的区域值越小,距离背景越远的区域值越大,结果图像上越亮的点,代表了离零点的距离越远。它的主要用途:可以根据距离变换的这个性质,经过简单的运算,用于细化字符的轮廓和查找物体质心(中心)。使用分水岭算法实现图像分割(7)获取前景区域函数的定义如下:dist_transform=cv2.distanceTransform(src,distanceType,maskSize)src是要进行距离转换的原始图像distanceType表示距离的计算方式参数maskSize表示距离变换掩膜大小,取值3或者5。使用分水岭算法实现图像分割distanceType的值cv2.DIST_L1,相当于1,距离的计算公式:|x1-x2|+|y1-y2|,曼哈顿距离cv2.DIST_L2,相当于2,简单的欧式距离;cv2.DIST_C,相当于3,距离的计算公式:max(|x1-x2|,|y1-y2|);DIST_L12,相当于4,距离的计算公式:2(sqrt(1+x*x/2)-1));cv2.DIST_FAIR,相当于5,距离的计算公式:c^2(|x|/c-log(1+|x|/c)),c=1.3998;cv2.DIST_WELSCH,相当于6,距离的计算公式:c^2/2(1-exp(-(x/c)^2)),c=2.9846;cv2.DIST_HUBER,相当于7,距离的计算公式:|x|<c?x^2/2:c(|x|-c/2),c=1.345;使用分水岭算法实现图像分割(7)获取前景区域通过distanceTransform得到了闭操作的结果对应的距离变换图形dist_transform=cv2.distanceTransform(closing,cv2.DIST_L2,5)cv2.DIST_L2表示距离的计算采用的是欧氏距离,maskSize的大小是5。dist_transform中值越大越可能是前景,下面的代码通过二值化操作获取前景区域:ret,sure_fg=cv2.threshold(dist_transform,0.3*dist_transform.max(),255,0)代码中使用0.3*dist_transform.max()得到区域相对比较大,如果希望得到的区域比较小,可以把0.3替换成更大的值,如果希望得到较大的区域,可以把0.3替换成较小的值。效果图展示的是0.3对应的前景的大小。使用分水岭算法实现图像分割(8)得到重合区域使用sure_bg与sure_fg相减,得到既有前景又有背景的重合区域:sure_fg=np.uint8(sure_fg)unknow=cv2.subtract(sure_bg,sure_fg)此时显示的白色部分既可能是前景(目标区域)也可能是背景。图中显示了运行结果,中间的白色圆环就是重合区域,实际上就是目标和背景之间的连接部分。使用分水岭算法实现图像分割(9)创建标签为前景创建标签,标签与原图像大小相同,数据类型为int32的数组。对于已经确定分类的区域,也就是背景和前景,使用整数标记,不确定的区域用0标记。可以使用connectedComponents函数完成该功能使用分水岭算法实现图像分割(9)创建标签ret,markers=cv2.connectedComponents(sure_fg)该方法将背景标记为0,把其他标记为从1开始的正整数。但是如果背景标记为0,那么分水岭算法会将其当成位置区域,所以使用1来表示背景,对于不确定的区域标记为0,下面的代码完成了该设置:markers=markers+1markers[unknow==255]=0使用分水岭算法实现图像分割(10)调用分水岭算法markers=cv2.watershed(img,markers)使用绿色标记分水岭:img[markers==-1]=[0,255,0]使用分水岭算法实现图像分割#导入库importnumpyasnpimportcv2#读取图像img=cv2.imread('images/mouse.jpg',1)cv2.imshow('ori',img)#转换为灰度图gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#二值化ret,thresh=cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)cv2.imshow('thresh',thresh)#开运算(去除外部噪声数据)kernel=np.ones((3,3),np.uint8)opening=cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel,iterations=2)cv2.imshow('opening',opening)使用分水岭算法实现图像分割#闭运算(去除内部噪声数据)closing=cv2.morphologyEx(opening,cv2.MORPH_CLOSE,kernel,iterations=20)cv2.imshow('closing',closing)#膨胀后确定的背景区域sure_bg=cv2.dilate(closing,kernel,iterations=3)cv2.imshow('sure_bg',sure_bg)#通过距离变换换数得到前景区域dist_transform=cv2.distanceTransform(closing,1,5)ret,sure_fg=cv2.threshold(dist_transform,0.3*dist_transform.max(),255,0)cv2.imshow('sure_fg',sure_fg)#找到连接区域(不确定区域)sure_fg=np.uint8(sure_fg)unknown=cv2.subtract(sure_bg,sure_fg)cv2.imshow('unknown',unknown)使用分水岭算法实现图像分割#标记标签ret,markers1=cv2.connectedComponents(sure_fg)#为所有标签加上1,这样背景就是1了不是0了markers=markers1+1#把位置区域标记为0markers[unknown==255]=0#调用分水岭算法进行计算markers3=cv2.watershed(img,markers)#使用绿色来标记分割线img[markers3==-1]=[0,255,0]cv2.imshow("img",img)#关闭窗

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论