使用C++的OpenCV进行SIFT特征检测与匹配
  TEZNKK3IfmPf 2024年03月29日 29 0

OpenCV安装可以看这个:

​​各平台安装OpenCV_小锋学长生活大爆炸的博客-CSDN博客​​


直接上代码吧:

#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/core.hpp>
#include <opencv2/xfeatures2d.hpp>

int main() {
int64 t1, t2;
double tkpt, tdes, tmatch_bf, tmatch_knn;

// 1. 读取图片
const cv::Mat image1 = cv::imread("../../images/1.png", 0); //Load as grayscale
const cv::Mat image2 = cv::imread("../../images/2.png", 0); //Load as grayscale
std::vector<cv::KeyPoint> keypoints1;
std::vector<cv::KeyPoint> keypoints2;

cv::Ptr<cv::SiftFeatureDetector> sift = cv::SiftFeatureDetector::create();
// 2. 计算特征点
t1 = cv::getTickCount();
sift->detect(image1, keypoints1);
t2 = cv::getTickCount();
tkpt = 1000.0*(t2-t1) / cv::getTickFrequency();
sift->detect(image2, keypoints2);


// 3. 计算特征描述符
cv::Mat descriptors1, descriptors2;
t1 = cv::getTickCount();
sift->compute(image1, keypoints1, descriptors1);
t2 = cv::getTickCount();
tdes = 1000.0*(t2-t1) / cv::getTickFrequency();
sift->compute(image2, keypoints2, descriptors2);


// 4. 特征匹配
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create(cv::DescriptorMatcher::BRUTEFORCE);
// cv::BFMatcher matcher(cv::NORM_L2);

// (1) 直接暴力匹配
std::vector<cv::DMatch> matches;
t1 = cv::getTickCount();
matcher->match(descriptors1, descriptors2, matches);
t2 = cv::getTickCount();
tmatch_bf = 1000.0*(t2-t1) / cv::getTickFrequency();
// 画匹配图
cv::Mat img_matches_bf;
drawMatches(image1, keypoints1, image2, keypoints2, matches, img_matches_bf);
imshow("bf_matches", img_matches_bf);

// (2) KNN-NNDR匹配法
std::vector<std::vector<cv::DMatch> > knn_matches;
const float ratio_thresh = 0.7f;
std::vector<cv::DMatch> good_matches;
t1 = cv::getTickCount();
matcher->knnMatch( descriptors1, descriptors2, 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]);
}
}
t2 = cv::getTickCount();
tmatch_knn = 1000.0*(t2-t1) / cv::getTickFrequency();

// 画匹配图
cv::Mat img_matches_knn;
drawMatches( image1, keypoints1, image2, keypoints2, 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);
cv::waitKey(0);



cv::Mat output;
cv::drawKeypoints(image1, keypoints1, output);
cv::imwrite("sift_image1_keypoints.jpg", output);
cv::drawKeypoints(image2, keypoints2, output);
cv::imwrite("sift_image2_keypoints.jpg", output);


std::cout << "图1特征点检测耗时(ms):" << tkpt << std::endl;
std::cout << "图1特征描述符耗时(ms):" << tdes << std::endl;
std::cout << "BF特征匹配耗时(ms):" << tmatch_bf << std::endl;
std::cout << "KNN-NNDR特征匹配耗时(ms):" << tmatch_knn << std::endl;
return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.22)
project(demo)
find_package(OpenCV REQUIRED)

IF(UNIX)
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -O0 -Wall -Wextra -Wunused-variable -DDEBUG -D_DEBUG")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -g -Wall -Wextra -Wunused-variable -DDEBUG -D_DEBUG")
ENDIF(UNIX)


set(CMAKE_CXX_STANDARD 20)

add_executable(demo main.cpp)
target_link_libraries(demo ${OpenCV_LIBS})
cmake .
make
./demo

效果

使用C++的OpenCV进行SIFT特征检测与匹配

使用C++的OpenCV进行SIFT特征检测与匹配

使用C++的OpenCV进行SIFT特征检测与匹配

使用C++的OpenCV进行SIFT特征检测与匹配

使用C++的OpenCV进行SIFT特征检测与匹配

其他算法如SURF、AKAZE等可类似修改,但注意SIFT这些是浮点数特征描述符,而ORB这些是二进制特征描述符,因此在特征匹配时注意区分是L2还是Hamming。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2024年03月29日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   19天前   24   0   0 C++
  TEZNKK3IfmPf   19天前   22   0   0 指针C++
  TEZNKK3IfmPf   2024年05月31日   23   0   0 算法C++
TEZNKK3IfmPf