亞像素在提高檢測精度上有着很大的作用,在實際的情況下,檢測到的角點不會是一個准確的像素點,精確來說是一個浮點數角點,這樣可以保證后面的三維重建及相機跟蹤才能夠更加精確。亞像素檢測是基於曲線擬合的方式采用高斯,多項式及橢圓曲面來進行亞像素定位。
下圖是亞像素的檢測結果:
亞像素檢測函數參數解釋:
cornerSubPix(gray,corners,winSize,zeroZone,criteria);
gray,輸入的灰度圖像;
corners,利用前面角點檢測函數提供初始坐標及轉化后精確的輸出坐標;
winSize,搜索窗口的一般尺寸大小;
zeroZone,死區的一半尺寸,避免自相關矩陣出現可能的奇異值;
criteria,角點迭代終止條件,迭代數目或設定的精度。
#include<opencv2/opencv.hpp> #include<iostream> using namespace std; using namespace cv; int init_value=50, max_value=555; Mat src,gray,dst; void subpix(int, void*); int main(int argc, char** argv) { src = imread("H:/cv_code/image/home.jpg"); if (src.empty()) { printf("could not find image"); return -1; } namedWindow("input"); imshow("input",src); cvtColor(src,gray,COLOR_BGR2GRAY); namedWindow("result"); createTrackbar("value:","result",&init_value,max_value, subpix); subpix(0,0); waitKey(0); return 0; } void subpix(int, void*) { if (init_value <= 1) init_value = 1; vector<Point2f> corners; goodFeaturesToTrack(gray,corners,init_value,0.01,10,Mat(),3,false,0.04); dst = src.clone(); int r = 4; for (int i = 0; i < corners.size(); i++) { circle(dst,corners[i],3,Scalar(0,0,255),-1,8,0); } imshow("result",dst); Size winSize = Size(5,5); Size zeroZone = Size(-1, -1);//此值代表沒有死區 TermCriteria criteria = TermCriteria(TermCriteria::EPS+ TermCriteria::MAX_ITER,40,0.001); cornerSubPix(gray,corners,winSize,zeroZone,criteria); for (int i = 0; i < corners.size(); i++) { cout << " \t>>精確角坐標[" << i << "](" << corners[i].x<<"," << corners[i].y<<")" << endl; } }