• OpenCV(四十六):特征点匹配


    1.特征点匹配的定义

           特征点匹配是一种在两幅图像中寻找相互对应的特征点,并建立它们之间的对应关系的过程。具体而言,首先通过特征检测算法在两幅图像中寻找相互对应的特征点,然后,对于每个特征点,通过描述子提取算法计算其描述子,最后,使用匹配算法对两组特征点的描述子进行比较,以找到相互匹配的特征点对。

    2.DMatch() 用于表示特征点匹配的数据结构

    cv::DMatch::DMatch ( int   queryldx,

    int    _trainldx,

    int     _imgldx,

    float  _distance

    )

    • queryIdx:查询描述子集合中的索引
    • trainIdx:训练描述子集合中的索引
    • imgldx:训练描述子来自的图像索引
    • distance:两个描述符之间的距离

    3.特征点匹配类DescriptorMatcher的介绍

            在OpenCV中,特征点匹配的类主要是cv::DescriptorMatcherDescriptorMatcher是一个抽象基类,用于特征点描述子之间的匹配操作。

    DescriptorMatcher类有以下常用方法和函数
       1.match():对两组特征描述子进行匹配,返回匹配结果(DMatch对象的向量)。

    void cv::DescriptorMatcher::match ( InputArray  queryDescriptors,

    InputArray    trainDescriptors,

    std::vector< DMatch > & matches,

    InputArray     mask = noArray()

    )const

    • queryDescriptors:查询描述子集合
    • trainDescriptors: 训练描述子集合
    • matches:两个集合描述子匹配结果
    • mask:描述子匹配时的掩码矩阵,用于指定匹配哪些描述子
      2.knnMatch():对两组特征描述子进行k近邻匹配,返回每个查询描述子的k个最佳匹配结果。

    void cv::DescriptorMatcher::knnMatch ( InputArray   queryDescriptors,

    InputArray   trainDescriptors,

    std::vector< std::vector< DMatch > > & matches,

    int     k,

    InputArray   mask = noArray(),

    bool    compactResult = false

    )const

    • queryDescriptors:查询描述子集合
    • trainDescriptors: 训练描述子集合
    • matches:描述子匹配结果
    • k:每个查询描述子在训练描述子集合中寻找的最优匹配结果的数目
    • mask:描述子匹配时的掩码矩阵,用于指定匹配哪些描述子。
    • compactResult:输出匹配结果数目是否与查询描述子数目相同的选择标志
      3.radiusMatch():对两组特征描述子进行半径匹配,返回每个查询描述子在指定半径内的最佳匹配结果。

    void cv::DescriptorMatcher::radiusMatch ( InputArray   queryDescriptors,

    InputArray    trainDescriptors,

    std::vector< std::vector< DMatch > > &matches,

    float     maxDistance,

    InputArray    mask = noArray(),

    bool   compactResult = false

    )const

    • queryDescriptors:查询描述子集合
    • trainDescriptors: 训练描述子集合
    • matches:描述子匹配结果
    • maxDistance:两个描述子之间满足匹配条件的距离阀值
    • mask:描述子匹配时的掩码矩阵,用于指定匹配哪些描述子
    • compactResult:输出匹配结果数目是否与查询描述子数目相同的选择标志

    4.特征点匹配函数BFMatcher()

    BFMatcher():暴力匹配

    cv::BFMatcher::BFMatcher ( int normType =ORM_L2,

    bool crossCheck = false

    )

    • normType:两个描述子之间距离的类型标志,可以选择的参数为NORM_LI、NORM_L2、NORM_HAMMING和NORM_HAMMING2。
    • crossCheck:是否进行交叉检测的标志。

    5.显示特征点匹配结果函数drawMatches()

    void cv::drawMatches ( InputArray   img1,

    const std::vector< KeyPoint > & keypoints1,

    InputArray    img2,

    const std::vector< KeyPoint > & keypoints2,

    const std::vector< DMatch > &matches1to2,

    InputOutputArray        outlmg,

    const Scalar &         matchColor = scalar: :all(-1),

    const Scalar &         singlePointColor = scalar: :all(-1),

    const std::vector&   matchesMask = std: :vector< char >(),

     DrawMatchesFlags     flags = DrawMatchesFlags: :DEFAULT

    )

    • imgl:第一张图像。
    • keypointsl:第一张图像中的关键点
    • img2:第二张图像。
    • keypoints2:第二张图像中的关键点。
    • matcheslto2:第一张图像中关键点与第二张图像中关键点的匹配关系。
    • outImg:显示匹配结果的输出图像。
    • matchColor:连接线和关键点的颜色。
    • singlePointColor: 没有匹配点的关键点的颜色
    • matchesMask:匹配掩码
    • flags:绘制功能选择标志

    6.示例代码

    1. void orb_fearures(Mat &gray,vector<KeyPoint> &keypoints,Mat &descriptions){
    2. Ptr<ORB> orb=ORB::create(1000,1.2f);
    3. orb->detect(gray,keypoints);
    4. orb->compute(gray,keypoints,descriptions);
    5. }
    6. void Matcher_f(Mat img1,Mat img2){
    7. //提取特征点
    8. vector<KeyPoint> keypoints1,keypoints2;
    9. Mat descriptions1,descriptions2;
    10. //计算特征点
    11. orb_fearures(img1,keypoints1,descriptions1);
    12. orb_fearures(img2,keypoints2,descriptions2);
    13. //特征点匹配
    14. vector<DMatch> matches;//定义存放匹配结果的变量
    15. BFMatcher matcher(NORM_HAMMING);//定义特征点匹配的类,使用汉明距离
    16. matcher.match(descriptions1,descriptions2,matches);//进行特征点匹配
    17. ostringstream ss;
    18. ss<<"matches="<<matches.size()<<endl;//匹配成功特征点数目
    19. //通过汉明距离删选匹配结果
    20. double min_dist=1000,max_dist=0;
    21. for(int i=0;i<matches.size();i++){
    22. double dist=matches[i].distance;
    23. if(dist<min_dist) min_dist=dist;
    24. if(dist>max_dist) max_dist=dist;
    25. }
    26. //输出所有匹配结果中最大韩明距离和最小汉明距离
    27. ss<<"min_dist="<<min_dist<<endl;
    28. ss<<"max_dist="<<max_dist<<endl;
    29. //将汉明距离较大的匹配点对删除
    30. vector<DMatch> good_matches;
    31. for(int i=0;i<matches.size();i++){
    32. if(matches[i].distance<=max(2*min_dist,20.0)){
    33. good_matches.push_back(matches[i]);
    34. }
    35. }
    36. ss<<"good_min="<<good_matches.size()<<endl;//剩余特征点数目
    37. LOGD("%s",ss.str().c_str());
    38. //绘制匹配结果
    39. Mat outimg,outimg1;
    40. drawMatches(img1,keypoints1,img2,keypoints2,matches,outimg);
    41. drawMatches(img1,keypoints1,img2,keypoints2,good_matches,outimg1);
    42. //显示结果
    43. imwrite("/sdcard/DCIM/outimg.png",outimg);//未筛选结果
    44. imwrite("/sdcard/DCIM/outimg1.png",outimg1);//最小汉明距离筛选
    45. }

    未筛选的特征点匹配结果 :

    最小汉明距离筛选特征点匹配结果:

  • 相关阅读:
    递归的本质
    kafka使用教程、快速上手
    Excel自定义函数提取超链接
    StreamLake“披荆斩棘”,消费到企业,快手进军PaaS能否一帆风顺
    19.7 Boost Asio 传输序列化数据
    Centos7 搭建JDK/Mysql8/redis/Nginx全套傻瓜指令
    【.NET 6+Loki+Grafana】实现轻量级日志可视化服务功能
    前端必备的 HTTP 知识
    红队内网攻防渗透:内网渗透之内网对抗:横向移动篇&入口差异&切换上线&IPC管道&AT&SC任务&Impacket套件&UI插件
    Python编程学习:random.shuffle的简介、使用方法之详细攻略
  • 原文地址:https://blog.csdn.net/weixin_63357306/article/details/132914789