You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.5 KiB

#include "Arith_FeaMatch.h"
// 构造函数
FeatureMatcher::FeatureMatcher(DetectorType detectorType, MatcherType matcherType)
: detectorType_(detectorType), matcherType_(matcherType)
{
initDetector();
initMatcher();
}
// 提取特征点和描述符
void FeatureMatcher::extractFeatures(cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors)
{
detector_->detectAndCompute(image, cv::noArray(), keypoints, descriptors);
}
// 匹配特征点
void FeatureMatcher::matchFeatures(cv::Mat& descriptors1, cv::Mat& descriptors2, std::vector<cv::DMatch>& matches)
{
if (matcherType_ == FLANN)
{
flannMatcher_->match(descriptors1, descriptors2, matches);
}
else
{
bfMatcher_->match(descriptors1, descriptors2, matches);
}
}
// 计算单应性矩阵
cv::Mat FeatureMatcher::computeHomography(std::vector<cv::KeyPoint>& keypoints1, std::vector<cv::KeyPoint>& keypoints2,
std::vector<cv::DMatch>& matches, double ransacReprojThreshold)
{
std::vector<cv::Point2f> points1, points2;
for (const auto& match : matches)
{
points1.push_back(keypoints1[match.queryIdx].pt);
points2.push_back(keypoints2[match.trainIdx].pt);
}
return cv::findHomography(points1, points2, cv::RANSAC, ransacReprojThreshold);
}
// 初始化特征检测器
void FeatureMatcher::initDetector()
{
switch (detectorType_)
{
case SIFT:
detector_ = cv::SIFT::create(100);
break;
case SURF:
//detector_ = cv::xfeatures2d::SURF::create();
#ifdef HAVE_OPENCV_XFEATURES2D
detector_ = cv::xfeatures2d::SURF::create();
#else
throw std::runtime_error("SURF is not supported in this OpenCV build.");
#endif
break;
case ORB:
6 months ago
detector_ = cv::ORB::create(1000);
break;
default:
throw std::invalid_argument("Unsupported feature detector type");
}
}
// 初始化匹配器
void FeatureMatcher::initMatcher()
{
if (matcherType_ == FLANN)
{
if (detectorType_ == SIFT || detectorType_ == SURF)
{
flannMatcher_ = cv::FlannBasedMatcher::create();
}
else
{
flannMatcher_ = cv::makePtr<cv::FlannBasedMatcher>(cv::FlannBasedMatcher(cv::makePtr<cv::flann::LshIndexParams>(12, 20, 2)));
}
}
else
{
if (detectorType_ == SIFT || detectorType_ == SURF)
{
bfMatcher_ = cv::BFMatcher::create(cv::NORM_L2);
}
else
{
bfMatcher_ = cv::BFMatcher::create(cv::NORM_HAMMING);
}
}
}