- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
cv::detail::AffineBestOf2NearestMatcher 是 OpenCV 库中用于实现基于仿射变换的图像匹配的一个类。这个类主要用于在图像拼接流程中,寻找图像间的对应关系,并假设图像间存在仿射变换(即考虑缩放、旋转和平移的变换)。它通过使用"最佳二近邻"策略来提高匹配的准确性,即对于每个特征点,找到其最近邻和次近邻,只有当最近邻与次近邻的距离比值小于一定阈值时,才认为匹配成功,以此来过滤掉不准确的匹配。
主要功能
- 特征匹配:该类主要负责在给定的两幅或多幅图像之间进行特征点匹配。
- 仿射变换估计:基于找到的匹配点对,估计图像之间的仿射变换参数。
使用场景
适用于需要对具有相同或相似平面视图的图像进行拼接的情况,例如扫描文档或物体表面的照片拼接。由于仿射变换模型相对简单,因此计算效率较高,但在处理透视变换较大的图像时可能不如单应性模型效果好。
相关方法
虽然具体的API可能会根据OpenCV版本有所变化,但通常这类匹配器会提供如下几种典型的方法:
- 创建匹配器对象。
- 设置匹配过程中的参数,如距离比率阈值等。
- 执行特征匹配操作。
- 获取匹配结果。
为了使用 cv::detail::AffineBestOf2NearestMatcher 类,你需要先确保你的项目已经正确配置了OpenCV库,并且包含了相应的头文件。然后可以通过实例化该类并调用其提供的接口来进行特征查找和匹配工作。
以下是一些关键的成员函数和属性介绍:
-
构造函数
AffineBestOf2NearestMatcher:构造函数可能允许设置一些初始化参数,如是否使用引导图(guided filtering)、对称匹配标志(symmetric matching flag)等。
-
成员函数
-
operator():重载的括号操作符,用于执行实际的匹配过程。接受源图像和目标图像的特征点集以及描述符作为输入,并输出匹配结果。
-
match:具体实现匹配逻辑的方法,通常在内部调用。它会根据输入的特征点和描述符来计算两幅图像之间的最佳仿射变换匹配。
-
collectGarbage:清理不再需要的数据,释放内存。
-
-
属性
-
confidenceThreshold:置信度阈值,用于决定哪些匹配是可靠的。这个阈值影响最近邻与次近邻距离比的判断标准。
-
maxInliers:定义最大内点数,用于RANSAC或其他模型验证方法中的内点选择。
-
matcher:指向底层特征点匹配器的指针,通常是cv::BFMatcher或cv::FlannBasedMatcher。
-
affineEstimator:用于估计仿射变换矩阵的组件。
代码示例
-
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 > featureDetector = ORB::create();
// 检测特征点和计算描述符
std::vector< KeyPoint > keypoints1, keypoints2;
Mat descriptors1, descriptors2;
featureDetector->detectAndCompute( img1, noArray(), keypoints1, descriptors1 );
featureDetector->detectAndCompute( img2, noArray(), keypoints2, descriptors2 );
// 创建AffineBestOf2NearestMatcher实例
Ptr< AffineBestOf2NearestMatcher > matcher = makePtr< AffineBestOf2NearestMatcher >( true, 0.3 ); // 设置对称匹配为true,距离比率阈值为0.3
// 将特征点和描述符封装到ImageFeatures结构中
ImageFeatures features1, features2;
features1.img_idx = 0;
features2.img_idx = 1;
features1.keypoints = keypoints1;
features2.keypoints = keypoints2;
// 使用.getUMat(ACCESS_READ)方法将Mat类型的描述符转换为UMat类型
features1.descriptors = descriptors1.getUMat( cv::ACCESS_READ );
features2.descriptors = descriptors2.getUMat( cv::ACCESS_READ );
// 存储匹配结果
MatchesInfo matches_info;
// 执行匹配
matcher->operator()( features1, features2, matches_info );
// 提取匹配结果
std::vector< DMatch > good_matches;
for ( const auto& m : matches_info.matches )
{
if ( m.distance < 0.3 )
{ // 使用一个简单的距离阈值来过滤匹配
good_matches.push_back( m );
}
}
// 绘制匹配结果
Mat img_matches;
drawMatches( img1, keypoints1, img2, keypoints2, good_matches, img_matches );
// 显示匹配结果
imshow( "Affine Matches", img_matches );
waitKey( 0 );
return 0;
}
运行结果
