• OpenCV(四十七):RANSAC优化特征点匹配


    1.RANSAC算法介绍

     RANSAC是一种常用的参数估计方法,全称为Random Sample Consensus(随机抽样一致性)。它的主要思想是通过随机选择一部分数据样本,构建模型并评估其拟合程度,迭代过程中逐步优化模型,最终得到一个拟合较好的模型。

    其基本流程如下:

    • 随机取样,计算规律(特征点匹配中计算单应矩阵)
    • 测试规律是否满足大多数数据
    • 循环前两步
    • 选取最佳规律,并输出满足数据的点

    2.RANSAC优化特征点匹配结果的函数findHomography()

    Mat cv::findHomography ( InputArray srcPoints,

    InputArray       dstPoints,

    int            method = 0,

    double     ransacReprojThreshold =3,

    OutputArray mask = noArray(),

    const intmaxlters = 2000,

    const double confidence = 0.995

    • SrcPoints:原始图像中特征点的坐标
    • dstPoints:目标图像中特征点的坐标
    • method:计算单应矩阵方法的标志
    • ransacReprojThreshold; 重投影的最大误差
    • mask:掩码矩阵,使用RANSAC算法时表示满足单应矩阵的特征点
    • maxIters:RANSAC算法迭代的最大次数
    • confidence:置信区间,取值范围0-1

    3.示例代码

    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. //RANSAC算法实现
    7. void ransac(vector<DMatch> matches,vector<KeyPoint> queryKeyPoint,vector<KeyPoint> trainKeyPoint,vector<DMatch> &matches_ransac){
    8. //定义保存匹配点对坐标
    9. vector<Point2f> srcPoints(matches.size()),dstPoints(matches.size());
    10. //保存从关键点中提取到的匹配点对坐标
    11. for(int i=0;i<matches.size();i++){
    12. srcPoints[i]=queryKeyPoint[matches[i].queryIdx].pt;
    13. dstPoints[i]=trainKeyPoint[matches[i].trainIdx].pt;
    14. }
    15. //匹配点对进行RANSAC过滤
    16. vector<int> inliersMask(srcPoints.size());
    17. findHomography(srcPoints,dstPoints,RANSAC,5,inliersMask);
    18. //手动的保留RANSAC过滤的匹配点对
    19. for(int i=0;i<inliersMask.size();i++){
    20. if(inliersMask[i]){
    21. matches_ransac.push_back(matches[i]);
    22. }
    23. }
    24. }
    25. void Ransac_f(Mat img1,Mat img2){
    26. //提取特征点
    27. vector<KeyPoint> keypoints1,keypoints2;
    28. Mat descriptions1,descriptions2;
    29. //计算特征点
    30. orb_fearures(img1,keypoints1,descriptions1);
    31. orb_fearures(img2,keypoints2,descriptions2);
    32. //特征点匹配
    33. vector<DMatch> matches;//定义存放匹配结果的变量
    34. BFMatcher matcher(NORM_HAMMING);//定义特征点匹配的类,使用汉明距离
    35. matcher.match(descriptions1,descriptions2,matches);//进行特征点匹配
    36. ostringstream ss;
    37. ss<<"matches="<<matches.size()<<endl;//匹配成功特征点数目
    38. //通过汉明距离删选匹配结果
    39. double min_dist=1000,max_dist=0;
    40. for(int i=0;i<matches.size();i++){
    41. double dist=matches[i].distance;
    42. if(dist<min_dist) min_dist=dist;
    43. if(dist>max_dist) max_dist=dist;
    44. }
    45. //输出所有匹配结果中最大韩明距离和最小汉明距离
    46. ss<<"min_dist="<<min_dist<<endl;
    47. ss<<"max_dist="<<max_dist<<endl;
    48. //将汉明距离较大的匹配点对删除
    49. vector<DMatch> good_matches;
    50. for(int i=0;i<matches.size();i++){
    51. if(matches[i].distance<=max(2*min_dist,20.0)){
    52. good_matches.push_back(matches[i]);
    53. }
    54. }
    55. ss<<"good_min="<<good_matches.size()<<endl;//剩余特征点数目
    56. LOGD("%s",ss.str().c_str());
    57. //用ransac算法筛选匹配结果
    58. vector<DMatch> good_ransac;
    59. ransac(good_matches,keypoints1,keypoints2,good_ransac);
    60. //绘制匹配结果
    61. Mat outimg2;
    62. drawMatches(img1,keypoints1,img2,keypoints2,good_ransac,outimg2);
    63. //显示结果
    64. imwrite("/sdcard/DCIM/outimg2.png",outimg2);//ransac筛选
    65. }

    ransac筛选结果: 

  • 相关阅读:
    C. You Are So Beautiful Codeforces Round 905 (Div. 2)
    一、React基础知识
    MySQL锁(乐观锁、悲观锁、多粒度锁)
    Linux bash 添加用户命令 adduser 和 useradd 对比试用 2208110652
    [Linux] Linux文件编程 1.1 文件打开及创建
    数字经济的下一步:Web3的潜力与前景
    处理器ChannelHandler的线程安全问题
    基于遥感和GIS技术的生态承载力评价的解决方案
    单基因泛癌+实验简单验证,要素丰富,没研究方向的赶紧上车
    「洛谷 P3834」「模板」可持久化线段树 题解报告
  • 原文地址:https://blog.csdn.net/weixin_63357306/article/details/132917262