【图像处理】ORB算法提取、描述、匹配特征点
程序员文章站
2024-03-25 23:33:46
...
这几天学习了OpenCV的最后部分特征提取,为了巩固知识,做个ORB算法的笔记;
ORB算法我觉得不仅在计算速度上比SIFT和SURF快,而且效果也比他们好。
1、ORB特征检测:FAST算法
这个定义基于特征点周围的图像灰度值,检测候选特征点周围一圈的像素值,如果候选点周围领域内有足够多的像素点与该候选点的灰度值的差别够大,则认为该候选点为一个特征点
FAST算法,使用N个周边像素来比较 即FAST-N,
2、ORB描述子,特征向量
Brief算法的核心思想是在关键点P的周围以一定的模式选取N个点对,把这个点对的比较结果组合起来作为描述子
示例代码:
#include<opencv2/opencv.hpp>
#include<opencv2/features2d/features2d.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/nonfree/features2d.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage = imread("demo.jpg", 1);
imshow("原始图",srcImage);
//灰度化
Mat grayImage;
cvtColor(srcImage,grayImage,COLOR_BGR2GRAY);
//检测SIFT特征点,并在图像中提取物体的描述符
OrbFeatureDetector featureDetector; //创建特征点检测对象
vector<KeyPoint> keyPoint;
Mat descriptors;
//调用detect函数检测特征关键点,保存在vector容器中
featureDetector.detect(grayImage,keyPoint);
//计算描述符 特征向量
OrbDescriptorExtractor featureExtractor; //创建特征点描述对象
featureExtractor.compute(grayImage,keyPoint,descriptors);
//基于FLANN的描述符对象匹配
flann::Index flannIndex(descriptors,flann::LshIndexParams(12,20,2),cvflann::FLANN_DIST_HAMMING);
//初始化视频采集
VideoCapture cap(0);
cap.set(CV_CAP_PROP_FRAME_HEIGHT,720);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 720);//设置采集视频的宽度
unsigned int frameCount = 0; //帧数
while (1)
{
double time0 = static_cast<double>(getTickCount()); //记录起始时间
Mat captureImage,captureImage_gray; //定义两个变量用于视频采集
cap>>captureImage;//采集视频
if(captureImage.empty())
continue;
cvtColor(captureImage,captureImage_gray,COLOR_BGR2GRAY);//将采集到的视频图像转化为灰度图
//检测SIFT关键点并提取测试图像中的描述符
vector<KeyPoint> captureKeyPoint;
Mat captureDescription;
featureDetector.detect(captureImage_gray,captureKeyPoint);
//计算描述符
featureExtractor.compute(captureImage_gray, captureKeyPoint,captureDescription);
//匹配和测试描述符,获取两个最近的描述符
Mat matchIndex(captureDescription.rows,2,CV_32SC1);
Mat matchDistance(captureDescription.rows, 2, CV_32FC1);
flannIndex.knnSearch(captureDescription,matchIndex,matchDistance,2,flann::SearchParams()); //调用K临近算法
//选出优秀的匹配点对
vector<DMatch> goodMatches;
for (int i = 0; i < matchDistance.rows; i++)
{
if (matchDistance.at<float>(i, 0) < 0.6*matchDistance.at<float>(i, 1))
{
DMatch dmatches(i,matchIndex.at<int>(i,0),matchDistance.at<float>(i,0));
goodMatches.push_back(dmatches);
}
}
//绘制并显示匹配窗口
Mat resultImage;
drawMatches(captureImage,captureKeyPoint,srcImage,keyPoint,goodMatches,resultImage);
imshow("匹配窗口",resultImage);
cout<<"帧率"<<getTickFrequency()/(getTickCount()-time0)<<endl;
if(char(waitKey(1)) == 27)
break;
}
return 0;
}
上一篇: git的基本流程