【OpenCV学习笔记】OpenCV角点检测汇总(深入feature2D组件)——亚像素级角点检测

前言

亚像素级角点检测的位置在摄像机标定,跟踪并重建摄像机的轨迹,或者重建被跟踪目标的三维结构时,是一个基本的测量值;
这就需要比较高的精度,而前面我们提到的goodFeaturesToTrack()函数只能提供简单的像素坐标(因为有时候我们需要的是实数坐标而不是整数坐标)

关于亚像素级角点检测的算法

本人能力有限无法清晰的阐述,所以有兴趣的小伙伴可以访问

https://blog.csdn.net/lwzkiller/article/details/54910784

正文

opencv中提供了 cornerSubPix(),函数用于寻找亚像素焦点位置(浮点型)
API:

void cornerSubPix( InputArray image,
				InputOutputArray corners,
				Size winSize, 
				Size zeroZone,
                TermCriteria criteria 
                );
  • 第一个参数,源图像
  • 第二个参数,类型corners ,verctor< Point2f >提供输入角点的初始坐标和精确的输出坐标(既是输入又是输出)
  • 第三个参数,搜索窗口一半的尺寸。若winSize=Size(5,5),那么搜索窗口大小为(52 + 1)(5*2 + 1) = 11 * 11 大小的搜索窗口
  • 第四个参数,表示死区的一尺寸半,作用用来规避自相关矩阵出现某些可能的奇异性,(-1,-1)表示没有死区
  • 第五个参数,TermCriteria类型的criteria,求角点的迭代过程的终止条件。
关于TermCriteria构造函数

转载于:https://blog.csdn.net/ilyhlf5201314/article/details/8232746

CvTermCriteria
迭代算法的终止准则
#define CV_TERMCRIT_ITER    1
#define CV_TERMCRIT_NUMBER  CV_TERMCRIT_ITER
#define CV_TERMCRIT_EPS     2
 
typedef struct TermCriteria
 {
  int    type;  /* CV_TERMCRIT_ITER 和CV_TERMCRIT_EPS二值之一,或者二者的组合 */
  int    max_iter; /* 最大迭代次数 */
  double epsilon; /* 结果的精确性 */
 }
 CvTermCriteria;
/* 构造函数 */
inline  CvTermCriteria  cvTermCriteria( int type, int max_iter, double epsilon );
/* 在满足max_iter和epsilon的条件下检查终止准则并将其转换使得type=CV_TERMCRIT_ITER+CV_TERMCRIT_EPS */
CvTermCriteria cvCheckTermCriteria( CvTermCriteria criteria,
                                    double default_eps,
                                    int default_max_iters 
                                    );

代码:

# include <opencv2\opencv.hpp>
# include <iostream>
using namespace std;
using namespace cv;
Mat src, dst, gray_src;
int max_corners = 30;
int max_count = 50;
const char *output_tittle = "Subpixel Result";
void Subpixel_Demo(int, void *);
int main(int argc, char**argv) {
	
	src = imread("H:\\tuku\\city.jpg");
	if (!src.data)
	{
		cout << "can't find the picture...";
		return -1;
	}
	imshow("in put", src);
	cvtColor(src, gray_src, COLOR_BGR2GRAY);
	namedWindow(output_tittle, 1);
	createTrackbar("Corners:", output_tittle, &max_corners, max_count, Subpixel_Demo);
	Subpixel_Demo(0, 0);
	waitKey(0);
	return 0;
}
void Subpixel_Demo(int, void*) {
	if (max_corners < 5) {
		max_corners = 5;
	}
	vector<Point2f> corners;
	double quality_level = 0.01;
	double minDistance = 10;
	int BlockSize = 3;
	int ksize = 3;
	double k = 0.04;
	goodFeaturesToTrack(gray_src, corners, max_corners, quality_level, minDistance, Mat(), BlockSize, false, k);
	cout << "number of corners:" << corners.size()<<endl;
	Mat ResultImag = src.clone();
	for (size_t i = 0; i < corners.size(); i++) {
		circle(ResultImag, corners[i], 2, Scalar(0, 0, 255), 2, 8, 0);
	}
	//建立goodTeaturesToTrack()目的 获取corners来输出精确坐标
	imshow(output_tittle, ResultImag);
	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 << t + 1 << ",Point[x,y]=" << corners[t].x << "," << corners[t].y << endl;
	}
}

效果图

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值