亚像素级角点定位原理及opencv实现

为何需要进行亚像素定位?


数字图像通常是离散化成像素;每个像素对应一个整数坐标位置;整数坐标位置对于很多应用并不精确,比如跟踪、相机标定、图像配准、图像拼接以及三维重构;为达到有些应用的精确性,需要精确到浮点坐标位置;所以亚像素定位问题。亚像素定位就是计算特征所在图像中的真实位置,而真实位置有时候并不在像素所在整数坐标位置上,而是在像素的内部。

image.png

点的灰度分布特征跟二维高斯模型很相似,中心处最亮,离中心距离越远会随之变暗。所以这里的图像特征,我们用高斯模型进行描述。

image.png

利用高斯模型,我们可以构建点的最终模型函数M,如下:


image.png

上述表达式中的各个参数解释如下:

>M:代表对应像素位置上的强烈程度

>(x,y):图像中某个像素位置

>A:背景的强烈程度,比如上面的黑色区域

>B:亮区域中的强烈程度的峰值

>(u,v):亮区域中的峰值所在的位置

>sigma:高斯模型方差

image.png

对应像素位置的强度与模型函数M估计出来的强度相同,那么我们认为用该模型匹配点区域的像素值是完美的,该模型是适合描述该区域的特征。事实上,在点区域里,保证不了左右两等式相等,我们只求左右两等式尽量逼近,求解模型的最佳参数,基本都是通过残差进行分析,如:

image.png

 在进行残差计算前,首先使用一个简单算法粗定位一个位置,将窗口中心移动至该位置上,再进行残差计算。我们的目的是最小化误差image.png,即可获取亚像素位置坐标(u,v)。 亚像素定位方法可以直接对误差函数的每一个参数进行偏导求取,也可以使用梯度下降法进行求解,最终得到模型的相关参数(这里极有可能得到的解是局部最优解)。当然求解的方法很多,最好使用的方法能解出全局最优解,这样解的模型才是最优的。

q1.png

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
 
#define WINDOW_NAME "Shi-Tomasi CornorDetect"
 
Mat src, gray;
vector<Point2f> corners;//声明为全局变量否则报错,圆心坐标
int maxCornerNum = 10;
int maxTrackbarNum = 300;
 
 
//滚动条回调函数
void cornersRefinement(int, void*){
	Mat copy = src.clone();
	if (maxCornerNum <= 1){
		maxCornerNum = 1;
	}
	//角点检测参数准备
	
	double qualityLevel = 0.2;//角点检测可接受的最小特征值0.01
	double minDistance = 10;//角点之间的最小距离
	int blockSize = 3;//计算导数自相关矩阵时的指定的领域范围
	double k = 0.04;//权重系数
 
	//进行Shi-Tomasi角点检测
	goodFeaturesToTrack(gray,
		corners,
		maxCornerNum,
		qualityLevel,
		minDistance,
		Mat(),
		blockSize,
		false,
		k);
	//像素级角点使用蓝色圆圈绘制
	for (int i = 0; i <maxCornerNum; i++){
		circle(copy, corners[i], 8, Scalar(255, 0, 0), 2, 8, 0);
	}
 
	/// 角点位置精准化参数
	Size winSize = Size(5, 5);
	Size zeroZone = Size(-1, -1);
	//迭代的终止条件
	TermCriteria criteria = TermCriteria(
		CV_TERMCRIT_EPS + CV_TERMCRIT_ITER,
		40, //maxCount=40
		0.001);    //epsilon=0.001
	/// 计算精准化后的角点位置
	cornerSubPix(gray, corners, winSize, zeroZone, criteria);
	//亚像素级角点使用品红色圆圈绘制
	for (int i = 0; i < maxCornerNum; i++){
		circle(copy, corners[i], 4, Scalar(255, 0, 255), 2, 8, 0);
		// 输出角点坐标  
		cout << " [" << i << "]  (" << corners[i].x << "," << corners[i].y << ")" << endl;
	}
	cout << endl;
	imshow(WINDOW_NAME, copy);
	
}
 
int main(){
	src = imread("Goldhill.bmp", 1);
	cvtColor(src, gray, CV_BGR2GRAY);
	namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE);
	imshow(WINDOW_NAME, src);
	
	createTrackbar("MaxNofCornor:", WINDOW_NAME, &maxCornerNum, maxTrackbarNum, cornersRefinement);
	cornersRefinement(0, 0);
 
 
	cvWaitKey(0);
	return 0;
}

————————————————

版权声明:本文为CSDN博主「凡是坚持」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_22424571/article/details/81674852



本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年4月    »
1234567
891011121314
15161718192021
22232425262728
2930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864