基于区域的图像分割

一、区域生长

区域生长是指从某个像素出发,按照一定的准则,逐步加入邻近像素,当满足一定的条件时,区域生长终止。区域生长的好坏决定于:

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<thresh and seedMark[tmpX,tmpY]==0:
                seedMark[tmpX,tmpY]=label
                seedList.append(Point(tmpX,tmpY))
    return seedMark

img = cv.imread("./imgs/chep.png")
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
#根据灰度直方图确定
# car=gray[40:100,95:195]
car=gray
seeds=[Point(10,10)]
cv.imshow('image',car)
for t in range(1,5):
    binaryImg=regionGrow(car,seeds,t)
    title=str(t)
    cv.imshow(title,binaryImg)
cv.waitKey(0)

二、区域分裂与合并

分裂合并:从整个图像出发,不断分裂得到各个子区域,然后再把前景区域合并,实现目标提取。分裂合并的假设是对于一幅图像,前景区域由一些相互连通的像素组成。因此,如果把一幅图像分裂到像素级,那么就可以判定该像素是否为前景像素。当所有像素点或者子区域完成判断以后,把前景区域或者像素合并就可得到前景目标。

(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()

结果如下:

猜你喜欢

转载自blog.csdn.net/hu_666666/article/details/127923301
今日推荐