如何快速在一張二值化了的圖片檢測那些像素是屬於一個物體塊?
注意快速連通物體檢測算法只能識別二值化了的圖片中哪些像素是相互連接的一個整體。換句話說就是這個算法可以檢測到哪些像素是相互連通的。它其實就是可以看作是計算機算法中的連通子圖問題。
連通物體檢測算法有哪些用?1. OCR文字識別中可以用連通物體檢測算法識別哪些像素是屬於一個漢字。然後對這個漢字識別 2. 物體檢測。
直接看下圖就懂了
我對上面這幅圖來描述一下增強你對它的理解。連通域快速標記算法一共需要遍歷兩遍。
第1遍:前面提到了連通域標記算法處理的是 二值化了的圖,這意味着這些像素非0即1,而且物體的像素值是1. 如果你還不懂二值化可以參考本項目中的這篇教程Otsu二值化圖像算法.現在從上到下從左到右遍歷所有像素點,只要遇到像素值是1,則判斷它周圍是否有像素被標記了。如果周圍沒有像素被標記那就標籤值+1(假設目前最大標籤值是2,現在當前像素點周圍沒有被標記過的像素,那當前像素點就被標記爲3)。
現在問題來了什麼叫做某個像素點“周圍”?請看下面這張圖。右兩種規則找周圍像素點,分別是4鄰接和8鄰接。標紅的圓圈○就是中心像素點的“周圍”。4鄰接和8鄰接就是兩種不同的判斷“周圍”像素的規則。
如果遇到周圍有多個像素點被標記那就講最小的那個標籤值賦值給當前像素點。並且創建一個樹將較大的那些像素點的標籤值加入到最小的那個像素值的子節點。存儲樹的結構是用一個數組來存儲。數組的值是父節點的下標。比如{2,0,4…}表示序號是0那個元素的父節點序號是2,序號是1那個元素的父節點序號是0,序號是2那個元素的父節點序號是4.
第2遍:使用並查集算法將同一顆樹下的所有元素都標記爲根節點那個標籤值。並查集算法有什麼用?答:根據第1遍所創建的那個數組來找樹的根節點。
參考文獻:
https://blog.csdn.net/hemeinvyiqiluoben/article/details/39854315
Python編程實踐二值圖連通域快速標記算法fast labeling algorithm
import numpy as np
img_mat = np.array([[0, 0, 1, 0, 0, 1, 0],
[1, 1, 1, 0, 1, 1, 1],
[0, 0, 1, 0, 0, 1, 0],
[0, 0, 0, 0, 1, 1, 0]], dtype=np.int8)
img_mat = np.pad(img_mat,(1,1),mode= 'constant',constant_values = 0)
import matplotlib.pyplot as plt
plt.imshow(img_mat,cmap='gray_r')
plt.show()
label = 2
# 用於獲取周圍元素的掩碼
surround_mask = np.array([[0,1,0],
[1,0,0],
[0,0,0]],np.int8)
tree_arr = np.zeros(img_mat.shape[0]*img_mat.shape[1],dtype=np.int8)
for row in range(1,img_mat.shape[0]-1):
for col in range(1,img_mat.shape[1]-1):
if img_mat[row,col]==0:
continue
surround_elem = surround_mask*img_mat[row-1:row+2,col-1:col+2]
surround_labels = surround_elem[surround_elem!=0]
if surround_labels.shape[0]!=0:
min_surround_label = surround_labels.min()
if min_surround_label!=0 and min_surround_label!=1:# 周圍存在被標記過的數據
img_mat[row,col] = min_surround_label
tree_arr[surround_labels[surround_labels!=min_surround_label]] = min_surround_label
continue
img_mat[row,col] = label
tree_arr[label] = label
label += 1
for i in range(2,label):
k = i
while k!=tree_arr[k]:
k = tree_arr[k]
tree_arr[i] = k
for row in range(img_mat.shape[0]):
for col in range(img_mat.shape[1]):
img_mat[row,col] = tree_arr[img_mat[row,col]]
plt.imshow(img_mat)
原圖
綠色和黃色是我們識別出的不同的兩個連通量(物體)