学习建设网站,内蒙古创意网站开发,找客户的十大方法,企业成本解决方案区域增长算法
目标
掌握区域生长法的基本思想掌握图像分裂合并分割的基本思想及步骤
区域生长法分割
大津算法的局限性#xff1a;噪声比较严重的图片、分割目标颜色渐变的情况#xff0c;分割效果差。 区域生长#xff1a;从种子点开始#xff0c;按照一定准则#x…区域增长算法
目标
掌握区域生长法的基本思想掌握图像分裂合并分割的基本思想及步骤
区域生长法分割
大津算法的局限性噪声比较严重的图片、分割目标颜色渐变的情况分割效果差。 区域生长从种子点开始按照一定准则如相邻像素灰度相似性向周围扩散将邻域相似像素加入区域中。 按照扩散顺序分为广度优先搜索优先比较原像素所有周边像素和深度优先搜索比较原像素某一特定方向的像素。
区域生长实现步骤
对图像顺序扫描。找到第1个还没有归属的像素设像素为(x0,y0x_0,y_0x0,y0);以(x0,y0x_0,y_0x0,y0)为中心考虑(x0,y0x_0,y_0x0,y0)的8邻域像素(x,y)(x,y)(x,y)如果(x,y)(x,y)(x,y)满足生长准则将(x,y)(x,y)(x,y)与(x0,y0x_0,y_0x0,y0)合并同时将(x,y)(x,y)(x,y)压入堆栈从堆栈中取出一个像素把它当作(x0,y0)(x_0,y_0)(x0,y0)返回到步骤2当堆栈为空时返回步骤1重复步骤1-4直到图像中的每个点都有归属时生长结束。
区域分裂合并
图像分裂分裂合并可采用基于四叉树的数据表示 对于像素方差不大的区域不用分裂像素方差大的区域进行分裂。将相邻像素的区域进行合并。 实现步骤
对区域分裂合并法无需预先指定种子点它按某种一致性准则分裂或合并区域可以先进行分裂运算然后再进行合并运算也可以分裂和合并运算同时进行经过连续的分裂和合并最后得到图像的精确分割效果。分裂合并法对分割复杂的场景图像比较有效。
总结
区域生长法基于相邻像素间的相似性由种子像素逐步生长得到分裂-合并基于图像块内在的相似性通过不断分裂得到区域外边界通过合并将不同块连接
分水岭算法
目标
掌握分水岭算法的基本思想了解分水岭算法的运行步骤
分水岭算法分割
如果以图像位置(x,y)(x,y)(x,y)为坐标则图像(x,y)(x,y)(x,y)可以看作是地形俯视图其中“山峰的高度”与图像中的灰度值对应。假设在每个“盆地”的最低点开始打洞让水漫上来并且让水以均匀速率上升那么当不同“盆地”的水开始汇聚时能通过修建一个“水坝”挡住这种聚合的弧线就是图像的分界线。 在漫水过程中存在三种类型的点局部极小值点该点对应一个盆地的最低点当我们在盆地滴一滴水的时候由于重力作用水最终会汇聚到该点。注意可能存在一个最小值面该平面内都是最小值点。盆地的其它位置点该位置滴的水滴会汇聚带局部最小点。盆地的边缘点是该盆地和其它盆地交接点在该点滴一滴水会等概率的流向任何一个盆地。
符号 T[n]T[n]T[n]满足灰度nnn的所有图像点的集合 C(Mi)C(M_i)C(Mi)与区域最小值集合MiM_iMi相联系的盆地图像点集合 C[n]C[n]C[n]在第n阶灰度计算的图像区域集合C[n]∪i1RCn(Mi)C[n] \cup_{i1}^RC_n(M_i)C[n]∪i1RCn(Mi) 目标迭代计算C[n]C[n]C[n]进一步获得区域分割线(水坝) 步骤
初始化从最低水面(最低灰度对应的点集)开始对应C[min1]T[min1]C[min1] T[min1]C[min1]T[min1]迭代计算由C[n−1]C[n-1]C[n−1]计算C[n]C[n]C[n] 令QQQ表示T[n]T[n]T[n]中连通分量的点集。对每个分量q∈Qq\in Qq∈Q如下处理 (1)q∩C[n−1]∅q\cap C[n-1]\varnothingq∩C[n−1]∅:发现新的区域连通分量q并入C[n]C[n]C[n] (2)q∩C[n−1]q\cap C[n-1]q∩C[n−1]:填充未溢出(到别的盆地)连通分量q并入C[n]C[n]C[n] (3)q∩C[n−1]q\cap C[n-1]q∩C[n−1]包含C[n−1]C[n-1]C[n−1]中的多个分量填充溢出在q内构筑水坝方法同前
分水岭算法的过分割问题 由于噪声或者其它干扰因素的存在使用分水岭算法常常存在过度分割的现象这是因为很多很小的局部极值点的存在。 在初始时给marker改善过分割问题 为了解决过分割的问题可以使用基于标记mark图像的分水岭算法就是指定mark图像(图中红色区域)在这个区域的洪水淹没过程中水平面都是定义的marker开始的这样可以避免一些很小的噪声极值区域的分割。 使用marker改善分割结果:
总结
分水岭算法基本思想来源于由低到高漫水和“修建水坝”。分割过程通过漫水和膨胀按照不同灰度级迭代进行。
图像分割实战演练(II)
目标
使用OpenCV实现区域漫水填充使用OpenCV实现分水岭分割
相关函数
漫水填充(区域生长法)
retval, image, mask, rect cv2.floodFill(image, mask, seedPoint, newVal[, loDiff[, upDiff[, flags]]])
#image:输入图像可以是一通道或者是三通道。
#mask:操作掩膜。 单通道8位在长宽上都比原图像image多2个像素点。漫水填充不会填充掩膜区域的非0像素点所以说掩膜是屏蔽了漫水填充的处理。如边缘检测算子的输出可以用来作为掩膜这样可防止边缘区域不被填充。因为掩膜比原图像大所以掩膜中的(x,y)对应的原图像的像素点为(x1,y1)。
#seedPoint:Point类型漫水填充的种子点即起始点。
#newVal:Scalar类型被填充的像素点新的值
#rect:Rect*类型有默认值0可选的参数设置函数将要重绘区域的最小边界矩形区域
#loDiffScalar类型有默认值Scalar()表示当前的观察点像素值与其相邻区域像素值或待加入该区域的像素之间的亮度或颜色之间负差(lower brightness/color difference)的最大值。
#upDiff:Scalar类型有默认值Scalar()表示当前的观察点像素值与其相邻区域像素值或待加入该区域的像素之间的亮度或颜色之间正差(lower brightness/color difference)的最大值。
#flags:int类型操作位标识符包括三个部分,控制算法连通性等
# 1.低八位0-7控制算法的连通性设置为4填充算法只考虑当前像素点垂直和水平方向设置为8除垂直和水平方向还会考虑对角线的相邻点
# 2.高八位(16-23)可以为0或者下列两种标识符组合。# FLOODFILL_FIXED_RANGE:考虑种子像素与种子像素之间的差否则考虑当前像素与与邻近像素的差。# FLOODFILL_MASK_ONLY :如果设置这个标识符函数不会填充或改变原始图像也就是忽略的newVal而是去填充掩膜图像。# 3.中间八位用于指定填充掩码图像的值如果flags中间八位值为0则掩码会用1填充分水岭法图像分割
makers cv2.watershed(image, markers)
#image三联通彩色图像
#markers记号点(种子点)每一个记号需要有不同的编号解决思路
图像采集(取到图像)图像预处理使用距离变换或计算图像梯度得到分水岭处理图像应用分水岭算法分割图像特征描述及目标分析得到最终结果
import cv2
import numpy as npimg cv2.imread(C:/python/img/water_coins.jpg)
gray cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV cv2.THRESH_OTSU)
# noise removal
kernel np.ones((3, 3),np.uint8)
opening cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations 2)#sure background area
sure_bg cv2.dilate(opening, kernel, iterations3)cv2.imshow(threshold,thresh) #阈值化图像
cv2.imshow(Opened image,opening) #开运算图像
cv2.imshow(Dilated image,sure_bg) #膨胀后图像cv2.waitKey()
cv2.destroyAllWindows()读入图像转换为灰度图像使用大津算法二值化使用形态学开运算二次去掉小的白色噪点使用膨胀运算确保背景与原图一致
#Finding sure foreground area
dist_transform cv2.distanceTransform(opening, cv2.DIST_L2, 5)
ret, sure_bg cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0)#Finding unkown region
sure_fg np.uint8(sure_fg)
unkown cv2.subtract(sure_bg, sure_fg)cv2.imshow(dist_ret, dist_transform)
cv2.imshow(threshold, sure_fg)
cv2.imshow(unkown regions, unkown)cv2.waitKey()
cv2.destroyAllWindows()使用距离变换(distance Transform)计算每个硬币中心。采用腐蚀变换可以实现类似效果使用阈值化得到分离的硬币通过相减得到相连接硬币的不确定区域(有待分割计算)
#Marker labelling
ret, markers cv2.connectedComponents(sure_fg)#Add one to all labels so that sure background is noe 0,but 1
markers markers 1
#Now, mark the region of unknown with zero
markers[unkown255]0markers cv2.watershed(img, markers)
img[markers -1] [255, 0, 0]markers np.uint8(markers)cv2.imshow(result image, img)
cv2.imshow(result, markers)cv2.waitKey()
cv2.destroyAllWindows()使用connectedComponents给每个连通区域做标记标记从0开始。0为背景标记值1让标记从1开始不确定区域标记置为0便于下一步分割使用watershed做分水岭标记分割线(水坝)用蓝色标记