OpenCv-C++-自定義角點檢測器(harris自定義)
阿新 • • 發佈:2018-11-30
學習了前面的harris角點檢測之後,現在利用harris原理來自定義角點檢測器,主要使用cornerEigenValsAndVecs()函式。
參考:https://blog.csdn.net/weixin_41695564/article/details/79979784
該函式引數解釋如下:
src:輸入影象矩陣,即單通道8位或者浮點型別的影象。 dst:輸出矩陣,即用來儲存結果的影象,大小與輸入影象一致並且為CV_32FC(6)型別。計算自相關矩陣M的特徵值和特徵向量,並將它們以(λ1, λ2, x1, y1, x2,y2)的形式儲存在目標影象dst中。其中λ1, λ2是M未經過排序的特徵值;x1, y1是對應於λ1的特徵向量;x2, y2是對應於λ2的特徵向量。因此是6通道的矩陣。 blockSize:鄰域大小。 ksize:Sobel運算元當中的核大小,只能取1、3、5、7。 borderType:畫素擴充套件的方法。
現將程式碼放入:
#include<opencv2/opencv.hpp> #include<iostream> #include<math.h> using namespace cv; using namespace std; Mat src, gray_src; int current_value = 30; int Max_value = 100; double minVal; double maxVal; Mat harris_res, harris_src; void custom_corner_harris(int, void*); const char* output_title = "output title"; int main(int argc, char** argv) { src = imread("D:/test/大廈.jpg"); if (src.empty()) { cout << "the image could not found..." << endl; return -1; } cvtColor(src, gray_src, COLOR_BGR2GRAY); harris_src = Mat::zeros(src.size(), CV_32FC(6)); harris_res = Mat::zeros(src.size(), CV_32FC1); imshow("input title", src); // 計算特徵值 int blocksize = 3; double k = 0.04; int ksize = 3; //Sobel運算元當中的核大小,只能取1、3、5、7 cornerEigenValsAndVecs(gray_src, harris_src, blocksize, ksize, BORDER_DEFAULT); //計算響應 for (int row = 0; row < harris_src.rows; row++) { for (int col = 0; col < harris_src.cols; col++) { double lamda1 = harris_src.at<Vec6f>(row, col)[0]; double lamda2 = harris_src.at<Vec6f>(row, col)[1]; harris_res.at<float>(row, col) = static_cast<float>(lamda1 * lamda2 - k * pow((lamda1 + lamda2), 2)); } } minMaxLoc(harris_res, &minVal, &maxVal, 0, 0, Mat()); namedWindow(output_title, CV_WINDOW_AUTOSIZE); createTrackbar("custom bar", output_title, ¤t_value, Max_value, custom_corner_harris); custom_corner_harris(0, 0); waitKey(0); return 0; } void custom_corner_harris(int, void*) { if (current_value < 10) { current_value = 10; } //cvtColor(gray_src, gray_src, COLOR_GRAY2BGR); Mat resultImg = gray_src.clone(); cvtColor(resultImg, resultImg, COLOR_GRAY2BGR); RNG rng(12345); Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); float t = static_cast<float>(minVal + (((double)current_value) / Max_value)*(maxVal - minVal));//閾值,如果大於某個百分比,則響應 for (int row = 0; row < src.rows; row++) { for (int col = 0; col < src.cols; col++) { float v = harris_res.at<float>(row, col); if (v > t) { circle(resultImg, Point(col, row), 2, Scalar(rng.uniform(0,255), rng.uniform(0, 255), rng.uniform(0, 255)), 2, 8, 0); } } } printf("corner num:%d\n", current_value); imshow(output_title, resultImg); }
執行結果:
值為30:
當值大於30時:
當值小於30時,視窗就會出現未響應的狀態,程式執行會很慢很卡:
就會出現這種狀態,所以,個人認為,當一開始取值為某個值時,最好不要低於剛開始的取值。