区域生长是指从某个像素出发,按照一定的准则,逐步加入邻近像素,当满足一定的条件时,区域生长终止。区域生长的好坏决定于:
1.初始点(种子点)的选取。
2.生长准则。
3.终止条件。
区域生长是从某个或者某些像素点出发,最后得到整个区域,进而实现目标的提取。
参考代码如下:
import numpy as np
import cv2 as cv
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
#p!=0为8邻域,p=0为4邻域
def regionGrow(img,seeds,thresh,p=0):
height,width=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(4):
tmpX=currentPoint.x+connects[i].x
tmpY=currentPoint.y+connects[i].y
if tmpX<0 or tmpY<0 or tmpX>=height or tmpY>=width:
continue
grayDiff=getGrayDiff(img,currentPoint,Point(tmpX,tmpY))
if grayDiff
分裂合并:从整个图像出发,不断分裂得到各个子区域,然后再把前景区域合并,实现目标提取。分裂合并的假设是对于一幅图像,前景区域由一些相互连通的像素组成。因此,如果把一幅图像分裂到像素级,那么就可以判定该像素是否为前景像素。当所有像素点或者子区域完成判断以后,把前景区域或者像素合并就可得到前景目标。
(1)先把图像分成4个相等的区域。确定一个分裂合并的准则,即区域特征一致性的量度;
(2)分析每个子区域的特征,如果不一致,则将该子区域分成4个相等的区域;
(3)如果相邻的子区域特征一致,则将其合并;
(4)重复(2)(3),直到所有区域不再满足分裂合并的条件为止。
参考代码如下:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
#分裂
def Division_Judge(img,h0,w0,h,w):
area=img[h0:h0+h,w0:w0+w]
mean=np.mean(area)
std=np.std(area,ddof=1)
total_points=0
operated_points=0
for row in range(area.shape[0]):
for col in range(area.shape[1]):
if (area[row][col]-mean)<2*std:
operated_points+=1
total_points+=1
if operated_points/total_points>=0.95:
return False
else:
return True
#双阈值100,200
def Merge(img,h0,w0,h,w):
for row in range(h0,h0+h):
for col in range(w0,w0+w):
if img[row,col]>100 and img[row,col]<200:
img[row,col]=0
else:
img[row,col]=255
def Recursion(img,h0,w0,h,w):
if Division_Judge(img,h0,w0,h,w) and min(h,w)>5:
#左上
Division_Judge(img,h0,w0,int(h0/2),int(w0/2))
#右上
Division_Judge(img,h0,w0+int(w0/2),int(h0/2),int(w0/2))
#左下
Division_Judge(img,h0+int(h0/2),w0,int(h0/2),int(w0/2))
#右下
Division_Judge(img,h0+int(h0/2),w0+int(w0/2),int(h0/2),int(w0/2))
else:
#合并
Merge(img,h0,w0,h,w)
def Division_Merge_Segmented():
img=cv.imread('./imgs/chep.png')
# img=img[40:100,95:155]
img_gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
segemented_img=img_gray.copy()
Recursion(segemented_img,0,0,segemented_img.shape[0],segemented_img.shape[1])
plt.figure()
plt.subplot(131);plt.imshow(img_gray);plt.axis('off')
plt.subplot(132);plt.imshow(img_gray,cmap='gray',vmin=0,vmax=255);plt.axis('off')
plt.subplot(133);plt.imshow(segemented_img,cmap='gray');plt.axis('off')
plt.tight_layout()
plt.show()
if __name__=='__main__':
Division_Merge_Segmented()
结果如下: