1 簡介
- 特徵點又被稱爲興趣點或者角點,是圖像的重要特徵。
- 點特徵,主要指圖像中的明顯點,比如我們肉眼看到的突出的角點、邊緣端點、極值點等。
- 用於特徵點提取的算子稱爲“興趣點提取檢測算子”,常用的算子有:Harris角點檢測、FAST特徵檢測、SIFT特徵檢測和SURF特徵檢測,且這些算子大都是對於圖像的灰度圖色彩空間上進行的像素值的計算!
2 基礎內容
-
一張圖像可以視爲由三種特徵構成:角點、邊界、平坦區域。
-
角點的概念
角點的概念的理解是在於邊緣特徵和無明顯特徵的比較中產生的。
概括總結:角點(特徵點)是當窗口向各方向移動,都會引起像素值發生很大變化的一個位置點;邊緣特徵是僅當窗口單方向上來回移動,纔會引起像素值發生較大變化的一個位置區域;平坦區域是無論窗口移動方向如何,都不會引起像素值發生很大的變化的區域。 -
圖像梯度的概念
圖像梯度表示一種現象:像素值發生了很大變化。
從表現形式來看,在數學中可以用微分或者導數表示;在數字圖像中是二維離散函數求梯度後使用差分近似求導;在實操中,即計算圖像中每個像素的某個領域內的灰度變化差值(細化流程:設置合適的算子與窗口大小進行卷積運算)。 -
判斷特徵點是否穩定的指標:尺度不變、旋轉不變、抗噪聲影響等,以及檢測出圖像中“真實”的角點、準確的定位性能、很高的重複檢測率、噪聲的魯棒性、較高的計算效率。
-
爲什麼說尺度不變性對圖像特徵很重要?原因在於:人的眼睛在辨識物體時具有較強的尺度不變性,人們在使用肉眼識別物體時,不管物體遠近,尺寸的變化都能認識物體。
-
非極大值抑制的原理是:在一個窗口內,如果有多個角點則用值最大的那個角點,其他的角點都刪除,窗口大小這裏我們用3*3,程序中通過圖像的膨脹運算來達到檢測極大值的目的,因爲默認參數的膨脹運算就是用窗口內的最大值替代當前的灰度值。
3 Harris角點檢測算法
- 算法思想:利用局部窗口在圖像上進行移動,判斷灰度是否發生極大的變化,以判定該窗口所在區域是否存在角點。
- 算法的步驟:計算局部窗口在水平或者垂直方向上移動每一步時的“窗口內部的像素值變化量E”;通過E求得該窗口下的角點響應函數R;將R與自定義的閾值threshold進行比較,以判斷該窗口是否包含一個角點特徵。換句說法是:關鍵流程包括轉化爲灰度圖像、計算差分圖像、高斯平滑、計算局部極值、確認角點。
4 基於OpenCV的實現
- API:cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])
- 參數解釋:src:輸入灰度圖像,float32類型;blocksize:窗口的尺寸大小;ksize:sobel算子的尺寸;k:計算角點響應函數的參數k,取值範圍在0.04-0.06之間。
- 代碼演示與說明
import cv2
import numpy as np
# detector parameters
block_size = 3
sobel_size = 3
k = 0.04
image = cv2.imread('Scenery.jpg')
print(image.shape)
height = image.shape[0]
width = image.shape[1]
channels = image.shape[2]
print("width: %s height: %s channels: %s" % (width, height, channels))
# 將一個三維的BGR彩色圖像轉化爲一張二維的灰度圖
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 因爲cornerHarris的參數類型要求,需要將灰度圖轉換爲float32。
gray_img = np.float32(gray_img)
# 開始運用Harris角點檢測算法進行角點的檢測
corners_img = cv2.cornerHarris(gray_img, block_size, sobel_size, k)
# 即是構造一個卷積核
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
print(kernel)
# dilate 的參數 :圖片數組、濾波器的核
dst = cv2.dilate(corners_img, kernel)
print(dst.shape)
cv2.imshow("dst",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 可以看出這個dst的灰度圖時一個膨脹後的圖像。
for r in range(height):
for c in range(width):
# 拿出每一個位置的像素值。
pix = dst[r, c]
if pix > 0.05 * dst.max():
# cicle 參數:圖像二維數組、中心位置座標、半徑、顏色、thickness:圓形輪廓的粗細
# 其中,thickness 正值表示圓形輪廓的粗細,而負厚度表示要繪製實心圓。
# 顏色 可以是三通道的元組模式,其中如果用cv顯示將被解析爲BGR,如果用plt則RGB
cv2.circle(image, (c, r), 5, (0, 0, 255), 1)
#將 BGR 的圖像轉換爲 RGB
#image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
cv2.imshow("image",image)
cv2.imwrite("corner_img.png",image)
cv2.waitKey(0)
cv2.destroyAllWindows()
########################## 輸出的內容 ##########################3
(480, 640, 3)
width: 640 height: 480 channels: 3
[[1 1 1]
[1 1 1]
[1 1 1]]
(480, 640)
另外,附上三張圖:
- 原圖Original
- 運用膨脹操作dilate後但會的dst對象是一個二維數組灰度圖像
- cv2展示的最終圖像
5 Harris角點檢測的性質總結
- 閾值決定角點的數量
- Harris角點的檢測算子對亮度和對比度的變化不敏感(光照敏感性),也就是說,對亮度和對比度的仿射變換並不會改變Harris響應的極值點出現的位置。
- Harris檢測算子具有旋轉不變性,即特徵位置發生轉動,特徵值並不會發生變化。
- Harris檢測算子不具有尺度不變性,即尺度的變化,會將角點變爲邊緣,或者邊緣變爲角點。而將Harris角點檢測算子與高斯尺度空間表示相結合,使Harris角點檢測算子具有尺度的不變性。 參考:Harris角點
6 初讀問題
- Harris角點檢測算子的具體形式如何?還是就是Sobel算子?
- 檢測時的窗口是不是與Sobel的尺寸必須相同?
- 線代理論是否需要掌握?
- 能否用比較清楚的動畫過程描述整個檢測過程?以代替算法的步驟。
7 補充
- 一階導數(即灰度的梯度)的局部最大所對應的像素點;
- 兩條及兩條以上邊緣的交點;
- 圖像中梯度值和梯度方向的變化速率都很高的點;
- 角點處的一階導數最大,二階導數爲零,指示物體邊緣變化不連續的方向。