这里写目录标题
1、特征点提取
(1)GFTT算法提取特征点
A.What(什么是GFTT)
B.GFTT的优势
- 稳定性好:GTFF 算法检测到的角点相对更加稳定,不容易出现聚簇现象,且角点信息的丢失和位置偏移也相对较少
- 参数可调节:通过设置相关参数,如最大角点数目、角点可接受的最小特征值、角点之间的最小距离等,可以根据具体需求和图像特点来优化特征点的提取效果
C.How(如何使用GFTT算法提取图像特征点)
int GetKpsByGTFF(const cv::Mat& imSrcGray, std::vector<cv::KeyPoint>& vkps)
{
//对参数进行检测
if(imSrcGray.empty() )
{
return -1;
}
if(imSrcGray.channels()!=1)
{
return -2;
}
if(!vkps.empty())
{
vkps.clear();
}
//提取图像特征点
cv::Ptr<cv::GFTTDetector> ptrGFTT =
cv::GFTTDetector::create(500, //关键点的最大数量
0.01, //角点的最小特征值
15); //角点之间允许的最短距离
ptrGFTT->detect(imSrcGray, vkps); //调用算法探测图像上的特征点
if(vkps.size()==0)
{ return -3; }
else
{ return 1; }
}
(2)FAST算法提取特征点
A.What(什么是FAST角点)
B.FAST角点的强度值
C.How(如何使用FAST算法提取图像特征点)
int GetKpsByFAST(const cv::Mat& imSrcGray, std::vector<cv::KeyPoint>& vkps)
{
//对参数进行检测
if(imSrcGray.empty() )
{
return -1;
}
if(imSrcGray.channels()!=1)
{
return -2;
}
if(!vkps.empty())
{
vkps.clear();
}
//使用FAST算法提取特征点
cv::Ptr<cv::FastFeatureDetector> ptrFAST =
cv::FastFeatureDetector::create(65);//65表关键点强度,即FAST角点的强度值(response)
ptrFAST->detect(imgSrcGray, vkps);
if(vkps.size()==0)
{
return -3;
}
else
{
return 1;
}
}
(3)BRISK算法提取特征点
A.What
B.How(如何使用BRISK算法提取特征点)
int GetKpsByBRISK(const cv::Mat& imSrcGray, std::vector<cv::KeyPoint>& vkps)
{
//对参数进行检测
if(imSrcGray.empty() )
{
return -1;
}
if(imSrcGray.channels()!=1)
{
return -2;
}
if(!vkps.empty())
{
vkps.clear();
}
//使用BRISK算法提取图像特征点
cv::Ptr<cv::BRISK> ptrBRISK =
cv::BRISK::create(60, 5); //60表示FAST角点的强度值必须达到60,才有可能被认为是关键点;5表示金字塔层数
ptrBRISK->detect(imSrcGray, vkps);
if (vkps.size() == 0)
{
return -3;
}
else
{
return 1;
}
}
(4)ORB算法提取特征点
A.What
- 特征点方向:每个被检测的兴趣点总是关联了一个方向。在FAST的中心点的圆形区域内计算重心,中心与重心的组成的向量即为该关键电的方向。
B.How(如何使用ORB算法提取特征点)
int GetKpsByORB(const cv::Mat& imSrcGray, std::vector<cv::KeyPoint>& vkps)
{
//对参数进行检测
if(imSrcGray.empty() )
{
return -1;
}
if(imSrcGray.channels()!=1)
{
return -2;
}
if(!vkps.empty())
{
vkps.clear();
}
//使用ORB算法对图像进行特征点提取
cv::Ptr<cv::ORB> ptrORB =
cv::ORB::create(500, 1.2, 8);//500:特征点数量;1.2:金字塔的缩放尺度;8:金字塔层数
ptrORB->detect(imSrcGray, vkps);
if (vkps.size() == 0)
{
return -3;
}
else
{
return 1;
}
}
2、描述子
(1)What
从数学的角度分析:要进行特征点的匹配,就应该考虑两个关键点的相似性,因此,如何衡量两个关键点的相似性成为了我们要考虑的首要问题
(2)How(如何衡量两个特征点相似性)
A.周围像素的特征
B.周围像素的描述子
C.基于深度学习的方法
(3)SIFT描述子实现关键点匹配
A.原理
B.How(如何得到SIFT特征点和描述子)
#include <opencv2/features2d/features2d.hpp>
int GetKpsAndDescriptorBySIFT(const cv::Mat& imSrc,
std::vector<cv::KeyPoint>& vkps,
cv::Mat& matDescriptor)
{
//对输入的参数进行检查
if (imSrc.empty())
{
return -1;
}
if (imSrc.channels() != 1)
{
return - 2;
}
if (!vkps.empty())
{
vkps.clear();
}
//提取关键点
cv::Ptr<cv::SIFT> ptrSIFT = cv::SIFT::create(500, 3);
ptrSIFT->detect(imSrc, vkps);
if (vkps.size() == 0)
{
return -3;
}
//计算关键点的描述子
ptrSIFT->compute(imSrc, vkps, matDescriptor);
if (matDescriptor.empty())
{
return -4;
}
return 1;
}
(4)ORB描述子实现关键点匹配
A.原理
B.BRIEF算法计算描述子
- 为减少噪声干扰,先对图像进行高斯滤波(方差为2,高斯窗口为9x9)
- 以特征点为中心,取s×s的邻域窗口,在窗口内随机选取一对点,比较二者像素的大小,进行二进制赋值:若p(x) > p(y),则赋值为1;若p(x) ≤ p(y),则赋值为0,其中p(x)、p(y)分别是随机点x=(u1,v1)、y=(u2,v2)的像素值。
- 在窗口中随机选取n对随机点(一般n=256),重复步骤2的二进制赋值,形成一个二进制编码,即特征描述子。
C.How(如何得到ORB特征点描述子)
int GetKpsAndDescriptorByORB(const cv::Mat& imSrc,
std::vector<cv::KeyPoint>& vkps,
cv::Mat& matDescriptor)
{
//对输入的参数进行检查
if (imSrc.empty())
{
return -1;
}
if (imSrc.channels() != 1)
{
return - 2;
}
if (!vkps.empty())
{
vkps.clear();
}
//提取ORB关键点
cv::Ptr<cv::Feature2D> ptrORB = cv::ORB::create(500, 1.2, 8);
ptrORB->detect(imSrc, vkps);
if (vkps.size() == 0)
{
return -3;
}
//计算关键点的描述子
ptrORB->compute(imSrc, vkps, matDescriptor);
if (matDescriptor.empty())
{
return -4;
}
return 1;
}