图像连通区域标记
由于最近做實(shí)驗(yàn)用到二值圖像連通區(qū)域(八連通)標(biāo)記,剛開始的時(shí)候?yàn)榱蓑?yàn)證算法有效性,用了遞歸的方法(太慢了,而且圖像一大就容易棧溢出),最后查看了opencv和MATLAB的實(shí)現(xiàn),做個(gè)記錄。(為了簡單說明,以下說明已四連通為例)
掃描法連通區(qū)域標(biāo)記:
例:對于二值圖像、四連通
第一次遍歷:
1.建立一個(gè)和圖像大小一樣的矩陣保存結(jié)果,原圖記為im,結(jié)果矩陣記為mask,mask各元素值可初始化為0. 從上到下,從左到右掃描原圖像,變量Mark記錄當(dāng)前賦值
2.若當(dāng)前訪問像素坐標(biāo)(i,j)且im[i,j]不為0,訪問mask[i-1][j](若未越界)和mask[i,j-1](若未越界),二者若均為0,Mark++,賦值給當(dāng)前坐標(biāo)對應(yīng)的mask. 若其中一個(gè)為0,將非0值賦值給mask[i][j]。 若均非0且相等,將mask[i][j]標(biāo)記為同一類,若不等將二者最小值賦予mask[i][j],同時(shí)將二者合并為同一類(并查集)。
第二次遍歷:
根據(jù)并查集的內(nèi)容對區(qū)域賦值。
?
?
def countRegion(img):[high,width] = np.shape(img)mask = np.zeros_like(img)mark = 0union = {}for i in range (high):for j in range(width):if i==0 and j==0:if img[i][j]==255:mark=mark+1mask[i][j]=markunion[mark]=markif i==0 and j!=0:if img[i][j]==255:left = mask[i][j-1]if left!=0:mask[i][j]=leftelse:mark = mark +1mask[i][j]=markunion[mark]=markif 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+1mask[i][j]=markunion[mark]=markif up==0 and up_right!=0:mask[i][j]=up_rightif up_right==0 and up!=0:mask[i][j]=upif up!=0 and up_right!=0:if up==up_right:mask[i][j]=upelse:mi = min(up,up_right)mask[i][j]=miif up<up_right:union[up_right]=upelse:union[up]=up_rightif 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 = 0if 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+1mask[i][j]=markunion[mark]=markelse:if up==up_right and up_right==up_left and up==left:mask[i][j]=upelse:mi = min(min(min(up, up_left), up_right), left)if mi!=0:mask[i][j]=miif up!=mi:union[up]=miif up_right!=mi:union[up_right]=miif up_left!=mi:union[up_left]=miif left!=mi:union[left]=mielse: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]=mi1for it in n_zero:if it!=mi1:union[it]=mi1for 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]=keyreturn mask八鄰域連通區(qū)域標(biāo)記Python實(shí)現(xiàn)
參考:MATLAB,opencv連通區(qū)域標(biāo)記算法
總結(jié)
- 上一篇: 125、新技术之微前端
- 下一篇: 计算机思维导论raptor实验报告,计算