自定義角點檢測器
阿新 • • 發佈:2020-08-18
自定義角點檢測器是基於Harris和Shi-Tomasi角點檢測的
首先通過計算矩陣M來得出λ1λ2兩個特徵值,然後根據他們得到角點響應值
然後自己設定閾值實現實現計算出閾值得到有效響應值的角點位置
API
cv::cornerEigenValsAndVecs
(
InputArray src,
OutputArray dst,
int blocksize,
int ksize,
int borderType=BORDER_DEFAULT
)
cv::cornerMinEigenVal
(
InputArray src,
OutputArray dst,
int blocksize,
int ksize=3,
int borderType=BORDER_DEFAULT
)
自定義CustomHarris角點檢測Demo
#include"pch.h" #include<iostream> #include<opencv2/opencv.hpp> #include<math.h> using namespace std; using namespace cv; const char* output_title = "Custom Harris CornerDetection Reslut"; double harris_mins_rsp;double harris_max_rsp; int qualityLevel = 30; int max_count = 100; Mat src, gray_src; Mat harris_dst, harriRspImg; void CustomHarris_Demo(int,void*); int main(int argc, char** argv) { src = imread("1.jpg"); imshow("input img", src); int blocksize = 3; int ksize = 3; double k = 0.04; harriRspImg= Mat::zeros(src.size(), CV_32FC1); harris_dst = Mat::zeros(src.size(), CV_32FC(6)); namedWindow(output_title, CV_WINDOW_AUTOSIZE); cvtColor(src, gray_src, COLOR_BGR2GRAY); //caculate eigen value計算特徵值 cornerEigenValsAndVecs(gray_src, harris_dst, blocksize, ksize, BORDER_DEFAULT); //計算響應 for(int row=0;row<harris_dst.rows;++row) for (int col = 0; col < harris_dst.cols; ++col) { double lamda1=harris_dst.at<Vec6f>(row, col)[0]; double lamda2 = harris_dst.at<Vec6f>(row, col)[1]; harriRspImg.at<float>(row, col) = lamda1 * lamda2 - k * pow((lamda1 + lamda2), 2);//pow求平方 } minMaxLoc(harriRspImg, &harris_mins_rsp, &harris_max_rsp, 0, 0,Mat()); createTrackbar("Quality value:", output_title, &qualityLevel, max_count, CustomHarris_Demo); CustomHarris_Demo(0, 0); waitKey(); return 0; } void CustomHarris_Demo(int, void*) { if (qualityLevel < 10) qualityLevel = 10; Mat resultImg = src.clone(); float t = harris_mins_rsp + (double(qualityLevel)) / max_count * (harris_max_rsp - harris_mins_rsp); for(int row=0;row<src.rows;++row) for (int col = 0; col < src.cols; ++col) { float v = harriRspImg.at<float>(row, col); if (v > t) circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0); } imshow(output_title, resultImg); }
自定義CustomShi-Tomasi角點檢測Demo
#include"pch.h" #include<iostream> #include<opencv2/opencv.hpp> #include<math.h> using namespace std; using namespace cv; const char* output_title = "Custom Shi-Tomasi CornerDetection Reslut"; double harris_mins_rsp; double harris_max_rsp; int qualityLevel = 30; int max_count = 100; Mat src, gray_src; Mat harris_dst, harriRspImg; //Shi-Tomasi Mat ShiTomasiRspImg; double ShiTomasi_max_rsp; double ShiTomasi_min_rsp; int SM_QualityLevel = 30; void CustomShiTomasi_Demo(int,void*); int main(int argc, char** argv) { src = imread("1.jpg"); imshow("input img", src); int blocksize = 3; int ksize = 3; double k = 0.04; harriRspImg = Mat::zeros(src.size(), CV_32FC1); harris_dst = Mat::zeros(src.size(), CV_32FC(6)); namedWindow(output_title, CV_WINDOW_AUTOSIZE); cvtColor(src, gray_src, COLOR_BGR2GRAY); //caculate eigen value計算特徵值 cornerEigenValsAndVecs(gray_src, harris_dst, blocksize, ksize, BORDER_DEFAULT); //計算響應 for(int row=0;row<harris_dst.rows;++row) for (int col = 0; col < harris_dst.cols; ++col) { double lamda1 = harris_dst.at<Vec6f>(row, col)[0]; double lamda2 = harris_dst.at<Vec6f>(row, col)[1]; harriRspImg.at<float>(row, col) = lamda1 * lamda2 - k * pow((lamda1 + lamda2), 2);//pow求平方 } minMaxLoc(harriRspImg, &harris_mins_rsp, &harris_max_rsp, 0, 0,Mat()); //createTrackbar("Quality value:", output_title, &qualityLevel, max_count, CustomHarris_Demo); //CustomHarris_Demo(0, 0); //計算最小特徵值 ShiTomasiRspImg = Mat::zeros(src.size(), CV_32FC1); cornerMinEigenVal(gray_src, ShiTomasiRspImg, blocksize, ksize, 4); minMaxLoc(ShiTomasiRspImg, &ShiTomasi_min_rsp, &ShiTomasi_max_rsp, 0, 0, Mat()); createTrackbar("Min Value:", output_title, &SM_QualityLevel, max_count, CustomShiTomasi_Demo); CustomShiTomasi_Demo(0, 0); waitKey(); return 0; } void CustomShiTomasi_Demo(int, void*) { if (qualityLevel < 20) qualityLevel = 20; Mat resultImg = src.clone(); float t = ShiTomasi_min_rsp + ((double(SM_QualityLevel)) / max_count) * (ShiTomasi_max_rsp - ShiTomasi_min_rsp); for(int row=0;row<src.rows;++row) for (int col = 0; col < src.cols; ++col) { float v = ShiTomasiRspImg.at<float>(row, col); if (v > t) circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0); } imshow(output_title, resultImg); }