代码:
#include "StereoMatch.h"
#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
using namespace cv;
using namespace cv::xfeatures2d;
#include <stdio.h>
using namespace std;
#include <Eigen/Eigen>
using namespace Eigen;
#include<chrono>
void FLANN_Mh(Mat &imgL, Mat imgR)
{
int keypoints_num = 400;
vector<KeyPoint>keypointL,keypointR;
Mat descritorL,descritorR;
Ptr<SURF> detector = SURF::create(keypoints_num); //创建SURF对象
detector->detectAndCompute(imgL,Mat(),keypointL,descritorL);
detector->detectAndCompute(imgR,Mat(),keypointR,descritorR);
chrono::steady_clock::time_point t1=chrono::steady_clock::now();
FlannBasedMatcher matcher;
vector<DMatch> matches; //匹配数据
matcher.match(descritorL,descritorR,matches); //描述匹配 将匹配结果存放至matches
//flann匹配基于距离匹配 进行最优距离查找
chrono::steady_clock::time_point t2=chrono::steady_clock::now();
chrono::duration<double> time_used=chrono::duration_cast<chrono::duration<double>>(t2-t1);
cout<<"FLANN方法的运行时间为:"<<time_used.count()<<"秒。"<<endl;
float maxdist = 3;
float mindist = 50;
//通过逐步收敛的办法查找到最大值最小值
for(int i=0;i<descritorL.rows;i++)
{
float distance = matches[i].distance;
distance*=100;
// cout<<"distance: "<<distance<<endl;
if(distance>maxdist)
maxdist = distance;
if(distance<mindist)
mindist = distance;
}
cout<<"maxdist: "<<maxdist<<endl;
cout<<"mindist: "<<mindist<<endl;
vector<DMatch> goodmatches; //定义最优的距离点集合
for(int i=0;i<descritorL.rows;i++)
{
float distance = matches[i].distance;
if(distance*100<=2*mindist)
{
//将查找到的最小距离添加到goodmatches中
goodmatches.push_back(matches[i]);
}
}
Mat matchimages;
//绘制匹配点 点数大大减少
drawMatches(imgL,keypointL,imgR,keypointR,goodmatches,matchimages);
waitKey(0);
while(1)
{
imshow("matchImages",matchimages);
int c= waitKey(0);
if (c==27)
break;
}
}
void ORB_Match(Mat &imgL, Mat imgR)
{
int keypoints_num = 400;
vector<KeyPoint>keypointL,keypointR;
Mat descritorL,descritorR;
Ptr<ORB> detector = ORB::create(keypoints_num); //创建SURF对象
detector->detectAndCompute(imgL,Mat(),keypointL,descritorL);
detector->detectAndCompute(imgR,Mat(),keypointR,descritorR);
chrono::steady_clock::time_point t1=chrono::steady_clock::now();
BFMatcher matcher(NORM_HAMMING); //hamming
vector<DMatch> matches; //匹配数据
matcher.match(descritorL,descritorR,matches); //描述匹配 将匹配结果存放至matches
chrono::steady_clock::time_point t2=chrono::steady_clock::now();
chrono::duration<double> time_used=chrono::duration_cast<chrono::duration<double>>(t2-t1);
cout<<"BF方法的运行时间为:"<<time_used.count()<<"秒。"<<endl;
double min=10000;
for(int i=0;i!=descritorL.rows;++i)
{
double dist=matches[i].distance;
//cout<<dist<<endl;
if(dist>=1)
min=min<dist?min:dist;
}
cout<<min<<endl;
//select good matchers
std::vector<DMatch> good_feature_match;
for(int i=0;i!=descritorL.rows;++i)
{
double dist=matches[i].distance;
if(dist<2.5*min&&dist>min)
good_feature_match.push_back(matches[i]);
}
cout<<good_feature_match.size()<<endl;
cv::Mat img_match,good_img_match;
drawMatches(imgL,keypointL,imgR,keypointR,matches,img_match);
drawMatches(imgL,keypointL,imgR,keypointR,matches,good_img_match);
while(1)
{
imshow("BF匹配结果",img_match);
imshow("处理后的BF匹配结果",good_img_match);
int c= waitKey(0);
if (c==27)
break;
}
}
int main()
{
Mat imgL = imread("../picture/left/left0.jpg",-1);
Mat imgR = imread("../picture/right/right0.jpg",-1);
//ComputePyramid_brief(imgL);
// ComputePyramid_brief(imgR); //resize
FLANN_Mh(imgL, imgR);
ORB_Match(imgL, imgR);
//ComputeStereoMatches(imgL , imgR);
waitKey(0);
}
效果对比:
FLANN和BF匹配运行时间对比:
FLANN是类似最近邻的快速匹配库
它会根据数据本身选择最合适的算法来处理数据
比其他搜索算法快10倍
BF是暴力匹配
这里记录一个想法,在双目特征提取匹配过程中,其实不需要暴力匹配的,因为双目可以认为两个摄像头的距离保持不变,就是单目基础上平移了基线长度的距离的两个单目。那么共视的程度保持不变。那么左图摄像头的特征点,应该能在右图对应位置的某个范围内能沟找到该特征点。
这样则不用全局匹配。暂时不知道flann的原理