当前位置: 首页 > java >正文

OpenCV中特征匹配算法GMS(Grid-based Motion Statistics)原理介绍和使用代码示例

GMS(Grid-based Motion Statistics)算法,是由 Jiawang Bian 等人于 2017 年提出的一种快速、鲁棒的特征匹配过滤算法,全名为:

GMS: Grid-based Motion Statistics for Fast, Ultra-robust Feature Correspondence

该方法的目标是在传统特征匹配的结果上进行鲁棒过滤,显著提高内点比例(inlier ratio),避免使用 RANSAC 等代价高昂的方法。
在这里插入图片描述


一、论文背景与创新点

背景

  • 在计算机视觉任务中(如 SfM、SLAM、图像拼接),特征匹配是关键步骤;
  • 传统匹配器(如 ORB + BFMatcher)容易产生大量误匹配
  • 为了鲁棒性,通常使用 RANSAC 等几何模型估计器进行剔除,但计算代价较高

创新点

编号创新内容
1提出基于网格的一致性统计(GMS),利用特征分布的局部空间一致性代替代价昂贵的几何模型拟合
2完全无需几何模型(如单应性、基础矩阵等),仅用点对分布统计即可剔除误匹配
3支持尺度和旋转不变性扩展(Multi-scale + Multi-orientation)
4可实时处理(30+ fps),适合嵌入式系统和大规模特征任务

二、算法整体框架

整个 GMS 过程可视为两阶段

第一阶段:快速构建初始匹配点对(如 ORB + BFMatcher)
第二阶段:基于局部运动一致性的网格过滤策略进行匹配剔除


三、算法原理与步骤详解

1. 特征提取与初始匹配

  • 任意特征点提取器(如 ORB、AKAZE、SIFT)
  • 使用暴力匹配(BFMatcher)或 KD-Tree 得到初始 N 个匹配点对 (pi,qi)(p_i, q_i)(pi,qi)

该阶段不涉及 GMS,仅作为输入。


2. 构建图像网格(Grid)

  • 将图像划分为 G×GG \times GG×G 网格(例如 20×20)

  • 对每个匹配点对,将其两个端点分别落入图像 1 和图像 2 的网格中:

    • (pi∈Gridk),(qi∈Gridl)(p_i \in \text{Grid}_{k}), (q_i \in \text{Grid}_{l})(piGridk),(qiGridl)

核心思想:如果匹配是正确的,那么在某一网格及其邻域中,源图像与目标图像网格间应该存在较多的一致映射。


3. 局部一致性统计(Motion Kernel)

对每个网格单元格 Gridk\text{Grid}_kGridk,统计其到目标图像所有匹配方向的投票数:

  • 以网格 Gridk\text{Grid}_kGridk 的匹配点为中心;
  • 将其对应目标图像网格的映射方向用作运动向量;
  • 如果某方向得票最多且超过阈值(比如 >6),则认为该网格内的该方向为主运动。

GMS 就是利用这个局部“投票原则”来判断哪些匹配可信,哪些不是。


4. 多尺度与多旋转支持(增强 GMS)

由于真实场景中存在视角/尺度变化,GMS 原算法提供扩展:

多尺度 GMS(Scale-aware GMS)
  • 使用金字塔图像分别构建匹配;
  • 尝试多组网格尺寸(例如 G = 20, 40, 60…);
  • 每层做一遍 GMS,合并最终内点。
多旋转 GMS(Rotation-aware GMS)
  • 对目标图像旋转多个角度(通常是 8 个方向,如 0°, 45°, 90°…);
  • 在每个旋转版本上执行一次 GMS;
  • 得到最佳匹配组合。

这两项扩展显著增强了 GMS 的旋转 & 尺度不变性。


四、关键技术点总结

技术点描述
网格划分策略可调网格数(G=20~40),用于投票统计
运动核检测判断局部运动方向是否一致,以此投票过滤匹配
匹配投票阈值通常设为 6,表示区域内要有足够匹配一致性
支持邻域默认 3x3 邻域一致性统计(更鲁棒)
Multi-scale + Multi-rotation增强匹配在实际变换场景下的稳定性

五、优点总结

优点说明
快速无需几何模型拟合,纯粹使用空间投票
鲁棒在重复纹理、仿射变换等下仍有效
无描述子依赖可用于任意描述子的匹配结果过滤
易部署可直接用于特征匹配前端、VIO、图像配准等系统
实时性在 CPU 上可轻松 30~60 FPS 运行(上千点匹配)

六、不足与局限性

不足说明
无全局几何检验无法判断匹配是否符合某个几何模型(如单应、基础矩阵)
对遮挡/大量错配无显式建模多目标运动场景下存在误判风险
网格尺度敏感网格大小选择影响性能(需调参)
对特征分布密度敏感稀疏特征场景下效果下降

七、论文与资源链接

  • 论文地址:https://arxiv.org/abs/1701.08396
  • GitHub 示例(C++):https://github.com/JiawangBian/GMS-Feature-Matcher
  • OpenCV 实现:位于 opencv_contrib/modules/xfeatures2d/src/matching.cpp

八、可选改进方向建议

方向描述
融合 GMS 与 F matrix 单应性验证提升鲁棒性
用 CNN 替代手工网格统计GMS with learned kernels
利用 GMS 初步过滤,再进行局部几何估计(如 E matrix)应用于 VO/VIO

九、 OpenCV中使用示例

在 OpenCV 中,GMS(Grid-based Motion Statistics)特征匹配功能位于 xfeatures2d 模块(contrib 扩展),提供了一个极简接口用于从粗匹配中快速剔除误匹配。


