ORB特征提取
ORB是Oriented Brief的简称,是brief的改进版本(在原有的描述子的基础上增加了旋转不变性,ORB算法综合性能在各种评测里相较于其他特征提取算法是最好的。
1.Brief描述子
Brief(Binary Robust Independent Elementary Feature)的缩写。描述子选取的主要思路:在特征点的附近随机的选取若干个点对,将这些点的灰度值的大小,组合成一个二进制串,并将这个二进制串作为特征点的特征描述子。
BRIEF的优点在于速度,缺点:
2.尺度不变性
ORB没有解决尺度不变性,因为FAST本就不具备尺度不变性,但是对于以速度为主的描述子,一般应用于实时的视频处理中。
3.计算速度
ORB算法的执行速度是SIFT的100倍,是SURF的10倍。
从opencv3.4.15源码路径下的features2d.hpp文件中可以看到:
该实例采用摄像头获取检测图像,使用FLANN-LSH进行匹配。
实现代码:
#include
#include
#include
using namespace std;
using namespace cv;
int main()
{
//[0]载入原图,并转化为灰度图
Mat srciamge = imread("../3.png");
imshow("原始图", srciamge);
Mat grayImage;
cvtColor(srciamge, grayImage, COLOR_BGR2GRAY);
//[1]参数定义
Ptr<ORB> featureDector = ORB::create();
vector<KeyPoint> keypoints;
Mat descriptors;
//[2]调用detect函数检测出特征关键点,保存在keypoints中
featureDector->detect(grayImage, keypoints);
cout << "========" << keypoints.size() << endl;
//[3]计算描述符(特征向量)
Ptr<ORB> descriptor = ORB::create();
descriptor->compute(grayImage, keypoints, descriptors);
//[4]基于FLANN的描述符对象匹配
flann::Index flannindex(descriptors, flann::LshIndexParams(12, 20, 2), cvflann::FLANN_DIST_HAMMING);
// Ptr flannindex= DescriptorMatcher::create("FlannBased");
//[5]初始化视频采集对象
VideoCapture cap(0);
cap.set(CAP_PROP_FRAME_WIDTH, 360); //设置采集视频的宽度
cap.set(CAP_PROP_FRAME_HEIGHT, 800); //高度
unsigned int frameCount = 0; // 帧数
// [6]轮询,直接按下ESC退出循环
while(1) {
double time0 = static_cast<double>(getTickCount()); //记录其实时间
Mat captureImage, captureImage_gray;//用于视频采集
cap >> captureImage; //采集视频帧
if(captureImage.empty())
continue;
cvtColor(captureImage, captureImage_gray, COLOR_BGR2GRAY);
//[7]绘制SIFT关键点并提取测试图像中的描述符
vector<KeyPoint> capturekeypoints;
Mat captureDescription;
//[8]调用detecta函数检测出关键点,并保存在容器中
featureDector->detect(captureImage_gray, capturekeypoints);
//[9]计算描述符
descriptor->compute(captureImage_gray, capturekeypoints, captureDescription);
imshow("x", captureImage_gray);
//[10]匹配和测试描述子,获取两个最近的描述子
Mat matchIndex(captureDescription.rows, 2, CV_32SC1);
Mat matchDistance(captureDescription.rows, 2, CV_32FC1);
flannindex.knnSearch(captureDescription, matchIndex, matchDistance, 2, flann::SearchParams());
//[11]根据劳式算法选出优秀的匹配
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);
}
}
//[12] 绘制并显示匹配框口
Mat resultImage;
drawMatches(captureImage, capturekeypoints, srciamge, keypoints, goodMatches,resultImage);
imshow("匹配窗口", resultImage);
//[13]显示帧率
cout << "帧率:" << getTickCount() / (getTickCount() - time0) << endl;
// 按下ESC退出
if(char (waitKey(1) == 27)) break;
}
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE "Debug")
find_package(OpenCV 3.4 REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(open 1.cpp)
target_link_libraries(open ${OpenCV_LIBS})
knnSearch
函数解析:
void cv::flann::GenericIndex
使用索引对给定查询点执行k-最邻近搜索。
参数: