OpenCv-C++-亞畫素級別角點檢測(檢測子畫素中的corner的位置)
阿新 • • 發佈:2018-11-30
使用亞畫素級別角點檢測,返回角點的浮點數值,它的精度比整數畫素更準確。可以用cornerSubPix()函式將角點定位到子畫素,從而取得亞畫素級別的角點檢測效果。
使用函式:
void cv::cornerSubPix ( InputArray image,
InputOutputArray corners,
Size winSize,
Size zeroZone,
TermCriteria criteria
)
參考:https://blog.csdn.net/holybin/article/details/41122493
函式引數說明如下:
image:輸入影象
corners:輸入角點的初始座標以及精準化後的座標用於輸出。
winSize:搜尋視窗邊長的一半,例如如果winSize=Size(5,5),則一個大小為的搜尋視窗將被使用。
zeroZone:搜尋區域中間的dead region邊長的一半,有時用於避免自相關矩陣的奇異性。如果值設為(-1,-1)則表示沒有這個區域。
criteria:角點精準化迭代過程的終止條件。也就是當迭代次數超過criteria.maxCount,或者角點位置變化小於criteria.epsilon時,停止迭代過程。
#include<opencv2/opencv.hpp> #include<iostream> #include<math.h> using namespace std; using namespace cv; Mat src,gray_src; int maxCorner = 20; int max_value = 200; const char* output_title = "subpixel window"; void subpixel(int,void*); int main(int argc, char** argv) { src = imread("D:/test/大廈.jpg"); if (!src.data) { cout << "圖片未找到" << endl; return -1; } cvtColor(src, gray_src, CV_BGR2GRAY); imshow("input title", src); namedWindow(output_title, CV_WINDOW_AUTOSIZE); createTrackbar("subpixel num", output_title, &maxCorner, max_value, subpixel); subpixel(0, 0); waitKey(0); return 0; } void subpixel(int, void *) { if (maxCorner < 5) { maxCorner = 5; } vector<Point2f>corners; goodFeaturesToTrack(gray_src, corners,maxCorner, 0.01, 10, Mat(), 3, false, 0.04); Mat resultImg = src.clone(); for (size_t i = 0; i < corners.size(); i++) { circle(resultImg, corners[i], 2, Scalar(0, 0, 255), 2, 8, 0); } cout << "corner num: " << corners.size() << endl; imshow(output_title, resultImg); Size size = Size(5, 5);//最多隻能取到5 //迭代演算法的終止準則,該類變數需要3個引數,一個是型別,第二個引數為迭代的最大次數,最後一個是特定的閾值 TermCriteria tc = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.01); cornerSubPix(gray_src, corners, size, Size(-1, -1), tc); //這裡的corner重新變了,變成cornerSubPix裡的corners了 for (size_t t = 0; t < corners.size(); t++) { cout << t + 1 << ".pixel[x,y]= " << corners[t].x <<","<< corners[t].y << endl; } return; }
可以看到,畫素座標返回的是一個浮點數,比原來的整數值更加精準。