ORB特征点由FAST角点与BRIEF描述子组成,首先通过FAST角点确定图像中与周围像素存在明显差异的像素点作为关键点,之后计算每个关键点的BRIEF描述子,从而唯一确定ORB特征点。
FAST角点通过比较图像像素灰度值变化确定关键点,其核心思想:如果在某个灰度值较小的区域中存在一个灰度值明显较大的像素点,此像素点在该区域就会有明显特征,以此作为特征点。此算法比较某区域中心像素灰度值与周围像素灰度值的关系,如果周围像素值与中心像素灰度值相比存在较大差异,那么可以判定其为FAST角点,计算过程如下:
第一步:选择某个像素点作为中心点*p*,其像素值为*Ip*。
第二步:设置判定FAST角点的像素阈值,例如*Tp=20%*Ip*
第三步:比较中心点p的像素值与半径为3的圆周上所有像素的像素值,如果存在连续N个像素的像素值大于(*Ip+Tp*)或者小于(*Ip-Tp*)那么中心点p为FAST角点,N一般选择12,称为FAST-12角点。
第四步:遍历图像中每个像素点,重复上述步骤,计算图像中的FAST角点。
Opencv4提供了直接检测图像ORB特征点的ORB类及其相关函数,该类继承了Features2D类,因此可以通过Features2D类中的detect()函数与compute()函数计算关键点和描述子,但是,前提是要先定义ORB类变量,用于表明从Features2D类中继承的函数是计算ORB特征点及ORB特征点数目等。ORB类中提供了create()函数用于创建ORB类变量,该函数原型如下。
static Ptrcv::ORB::create(int nfeatures=500,
float scaleFactor=1.2f,
int nlevels=8,
int edgeThreshold=31,
int firstLevel=0,
int WTA_K=2,
ORB::ScoreType scoreType=ORB::HARRIS_SCORE,
int patchSize=31,
int fastThreshold =20)
nfeatures:检测ORB特征点的数目。
scaleFactor:"金字塔"尺寸缩小的比例,如果是2,那么表示“金字塔”的下层图像尺寸是上层图像的2倍。
nlevels:"金字塔"层数。
edgeThreshold:边缘阈值。
firstLevel:将原图像放入“金字塔”中的等级,例如放入第0层。
WTA_K:生成每位描述子时需要的像素点数目。
scoreType:检测关键点时关键点的评价方法。
patchSize:生成描述子时关键点周围邻域的尺寸。
fastThreshold:计算FAST角点时像素值差值的阈值。
以下是使用案例:
#include
#include
#include
using namespace std;
using namespace cv;
int main() {
Mat img = imread("D:/样本/lena.png");
if (!img.data) {
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Ptr<ORB>orb = ORB::create(500, 1.2f, 8, 31, 0, 2, ORB::HARRIS_SCORE, 31, 20);
vector<KeyPoint>Keypoints;
orb->detect(img, Keypoints);
Mat descriptions;
orb->compute(img, Keypoints, descriptions);
Mat imgAngel;
img.copyTo(imgAngel);
drawKeypoints(img, Keypoints, img, Scalar(255, 255, 255));
drawKeypoints(img, Keypoints, imgAngel, Scalar(255, 255, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imshow("不含角度和大小的结果", img);
imshow("含有角度和大小的结果", imgAngel);
waitKey(0);
return 0;
}