1.原理:
假设起始角点在实际亚像素角点附近,检测所有q-p向量,下面两种情况点p梯度与q-p向量的点积均为0:(1)点p附近图像均匀,即点p处梯度为0(2)边缘的梯度与沿边缘方向的q-p向量正交(向量与其正交向量点积为0),如下图:
则可以在p点周围找到很多组梯度以及相关向量q-p,令其点积为0,求解方程组,解即为角点q的亚像素级精度位置。
2.作用:
将角点位置精确到亚像素级精度(精确的浮点类型位置),可用于几何测量、摄像机标定、跟踪并重建摄像机的轨迹。
1.作用:
寻找亚像素级角点
2.函数原型:
void cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteria criteria)
3.参数说明:
(1)输入图像
(2)输入角点的初始坐标和精确的输出坐标
(3)搜索窗口一半,若 winSize=Size(5,5),表示使用(5*2+1)*(5*2+1)=11*11大小窗口
(4)死区一半,死区为不对搜索区的中央位置做求和运算的区域,用来避免自相关矩阵出现的某些可能的奇异性,值(-1,-1)表示没有死区
(5)求角点的迭代过程的终止条件。即角点位置的确定,迭代数大于或精确达到某设定值,此参数为最大迭代数或精确度或它们的组合
/*
程序说明:在Shi-Tomasi角点检测示例程序基础上,在on_GoodFeaturesToTrack()回调函数中加上亚像素角点检测代码,完成亚像素级角点检测
*/
#include
#include
#include
using namespace cv;
using namespace std;
//定义辅助宏
#define WINDOW_NAME "【亚像素级角点检测】"
//全局变量
Mat g_srcImage, g_grayImage, g_dstImage;
int g_maxCornerNumber = 30;
int g_maxTrackbarNumber = 500;
RNG g_rng(12345);
//全局函数
void on_GoodFeaturesToTrack(int, void*);
void ShowHelpText();
int main()
{
cout << "\n\n\t欢迎来到【亚像素角点检测】示例程序\n" << endl;
//载入原图
g_srcImage = imread("1.jpg",1);
cvtColor(g_srcImage, g_grayImage, COLOR_RGB2GRAY);
namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE);
imshow(WINDOW_NAME, g_srcImage);
//创建滑动条,回调函数初始化
createTrackbar("最大角点数", WINDOW_NAME, &g_maxCornerNumber, g_maxTrackbarNumber, on_GoodFeaturesToTrack);
on_GoodFeaturesToTrack(0, 0);
waitKey(0);
return 0;
}
void on_GoodFeaturesToTrack(int, void*)
{
//对变量小于1时的处理
if (g_maxCornerNumber <= 1) { g_maxCornerNumber = 1; }
//【1】Shi-Tomasi算法参数设置
vector<Point2f>corners;
double qualityLevel = 0.01;
double minDistance = 10;
int blockSize = 3;
double k = 0.04;
g_dstImage = g_srcImage.clone();
//进行Shi-Tomasi角点检测
goodFeaturesToTrack(g_grayImage, corners, g_maxCornerNumber, qualityLevel, minDistance, Mat(), blockSize, false, k);
//输出文字信息
cout << "\t>此次检测到的角点数量为:" << corners.size() << endl;
//绘制角点
int r = 4;
for (int i = 0; i < corners.size(); i++)
{
//以随机颜色绘制出角点
circle(g_dstImage, corners[i], r, Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)), -1, 8, 0);
}
//显示更新窗口
imshow(WINDOW_NAME, g_dstImage);
//【2】亚像素角点检测参数设置
Size winSize = Size(5, 5);
Size zeroZone = Size(-1, -1);
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001);
//计算出亚像素角点位置
cornerSubPix(g_grayImage, corners, winSize, zeroZone, criteria);
//输出角点信息
for (int i = 0; i < corners.size(); i++)
{
cout << "\t>>精确角点坐标[" << i << "](" << corners[i].x << "," << corners[i].y << ")" << endl;
}
}