【火爐煉AI】機器學習048-Harris檢測影像角點
(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
角點檢測演算法大致有三類:基於灰度影像的角點檢測,基於二值影像的角點檢測,基於輪廓曲線的角點檢測。基於灰度影像的角點檢測又可分為基於梯度、基於模板和基於模板梯度組合3類方法,其中基於模板的方法主要考慮畫素領域點的灰度變化,即影像亮度的變化,將與鄰點亮度對比足夠大的點定義為角點。常見的基於模板的角點檢測演算法有Kitchen-Rosenfeld角點檢測演算法,Harris角點檢測演算法、KLT角點檢測演算法及SUSAN角點檢測演算法。
1. Harris角點檢測器
Harris角點檢測主要經過以下步驟:
1,對影像進行高斯濾波
2,對每個畫素,估計其垂直方向的梯度大小值,使用近似於導數的核做兩次一維卷積。
3,對每一畫素核給定的鄰域視窗:計算區域性結構矩陣和響應函式。
4,選取響應函式的一個閾值,以選擇最佳候選角點並完成非極大值抑制。
關於Harris角點檢測器的具體演算法,可以參考這篇博文:harris角點檢測器
下面我們來一步一步的使用Harris來檢測影像中的角點
# Harris 角點檢測器
img_gray = np.float32(gray) # Harris角點檢測器需要float型資料
img_harris = cv2.cornerHarris(img_gray, 7, 5, 0.04) # 使用角點檢測
plt.imshow(img_harris,cmap='gray')
複製程式碼
上面使用cv2.cornerHarris()函式檢測到了圖片中的角點,但是從圖中可以看出,也檢測出了很多邊緣線條,故而我們要想辦法去掉這些邊緣線條而保留角點。
# 為了影像更加平滑,使用膨脹來將影像邊緣減小,使得角點更突出
img_harris = cv2.dilate(img_harris, None)
plt.imshow(img_harris,cmap='gray')
複製程式碼
從圖片中可以看出,經過膨脹操作之後,邊緣線條的寬度變小,而角點幾乎不變。
但是我們要確定一個角點定義方法,此處我們定義畫素值為最大值的1%以上為角點,從程式碼中可以看出:
# 確定角點的方法:此處我們定義角點為:其畫素值為最大值的1%以上為角點,如下:
is_corner=img_harris > 0.01 * img_harris.max()
plt.imshow(is_corner,cmap='gray') # 將角點繪製出來看一下
複製程式碼
上面的二值化圖可以很明顯的判斷出哪些是角點,那麼將這些角點繪製到原圖中是怎麼樣了?
img[is_corner]=[0, 0, 255] # 用紅色標註這些角點
img2=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img2)
複製程式碼
可以從圖中看出,角點檢測的還是比較準確的。
########################小**********結###############################
1,角點的檢測有一個難點在於cv2.cornerHarris的引數的選擇,這個可能要多次嘗試看效果。
2,本專案檢測的角點比較準確,有一個重要原因是圖片的背景是純白,背景顏色簡單,圖片物體前景只是一個箱子,角點非常明顯,故而檢測比較容易,在其他很多情況下,可能難以簡單的獲得比較滿意的結果。
#################################################################
注:本部分程式碼已經全部上傳到(我的github)上,歡迎下載。
參考資料:
1, Python機器學習經典例項,Prateek Joshi著,陶俊傑,陳小莉譯