9.1、函数接口说明:cv::xfeatures2d::matchGMS

namespace cv {
namespace xfeatures2d {/*** @brief Performs GMS (Grid-based Motion Statistics) feature matching filtering** @param size1         size of the first image* @param size2         size of the second image* @param keypoints1    keypoints from image1* @param keypoints2    keypoints from image2* @param matches1to2   initial matches (e.g., from BFMatcher)* @param matchesGMS    output: filtered matches after GMS* @param withRotation  enable rotation-invariant GMS (default: false)* @param withScale     enable scale-invariant GMS (default: false)* @param thresholdFactor threshold for motion consistency (default: 6.0)*/
void matchGMS(const Size& size1,const Size& size2,const std::vector<KeyPoint>& keypoints1,const std::vector<KeyPoint>& keypoints2,const std::vector<DMatch>& matches1to2,std::vector<DMatch>& matchesGMS,bool withRotation = false,bool withScale = false,double thresholdFactor = 6.0
);}} // namespace cv::xfeatures2d

参数详解

参数名类型说明
size1 / size2cv::Size两张图像的尺寸
keypoints1 / keypoints2std::vector<cv::KeyPoint>特征点列表
matches1to2初始匹配点对通常来自 ORB/SIFT + BFMatcher
matchesGMS输出GMS 过滤后的匹配结果
withRotationbool是否启用旋转不变性
withScalebool是否启用尺度不变性
thresholdFactordouble投票一致性阈值(建议为 6.0)

9.2、使用代码示例

以下代码展示如何用 ORB 提取特征,然后用 GMS 过滤匹配:

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <iostream>int main()
{cv::Mat img1 = cv::imread("img1.jpg", cv::IMREAD_GRAYSCALE);cv::Mat img2 = cv::imread("img2.jpg", cv::IMREAD_GRAYSCALE);if (img1.empty() || img2.empty()) {std::cerr << "Image loading failed!" << std::endl;return -1;}// 1. 特征提取auto orb = cv::ORB::create(1000);std::vector<cv::KeyPoint> kp1, kp2;cv::Mat desc1, desc2;orb->detectAndCompute(img1, cv::noArray(), kp1, desc1);orb->detectAndCompute(img2, cv::noArray(), kp2, desc2);// 2. 初始匹配(暴力匹配器)std::vector<cv::DMatch> matches_all;cv::BFMatcher matcher(cv::NORM_HAMMING);matcher.match(desc1, desc2, matches_all);// 3. GMS 过滤std::vector<cv::DMatch> matches_gms;bool withRotation = true;bool withScale = true;double threshold = 6.0;cv::xfeatures2d::matchGMS(img1.size(), img2.size(),kp1, kp2,matches_all,matches_gms,withRotation,withScale,threshold);std::cout << "Initial Matches: " << matches_all.size() << std::endl;std::cout << "GMS Matches:     " << matches_gms.size() << std::endl;// 4. 可视化cv::Mat img_matches;cv::drawMatches(img1, kp1, img2, kp2, matches_gms, img_matches);cv::imshow("GMS Filtered Matches", img_matches);cv::waitKey(0);return 0;
}

9.3、匹配结果示意图

匹配点通常可视化如下:

cv::drawMatches(img1, kp1, img2, kp2, matches_gms, img_matches);
cv::imshow("GMS Matches", img_matches);

可视化会看到原始匹配很多错误点,而 GMS 匹配线更加集中与正确区域。


9.4、实际应用建议

场景是否推荐使用 GMS
图像拼接强烈推荐
SLAM 前端可大幅减少误匹配输入
目标跟踪可提升匹配精度
小视差图像对齐特别有效
多目标匹配无法分辨多目标,建议配合几何验证(如单应矩阵)

http://www.xdnf.cn/news/15957.html

相关文章:

  • ZooKeeper学习专栏(三):ACL权限控制与Zab协议核心原理
  • 基于ECharts的电商销售可视化系统(数据预测、WebsSocket实时聊天、ECharts图形化分析、缓存)
  • CMake与catkin_make的find_package()命令使用说明
  • java和ptyhon对比
  • 多片RFSoC同步,64T 64R
  • 网络数据编码技术及其应用场景的全面解析
  • Spring Boot注解详解
  • 抽象类不能实例化原因
  • 自反馈机制(Self-Feedback)在大模型中的原理、演进与应用
  • ANSYS 2025 R1软件下载及安装教程|附安装文件
  • Dynamics 365 Contact Center是什么
  • 【Elasticsearch】settings
  • 【图论】CF——B. Chamber of Secrets (0-1BFS)
  • 讯飞输入法3.0.1742功能简介
  • node.js 为什么要装 express组件
  • DevCon 6记录
  • 数据库和数据仓库的区别
  • 轮状太空城的科学依据浅谈
  • ROS 与 Ubuntu 版本的对应关系
  • 热室机械手市场报告:智能装备推动高温制造自动化升级
  • 文远知行推出与联想共研的100%车规级HPC 3.0计算平台
  • 图立得-html纯前端图片拾色器V202507
  • [论文阅读] 人工智能 | ZipMPC:让短视的MPC拥有长远眼光——通过模仿学习压缩长 horizon 智慧
  • Pandas - JSON格式数据操作实践
  • 深入详解随机森林在医学图像质量评估中的应用与实现细节
  • git_guide
  • 关于JVM
  • 开源 Arkts 鸿蒙应用 开发(八)多媒体--相册和相机
  • QT6 源,七章对话框与多窗体(6) 颜色对话框 QColorDialog :本类的属性,信号函数,静态成员函数,以及源代码
  • “hidden act“:“gelu“在bert中作用