一、CornerHarris概述
CornerHarris函數是一種常用的角點檢測算法,又稱Harris角點檢測算法。其基本思想是利用圖像像素點的灰度值變化情況,通過計算像素梯度的變化率,來判斷圖像上的角點位置。
CornerHarris函數的定義形式如下:
void cornerHarris(InputArray src, OutputArray dst, int blockSize, int ksize, double k, int borderType=BORDER_DEFAULT);
參數含義如下:
src
: 輸入圖像dst
: 輸出圖像,包含每個像素的響應強度blockSize
: 計算協方差矩陣時每個小區域的大小ksize
: Sobel算子的大小k
: Harris算子中的自由參數borderType
: 圖像邊界處理方式,默認為BORDER_DEFAULT
二、CornerHarris的實現原理
1. Sobel算子計算圖像梯度
CornerHarris函數首先利用Sobel算子計算圖像每個像素的梯度值,而Sobel算子本質上是一個二維濾波器。
Sobel算子的定義形式如下:
void CV_EXPORTS Sobel(InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize=3, double scale=1, double delta=0, int borderType=BORDER_DEFAULT);
參數含義如下:
src
: 輸入圖像dst
: 輸出圖像,包含每個像素的梯度強度ddepth
: 輸出圖像的數據類型dx
: x方向的差分階數dy
: y方向的差分階數ksize
: Sobel算子的大小scale
: 縮放因子delta
: 偏移量borderType
: 圖像邊界處理方式,默認為BORDER_DEFAULT
2. 協方差矩陣計算
利用Sobel算子計算得到的梯度值,我們可以計算圖像局部區域的協方差矩陣,其中包括x方向的梯度統計值和y方向的梯度統計值。
協方差矩陣的計算公式如下:
3. Harris響應函數計算
接下來,我們需要計算每個像素的Harris響應函數值:
其中,k
為Harris算子中的自由參數,一般取值為0.04到0.06之間。
4. 非極大值抑制
通過計算得到每個像素的Harris響應函數值,我們現在需要篩選出角點的位置。通常情況下,我們會選擇對響應函數值較大的、極值點進行保留,而非極大值抑制則是一種常用的處理方式。
三、CornerHarris應用場景
1. 角點檢測
作為一種角點檢測算法,CornerHarris的主要應用場景便是在計算機視覺領域中。例如,我們可以利用CornerHarris算法檢測攝像頭捕捉到的圖像中的人臉位置,並在人臉位置處添加特定的處理,如眼睛的識別、人臉的三維重建、人臉素描的生成等。
2. 物體跟蹤
除了角點檢測之外,CornerHarris還可以廣泛應用於物體跟蹤等其他方面。例如,在移動機械人的路徑規劃中,我們可以藉助CornerHarris算法來檢測機械人行進的路徑上是否有較為複雜的轉角。
3. 三維重建
在進行圖像處理和計算機視覺方面的研究時,CornerHarris算法還可以幫助我們進行三維重建等工作。例如,在建模一個房間的時候,我們可以在每個角落中運用CornerHarris算法來檢測出每個牆壁之間的空間並加以準確描述。
四、CornerHarris代碼示例
1. Python代碼
import cv2 import numpy as np # Load the image img = cv2.imread('chessboard.png') # Convert the image to grayscale gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # Detect Harris corners dst = cv2.cornerHarris(gray,2,3,0.04) # Threshold to obtain the optimal value dst = cv2.dilate(dst,None) ret, dst = cv2.threshold(dst,0.01*dst.max(),255,0) # Draw corners on the original image img[dst>0.01*dst.max()] = [0,0,255] # Display the image cv2.imshow('dst',img) cv2.waitKey(0) cv2.destroyAllWindows()
2. C++代碼
#include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include using namespace cv; using namespace std; int main() { // Load the image Mat src = imread("chessboard.png"); // Convert the image to grayscale Mat gray; cvtColor(src, gray, COLOR_BGR2GRAY); // Detect Harris corners Mat dst; int blockSize = 2; int ksize = 3; double k = 0.04; cornerHarris(gray, dst, blockSize, ksize, k); // Threshold to obtain the optimal value Mat dst_norm, dst_norm_scaled; normalize(dst, dst_norm, 0, 255, NORM_MINMAX, CV_32FC1, Mat()); convertScaleAbs(dst_norm, dst_norm_scaled); // Draw corners on the original image for (int i = 0; i < dst_norm.rows; i++) { for (int j = 0; j < dst_norm.cols; j++) { if ((int)dst_norm.at(i, j) > 100) { circle(src, Point(j, i), 5, Scalar(0, 0, 255), 2, 8, 0); } } } // Display the image imshow("dst", src); waitKey(0); return 0; }
原創文章,作者:ZXCS,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/149202.html