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算法有一个更直观的理解,并能够在实际项目中应用这一技术。
热门推荐
洁牙后牙缝变大?这些原因和预防方法你需要知道
年轻人的自嘲文化:负重前行下的心理慰藉
美国留学需要录音笔吗?选对工具提高学习效率?
脑膜刺激征阳性的临床意义
每个阶段的孩子,都适合什么运动?
水杉:植物界的“活化石”✨
带情的语有哪些成语?情感表达必备!这些成语你都知道吗?!
景顺:地缘政治风险增加 应增持实物黄金
益寿强身膏成分、功效与服用方法全解析
Excel中求解“K”值的多种方法
详解新能源滤波器在电力系统中的应用与发展
除了漠河舞厅,打卡这座小城还有一个理由
66岁乐手孔鏘脚肿如猪蹄 查不出原因! 医生解析水肿四大类型
如何延长相机电池续航时间
欧吉桑是什么意思,欧吉桑日语
低烟无卤电力电缆:安全与环保的选择
如何高效练习科二以提高驾驶技能?科二练习的技巧有哪些要点?
Steam平台20款高品质免费游戏推荐!好评如潮!
7一15岁儿童必看励志电影 七部教育孩子必看的电影
肉苁蓉选购指南:从产地到种类的全面解析
如何正确测量电视的尺寸大小?
水质亚硝酸盐超标对环保的影响及监测必要性
郑州十大经典美食盘点:从烩面到胡辣汤,品味中原美食文化
外媒评述:中老铁路为老挝带来发展红利
肘管综合征怎么治疗
劳动仲裁能匿名吗?被辞退如何申请劳动仲裁?
汽车贴膜颜色深隔热效果好吗?一文读懂汽车膜选购要点
丽江古城区聚焦文旅品牌建设,全力打造世界文化旅游名城
这可能是最全的输入法教程了
祝贺!福建这座大桥喜提全球桥梁设计建造最高奖