void matchPic(Mat img_11, Mat img_22, int *coor1, int *coor2)
{
  namedWindow("p2", 0);
  namedWindow("p1", 0);
  imshow("p2", img_11);
  imshow("p1", img_22);
//匹配范围坐标
  int xmin1 = coor1[0], xmax1 = coor1[1],ymin1 = coor1[2],  ymax1 = coor1[3];
  int xmin2 = coor2[0],  xmax2 = coor2[1],ymin2 = coor2[2], ymax2 = coor2[3];
  //匹配范围图像截取
  Mat im_1, im_2;
  im_1 = img_11(Range(ymin1, ymax1), Range(xmin1, xmax1));
  im_2 = img_22(Range(ymin2, ymax2), Range(xmin2, xmax2));
//分两部分匹配//1,3为初期图像,2,4为末期图像
  Mat image_1, image_2, image_3, image_4;
  image_1 = img_11(Range(ymin1, ymax1), Range(xmin1, (xmax1 + xmin1) / 2));
  image_2 = img_22(Range(ymin2, ymax2), Range(xmin2, (xmax2 + xmin2) / 2));
  image_3 = img_11(Range(ymin1, ymax1), Range((xmax1 + xmin1) / 2, xmax1));
  image_4 = img_22(Range(ymin2, ymax2), Range((xmax2 + xmin2) / 2, xmax2));

  Mat img_01, img_02, img_1, img_2, img_03, img_04, img_3, img_4, im_01, im_02, im_001, im_002;
  //锐化
  Mat kernel(3, 3, CV_32F, Scalar(-1));
  kernel.at<float>(1, 1) = 9.9;
  filter2D(image_1, img_01, -1, kernel);
  filter2D(image_2, img_02, -1, kernel);
  filter2D(image_3, img_03, -1, kernel);
  filter2D(image_4, img_04, -1, kernel);
  filter2D(im_1, im_01, -1, kernel);
  filter2D(im_2, im_02, -1, kernel);

  //灰度图转换
  cvtColor(img_01, img_1, CV_RGB2GRAY);
  cvtColor(img_02, img_2, CV_RGB2GRAY);
  cvtColor(img_03, img_3, CV_RGB2GRAY);
  cvtColor(img_04, img_4, CV_RGB2GRAY);
  cvtColor(im_01, im_001, CV_RGB2GRAY);
  cvtColor(im_02, im_002, CV_RGB2GRAY);
//开始匹配准备
  vector<KeyPoint> keyPoint1, keyPoint2, keyPoint3, keyPoint4;//四块图像关键点设置
  //提取角点,预设1500个角点
  Ptr<ORB> orb = ORB::create(1500, 1.2f, 8, 10, 0, 2, ORB::HARRIS_SCORE, 21, 20);
  //检测角点位置
  orb->detect(img_1, keyPoint1);
  orb->detect(img_2, keyPoint2);
  orb->detect(img_3, keyPoint3);
  orb->detect(img_4, keyPoint4);
//3、4坐标转换
  int i;
  for (i = 0; i < keyPoint3.size(); i++)
  {
   keyPoint3[i].pt.x = keyPoint3[i].pt.x + (xmax1 - xmin1) / 2;
  }
  for (i = 0; i < keyPoint4.size(); i++)
  {
   keyPoint4[i].pt.x = keyPoint4[i].pt.x + (xmax2 - xmin2) / 2;
  }
//另存角点坐标,1、3存于Point1,2、4存于Point2,作为两期图像的关键点
  vector<KeyPoint>  Point1, Point2;
  for (i = 0; i < keyPoint1.size(); i++)
  {
   Point1.push_back(keyPoint1[i]);
  }
  for (i = 0; i < keyPoint3.size(); i++)
  {
   Point1.push_back(keyPoint3[i]);
  }
  for (i = 0; i < keyPoint2.size(); i++)
  {
   Point2.push_back(keyPoint2[i]);
  }
  for (i = 0; i < keyPoint4.size(); i++)
  {
   Point2.push_back(keyPoint4[i]);
  }
//根据角点位置计算BRIEF描述子,001和002为两期图像的灰度图
  Mat descriptors_1, descriptors_2;
  orb->compute(im_001, Point1, descriptors_1);
  orb->compute(im_002, Point2, descriptors_2);
//输出检测出的所有特征点
  Mat outimg1;
  drawKeypoints(im_1, Point1, outimg1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
  namedWindow("全部特征点", 0);
  imshow("全部特征点", outimg1);
//对两幅图像中的BRIEF描述子进行匹配,使用 Hamming 距离
//DMatch是用于存放匹配结果的结构 ,包含以下参数
  //int queryIdx;  //此匹配对应的查询图像的特征描述子索引
  //int trainIdx;   //此匹配对应的训练(模板)图像的特征描述子索引 
  //int imgIdx;    //训练图像的索引(若有多个) 
  //float distance;  //两个特征向量之间的欧氏距离,越小表明匹配度越高。
  vector<DMatch> matches;
//创建一个BFMatcher匹配器,使用hamming距离//尝试所有可能的匹配,从而使得它总能够找到最佳匹配
  BFMatcher matcher(NORM_HAMMING);
//调用matcher的match方法进行匹配,这里用到了描述子,没有用关键点。
  matcher.match(descriptors_1, descriptors_2, matches);
//遍历matches[]数组,找出匹配点的最大距离和最小距离,用于后面的匹配点筛选。
  /*double min_dist1 = 0, max_dist1 = 0;//定义距离
  for (int i = 0; i < descriptors_1.rows; ++i)//遍历
  {
   double dist1 = matches[i].distance;
   if (dist1<min_dist1) min_dist1 = dist1;
   if (dist1>max_dist1) max_dist1 = dist1;
  }
  */
  //printf("Max dist: %f\n", max_dist1);
  //printf("Min dist: %f\n", min_dist1);
  //根据最小距离,对匹配点进行筛选
  std::vector<DMatch> good_matches;
  int j;
  for (j = 0; j < descriptors_1.rows; ++j)
  {
   //if (matches[j].distance <= max(2* min_dist1, 10.0))
   good_matches.push_back(matches[j]);
  }

  //绘制匹配结果
  /*
  Mat img_match;
  drawMatches(img_01, keyPoint1, img_02, keyPoint2, matches1, img_match);
namedWindow("所有匹配点对", 0);
  imshow("所有匹配点对", img_match);
 */
  Mat img_goodmatch;//筛选后的匹配点图
  drawMatches(im_1, Point1, im_2, Point2, good_matches, img_goodmatch);
  namedWindow("所有匹配点对", 0);
  imshow("所有匹配点对", img_goodmatch);
//利用RANSAC进行消除无匹配点
  //根据matches将特征点对齐,将坐标转换为float类型
  vector<KeyPoint> R_keypoint01, R_keypoint02;
  for (size_t i = 0; i < good_matches.size(); i++)
  {
   R_keypoint01.push_back(Point1[good_matches[i].queryIdx]);//查询特征描述索引
   R_keypoint02.push_back(Point2[good_matches[i].trainIdx]);//训练特征描述索引
   //这两句话的理解:R_keypoint1是要存储img01中能与img02匹配的特征点,
   //matches中存储了这些匹配点对的img01和img02的索引值
  }
//坐标转移
  vector<Point2f> p01, p02;
  for (size_t i = 0; i < good_matches.size(); i++)
  {
   p01.push_back(R_keypoint01[i].pt);
   p02.push_back(R_keypoint02[i].pt);
  }
vector<uchar> RansacStatus;
//利用基础矩阵剔除误匹配点
  //Mat Fundamental =findFundamentalMat(p01, p02, RansacStatus, FM_RANSAC);
//单应性矩阵剔除误差点
  Mat homography = findHomography(p01, p02, FM_RANSAC, 20, RansacStatus);
//重新定义RR_keypoint 和RR_matches来存储新的关键点和匹配矩阵
  vector<KeyPoint> RR_keypoint01, RR_keypoint02;
  vector<DMatch> RR_matches;
  int index = 0;
  for (size_t i = 0; i < good_matches.size(); i++)
  {
   if (RansacStatus[i] != 0)
   {
    RR_keypoint01.push_back(R_keypoint01[i]);
    RR_keypoint02.push_back(R_keypoint02[i]);
    good_matches[i].queryIdx = index;
    good_matches[i].trainIdx = index;
    RR_matches.push_back(good_matches[i]);
    index++;
   }
  }
//显示消除误匹配点的结果
  Mat img_RR_matches;
  drawMatches(img_11(Range(ymin1, ymax1), Range(xmin1, xmax1)), RR_keypoint01, img_22(Range(ymin2, ymax2), Range(xmin2, xmax2)), RR_keypoint02, RR_matches, img_RR_matches);
  namedWindow("消除误匹配点后", 0);
  imshow("消除误匹配点后", img_RR_matches);

  waitKey(0);
}

代码里有部份用到他人代码,仅用于个人学习。

交通指示牌的特征匹配代码相关推荐

  1. 学习笔记 2.1 — Harris角点检测与特征匹配【含实例】

    一. 图像特征匹配 最近刚入门了计算机视觉这门课程,觉得非常有意思,想象一下如果你能够自己做出一款全景拍照的软件,真实地令人激动,当然这全景图像其中的原理就是图像的特征匹配,把不同的图片通过相同的局部 ...

  2. SLAM之特征匹配(一)————RANSAC-------OpenCV中findFundamentalMat函数使用的模型

    目录 1.RANSAC原理 2. RANSAC算法步骤: 3. RANSAC源码解析 step one niters最初的值为2000,这就是初始时的RANSAC算法的循环次数,getSubset() ...

  3. akaze特征匹配怎么去掉不合适的点_图像匹配几种常见算法与实践

    奇技 · 指南 本文主要内容 1.模版匹配 2.特征匹配 3.深度学习去找目标 图像匹配的应用及背景 图像匹配是指通过一定的匹配算法在两幅或多幅图像之间识别同名点. 应用:遥感(制图更新),计算机视觉 ...

  4. FLANN特征匹配(Python)

    输入图片 算法输出图 可以看到,这里的算法效果比之前的ORB算法要好很多了! 可以点击来访问一下,就知道差别了~ ORB特征匹配(python) 代码 import cv2 from matplotl ...

  5. 图片SIFT特征匹配处理

    1.SIFT特征原理描述 SIFT的全称是Scale Invariant Feature Transform,由加拿大教授David G.Lowe提出的.SIFT特征不只具有尺度不变性,即使改变旋转角 ...

  6. 【图像处理】——特征匹配(SIFT特征检测器+FLANN特征匹配方法+KNN近邻最优匹配筛选)——cv.xfeatures2d.SIFT_create()sift.detectAndCompute

    转载请注明地址 目录 1.特征检测和特征匹配方法 (1)特征检测算法 (2)特征匹配算法 (3)各种特征检测算法的比较 2.特征匹配的基本步骤(附带主要的函数) (1)图像预处理--灰度化(模板--查 ...

  7. Harris的角点检测和特征匹配

    一.特征检测(提取) 基于特征的图像配准方法是图像配准中最常见的方法之一.它不是直接利用图像像素值,二十通过像素值导出的符号特征(如特征点.特征线.特征区域)来实现图像配准,因此可以克服利用灰度信息进 ...

  8. OpenCV2简单的特征匹配

    特征的匹配大致可以分为3个步骤: 特征的提取 计算特征向量 特征匹配 对于3个步骤,在OpenCV2中都进行了封装.所有的特征提取方法都实现FeatureDetector接口,DescriptorEx ...

  9. OpenCV精进之路(十五):特征检测和特征匹配方法汇总

    一幅图像中总存在着其独特的像素点,这些点我们可以认为就是这幅图像的特征,成为特征点.计算机视觉领域中的很重要的图像特征匹配就是一特征点为基础而进行的,所以,如何定义和找出一幅图像中的特征点就非常重要. ...

最新文章

  1. 云栖社区 测试技术社区大群 正式成立!还在等什么,快来加入我们...
  2. python频率_Python中的频率分析
  3. 用于Play框架分布式应用程序的Init.d Shell脚本
  4. php 注册自动登录,php – 创建第二个自动登录用户的登录页面
  5. Javaweb MVC设计模式、Modle发展史、项目分层和三层架构
  6. 2.3基本算法之递归变递推_3525上台阶
  7. 利用virt-manager,xmanager, xshell启动界面来管理虚拟机
  8. 给网站添加灰白滤镜(默哀主题色)
  9. UVA11219 How old are you?【日期】
  10. 【动态规划】LeetCode 377. Combination Sum IV
  11. JAVAweb开发中Ajax教程
  12. Java SE Lesson22_ClassLoader
  13. 使用python批量解压7z格式压缩包
  14. 一个 SAP 开发工程师的 2022 年终总结:四十不惑
  15. 肖哥教你解决安装和运行eNSP过程中遇到的各种问题
  16. word表格跨页显示时缺少上框线
  17. 未来哪些行业值得加入?
  18. matlab四维图形,MATLAB二维、三维、四维绘图
  19. 利用VBA代码解决Excel下拉菜单跳过空单元格的问题
  20. Linux命令:wget

热门文章

  1. 什么是数据模型?常用的数据模型有哪些?
  2. python处理word替换_python替换word中的关键文字(使用通配符)
  3. outlook服务器响应错误,outlook 错误代码解析与解决方法
  4. ubuntu 安装java运行环境,Ubuntu 安装java环境搭建
  5. 技术杂谈 | 分享Iteye的开涛对IoC的精彩讲解
  6. 某鱼最近卖的很火蓝色版微信去水印小程序源码+接口
  7. 2022年AI领域有哪些重要突破?(附报告全文)
  8. windows store 应用商店消失 ,找不到
  9. RASNet视频目标跟踪论文笔记
  10. Blazor发布问题,localhost可以访问,局域网无法访问