影象連通區域標記
阿新 • • 發佈:2018-12-17
由於最近做實驗用到二值影象連通區域(八連通)標記,剛開始的時候為了驗證演算法有效性,用了遞迴的方法(太慢了,而且影象一大就容易棧溢位),最後查看了opencv和MATLAB的實現,做個記錄。(為了簡單說明,以下說明已四連通為例)
掃描法連通區域標記:
例:對於二值影象、四連通
第一次遍歷:
1.建立一個和影象大小一樣的矩陣儲存結果,原圖記為im,結果矩陣記為mask,mask各元素值可初始化為0. 從上到下,從左到右掃描原影象,變數Mark記錄當前賦值
2.若當前訪問畫素座標(i,j)且im[i,j]不為0,訪問mask[i-1][j](若未越界)和mask[i,j-1](若未越界),二者若均為0,Mark++,賦值給當前座標對應的mask. 若其中一個為0,將非0值賦值給mask[i][j]。 若均非0且相等,將mask[i][j]標記為同一類,若不等將二者最小值賦予mask[i][j],同時將二者合併為同一類(並查集)。
第二次遍歷:
根據並查集的內容對區域賦值。
def countRegion(img): [high,width] = np.shape(img) mask = np.zeros_like(img) mark = 0 union = {} for i in range (high): for j in range(width): if i==0 and j==0: if img[i][j]==255: mark=mark+1 mask[i][j]=mark union[mark]=mark if i==0 and j!=0: if img[i][j]==255: left = mask[i][j-1] if left!=0: mask[i][j]=left else: mark = mark +1 mask[i][j]=mark union[mark]=mark if j==0 and i!=0: if img[i][j]==255: up = mask[i-1][j] up_right = mask[i-1][j+1] if up==0 and up_right==0: mark = mark+1 mask[i][j]=mark union[mark]=mark if up==0 and up_right!=0: mask[i][j]=up_right if up_right==0 and up!=0: mask[i][j]=up if up!=0 and up_right!=0: if up==up_right: mask[i][j]=up else: mi = min(up,up_right) mask[i][j]=mi if up<up_right: union[up_right]=up else: union[up]=up_right if i!=0 and j!=0: if img[i][j]==255: up = mask[i-1][j] up_left = mask[i-1][j-1] left = mask[i][j-1] up_right = 0 if j+1<width: up_right = mask[i-1][j+1] ma = max(max(max(up,up_left),up_right),left) if ma==0: mark = mark+1 mask[i][j]=mark union[mark]=mark else: if up==up_right and up_right==up_left and up==left: mask[i][j]=up else: mi = min(min(min(up, up_left), up_right), left) if mi!=0: mask[i][j]=mi if up!=mi: union[up]=mi if up_right!=mi: union[up_right]=mi if up_left!=mi: union[up_left]=mi if left!=mi: union[left]=mi else: n_zero = [] if up!=0: n_zero.append(up) if up_left!=0: n_zero.append(up_left) if up_right!=0: n_zero.append(up_right) if left!=0: n_zero.append(left) mi1 = min(n_zero) mask[i][j]=mi1 for it in n_zero: if it!=mi1: union[it]=mi1 for i in range(high): for j in range(width): key = mask[i][j] if key!=0: while union[key]!=key: key = union[key] mask[i][j]=key return mask
八鄰域連通區域標記Python實現
參考:MATLAB,opencv連通區域標記演算法