OpenCV C++ SIFT 特征匹配
创作时间:
作者:
@小白创作中心
OpenCV C++ SIFT 特征匹配
引用
CSDN
1.
https://m.blog.csdn.net/m0_73782904/article/details/137087080
SIFT(尺度不变特征变换)是一种在计算机视觉领域中广泛应用的特征检测和描述算法。它能够检测图像中的局部特征,并对这些特征进行描述,使得在图像旋转、尺度变化、亮度变化等情况下仍能保持较好的检测效果。本文将通过一个具体的代码示例,详细介绍如何使用OpenCV库中的SIFT算法进行特征匹配。
代码实现
#include <opencv2/opencv.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main() {
int i;
Mat img[2];
img[0] = imread("E:/study/cv/计算机视觉/imgMain/lena.jpg");
img[1] = imread("E:/study/cv/计算机视觉/imgMain/lena_copy.jpg");
if (img[0].empty() || img[1].empty())
return 0;
Ptr<SiftFeatureDetector> sift = SiftFeatureDetector::create(100);
std::vector<KeyPoint> keyPoints[2];
Mat descriptors[2];
for (i = 0; i < 2; i++) {
// 计算特征点
sift->detect(img[i], keyPoints[i]);
// 计算特征描述符
sift->compute(img[i], keyPoints[i], descriptors[i]);
// 绘制KeyPoints
drawKeypoints(img[i], keyPoints[i], img[i]);
}
// 特征匹配:Flann-based matcher 使用快速近似最近邻搜索算法寻找 当我们需要找到一个相对好的匹配但是不需要最佳匹配的时候往往使用FlannBasedMatcher
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create(cv::DescriptorMatcher::FLANNBASED);
// KNN-NNDR匹配法
// KNN:K最邻近。如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中大多数属于某一个类别,则该样本叶属于这个类别
// NNDR:最近邻距离比率。最近邻距离和次近邻距离的比值
std::vector<std::vector<cv::DMatch>> knn_matches;
const float ratio_thresh = 0.7f;
std::vector<cv::DMatch> good_matches;
matcher->knnMatch(descriptors[0], descriptors[0], knn_matches, 2);
for (auto& knn_matche : knn_matches)
{
if (knn_matche[0].distance<ratio_thresh * knn_matche[1].distance)
good_matches.push_back(knn_matche[0]);
}
// 最匹配图
cv::Mat img_matches_knn;
drawMatches(img[0], keyPoints[0], img[1], keyPoints[1], good_matches, img_matches_knn, cv::Scalar::all(-1),
cv::Scalar::all(-1), std::vector<char>(), cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
cv::imshow("knn_matches", img_matches_knn);
waitKey();
}
关键步骤解释
创建SIFT特征检测器对象:
Ptr<SiftFeatureDetector> sift = SiftFeatureDetector::create(100);
这里参数100表示预期检测到的特征点数目。
特征检测与描述符计算:
sift->detect(img[i], keyPoints[i]); sift->compute(img[i], keyPoints[i], descriptors[i]);
detect
函数用于检测特征点,compute
函数用于计算特征描述符。特征匹配:
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create(cv::DescriptorMatcher::FLANNBASED); matcher->knnMatch(descriptors[0], descriptors[0], knn_matches, 2);
使用FLANN(快速最近邻)匹配器进行特征点匹配,
knnMatch
函数返回每个特征点的两个最佳匹配。筛选优秀匹配点对:
for (auto& knn_matche : knn_matches) { if (knn_matche[0].distance<ratio_thresh * knn_matche[1].distance) good_matches.push_back(knn_matche[0]); }
通过比较最近邻距离和次近邻距离的比值来筛选出优秀的匹配点对。
绘制匹配结果:
drawMatches(img[0], keyPoints[0], img[1], keyPoints[1], good_matches, img_matches_knn); imshow("knn_matches", img_matches_knn);
使用
drawMatches
函数绘制匹配结果,并显示在窗口中。
匹配结果展示
通过上述步骤,我们可以清晰地看到两张图像之间的特征匹配结果。SIFT算法的强大之处在于它能够在不同的光照条件、尺度和旋转角度下保持特征的稳定性,因此在图像拼接、目标识别、3D重建等领域都有广泛的应用。
本文通过一个简单的代码示例,展示了如何使用OpenCV实现SIFT特征匹配。希望读者能够通过这个示例,对SIFT算法有一个更直观的理解,并能够在实际项目中应用这一技术。
热门推荐
历时三个月,全网唯一助听器电池横向评测:续航与价格的深度剖析
应用抗生素能打乙肝疫苗吗
选择更富激情的穿越机 最初练一次就要吐一次
数学差,最先补什么?掌握这几点成绩,蹭蹭往上涨
鸡蛋蛋白质含量及营养价值详解
支气管扩张气喘要注意,医生总结可能是这五种病
物是人非是什么意思
【原】钓鱼如何找到最理想的钓位,七大技巧教你选对钓位
家庭厨艺-手抓美食(以Q弹香辣鸡爪为例)
华硕主板Intel 600/700系列BIOS下RAID组建指南
劳动者请休病假需合法合规
婚礼摄影纪实风格:真实记录,捕捉自然瞬间
学古筝的人如何修炼通关?快速指序攻略
宁德 | 秋日就要“野”一下,秋季露营指南看这篇就够啦!
强人工智能与弱人工智能:AI技术的两种发展方向
破解香港 business register(BR) 的秘密:全面解析与指导
怎么消除软件卸载后的注册表?
品牌标识VI规范设计怎么做高级
肚脐眼内疼痛的可能原因是什么
家里养六月雪真的会影响风水吗?养护要点全解析
做好防范,谨防中招 ——防范诺如病毒健康科普
玄武门之变后:李世民如何处理李建成的妻儿与心腹
圆明园的损失有多少?无法估量的文化浩劫!
Fox前叉全阵容指南
牛肉价格跌至近六年新低,2025年2月食材采购行情全解析
科学分析:关于美国登月真实性的质疑声,揭示真相
如何准备国外博士申请材料
工程机械出海布局:三巨头的全球扩张之路
猕猴桃环割与环剥技术详解:原理、操作与效果
中国生育成本报告2024版:养育一个孩子平均需68万元