原像素矩陣M為:
根據原像素矩陣M大小,初始化標記矩陣labelM:

算法流程
1. 首先要確定是標記8鄰域連通還是4鄰域連通,如果是8鄰域連通,就用模板1,如果是4鄰域連通,就用模板2。中間像素記為目標像素,模版其余像素記為包圍像素。

(1) (2)
2. 若原像素矩陣M中,包圍像素均為0,則labelM中目標像素標記號+1;如果不全為0,則labelM中目標像素標記號取labelM中周圍像素標記號的最小值;將labelM中周圍像素不同標記號的並集記為等價對。
3. 等價對的處理:
假設有如下等價對:
(1,2),(1,6),(3,7),(9-3),(8,1),(8,10),(11,5),(11,8),(11,12),(11,13),(11,14),(15,11)
我們需要得到最終序列是:
最終1-2-5-6-8-10-11-12-13-14-15均標記為1;3-7-9標記為2;4標記為3。
算法的python實現
LableConnectedRagion4( M, labelM, eqLable )用於4鄰域連通,獲得等價對
LableConnectedRagion8( M, labelM, eqLable )用於8鄰域連通,獲得等價對
EquivalentLabelPairs( N, labelM, eqLabel )用於處理等價,並重新編號
1 def EquivalentLabelPairs( N, labelM, eqLable): 2 L={} 3 invalidLabel=[] #the invalid label number in equivalent label pairs 4 for i in range(1, N+1): 5 6 if i in invalidLabel: #if i is an invalid label 7 continue 8 9 L[i]=[] 10 for j in range(0, len(eqLable)): 11 if i in eqLable[j]: 12 invalidLabel.append(max(eqLable[j])) 13 L[i].append(max(eqLable[j])) 14 15 for k in L[i]: #deep search 16 for j in range(0, len(eqLable)): 17 if (k in eqLable[j]) & (max(eqLable[j])!=k): 18 invalidLabel.append(max(eqLable[j])) 19 L[i].append(max(eqLable[j])) 20 21 trueLable = 1 22 for k in L: 23 labelM[labelM==k]=trueLable 24 for labelNo in L[k]: 25 labelM[labelM==labelNo]=trueLable 26 trueLable+=1 27 28 29 def LableConnectedRagion8(M, labelM, eqLabel): 30 row = M.shape[0] 31 col = M.shape[1] 32 33 label = 0 34 R = 0 #the first row 35 for C in range(0, col): 36 if M[R, C]==1: 37 if C==0: 38 label+=1 39 labelM[R, C]=label 40 else: 41 if labelM[R, C-1]!=0: 42 labelM[R, C]=labelM[R, C-1] 43 elif labelM[R, C-1]==0: 44 label+=1 45 labelM[R, C]=label 46 47 for R in range(1, row): #the rest rows 48 for C in range(0, col): 49 if M[R, C]==1: 50 if C==0: #the first column 51 if (M[R-1, C]==0) & (M[R-1, C+1]==0) : 52 label+=1 53 labelM[R, C]=label 54 elif M[R-1, C] + M[R-1, C+1]==1: 55 labelM[R, C]=max(labelM[R-1, C],labelM[R-1, C+1]) 56 else: 57 labelM[R, C]=min(labelM[R-1, C], labelM[R-1, C+1]) 58 if labelM[R-1, C] != labelM[R-1, C+1]: 59 if [labelM[R-1, C], labelM[R-1, C+1]] not in eqLabel: 60 eqLabel.append([labelM[R-1, C], labelM[R-1, C+1]]) 61 62 elif C!=col-1: #columns except the first and the last 63 if M[R-1, C-1]+M[R-1, C]+M[R-1,C+1]+M[R,C-1]==0 : 64 label+=1 65 labelM[R, C]=label 66 elif M[R-1, C-1]+M[R-1, C]+M[R-1,C+1]+M[R,C-1]==1: 67 labelM[R, C]=max(labelM[R-1, C-1], labelM[R-1, C], labelM[R-1,C+1], labelM[R,C-1]) 68 else: 69 listLabelM=[ labelM[R-1, C-1], labelM[R-1, C], labelM[R-1,C+1], labelM[R,C-1] ] 70 listLabelM=list(set(listLabelM)) 71 72 if 0 in listLabelM: 73 listLabelM.remove(0) 74 labelM[R, C]=min(listLabelM) 75 if len(listLabelM)!=1: 76 if listLabelM not in eqLabel: 77 eqLabel.append(listLabelM) 78 79 else: #the last column 80 if M[R-1, C-1]+M[R-1, C]+M[R,C-1]==0 : 81 label+=1 82 labelM[R, C]=label 83 elif M[R-1, C-1]+M[R-1, C]+M[R,C-1]==1: 84 labelM[R, C]=max(labelM[R-1, C-1], labelM[R-1, C], labelM[R,C-1]) 85 else: 86 listLabelM=[ labelM[R-1, C-1], labelM[R-1, C], labelM[R,C-1] ] 87 listLabelM=list(set(listLabelM)) 88 89 if 0 in listLabelM: 90 listLabelM.remove(0) 91 labelM[R, C]=min(listLabelM) 92 if len(listLabelM)!=1: 93 if listLabelM not in eqLabel: 94 eqLabel.append(listLabelM) 95 return label 96 97 98 def LableConnectedRagion4(M, labelM, eqLable): 99 row = M.shape[0] 100 col = M.shape[1] 101 102 labelNo = 0 103 R = 0 104 for C in range(0, col): 105 if M[R, C]==1: 106 if C==0: 107 labelNo+=1 108 labelM[R, C]=labelNo 109 else: 110 if labelM[R, C-1]!=0: 111 labelM[R, C]=labelM[R, C-1] 112 elif labelM[R, C-1]==0: 113 labelNo+=1 114 labelM[R, C]=labelNo 115 116 for R in range(1, row): 117 for C in range(0, col): 118 if M[R, C]==1: 119 if C==0: 120 if M[R-1, C]==0 : 121 labelNo+=1 122 labelM[R, C]=labelNo 123 else: 124 labelM[R, C]=labelM[R-1, C] 125 else: 126 if M[R-1, C]+M[R, C-1]==0: 127 labelNo+=1 128 labelM[R, C]=labelNo 129 elif M[R-1, C]+M[R, C-1]==1: 130 labelM[R, C]=max(labelM[R-1, C], labelM[R, C-1]) 131 else: 132 labelM[R, C]=min(labelM[R-1, C], labelM[R, C-1]) 133 if labelM[R-1, C] != labelM[R, C-1]: 134 if [labelM[R-1, C], labelM[R, C-1]] not in eqLable: 135 eqLable.append([labelM[R-1, C], labelM[R, C-1]]) 136 137 return labelNo 138
處理結果
對於8鄰域聯通,未處理等價對時:

所有的等價對為:

處理等價對並重新編號:

參考地址:
http://blog.sina.com.cn/s/blog_ad81d4310102vmll.html
http://fuda641.blog.163.com/blog/static/2075142162013111655644406/



