opencv角点检测简介

1)相关概念
1兴趣点
在图像处理和计算机视觉领域,兴趣点也被称为 关键点或者特征点被大量用于解决物体识别,图像识别,图像匹配,视觉追踪,三维重建,等一系列问题,我们不再观察整幅图,而是选择某些特殊的点,然后对他们进行分析,如果能检测到足够的这种点,同时他们的区分度很高,并且可以精准定位稳定的特征,这个方法就具有实用价值,图像特征类型被分为如下三种:
*边缘
*角点(感兴趣关键点)
*斑点(Blob)(感兴趣区域)
2角点
角点通常被定义为两个边的交点,也被定义为在任意方向上的一个微小变动都会引起灰度很大变化的点,角点作为图像上的特征点,包含有重要的信息,在图像融合和目标追踪以及三维重建中有重要应用价值,另外,角点的描述可以有如下几种
&&一阶导数(灰度的梯度)的局部最大所对应的像素点
&&两条及两条以上边缘的交点
&&图像中梯度值和梯度放向的变化速率都很高的点
&&角点处一阶导数最大,二阶导数为0,他指明了物体边缘变化不连续的方向
3 角点检测
现有的角点检测算法并不是非常健壮,很多方法需要大量的训练集合冗余数据来防止或减少错误特征的出现,另外,角点检测方法的一个重要衡量标准是对多福图像中相同或相似特征的检测能力,并且能够应对光照变化,图像旋转等变化,目前的角点检测算法可以归结为以下三类
*基于灰度图像的 角点检测
*基于二值图像的角点检测
*基于轮廓曲线的 角点检测
基于灰度图像的角点检测又可以分为基于梯度,基于模板和基于模板梯度组合三类方法,其中基于模板的方法主要考虑像素邻域点的灰度变化,即图像亮度的变化,将与邻点亮度对比足够大的点定义为角点,常用的Harris角点检测算法就是基于模板的角点检测方法
2)Harris角点检测—cornerHarris()
harris角点检测是一种直接基于灰度图像的角点提取方法,稳定性高,但是由于采用高斯滤波,运算速度比较慢,角点信息有丢失和位置偏移的现象,以及聚蔟的现象 Opencv提供connerHarris()函数来进行harris角点检测,他是对每一个像素(x,y)在blockSize *blocksSize 邻域内,计算2*2梯度的协方差矩阵M(x,y)
就可以找到局部最大值,也就是找到了角点,可以用阈值化筛选自己要的角点
void cornerHarris(InputArray src ,OutputArray dst,int blockSize,int Ksize,double k,int borderType=BORDER_DEFAULT);
&&src:输入原图,需为8位单通道或浮点类型图像
&&dst:Harris角点检测结果,类型为CV_32FC1,大小和原图一样
&&blockSize:邻域大小,更多信息查看cornerEigenValsAndVecs()
&&ksize:表示Sobel()算子孔径大小
&&k:Harris检测常量参数,通常情况取值为0.04–0.0.6
&&borderType:图像像素的边界模式,一般采用默认值

Mat img=imread("2.jpg");
imshow("src",img);
Mat result=img.clone();
Mat gray;
cvtColor(img,gray,CV_BGR2GRAY);//转成单通道
Mat dst;
Mat corner_img;//存放检测后的角点检测
cornerHarris(gray,corner_img,2,3,0,04);//Harris角点检测
imshow("corner",corner_img);
threshold(corner_img,dst,0.005,255,CV_THRESH_BINARY);
imshow("dst",dst);
int rowNumber=gray.rows;//获取行数
int colNumber=gray.cols;//获取每一行的元素
cout<<rowNumber<<endl;
cout<<colNumber<<endl;
cout<<dst.type()<<endl;
for(int i=0,i<rowNumber;i++)
{
 for(int j=0;j<colNumber;j++)
 {
   if(dst.st<float>(i,j)==255)
   {
    circle(result,Point(j,i),5,Scalar(0,0,255),2,8);//画圆标记角点
   }
 }
imshow("result",result);
waitKey(0);
}

