《數字圖像處理-OpenCV/Python》第17章:圖像的特征描述
本書京東 優惠購書鏈接 https://item.jd.com/14098452.html
本書CSDN 獨家連載專欄 https://blog.csdn.net/youcans/category_12418787.html
第17章:圖像的特征描述
特征檢測與匹配是計算機視覺的基本任務,包括檢測、描述和匹配三個相互關聯的步驟。廣泛應用于目標檢測、圖像檢索、視頻跟蹤和三維重建等諸多領域。
OpenCV提供了豐富的特征檢測和匹配算法,不僅繼承了cv::Feature2D 類,而且采用了統一的定義和封裝。
17.1 角點檢測之Harris算法
角是直線方向的快速變化,角點定義為兩條邊的交點,是簡單高效的特征。角點檢測(Corner Detection)是特征檢測的基礎,Harris算法是經典的角點檢測算法。
Harris角點檢測
Harris角點檢測算法的原理是,通過檢測窗口在圖像上移動,計算移動前后窗口中像素的灰度變化。角點是兩條邊的交點,其特征是檢測窗口沿任方向移動都會導致灰度的顯著變化。
Harris算法計算梯度的協方差矩陣M,協方差矩陣形狀為橢圓,長短半軸由特征值 ( λ 1 , λ 2 ) (λ_1, λ_2) (λ1?,λ2?)決定,方向由特征向量決定。定義如下的角點響應函數 R。
R = d e t ( M ) ? k [ t r a c e ( M ) ] 2 d e t ( M ) = λ 1 ? λ 2 t r a c e ( M ) = λ 1 + λ 2 \begin{aligned}R =& det(M) - k [trace(M)]^2 \\&det(M) = \lambda _1 * \lambda _2 \\&trace(M) = \lambda _1 + \lambda _2\end{aligned} R=?det(M)?k[trace(M)]2det(M)=λ1??λ2?trace(M)=λ1?+λ2??
角點響應 R 只與矩陣 M 的特征值 λ 1 , λ 2 \lambda _1,\lambda _2 λ1?,λ2? 有關,可以用來判斷區域是拐角、邊緣還是平坦:
- λ 1 , λ 2 \lambda _1,\lambda _2 λ1?,λ2? 較小時, ∣ R ∣ |R| ∣R∣ 較小,即各個方向上灰度基本不變,表明檢測器處于平坦區域;
- λ 1 > > λ 2 \lambda _1 >> \lambda _2 λ1?>>λ2? 或 λ 2 > > λ 1 \lambda _2 >> \lambda _1 λ2?>>λ1? 時, R < 0 R <0 R<0 ,即灰度在某個方向變化,但在其正交方向不變化,表明檢測器處于邊緣區域;
- λ 1 , λ 2 \lambda _1,\lambda _2 λ1?,λ2? 較大且數值相當時,灰度在某個方向及其正交方向都變化強烈,表明存在角點或孤立點。
Harris角點檢測算法的重復性好、檢測效率高,應用比較廣泛。
Shi-Tomas角點檢測
Shi-Tomas算法是對Harris角點檢測算法的改進,區別在于將角點響應函數修改如下。
R = m i n ( λ 1 , λ 2 ) R = min(\lambda _1 , \lambda _2) R=min(λ1?,λ2?)
只有當梯度協方差矩陣M的特征值 λ 1 , λ 2 λ_1, λ_2 λ1?,λ2? 都大于閾值時,才判定為角點。
OpenCV的角點檢測函數
在OpenCV中提供了函數cv.cornerEigenValsAndVecs計算圖像或矩陣的特征值和特征向量,函數cv.cornerMinEigenVal計算梯度矩陣的最小特征值,函數cv.cornerHarris實現Harris角點檢測。
函數原型
cv.cornerHarris(src, blockSize, ksize, k[, dst, borderType]) → dst
cv.cornerEigenValsAndVecs(src, blockSize, ksize[, dst, borderType]) → dst
cv.cornerMinEigenVal(src, blockSize[, dst, ksize, borderType]) → dst
參數說明
? src:輸入圖像,單通道,數據類型為CV_8U或浮點數類型。
? dst:輸出圖像,角點響應函數,大小與src相同,格式為CV_32FC1。
? blockSize:檢測器的滑動窗口尺寸,為整數。
? ksize:Sobel梯度算子的孔徑,即卷積核的大小,為整數。
? k:Harris角點響應函數的調節參數,通常取0.04~0.06。
? borderType:邊界擴充的類型,不支持BORDER_WRAP。
注意問題
⑴ 函數cv.cornerHarris返回值是如下的Harris的角點響應圖像R。
R = d s t ( x , y ) = d e t ( M ( x , y ) ) ? k ? [ t r a c e ( M ( x , y ) ) ] 2 R=dst(x,y)=det(M(x,y))-k*[trace(M(x,y))]^2 R=dst(x,y)=det(M(x,y))?k?[trace(M(x,y))]2
從角點響應圖像中篩選大于檢測閾值、且為局部最大值的點,就是圖像的角點。檢測閾值通常可以設為最大響應值的0.01~0.1。
⑵ 函數cv.cornerMinEigenVal與cv.cornerEigenValsAndVecs類似,區別在于它計算和保存矩陣M的最小特征值,即 m i n ( λ 1 , λ 2 ) min(λ_1 ,λ_2) min(λ1?,λ2?)。
在OpenCV中提供了函數cv.goodFeaturesToTrack實現Shi-Tomas角點檢測。
先使用cornerHarris或cornerMinEigenVal計算角點響應函數,最小特征值小于閾值的角點被剔除;并進行非最大值抑制,只保留(3×3)鄰域中的局部最大值;最后按照角點響應函數的大小排序,輸出前N個結果。
函數原型
cv.goodFeaturesToTrack(image, maxCorners, qualityLevel, minDistance[, corners, mask, blockSize, useHarrisDetector, k=0.04]) → corners
參數說明
? src:輸入圖像,單通道,數據類型為CV_8U或浮點數類型。
? corners:二維點向量集合的坐標(x,y),形如(n,1,2)的Numpy數組,浮點數。
? maxCorners:角點數量的最大值N,整數。
? qualityLevel:角點閾值系數,浮點數,取值范圍0.0~1.0。
? minDistance:角點之間的最小歐式距離。
? mask:掩模圖像,指定檢測角點的區域,可選項。
? blockSize:檢測器的滑動窗口尺寸,可選項,默認值為3。
? k:Harris角點響應函數的調節參數,可選項,默認值0.04。
? useHarrisDetector:計算角點響應的方法,默認值false,使用cornerMinEigenVal計算,true表示使用cornerHarris計算。
注意問題
⑴ 輸出參數corners是形如(n,1,2)的Numpy數組,表示檢測到n個角點的坐標(x,y)。
⑵ 檢測閾值是閾值系數qualityLevel與最大響應值的乘積,小于閾值的角點都被拒絕。例如,最大響應為1500,系數為0.1,則檢測閾值為150。
⑶ 剔除間距小于maxDistance的角點,實現非最大值抑制方法,避免重復的鄰近角點。
【例程1701】角點檢測之Harris算法和Shi-Tomas算法
本例程示例Harris角點檢測算法和Shi-Tomas角點檢測算法的使用。
Harris角點檢測函數的返回值是角點響應圖像,需要進行閾值處理才能得到角點坐標。Shi-Tomas角點檢測函數的返回值是角點坐標。
# 【1701】角點檢測之Harris算法和Shi-Tomas算法
import cv2 as cv
import numpy as np
from matplotlib import pyplot as pltif __name__ == '__main__':img = cv.imread("../images/Fig1201.png", flags=1)gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# Harris 角點檢測算法dst = cv.cornerHarris(gray, 5, 3, k=0.04) # 角點響應圖像,坐標(y,x)# Harris[dst>0.1*dst.max()] = [0,0,255] # 篩選角點,紅色標記stack = np.column_stack(np.where(dst>0.2*dst.max())) # 閾值篩選角點 (n,2)corners = stack[:, [1, 0]] # 調整坐標次序:(y,x) -> (x,y)print("num of corners by Harris: ", corners.shape)imgHarris = img.copy()for point in corners: cv.drawMarker(imgHarris, point, (0,0,255), cv.MARKER_CROSS, 10, 1) # 在點(x,y)標記# Shi-Tomas 角點檢測算法maxCorners, qualityLevel, minDistance = 100, 0.1, 5corners = cv.goodFeaturesToTrack(gray, maxCorners, qualityLevel, minDistance) # 角點坐標 (x,y)corners = np.squeeze(corners).astype(np.int) # 檢測到的角點 (n,1,2)->(n,2)print("num of corners by Shi-Tomas: ", corners.shape[0])imgShiTomas = np.copy(img)for point in corners: # 注意坐標次序cv.drawMarker(imgShiTomas, (point[0], point[1]), (0,0,255), cv.MARKER_CROSS, 10, 2) # 在點(x,y)標記plt.figure(figsize=(9, 3.3))plt.subplot(131), plt.title("1. Original")plt.axis('off'), plt.imshow(cv.cvtColor(img, cv.COLOR_BGR2RGB))plt.subplot(132), plt.title("2. Harris corners")plt.axis('off'), plt.imshow(cv.cvtColor(imgHarris, cv.COLOR_BGR2RGB))plt.subplot(133), plt.title("3. Shi-tomas corners")plt.axis('off'), plt.imshow(cv.cvtColor(imgShiTomas, cv.COLOR_BGR2RGB))plt.tight_layout()plt.show()
運行結果:
num of corners by Harris: 589
num of corners by Shi-Tomas: 66
圖17-1 Harris角點檢測和Shi-Tomas角點檢測
程序說明:
⑴ 程序運行結果如圖17-1所示。子圖1是原始圖像,子圖2是Harris角點檢測的結果,子圖3是Shi-Tomas角點檢測的結果。
⑵ 運行結果表明,Harris算法函數檢測到的角點數量遠大于Shi-Tomas算法函數的結果。這是由于角點周圍像素的響應值都很高,都被識別為角點,因此Harris函數會檢測到大量重復的角點。
版權聲明:
youcans@xupt 原創作品,轉載必須標注原文鏈接:(https://blog.csdn.net/youcans/article/details/140212758)
Copyright 2024 youcans, XUPT
Crated:2024-07-05
《數字圖像處理-OpenCV/Python》 獨家連載專欄 : https://blog.csdn.net/youcans/category_12418787.html