先前文章有使用連通域分析來印出物件的位置及高寬面積及達成物件定位等功能。
[OpenCV應用][Python]利用連通域分析達成物件定位
[OpenCV基礎][Python]connectedComponent連通域分析
這次我們將利用它來達成過濾掉不重要的雜點,在先前的文章中有利用OpenCV找輪廓的方式來濾除,這一次我們利用連通域分析來設定更多條件濾除。
[OpenCV基礎][Python]遮罩,旋轉,輪廓應用濾除斑點
左邊是原圖有一推雜點跟痕跡,右邊是我們設定條件濾除掉的結果。只保留想檢測OCR的部分。
import cv2
import numpy as np
def __connectorFileter(binaryImg: np.array , obj_Spec: tuple) -> np.array:
'''
binaryImg : 輸入的二值化圖像,僅包含0和255的值。
obj_Spec :
obj_Spec: tuple:一個元組,用來定義要過濾物件的規格
WidthMax:物件的最大寬度
HeightMin:物件的最小高度
HeightMax:物件的最大高度
AreaMin:物件的最小面積
'''
WidthMin,WidthMax,HeightMin,HeightMax,AreaMin = obj_Spec
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binaryImg, connectivity=8)
imgH, imgW = binaryImg.shape
obj = set()
objLoc = {}
# 移除雜訊區塊
if True:
for i in range(len(stats)): #x, y, w, h = stats[i][:4]
# 排除法
# 物件座標
if stats[i][0] == 0 or stats[i][1] == 0:
continue
# 物件邊界
if stats[i][0] + stats[i][2] >= imgW or stats[i][1] + stats[i][3] >= imgH:
continue
# 物件寬度
if stats[i][2] < WidthMin or stats[i][2] > WidthMax:
continue
# 物件高度
if stats[i][3] < HeightMin or stats[i][3] >= HeightMax:
continue
# 物件面積
if stats[i][4] <= AreaMin:
continue
objLoc[i] = (stats[i][0], stats[i][1], stats[i][2], stats[i][3])
# 移除字母內的瑕疵
for i in obj:
noise = False
left_i = objLoc[i][0]
right_i = objLoc[i][0]+ objLoc[i][2]
top_i = objLoc[i][1]
bottom_i = objLoc[i][1]+objLoc[i][3]
for j in objLoc:
left_j = objLoc[j][0]
right_j = objLoc[j][0]+ objLoc[j][2]
top_j = objLoc[j][1]
bottom_j = objLoc[j][1]+objLoc[j][3]
if i != j and left_j < left_i and right_i< right_j and top_j< top_i and bottom_i < bottom_j:
noise = True
break
if not noise:
obj.add(i)
# 字母保留區塊
for i in range(num_labels):
if i in letters:
labels[labels == i] = True
else:
labels[labels == i] = False
# convert to binary image
labels[labels>0]=255
labels[labels==0]=0
labels = np.array(labels, dtype='uint8')
return labels
if __name__ == "__main__" :
# 讀取圖檔
imgpath ='F:/python/opencv/chars_training_dirty.png'
img = cv2.imdecode(np.fromfile(file=imgpath, dtype=np.uint8), cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Otsu's 方法進行自動二值化
threshold_img = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# 需讓OCR轉換成白色字體才能用連通域分析
threshold_img = 255 - threshold_img
#設定過濾條件
Filete_spec = (10,100,10,100,200)
Fileter_img = __connectorFileter(threshold_img,Filete_spec)
#顯示結果圖
cv2.imshow('Orignal_img',threshold_img)
cv2.imshow('Fileter_img',Fileter_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
objLoc
字典,記錄它們的座標和尺寸。labels: np.array
:最後經過處理的二值化影像,其中保留了符合規格的物件,移除了雜訊和瑕疵。set()
:用來儲存符合條件的物件索引。