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算法有一个更直观的理解,并能够在实际项目中应用这一技术。
热门推荐
实木家具新革命:2025绿色家居消费指南(附甲醛检测表)
如何选择合适的节目以提高观看体验
财富自由意味着什么?实现财富自由需要哪些条件?
糖尿病人嘴里发甜是怎么回事
口甜是什么原因
LIS系统如何在高峰时段保持样本处理的高效性?
文化市场喜迎这一代中老年
毛主席革命生涯中的三次重大挫折
延长手机电池续航时间的有效方法
高速公路匝道行车安全指南:11个关键注意事项
生物农药金满维:红蜘蛛防治综合策略与技术要点解析
赤小豆汤的功效与制作方法
国际法院的全面介绍与概述
什么是基金分红?为什么分红后基金单位净值会下跌?
如何构建和管理一个多元化的股票组合:六步策略助你优化投资组合
人工智能测谎技术问世:比人类更强,但需谨慎使用
散光175度严重吗?全方位解析其影响与应对措施
吡虫啉对红蜘蛛的防治方法及使用频率
如何在美国进行高尔夫留学的全面指南
酒驾的危害性及预防措施是怎样的
如何正确连接有线和无线耳机到电脑的详细指南与注意事项
如何做好建设工程项目的现场管理
大型铸造加工厂家讲解大型铸钢件的退火
定格宇宙级浪漫!当摄影邂逅彗星——
一季度广东电子信息业强势回暖,工业大省谋求产业多元支撑
甲状腺结节需要做哪些检查项目
道教法事犯法吗?法事活动需注意的法律法规
如何掌握A-Level地理词汇提高成绩
MidJourney 常用提示词与图片链接的全面指南
选购暖气片时如何确保暖气片的安全性