传统图像分割算法-基于区域的分割算法
这类方法按照图像的相似性准则划分不同的区域块。其中较为典型的方法优:种子区域生长法、分水岭法、区域分裂合并法。
种子区域生长法:首先通过一组表示不同区域的种子像素开始,逐步合并与种子周围相似的像素,从而扩大区域,直到无法合并像素点或者区域为止。这个相似性度量可以采用平均灰度值、纹理、颜色等信息。该方法的关键就是如何选择初始的种子像素以及生长准则。
区域分裂合并法:该方法首先要确定分裂合并的准则,然后对图像进行分裂(1->4;4->16...),直到相邻区域满足一致性特征时,将他们合并为一个大区域,直到所有区域不满足分裂合并准则为止。分裂的最差一种情况就是,分裂到单个像素级别,这就类似种子区域生长法了,合并与种子周围相似的像素。但是该方法不同于种子生长法,该方法可以从一个大的区域开始生长,而种子区域生长法只能从一个像素开始。
分水岭法:我们可以获取到图像中某个区域的中的最小灰度值(局部极小值),而这个像素点与周围的环境形成一个集水盆。而这个算法要做的就是不停的像这个集水盆中倒水,如果水位达到一定高度就会溢出,我们在这个溢出的位置修建堤坝。重复这个过程,知道图像中的所有点都被淹没,这时候所建立的堤坝就是分开各个盆地的分水岭。从而实现了图像的分割。该方法对于弱边缘有着较好的分割,但是图像中的噪声会造成过分割现象。
基于种子区域生长法Code实现:
import numpy as np import cv2 #首先是区域生长一些函数的定义: class Point(object): def __init__(self,x,y): self.x = x self.y = y def getX(self): return self.x def getY(self): return self.y def getGrayDiff(img,currentPoint,tmpPoint): return abs(int(img[currentPoint.x,currentPoint.y]) - int(img[tmpPoint.x,tmpPoint.y])) def selectConnects(p): if p != 0: connects = [Point(-1, -1), Point(0, -1), Point(1, -1), Point(1, 0), Point(1, 1), \ Point(0, 1), Point(-1, 1), Point(-1, 0)] else: connects = [ Point(0, -1), Point(1, 0),Point(0, 1), Point(-1, 0)] return connects def regionGrow(img,seeds,thresh,p = 1): height, weight = img.shape seedMark = np.zeros(img.shape) seedList = [] for seed in seeds: seedList.append(seed) label = 1 connects = selectConnects(p) while(len(seedList)>0): currentPoint = seedList.pop(0) seedMark[currentPoint.x,currentPoint.y] = label for i in range(8): tmpX = currentPoint.x + connects[i].x tmpY = currentPoint.y + connects[i].y if tmpX < 0 or tmpY < 0 or tmpX >= height or tmpY >= weight: continue grayDiff = getGrayDiff(img,currentPoint,Point(tmpX,tmpY)) if grayDiff < thresh and seedMark[tmpX,tmpY] == 0: seedMark[tmpX,tmpY] = label seedList.append(Point(tmpX,tmpY)) return seedMark # 创建一个图像 image = np.ones((256, 256)) cv2.circle(image, (256//2, 256//2), int(100), (0,0,0), -1) cv2.circle(image, (256//2, 256//2), int(50), (255,255,255), -1) cv2.imwrite('test.png', 255*image) # 分割中间白色部分 image_copy = image.copy()//255 seeds = [Point(256//2,256//2)] binaryImg = regionGrow(image_copy,seeds,1) cv2.imwrite('test1.png', 255 * binaryImg)
结果:
原图 | 结果 |
![]() |
![]() |