亚像素角点检测

        常规的角点检测算法输出的角点坐标是整数,即角点位置恰好与像素位置重合。

        实际场景中角点位置是连续的,而相机的像素是离散的,两者总是有偏差。如果需要基于图像进行几何测量,这个偏差是不能容忍的。这就是亚像素角点检测问题的背景。相比常规角点检测,亚像素角点检测用实数取代整数来表示角点坐标。

亚像素角点检测算法

亚像素角点检测需要先运行常规的角点检测,得到整数表示的角点坐标。然后算法对每个角点做细化,得到实数表示的角点坐标

第一步:goodFeaturesToTrack()    //检测角点

第二步:TermCriteria()            //设置迭代算法的终止条件

TermCriteria(int type,int max_iter, double epsilon);

参数

type:终止条件类型;

CV_TERMCRIT_ITER--max_iter达到最大值后停止算法;

CV_TERMCRIT_EPS--当算法依赖的精确度低于epsilon后,停止算法;

CV_TERMCRIT_ITER+CV_TERMCRIT_EPS--当max_iter达到最大值或算法依赖的精确度低于epsilon任一个满足时,停止算法;

max_iter:最大迭代次数;

epsilon:要求精度;
 

第三步:cornerSubPix()         //细化角点位置;

void cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteria criteria);

参数:

image:输入图像;

corners:初始化输入角点的坐标,为输出提供细化的坐标;

winSize:搜索窗口的边长的一半;

zeroZone:搜索区域中间的死区的一半大小,对它在下边的求和公式不计算,有时候它用来避免可能的自相关矩阵的奇异性,(-1,-1)用来表明这里没有这样的规模;

criteria:角点细化的迭代过程的终止条件;

代码示例:

#include <iostream>
#include "opencv2/opencv.hpp"


using namespace cv;
using namespace std;

int num_corners = 10;
int max_count = 100;
Mat src, gray_src;
const char* output_title = "SubPixel Result";
void SubPixel_Demo(int, void*);
int main(int argc, char** argv) 
{
	src = imread("D:/cv400/house.jpg");
	if (src.empty()) 
	{
		cout<<"could not load image..."<<endl;
		return -1;
	}
	namedWindow("input image", WINDOW_AUTOSIZE);
	imshow("input image", src);
	cvtColor(src, gray_src, COLOR_BGR2GRAY);
	namedWindow(output_title, WINDOW_AUTOSIZE);
	createTrackbar("Corners:", output_title, &num_corners, max_count, SubPixel_Demo);
	SubPixel_Demo(0, 0);

	waitKey(0);
	return 0;
}

void SubPixel_Demo(int, void*) 
{
	if (num_corners < 5)
		num_corners = 5;

	vector<Point2f> corners;
	double qualityLevel = 0.01;
	double minDistance = 10;
	int blockSize = 3;
	double k = 0.04;
	goodFeaturesToTrack(gray_src, corners, num_corners, qualityLevel, minDistance, Mat(), blockSize, false, k);
	cout << "number of corners: " << corners.size() << endl;
	Mat resultImg = src.clone();
	for (size_t t = 0; t < corners.size(); t++)
		circle(resultImg, corners[t], 2, Scalar(0, 0, 255), 2, 8, 0);
	imshow(output_title, resultImg);

	Size winSize = Size(5, 5);
	Size zerozone = Size(-1, -1);
	TermCriteria tc = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001);
	cornerSubPix(gray_src, corners, winSize, zerozone, tc);

	for (size_t t = 0; t < corners.size(); t++)
		cout << "corners"<<(t + 1) << " .[x, y] = " << corners[t].x << " , " << corners[t].y << endl;
	
	return;
}

原图:

角点检测:

角点坐标:

猜你喜欢

转载自blog.csdn.net/andylanzhiyong/article/details/84675463
今日推荐