- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
cv::cuda::DescriptorMatcher 是 OpenCV 的 CUDA 模块中用于在 GPU 上执行特征描述符匹配的类。它允许你利用 NVIDIA GPU 的并行计算能力来加速特征匹配过程,这对于需要实时处理或处理大规模数据集的应用来说非常有用。
主要功能
- 特征描述符匹配:可以在 GPU 上高效地匹配两组特征描述符(如 SIFT、SURF 等)。
- 多种匹配策略:支持 K-最近邻匹配(KNN)、基于半径的匹配等。
- 跨平台兼容性:能够在任何支持 CUDA 的平台上运行。
类概述
以下是 cv::cuda::DescriptorMatcher 的一些关键成员函数和说明:
构造函数
DescriptorMatcher(const Ptr& matcher):创建一个 DescriptorMatcher 对象,通常使用其派生类(例如 BruteForceMatcher 或 FlannBasedMatcher)进行实例化。
匹配方法
- void match(Ptr& queryDescriptors, std::vector& matches, const GpuMat& trainDescriptors = GpuMat()):在两组描述符之间找到最佳匹配项。
- void knnMatch(Ptr& queryDescriptors, std::vector<std::vector>& matches, int k, const GpuMat& trainDescriptors = GpuMat(), bool compactResult = false):为每一条查询描述符找到其前 k 个最佳匹配。
- void radiusMatch(Ptr& queryDescriptors, std::vector<std::vector>& matches, float maxDistance, const GpuMat& trainDescriptors = GpuMat(), bool compactResult = false):找到所有距离小于指定最大值的匹配。
添加训练描述符
- void add(const std::vector& descriptors):添加一组训练描述符。
- void clear():清除所有的训练描述符。
获取训练描述符
- std::vector getTrainDescriptors() const:返回当前所有的训练描述符。
- bool isMaskSupported() const:检查是否支持掩码。
示例代码
下面是一个简单的示例,演示如何使用 cv::cuda::DescriptorMatcher 进行特征匹配:
cpp
#include <opencv2/cudafeatures2d.hpp>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/opencv.hpp>
int main()
{
// 加载图像
cv::Mat img1 = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/left.jpg", cv::IMREAD_GRAYSCALE );
cv::Mat img2 = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/right.jpg", cv::IMREAD_GRAYSCALE );
if ( img1.empty() || img2.empty() )
{
std::cerr << "无法加载图像" << std::endl;
return -1;
}
// 转换到 GPU 内存
cv::cuda::GpuMat d_img1( img1 ), d_img2( img2 );
// 创建 CUDA ORB 检测器
cv::Ptr< cv::cuda::ORB > orb = cv::cuda::ORB::create();
// 存储结果:关键点是 CPU 上的 vector,描述符是 GPU 上的 GpuMat
std::vector< cv::KeyPoint > keypoints1, keypoints2;
cv::cuda::GpuMat descriptors1, descriptors2;
// 提取关键点和描述符
orb->detectAndCompute( d_img1, cv::cuda::GpuMat(), keypoints1, descriptors1 );
orb->detectAndCompute( d_img2, cv::cuda::GpuMat(), keypoints2, descriptors2 );
// 创建匹配器
cv::Ptr< cv::cuda::DescriptorMatcher > matcher = cv::cuda::DescriptorMatcher::createBFMatcher( cv::NORM_HAMMING );
// 匹配描述符
std::vector< cv::DMatch > matches;
matcher->match( descriptors1, descriptors2, matches );
// 将 GPU 描述符下载回 CPU(如果需要可视化)
cv::Mat descriptors1_cpu, descriptors2_cpu;
descriptors1.download( descriptors1_cpu );
descriptors2.download( descriptors2_cpu );
// 绘制匹配结果
cv::Mat img_matches;
cv::drawMatches( img1, keypoints1, img2, keypoints2, matches, img_matches );
cv::imshow( "Matches", img_matches );
cv::waitKey( 0 );
return 0;
}
运行结果
