- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
cv::detail::BestOf2NearestRangeMatcher 是 OpenCV 库中用于图像拼接模块的一个匹配器类,专门用于寻找两幅图像之间的最佳特征点匹配。它是基于"最近邻与次近邻距离比"原则来过滤匹配点对的,以提高匹配结果的准确性。这个类特别适用于需要在多张图片之间进行特征匹配和筛选的应用场景,比如全景图拼接。
主要特点
- 基于范围的匹配:此匹配器不仅考虑两张图片之间的直接匹配,还会考虑一个范围内其他图片间的匹配关系,这对于全景图像拼接等任务非常有用。
- 最近邻与次近邻距离比测试:通过比较每个特征点与其最近和次近邻居的距离比值来决定是否接受该匹配,这是一种常用的减少误匹配的技术。
以下是该类的一些成员函数和变量的介绍:
构造函数
BestOf2NearestRangeMatcher(bool try_use_gpu = false, float match_conf = 0.3f, int num_matches_thresh1 = 6, int num_matches_thresh2 = 6, int range_width = -1);
- try_use_gpu: 是否尝试使用 GPU 进行加速。
- match_conf: 匹配置信度阈值,用来过滤不可靠的匹配对。
- num_matches_thresh1: 第一个匹配数量阈值,低于此值将不会计算单应性矩阵。
- num_matches_thresh2: 第二个匹配数量阈值,低于此值将不会进行运动估计的细化。
- range_width: 范围宽度,用于限制匹配搜索的范围,默认为 -1 表示没有限制。
成员函数
-
void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info);
执行两幅图像间的特征匹配,并填充 MatchesInfo 结构体,包含匹配结果和可能的单应性变换矩阵。
-
void operator()(const std::vector &features, std::vector &pairwise_matches, const UMat &mask);
对一组图像执行特征匹配,生成所有图像对之间的匹配信息。
其他成员
- impl_: 实现细节指针,指向具体的匹配器实现(可能是基于 CPU 或者 GPU)。
- is_thread_safe_: 标识是否线程安全。
- num_matches_thresh1_, num_matches_thresh2_: 上述构造函数参数中的两个匹配数量阈值。
- range_width_: 上述构造函数参数中的范围宽度。
代码示例
cpp
#include <opencv2/opencv.hpp>
#include <opencv2/stitching/detail/matchers.hpp>
using namespace cv;
using namespace cv::detail;
int main()
{
// 读取两幅待匹配的图像
Mat img1 = imread( "/media/dingxin/data/study/OpenCV/sources/images/stich1.png" );
Mat img2 = imread( "/media/dingxin/data/study/OpenCV/sources/images/stich2.png" );
if ( img1.empty() || img2.empty() )
{
std::cerr << "无法读取图像文件" << std::endl;
return -1;
}
// 初始化特征检测器和描述符提取器 (这里以ORB为例)
Ptr< Feature2D > detector = ORB::create( 500 ); // 提取500个关键点
// 检测特征点并计算描述符
std::vector< KeyPoint > keypoints1, keypoints2;
Mat descriptors1, descriptors2;
detector->detectAndCompute( img1, noArray(), keypoints1, descriptors1 );
detector->detectAndCompute( img2, noArray(), keypoints2, descriptors2 );
// 特征匹配
BFMatcher matcher( NORM_HAMMING );
std::vector< DMatch > matches;
matcher.match( descriptors1, descriptors2, matches );
// 绘制匹配结果
Mat img_matches;
drawMatches( img1, keypoints1, img2, keypoints2, matches, img_matches );
// 显示匹配结果
imshow( "Matches", img_matches );
waitKey( 0 );
return 0;
}
运行结果
