亚像素角点检测
亚像素角点检测原理:
为了检测出图像中精确的亚像素角点,可以采用如下的算法。
API介绍:
1.cornerSubPix()函数
image: 输入图像,即源图像;
corners: 提供输入角点的初始坐标和精确的输出坐标。
winSize: Size类型,表示搜索窗口的半径。若winSize=Size(5,5),那么就表示使用(5*2+1)x(5*2+1)=11*11大小的搜索窗口。
zeroZone: Size类型,表示死区的一半尺寸。而死区为不对搜索区的中央位置做求和运算的区域,用来避免自相关矩阵出现的某些可能的奇异性。
值为(-1,-1)表示没有死区。
criteria: TermCriteria类型,求角点的迭代过程的终止条件。
2.其中criteria: TermCriteria类型的定义如下
TermCriteria(int type,int maxCount,double epsilon);
参数说明:
1.type 迭代终止条件类型
type=TermCriteria::MAX_ITER/TermCriteria::COUNT 迭代到最大迭代次数终止
type= TermCriteria::EPS 迭代到阈值终止
type= TermCriteria::MAX_ITER+ TermCriteria::EPS上述两者都作为迭代终止条件
2.maxCount 迭代的最大次数
3.epsilon 阈值(中心位移值)
下面的代码这样定义的:TermCriteria tc = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001);
1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 4 using namespace cv; 5 using namespace std; 6 int max_corners = 20; 7 int max_count = 50; 8 Mat src, gray_src; 9 const char* output_title = "SubPixel Result"; 10 void SubPixel_Demo(int, void*); 11 int main(int argc, char** argv) { 12 src = imread("L:/6.jpg"); 13 if (src.empty()) { 14 printf("could not load image...\n"); 15 return -1; 16 } 17 namedWindow("input image", CV_WINDOW_AUTOSIZE); 18 imshow("input image", src); 19 cvtColor(src, gray_src, COLOR_BGR2GRAY); 20 namedWindow(output_title, CV_WINDOW_AUTOSIZE); 21 createTrackbar("Corners:", output_title, &max_corners, max_count, SubPixel_Demo); 22 SubPixel_Demo(0, 0); 23 24 waitKey(0); 25 return 0; 26 } 27 28 //亚像素检测函数: 29 void SubPixel_Demo(int, void*) { 30 if (max_corners < 5) { 31 max_corners = 5; 32 } 33 vector<Point2f> corners; 34 double qualityLevel = 0.01; 35 double minDistance = 10; 36 int blockSize = 3; 37 double k = 0.04; 38 goodFeaturesToTrack(gray_src, corners, max_corners, qualityLevel, minDistance, Mat(), blockSize, false, k); 39 //ShiTomasi角点检测函数的API 40 cout << "number of corners: " << corners.size() << endl; 41 //C++的快速打印函数:cout<< "内容" << 变量.size(打印变量的size) <<endl 42 Mat resultImg = src.clone(); 43 for (size_t t = 0; t < corners.size(); t++) { 44 circle(resultImg, corners[t], 2, Scalar(0, 0, 255), 2, 8, 0); 45 //检测出的corners是一个数组 ,所以直接用corners.[]表示对应的点 46 } 47 imshow(output_title, resultImg); 48 49 //参数定义: 50 Size winSize = Size(5, 5); //Size类型,表示搜索窗口的半径。 51 //若winSize=Size(5,5),那么就表示使用(5*2+1)x(5*2+1)=11*11大小的搜索窗口。 52 53 Size zerozone = Size(-1, -1); 54 //Size类型,表示死区的一半尺寸。而死区为不对搜索区的中央位置做求和运算的区域, 55 //用来避免自相关矩阵出现的某些可能的奇异性。值为(-1,-1)表示没有死区。 56 57 TermCriteria tc = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001); 58 //TermCriteria类型,求角点的迭代过程的终止条件。 见上图API详解 59 // 参数:1.type 迭代终止条件类型 2.maxCount 迭代的最大次数 3.epsilon 阈值(精度) 60 61 cornerSubPix(gray_src, corners, winSize, zerozone, tc); 62 //亚像素检测参数:1.输入图像 2.亚像素角点 3.检测窗口大小 4.zerozone 5.tc 63 for (size_t t = 0; t < corners.size(); t++) { 64 cout << "精确角点坐标[" << t + 1 << "]" << " .point[x, y] = " << corners[t].x << " , " << corners[t].y << endl; 65 } 66 return; 67 }
结果如下:
优质内容筛选与推荐>>