### 4.2 區域分離與聚合 區域分裂合并算法的基本思想是將圖像細分為一組不相交的區域,然后聚合或者分離這些區域。 分離和聚合的判據是用戶選擇的謂詞邏輯 Q,通常是目標區域特征一致性的測度,例如灰度均值和方差。 分離過程先判斷當前區域是否滿足目標的特征測度,如果不滿足則將當前區域分離為多個子區域進行判斷;不斷重復判斷、分離,直到拆分到最小區域為止。典型的區域分裂方法,是將區域按照 4 個象限分裂為 4 個子區域,可以簡化處理和運算過程。 區域分離的分割結果通常包含具有相同性質的鄰接區域,通過聚合可以解決這個問題。僅當鄰接區域的并集滿足目標的特征測度,才將進行聚合。 區域分離與聚合基本方案的過程如下: 例程 11.26:圖像分割之區域分離# 11.26 圖像分割之區域分離 def SplitMerge(src, dst, h, w, h0, w0, maxMean, minVar, cell=4): win = src[h0: h0+h, w0: w0+w] mean = np.mean(win) # 窗口區域的均值 var = np.std(win, ddof=1) # 窗口區域的標準差,無偏樣本標準差 if (mean<maxMean) and (var>minVar) and (h<2*cell) and (w<2*cell): # 該區域滿足謂詞邏輯條件,判為目標區域,設為白色 dst[h0:h0+h, w0:w0+w] = 255 # 白色 # print("h0={}, w0={}, h={}, w={}, mean={:.2f}, var={:.2f}". # format(h0, w0, h, w, mean, var)) else: # 該區域不滿足謂詞邏輯條件 if (h>cell) and (w>cell): # 區域能否繼續分拆?繼續拆 SplitMerge(src, dst, (h+1)//2, (w+1)//2, h0, w0, maxMean, minVar, cell) SplitMerge(src, dst, (h+1)//2, (w+1)//2, h0, w0+(w+1)//2, maxMean, minVar, cell) SplitMerge(src, dst, (h+1)//2, (w+1)//2, h0+(h+1)//2, w0, maxMean, minVar, cell) SplitMerge(src, dst, (h+1)//2, (w+1)//2, h0+(h+1)//2, w0+(w+1)//2, maxMean, minVar, cell) # else: # 不能再分拆,判為非目標區域,設為黑色 # src[h0:h0+h, w0:w0+w] = 0 # 黑色 img = cv2.imread("../images/Fig0938a.tif", flags=0) hImg, wImg = img.shape mean = np.mean(img) # 窗口區域的均值 var = np.std(img, ddof=1) # 窗口區域的標準差,無偏樣本標準差 print("h={}, w={}, mean={:.2f}, var={:.2f}".format(hImg, wImg, mean, var)) maxMean = 80 # 均值上界 minVar = 10 # 標準差下界 src = img.copy() dst1 = np.zeros_like(img) dst2 = np.zeros_like(img) dst3 = np.zeros_like(img) SplitMerge(src, dst1, hImg, wImg, 0, 0, maxMean, minVar, cell=32) # 最小分割區域 cell=32 SplitMerge(src, dst2, hImg, wImg, 0, 0, maxMean, minVar, cell=16) # 最小分割區域 cell=16 SplitMerge(src, dst3, hImg, wImg, 0, 0, maxMean, minVar, cell=8) # 最小分割區域 cell=8 plt.figure(figsize=(9, 7)) plt.subplot(221), plt.axis('off'), plt.title("Origin") plt.imshow(img, 'gray') plt.subplot(222), plt.axis('off'), plt.title("Region split (c=32)") plt.imshow(dst1, 'gray') plt.subplot(223), plt.axis('off'), plt.title("Region split (c=16)") plt.imshow(dst2, 'gray') plt.subplot(224), plt.axis('off'), plt.title("Region split (c=8)") plt.imshow(dst3, 'gray') plt.tight_layout() plt.show()1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 (本節完) |
|