3)Shi-Tomasi角点检测–goodFeaturesToTrack()
Shi-Tomasi算法是Harris算法的改进,Harris算法最原始的定义是将矩阵M的行列式值与M的迹相减,再将差值同预先给定的阈值进行比较,后来Shi和Tomasi提供改进的方法,若两个特征值中较小的一个大于最小阈值,则会得到强角点
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:角点检测可接受的最小特征值,实际用于过滤角点的最小特征是qualityLevel和图像中最大特征值得乘积,所有qualityLevel一般不超过1(通常取0.10或者0.01)
&&minDistance:角点之间的最小距离,此参数用于保证返货的角点之间的距离不小于minDistance个像素
&&mask:可选参数,表示就感兴趣区域的掩码用于指定角点检测区域
&&blockSize:默认值3,是计算导数自相关矩阵时指定的邻域范围
&&useHarrisDetctor:默认值false,指定是否使用Harris角点检测
&&K:默认值0.04用于设置heaaian自相关矩阵行列式的相对权重的权重系数

Mat img=imread("0.jpg");
imshow("src",img);
Mat result=img。clone();
Mat gray;
cvtColor(img,gray,CV_BGR2GRAY);
vector<Point2f>corners;
goodFeaturesToTrack(gray,corners,100,0.01,10,Mat(),3,false,0.04);
count<<"角点数量"<<corners.size()<<endl;
for(int i=0;i<corners.size();i++)
{
 circle(result,corners[i],5,Scalar(0,255,0),2,8);
}
imshow("result",result);
waitKey(0);

4)亚像素角点检测——-cornerSubPix()
如果我们进行图像处理的目的不是提取用于之别的特征点,而是进行几何测量,通常需要更高的精度,而前面的角点检测方法都只能提供像素点坐标,但是有时候需要更高的精度比如亚像素(浮点坐标)精度,亚像素级角点检测在摄像机标定,三维结构重建方面是一个基本的测量值
void cornerSubPix(InputArray image,InputOutArray corners,Size winSize,Size zeroZone,TermCriteria criteria);
&&image:输入图像
&&corners:提供输入角点初始坐标和精确的输出坐标
&&winSize:搜索窗口的一半尺寸,若winSize=(5,5),那么表示使用(5*2+1)*(5*2+1)=11*11大小的搜索窗口
&&zeroZone:表示死区的一半尺寸,值为(-1,-1)表示没有死区
&&criteris:TermCriteria类型,表示求角点的迭代过程的终止条件,即角点位置的确定,cirteria可以是最大迭代数目,或者是设定的精度,也可以是他们的组合

Mat img=imread("3.jpg");
imshow("src",img);
Mat reult=img.clone();
Mat gray;
cvtColor(img,gray,CV_BGR2GRAY);
vector<Point2f>corners;
goodFeaturesToTrack(gray,corners,100,0.01,10,Mat(),3,fasle,0.04);
cout<<"角点数量"<<corners.size()<<endl;
for(int i=0;i<corners.size();i++)
{
  cout<<"像素坐标;("<<corners[i].x<<","<<corners[i],y<<")"<<endl;
  circle(result,corners[i],5,Scalar(0,255,0),2,8);
}
imshow("result",result);
Size winSize=Size(5,5);
Size zeroZone=Size(-1,-1);
//最大迭代数目或精度其中一个达到
TermCriteris criteria=TermCriteria(CV_TERMCRIT_EPS+CV_THETMCRIT_ITER,40,0.001);
cornerSubPix(gray,cornerswinSize,zeroZone,criteria);
for(int j=0;j<corners.size();j++)
{
  cout<<"亚像素坐标:("<<corners[j].x<<","<<corners[j].y<<")"<<endl;
  circle(img,corners[j],5,Scalar(0,255,0),-1,8);
}
imshow("subPix",img);
waitKey(0);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值