最近复现SLAM14讲第7讲关于ORB的代码,特征提取的原理懂了,opencv里的实现方式,特别是如何构造特征点提取函数、描述子函数和暴力匹配等方法的函数不熟悉,因此翻到了《opencv编程入门》第三版了解了解,对整个流程有了个概念。我发现我的opencv版本不能构建fast的描述子,sift更是没有了,sift好像被专利保护了吧。目前只能用ORB了,其他的也暂时用不到,先不管了。
//关键点
FeatureDetector featuredector;
//还可以Ptr构造智能指针型,比较安全,要指定特征点类型
//Ptr featuredector = ORB::create();
vector<KeyPoint> keypoints1, ketpoints2;
featuredector.detect(image1,keypoints1);
//描述子
Mat descriptor1, descriptor2;
DescriptorExtractor extractor;
//智能指针构造
Ptr<DescriptorExractor> extractor = ORB::create();
extractor.compute(image1, keypoints1, descriptor1);
//计算距离,通用的方法
Ptr<DescriptorMatcher> mathcer = DescriptorMatcher::create(2);
/*
FLANNBASED = 1,
BRUTEFORCE = 2,
BRUTEFORCE_L1 = 3,
BRUTEFORCE_HAMMING = 4,
BRUTEFORCE_HAMMINGLUT = 5,
BRUTEFORCE_SL2 = 6
*/
//也可以用暴力匹配的名称构造(仅限于BF)
//BFmathcer matcher;
vector<DMatch> matches;
matcher->match(descriptor1,descriptor2, matches);
int main()
{
Mat src_image = imread("3.png",0);
Ptr<FeatureDetector> featuredector = ORB::create();
vector<KeyPoint> keypoint1;
featuredector->detect(src_image,keypoint1);
//descriptor
Ptr<DescriptorExtractor> descriptorExtractor = ORB::create();
Mat descriptor1;
descriptorExtractor->compute(src_image,keypoint1,descriptor1);
//训练BF //TODO
BFMatcher matcher;
vector<Mat> train_desc(1,descriptor1);
matcher.add(train_desc);
matcher.train();
VideoCapture cap(0);
while(char(waitKey(1))!='q')
{
Mat captureimage;
double time0 = cvGetTickCount();
cap >> captureimage;
cvtColor(captureimage,captureimage,COLOR_RGB2GRAY);
if (captureimage.empty())
continue;
vector<KeyPoint> keypoint2;
featuredector->detect(captureimage,keypoint2);
Mat descriptor2;
descriptorExtractor->compute(captureimage,keypoint2,descriptor2);
//knn树匹配
vector<vector<DMatch>> matches;
matcher.knnMatch(descriptor2,matches,2);
vector<DMatch> goodmatches;
for (int i = 0; i < matches.size(); ++i) {
if (matches[i][0].distance < matches[i][1].distance * 0.6)
goodmatches.push_back(matches[i][0]);
}
Mat dstimage;
drawMatches(src_image,keypoint1,captureimage,keypoint2,goodmatches,dstimage);
imshow("dstimage",dstimage);
cout << "frame fs = " << getTickFrequency() / (cvGetTickCount() - time0) << endl;
}
return 0;
}
//初始化ORB特征点提取器,描述子、距离计算——bruteforce
Ptr<FeatureDetector> orb = ORB::create();
vector<KeyPoint> KeyPoints1_, KeyPOints2_;
Ptr<DescriptorExtractor> extractor = ORB::create();
vector<DMatch> matches;
orb->detect(image_1,KeyPoints1_);
orb->detect(image_2,KeyPOints2_);
Mat descriptor1, descriptor2;
extractor->compute(image_1,KeyPoints1_,descriptor1);
extractor->compute(image_2,KeyPOints2_,descriptor2);
//暴力匹配
BFMatcher matcher;
matcher.match(descriptor1,descriptor2,matches);
//找到最大、最小距离
double min_dst = 1000000.0;
double max_dst = 0.0;
for (int i = 0; i < matches.size(); ++i) {
if (matches[i].distance < min_dst)
min_dst = matches[i].distance;
}
//筛除误匹配特征
vector<DMatch> goodmatches;
for (int j = 0; j < matches.size(); ++j) {
if (matches[j].distance <= max(30.0, 2*min_dst))
goodmatches.push_back(matches[j]);
}