OpenCV 亚像素级角点检测

角点检测可能应用于工业检测中,可以作为特征点作为后续处理的条件,也可以做图像分割,比如工件外轮廓由直线、圆弧等连接而成,可以通过角点检测把直线和圆弧分割开等。OpenCV中通过两个函数实现图像的亚像素级角点检测。
1、goodFeaturesToTrack()

void goodFeaturesToTrack(InputArray image, OutputArray corners, int maxCorners, double qualityLevel, double minDistance, InputArray mask=noArray(), int blockSize=3, bool useHarrisDetector=false, double k=0.04 )

寻找像素级角点。
参数:

image:输入8位或32位浮点单通道图像;

corners:输出检测角点的向量;

maxCorners:返回角落的最大数量,如果检测到更多的角度,就返回它们中的最强壮的一个;

qualityLevel:表征图像角点的最小可接受质量的参数,参数值乘以最好角点质量–最小特征值或哈里斯函数响应;

minDistance:返回角点之间可能的最小的欧氏距离;

mask:可选的感兴趣区域,如果角点是空的,它就指定了检测到角点的区域;

blockSize:用于计算每个像素领域的协变导数矩阵的平均块大小;

useHarrisDetector:使用哈里斯检测器的指示参数;

k:哈里斯探测器的自由参数;
2、cornerSubPix()

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

通过上述函数找到的角点进行亚像素级角点定位。
参数:

image:输入图像;

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

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

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

criteria:角点细化的迭代过程的终止条件;
3、创建TrackBar
自定义角点数。

createTrackbar("角点数", output_winName, &max_corners, max_count, SubPixel_Demo);  //创建TrackBar

4、代码实现

void SubPixel_Demo(int, void*)
{
	if (max_corners < 5)
	{
		max_corners = 5;   //控制下限
	}
	vector<Point2f> corners;           // 里面存放找到的角点坐标
	double qualityLevel = 0.01;
	double minDistance = 10;
	int blockSize = 3;
	double k = 0.04;

	// 调用goodFeaturesToTrack进行shi-Tomasi角点检测
	goodFeaturesToTrack(gray_img, corners, max_corners, qualityLevel, minDistance, Mat(), blockSize, false, k);
	cout << "角点数: " << corners.size() << endl;
	Mat result_img = src_img.clone();
	Mat result_img1 = src_img.clone();
	for (auto t = 0; t < corners.size(); ++t)
	{
		circle(result_img, corners[t], 2, Scalar(0,0,255), 2, 8, 0);    
	}
	
	// 参数设置
	Size winSize = Size(5, 5);
	Size zerozone = Size(-1, -1);
	TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001);
	cornerSubPix(gray_img, corners, winSize, zerozone, criteria);   	//  调用cornerSubPix函数计算出亚像素角点的位置

																		// 输出亚像素角点信息
	for (auto t = 0; t < corners.size(); ++t)
	{

		circle(result_img, corners[t], 2, Scalar(255, 0, 0), 2, 8, 0);
		cout << "亚像素角点坐标[" << t + 1 << "]" << " point[x, y] = " << corners[t].x << " , " << corners[t].y << endl;
		
	}
	imshow(output_winName, result_img);
}

5、结果
在这里插入图片描述
该代码是以前从大佬博客学习复制,今天写博客没有找到原作者,若涉嫌抄袭,请联系作者删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值