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