features2d_1_特征点检测与匹配

本文详细介绍了OpenCV中的一角点检测算法,如Harris和Shi-Tomasi,以及如何创建自定义角点检测。接着,讨论了特征检测与匹配,包括KeyPoint类、FeatureDetector、DescriptorExtractor等,提到了FAST、BRISK、SIFT、SURF和ORB等特征检测器,并展示了它们的应用和性能对比。最后,文章探讨了特征匹配的方法,如BFMatcher和FlannBasedMatcher,以及如何寻找已知物体。
摘要由CSDN通过智能技术生成

一角点检测

兴趣点=关键点=特征点,检测足够多的点,同时他们的区分度很高,则可以精确定位稳定的特征
特征类型分为:
[1]边缘
[2]角点(感兴趣关键点)
[3]斑点(Blobs) (感兴趣区域)

角点是在任意方向的一个微小变动都会引起灰度很大的变化的点。
角点:
[1]一阶导数(灰度的梯度)的局部最大所对应的像素点
[2]两条及两条以上边缘的交点
[3]图像中梯度和梯度方向的变化速率都很高的点
[4]角点处的一阶导数最大,二阶导数为0,它指示了物体边缘变化不连续的方向

1,Harris角点检测
基于灰度图像的角点提取算法,稳定性高。采用高斯滤波,速度较慢,角点信息有丢失和位置偏移的现象,有聚簇现象。
针对每一个像素,在blockSize×blockSize的邻域内,计算
这里写图片描述
这里写图片描述
根据设定的阈值threshold,如果R>threshold,则判断为角点

void cornerHarris(InputArray src, OutputArray dst, 
                  int blockSize, int ksize, double k, 
                  int borderType=BORDER_DEFAULT )
//src,单通道8-bit或浮点型图像
//dst,与src同size,type为CV_32FC1,用来存储R值
//blockSize,针对每一个像素的邻域大小
//ksize,进行Sobel边缘检测的ksize
//k,计算公式中的参数k
//borderType,边界拓展类型                  

应用:

//转化成灰度图
cv::cvtColor(image,Image,CV_BGR2GRAY);

//进行角点检测
cv::Mat process;
int blockSize=2;
int ksize=3;
double k=0.04;
cv::cornerHarris(Image,process,blockSize,ksize,k);

//进行归一化,使值落在0~255
cv::normalize(process,process,0,255,cv::NORM_MINMAX,
              CV_32FC1);

//对于大于设定阈值的点,判断为角点
int thresh=120;
for(int i=0;i<result.rows;i++)
for(int j=0;j<result.cols;j++)
if(process.at<float>(i,j)>thresh)
{
cv::circle(result,cv::Point(j,i),5,cv::Scalar(0,0,255),2);
}

效果图:
这里写图片描述

2,Shi-Tomasi角点检测
用于强角点的检测,是Harris算法的改进版,两个特征值中较小的一个大于最小阈值,会得到强角点
角点检测原理:
[1]首先利用cornerHarris()或者cornerMnEigenVal(),计算角点的质量
[2]执行非极大抑制,在3*3邻域内局部最大值被保留
[3]有最小特征值比这里写图片描述还要小的点被抛弃
[4]剩下的角点,根据质量进行递减排序
[5]根据角点间距离minDistance,留下质量好的角点

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-bit或者32位浮点型
 *corners,输出被检测到的角点向量,vector<Point2f>
 *maxCorners,角点的最大数量
 *qualityLevel,用于计算最小特征值的参数,最小特征值
 *=qualityLevel×最大特征值,一般为0.01/0.1
 *minDistance,角点间的最小距离
 *mask,掩码
 *blockSize,每个像素邻域
 *useHarrisDetector,如果true使用cornerHarris(),否则
 *cornerMnEigenVal()
 *k,Harris的参数
 */                         

应用:

//转化成灰度图
cv::cvtColor(image,Image,CV_BGR2GRAY);

//查找角点
std::vector<cv::Point2f> corners;
cv::goodFeaturesToTrack(Image,corners,100,0.01,8);

cv::Size winSize(5,5);
cv::Size zeroZone(-1,-1);
cv::TermCriteria criteria=
cv::TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,40,0.01);
//进行亚像素精确化
cv::cornerSubPix(Image,corners,winSize,zeroZone,criteria);
//进行标记
for(int i=0;i<corners.size();i++)
{
cv::circle(result,corners[i],5,cv::Scalar(0,0,255),2);
}

效果图:
这里写图片描述

3,创建自己的角点检测
1>计算角点检测特征值和特征向量
对于每一个像素p,在blockSize×blockSize区域内,通过Sobel计算协变矩阵:
这里写图片描述

这里写图片描述为M的非排序特征值。
x1,y1为这里写图片描述的特征向量
x2,y2为这里写图片描述的特征向量
存储在dst中这里写图片描述

void cornerEigenValsAndVecs(InputArray src, OutputArray dst, 
                            int blockSize, int ksize, 
                            int borderType=BORDER_DEFAULT )
//src,单通道,8-bit或浮点型图像
//dst,与src同size,type为CV_32FC(6)
//blockSize,邻域大小
//ksize,Sobel边缘检测的ksize
//borderType,边界拓展类型                            

2>为角点检测,计算梯度矩阵的最小的特征值
用来寻找这里写图片描述中的最小值

void cornerMinEigenVal(InputArray src, OutputArray dst, 
                       int blockSize, int ksize=3, 
                       int borderType=BORDER_DEFAULT )
//src,单通道,8-bit或浮点型图像
//dst,存储最小的特征值,与src同size,type为CV_32
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值