OpenCV图像特征提取与检测C++(五)特征描述子--Brute-Force匹配、FLANN特征匹配、平面对象识别、AKAZE局部特征检测与匹配、BRISK特征检测与匹配、ORB特征提检测与匹配

特征描述子
即图像中每个像素位置的描述,通过此描述去匹配另一张图像是否含有相同特征。
暴力匹配:Brute-Force
图像匹配本质上是特征匹配。因为我们总可以将图像表示成多个特征向量的组成,因此如果两
幅图片具有相同的特征向量越多,则可以认为两幅图片的相似程度越高。而特征向量的相似程度通常是用它们之间的欧氏距离来衡量,欧式距离越小,则可以认为越相似。
代码:

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include<iostream>
#include<math.h>
#include <string> 
#include<fstream> 
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;

int main() {
    Mat src1, src2;
    src1 = imread("C:/Users/Administrator/Desktop/pic/04.jpg");
    src2 = imread("C:/Users/Administrator/Desktop/pic/03.jpg");
    imshow("src1", src1);
    imshow("src2", src2);

    int minHessian = 400;
    Ptr<SURF> detector = SURF::create(minHessian);
    vector<KeyPoint> keypoints1;
    vector<KeyPoint> keypoints2;
    Mat descriptor1, descriptor2;
    detector->detectAndCompute(src1,Mat(), keypoints1, descriptor1);
    detector->detectAndCompute(src2,Mat(), keypoints2, descriptor2);
    cout << "keypoint1.size=" << keypoints1.size() << endl;
    cout << "keypoint2.size=" << keypoints2.size() << endl;
    cout << "descriptor1 depth" << descriptor1.depth()<<",type=" <<descriptor1.type()<< endl;
    cout << "descriptor2 depth" << descriptor2.depth() << ",type=" << descriptor2.type() << endl;

    BFMatcher matcher(NORM_L2); //Brute - Force 匹配,参数表示匹配的方式,默认NORM_L2(欧几里得) ,NORM_L1(绝对值的和)
    vector<DMatch>matches;// 保存匹配的结果
    matcher.match(descriptor1, descriptor2, matches); //在descriptor_2中暴力匹配descriptor_1中含有的特征描述子匹配
    cout << "matches.size=" << matches.size() << endl;
    Mat dst;
    drawMatches(src1, keypoints1, src2, keypoints2, matches, dst);
    imshow("dst", dst);
    waitKey(0);
}

结果:
这里写图片描述

FLANN特征匹配
算法速度特别快
特征匹配记录下目标图像与待匹配图像的特征点(KeyPoint),并根据特征点集合构造特征量(descriptor),对这个特征量进行比较、筛选,最终得到一个匹配点的映射集合。我们也可以根据这个集合的大小来衡量两幅图片的匹配程度。

代码:

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include<iostream>
#include<math.h>
#include <string> 
#include<fstream> 
using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;

int main() {
    Mat src1, src2;
    src1 = imread("C:/Users/Administrator/Desktop/pic/test3.jpg");
    src2 = imread("C:/Users/Administrator/Desktop/pic/test4.jpg");
    imshow("src1", src1);
    imshow("src2", src2);

    int minHessian = 300;
    Ptr<SURF> detector = SURF::create(minHessian);// 也可以用 SIFT 特征
    vector<KeyPoint> keypoints1; // 保存特征点
    vector<KeyPoint> keypoints2;
    Mat descriptor1, descriptor2;// 特征描述子
    detector->detectAndCompute(src1, Mat(), keypoints1, descriptor1);
    detector->detectAndCompute(src2, Mat(), keypoints2, descriptor2);
    cout << "keypoint1.size=" << keypoints1.size() << endl;
    cout << "keypoint2.size=" << keypoints2.size() << endl;
    cout << "descriptor1 depth" << descriptor1.depth() << ",type=" << descriptor1.type() << endl;
    cout << "descriptor2 depth" << descriptor2.depth() << ",type=" << descriptor2.type() << endl;

    FlannBasedMatcher matcher; //Flann匹配
    vector<DMatch>matches;// 保存匹配的结果
    matcher.match(descriptor1, descriptor2, matches); //在descriptor_2中匹配descriptor_1中含有的特征描述子匹配
    cout << "matches.size=" << matches.size() << endl;

    //找到好的匹配点
    double minDist = 1000;
    double maxDist = 0;
    for (int i = 0; i < descriptor1.rows; i++) {
        cout << "matches[" << i << "].queryIdx" << matches[i].queryIdx << ","<<endl;
        cout << "matches[" << i << "].trainIdx" << matches[i].trainIdx << ","<<endl;
        cout << "matches[" << i << "].distanIdx" << matches[i].distance<< ","<<endl;
        double dist = matches[i].distance;
        if (dist > maxDist) {
            maxDist = dist;

        }
        if (dist < minDist) {
            minDist = dist;
        }
    }
    cout << "maxdistance=" << maxDist << endl;
    cout << "mindistance=" << minDist << endl;
    vector<DMatch>goodMatches;
    for (int i = 0; i < descriptor1.rows; i++) {
        double dist = matches[i].distance;
        if (dist < max(3 * minDist, 0.02)) {
            goodMatches.push_back(matches[i]);
        }
    }

    Mat dst;
    drawMatches(src1, keypoints1, src2, keypoints2, goodMatches, dst, Scalar::all(-1),
        Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
    imshow("
  • 1
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值