一、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
微信掃一掃
支付寶掃一掃