亚像素级角点检测
亚像素级角点检测
1、概念;
2、API;
3、Code;
亚像素级角点检测
1、若我们进行图像处理的目的不是提取用于识别的特征点而是进行几何测量,这通常需要更高的精度,而函数goodFeatureToTrack()只能提供简单的像素坐标值,即,有时需要实数坐标值而不是整数坐标值;
2、亚像素 级角点检测也即将角点检测的位置精确到亚像素级精度; 在摄像机标定,跟踪并重建摄像机的轨迹,或者重建被跟踪目标的三维结构时,是一个基本的测量值;
API
1、cornerSubPix()
: 寻找亚像素角点位置(不是整数类型的位置,而是更精确的浮点数类型的数据)
参数说明:
corner : 输入Shi-Tomasi找到的角点初始坐标,同时函数计算的精确坐标也将保存在其中
winSize : 搜索窗口尺寸的一半
zeroZone : 死区的大小
TermCriteria : 终止条件; criteria : 标准
//use
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, //设置终止条件为迭代次数和精确度
40, //设置迭代次数
0.001); //设置精确度
参考 : https://www.cnblogs.com/riddick/p/8476456.html
Code
//亚像素级角点检测
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat srcimg, grayimg, dstimg;
const char* input_win = "input image";
RNG rng(12345);
int corners_value = 30;
int corners_max = 100;
void on_SubPixelTest(int, void*);
int main(int argc, char** argv)
{
srcimg = imread("C:\\Users\\hello\\Desktop\\4.jpg");
if (srcimg.empty())
{
cout << "could not load the image.." << endl;
return -1;
}
imshow(input_win, srcimg);
cvtColor(srcimg, grayimg, CV_BGR2GRAY);
createTrackbar("最大角点数:", input_win, &corners_value, corners_max, on_SubPixelTest);
on_SubPixelTest(0, 0);
waitKey(0);
return 0;
}
void on_SubPixelTest(int, void*)
{
//
dstimg = srcimg.clone();
vector<Point2f> corners;
double quality = 0.01;
double mindistance = 10;
goodFeaturesToTrack(grayimg, corners, corners_value, quality, mindistance, Mat(), 3, false, 0.04);
cout << "> 此次检测到的角点数量为:" << corners.size() << endl;
//绘制点
for (int i = 0; i < corners.size(); i++)
{
circle(dstimg, corners[i], 5, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), -1, 8, 0);
}
imshow("亚像素检测", dstimg);
//亚像素角点检测参数设置
Size winSize = Size(5, 5); //搜索窗口大小为 11 * 11
Size zeroZone = Size(-1, -1); //死区尺寸设置
TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001);
//计算出亚像素角点位置
cornerSubPix(grayimg, corners, winSize, zeroZone, criteria);
//输出像素坐标
for (int i = 0; i < corners.size(); i++)
{
cout << "\t>>精确点坐标[" << i << "] (" << corners[i].x << "," << corners[i].y << ")" << endl;
}
}
效果
坐标值检测更精确: