亚像素在提高检测精度上有着很大的作用,在实际的情况下,检测到的角点不会是一个准确的像素点,精确来说是一个浮点数角点,这样可以保证后面的三维重建及相机跟踪才能够更加精确。亚像素检测是基于曲线拟合的方式采用高斯,多项式及椭圆曲面来进行亚像素定位。
下图是亚像素的检测结果:

亚像素检测函数参数解释: 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;
}
}
来源:https://www.cnblogs.com/fuzhuoxin/p/12012347.html