parent
cdc98d9952
commit
24220189b7
@ -0,0 +1,64 @@
|
|||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// 定义相机节点
|
||||||
|
struct CameraNode {
|
||||||
|
int cameraId; // 相机 ID
|
||||||
|
cv::Mat R; // 旋转矩阵
|
||||||
|
cv::Mat t; // 平移向量
|
||||||
|
cv::Mat K; // 内参矩阵
|
||||||
|
};
|
||||||
|
|
||||||
|
// 定义三维点节点
|
||||||
|
struct PointNode {
|
||||||
|
int pointId; // 三维点 ID
|
||||||
|
cv::Point3f X; // 三维点坐标
|
||||||
|
};
|
||||||
|
|
||||||
|
// 定义观测边
|
||||||
|
struct ObservationEdge {
|
||||||
|
int cameraId; // 相机 ID
|
||||||
|
int pointId; // 三维点 ID
|
||||||
|
cv::Point2f x; // 观测到的二维点坐标
|
||||||
|
};
|
||||||
|
|
||||||
|
// 定义 Bundle Adjustment 图结构
|
||||||
|
class BundleAdjustmentGraph {
|
||||||
|
public:
|
||||||
|
// 添加相机节点
|
||||||
|
void addCameraNode(const CameraNode& camera) {
|
||||||
|
cameras[camera.cameraId] = camera;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加三维点节点
|
||||||
|
void addPointNode(const PointNode& point) {
|
||||||
|
points[point.pointId] = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加观测边
|
||||||
|
void addObservationEdge(const ObservationEdge& edge) {
|
||||||
|
observations.push_back(edge);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取相机节点
|
||||||
|
CameraNode getCameraNode(int cameraId) {
|
||||||
|
return cameras[cameraId];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取三维点节点
|
||||||
|
PointNode getPointNode(int pointId) {
|
||||||
|
return points[pointId];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取观测边
|
||||||
|
std::vector<ObservationEdge> getObservationEdges() {
|
||||||
|
return observations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<int, CameraNode> cameras; // 相机节点集合
|
||||||
|
std::map<int, PointNode> points; // 三维点节点集合
|
||||||
|
std::vector<ObservationEdge> observations; // 观测边集合
|
||||||
|
};
|
@ -0,0 +1,92 @@
|
|||||||
|
#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:
|
||||||
|
detector_ = cv::ORB::create();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef FEATURE_MATCHER_H
|
||||||
|
#define FEATURE_MATCHER_H
|
||||||
|
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include <vector>
|
||||||
|
#include <stdexcept>
|
||||||
|
#ifdef HAVE_OPENCV_XFEATURES2D
|
||||||
|
#include <opencv2/xfeatures2d.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 特征检测器类型
|
||||||
|
enum DetectorType
|
||||||
|
{
|
||||||
|
SIFT,
|
||||||
|
SURF,
|
||||||
|
ORB
|
||||||
|
};
|
||||||
|
|
||||||
|
// 匹配器类型
|
||||||
|
enum MatcherType
|
||||||
|
{
|
||||||
|
FLANN,
|
||||||
|
BF
|
||||||
|
};
|
||||||
|
class FeatureMatcher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
// 构造函数
|
||||||
|
FeatureMatcher(DetectorType detectorType, MatcherType matcherType);
|
||||||
|
|
||||||
|
// 提取特征点和描述符
|
||||||
|
void extractFeatures(cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors);
|
||||||
|
|
||||||
|
// 匹配特征点
|
||||||
|
void matchFeatures(cv::Mat& descriptors1, cv::Mat& descriptors2, std::vector<cv::DMatch>& matches);
|
||||||
|
|
||||||
|
// 计算单应性矩阵
|
||||||
|
cv::Mat computeHomography(std::vector<cv::KeyPoint>& keypoints1, std::vector<cv::KeyPoint>& keypoints2,
|
||||||
|
std::vector<cv::DMatch>& matches, double ransacReprojThreshold = 3.0);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 初始化特征检测器
|
||||||
|
void initDetector();
|
||||||
|
|
||||||
|
// 初始化匹配器
|
||||||
|
void initMatcher();
|
||||||
|
|
||||||
|
DetectorType detectorType_; // 特征检测器类型
|
||||||
|
MatcherType matcherType_; // 匹配器类型
|
||||||
|
cv::Ptr<cv::Feature2D> detector_; // 特征检测器
|
||||||
|
cv::Ptr<cv::DescriptorMatcher> flannMatcher_; // FLANN匹配器
|
||||||
|
cv::Ptr<cv::DescriptorMatcher> bfMatcher_; // 暴力匹配器
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FEATURE_MATCHER_H
|
Loading…
Reference in new issue