From 0acfe7114f01881746e2c675a3bf8e99e8820bcf Mon Sep 17 00:00:00 2001 From: wangchongwu <759291707@qq.com> Date: Fri, 7 Feb 2025 18:19:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E5=A2=9E=E9=87=8FBA=E4=BA=86?= =?UTF-8?q?=EF=BC=8C=E6=9C=89=E5=86=85=E5=AD=98=E5=BC=82=E5=B8=B8=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E5=BE=85=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.cpp | 11 +- stitch/src/API_VideoStitch.h | 6 +- stitch/src/Arith_BAModule.cpp | 15 -- stitch/src/Arith_BAModule.h | 32 ---- stitch/src/Arith_BATask.cpp | 292 ++++++++++++++++--------------- stitch/src/Arith_BATask.h | 57 +++--- stitch/src/Arith_FeaMatch.cpp | 1 + stitch/src/Arith_VideoStitch.cpp | 44 ++--- stitch/src/Arith_VideoStitch.h | 7 +- stitch/src/FileCache.h | 5 + stitch/src/StitchStruct.h | 3 +- 11 files changed, 220 insertions(+), 253 deletions(-) delete mode 100644 stitch/src/Arith_BAModule.cpp delete mode 100644 stitch/src/Arith_BAModule.h diff --git a/main.cpp b/main.cpp index e4468a9..587297a 100644 --- a/main.cpp +++ b/main.cpp @@ -188,17 +188,17 @@ int main(int, char**) << std::endl; // 基于外参的快拼 - // stitcher->GeoStitch(frame,info); + stitcher->GeoStitch(frame,info); + - // 基于地理+BA拼接 - //auto nNum = stitcher->BAStitch(frame,info); // test接口 auto a = stitcher->ReceiveFrame(frame,info); } - + imshow("pan", mat_pan); + waitKey(1); @@ -207,9 +207,8 @@ int main(int, char**) // 处理帧 stitcher->ProcessFrame(); - imshow("pan", mat_pan); + imshow("pan_opt", mat_pan); waitKey(0); - //waitKey(0); } diff --git a/stitch/src/API_VideoStitch.h b/stitch/src/API_VideoStitch.h index d736ceb..ede01da 100644 --- a/stitch/src/API_VideoStitch.h +++ b/stitch/src/API_VideoStitch.h @@ -41,9 +41,9 @@ public: - // 基于特征点拼接,全局光束平差方法,分为更新和优化调整两个接口 - virtual SINT32 BAStitch(GD_VIDEO_FRAME_S img, FrameInfo para) = 0; - virtual SINT32 BAOpt() = 0; + //// 基于特征点拼接,全局光束平差方法,分为更新和优化调整两个接口 + //virtual SINT32 BAStitch(GD_VIDEO_FRAME_S img, FrameInfo para) = 0; + //virtual SINT32 BAOpt() = 0; diff --git a/stitch/src/Arith_BAModule.cpp b/stitch/src/Arith_BAModule.cpp deleted file mode 100644 index 894187f..0000000 --- a/stitch/src/Arith_BAModule.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "Arith_BAModule.h" - -BA_Module::BA_Module(FileCache* cache) -{ - _cache = cache; -} - -BA_Module::~BA_Module() -{ -} - -bool BA_Module::updateCacheH(KeyType Key, cv::Mat H) -{ - return false; -} diff --git a/stitch/src/Arith_BAModule.h b/stitch/src/Arith_BAModule.h deleted file mode 100644 index 7f938f2..0000000 --- a/stitch/src/Arith_BAModule.h +++ /dev/null @@ -1,32 +0,0 @@ -// 全局BA -/*********版权所有(C)2025,武汉高德红外股份有限公司*************************************** -* 文件名称: Arith_BAProc.h -* 文件标识:BA -* 内容摘要:光束平差 -* 其它说明: -* 当前版本:V0.5 -* 创建作者:04046wcw -* 创建日期:2025/01/15 -* 包含关系: -*****************************************************************************************/ - -#pragma once - -#include "FileCache.h" - - -class BA_Module -{ -public: - BA_Module(FileCache* cache); - ~BA_Module(); - - -public: - - // 更新缓存中的帧H矩阵,并存储 - bool updateCacheH(KeyType Key, cv::Mat H); - -private: - FileCache* _cache; -}; diff --git a/stitch/src/Arith_BATask.cpp b/stitch/src/Arith_BATask.cpp index 32e6dda..a5750dd 100644 --- a/stitch/src/Arith_BATask.cpp +++ b/stitch/src/Arith_BATask.cpp @@ -1,15 +1,17 @@ #include "Arith_BATask.h" #include "ceres/ceres.h" +#include "Arith_GeoSolver.h" #include "math.h" using namespace ceres; // 定义残差结构体 -struct HomographyResidual +struct HomographyResidual { - HomographyResidual(const cv::KeyPoint& keypoint_i, const cv::KeyPoint& keypoint_j,const cv::Mat H1, const cv::Mat H2) - : keypoint_i_(keypoint_i), keypoint_j_(keypoint_j),H1_(H1),H2_(H2) {} + HomographyResidual(const cv::KeyPoint& keypoint_i, const cv::KeyPoint& keypoint_j, const cv::Mat H1, const cv::Mat H2) + : keypoint_i_(keypoint_i), keypoint_j_(keypoint_j), H1_(H1), H2_(H2) { + } template - bool operator()(const T* const h_i, const T* const h_j, T* residual) const + bool operator()(const T* const h_i, const T* const h_j, T* residual) const { // 残差计算逻辑 T H_i[9] = { h_i[0], h_i[1], h_i[2], @@ -26,15 +28,15 @@ struct HomographyResidual T P_i[3] = { T(0), T(0), T(0) }; T P_j[3] = { T(0), T(0), T(0) }; - for (int row = 0; row < 3; row++) + for (int row = 0; row < 3; row++) { - for (int col = 0; col < 3; col++) + for (int col = 0; col < 3; col++) { P_i[row] += H_i[row * 3 + col] * p_i[col]; P_j[row] += H_j[row * 3 + col] * p_j[col]; } } - + P_i[0] /= P_i[2]; P_i[1] /= P_i[2]; P_j[0] /= P_j[2]; @@ -66,69 +68,31 @@ private: const cv::KeyPoint keypoint_j_; // 第 j 帧图像中的特征点 const cv::Mat H1_; - const cv::Mat H2_; + const cv::Mat H2_; }; - -BA_Task::BA_Task(GeoSolver * pGeoTrans) +BA_Task::BA_Task(FileCache* cache) { - _GeoStitcher = pGeoTrans; + _cache = cache; _FeaMatcher = new FeatureMatcher(DetectorType::SIFT, MatcherType::FLANN); - _imgVec.reserve(100); } BA_Task::~BA_Task() { } -SINT32 BA_Task::addFrame(GD_VIDEO_FRAME_S img, FrameInfo para) -{ - cv::Mat frame = Mat(img.u32Height, img.u32Width, CV_8UC1, (void*)img.u64VirAddr[0]); - - // 缓存图像帧 - if (img.enPixelFormat == GD_PIXEL_FORMAT_E::GD_PIXEL_FORMAT_GRAY_Y8) - { - _imgVec.emplace_back(frame.clone()); - } - // 缓存外参 - _paraVec.push_back(para); - - // 缓存初始H - auto H = _GeoStitcher->findHomography(para); - _origMatrix.push_back(H.clone()); - _currMatrix.push_back(H.clone()); - - - // 提取特征点 - std::vector keypoints; - cv::Mat descriptors; - _FeaMatcher->extractFeatures(frame,keypoints,descriptors); - _FeaPtVec.push_back(keypoints); - _FeaDespVec.push_back(descriptors); - - // 缓存包围多边形 - _polygon.push_back(warpRectWithH(H,cv::Size(img.u32Width,img.u32Height))); - - return _imgVec.size(); -} - -//void BA_Task::setPanPara(PanInfo info) -//{ -// _panPara = info; -//} - - -//#define SHOW_MATCH -void BA_Task::optimizeBA(cv::Mat H_pan) +void BA_Task::OptFrame(vector frameInd,cv::Mat H_map) { + // 读取帧信息 + readFrameInfo(frameInd); + + // 邻接关系计算 + CalMatchMat(); - //remap(_origMatrix, H_pan, "_origMatrix"); - - // 计算匹配性矩阵 - CalMatchMat(0.3); + // 开始BA google::InitGoogleLogging("ceres"); @@ -154,36 +118,7 @@ void BA_Task::optimizeBA(cv::Mat H_pan) { continue; } -#ifdef SHOW_MATCH - cv::Mat image(1000, 1000, CV_8UC3, cv::Scalar(0, 0, 0)); - cv::Mat imagetmp(1000, 1000, CV_8UC3, cv::Scalar(0, 0, 0)); - vector> tmpPoly; - tmpPoly.push_back(_polygon[i]); - tmpPoly.push_back(_polygon[j]); - cv::warpPerspective(_imgVec[i], imagetmp, _origMatrix[i], imagetmp.size()); - - // 生成遮罩(全白图像,表示有效区域) - cv::Mat mask1 = cv::Mat::ones(_imgVec[i].size(), CV_8UC1) * 255; - cv::Mat warped_mask1; - cv::warpPerspective(mask1, warped_mask1, _origMatrix[i], image.size()); - - imagetmp.copyTo(image, warped_mask1); - - cv::warpPerspective(_imgVec[j], imagetmp, _origMatrix[j], imagetmp.size()); - cv::Mat mask2 = cv::Mat::ones(_imgVec[i].size(), CV_8UC1) * 255; - cv::Mat warped_mask2; - cv::warpPerspective(mask2, warped_mask2, _origMatrix[j], image.size()); - - imagetmp.copyTo(image, warped_mask2); - - drawPolygons(image, tmpPoly); - - // 显示绘制结果 - cv::imshow("Polygons", image); - cv::waitKey(1); - -#endif std::vector matches; //_FeaMatcher->matchFeatures(_FeaDespVec[i],_FeaDespVec[j],matches); _FeaMatcher->matchFeatures_WithH(_FeaPtVec[i], _FeaDespVec[i], _FeaPtVec[j], _FeaDespVec[j], _origMatrix[i], _origMatrix[j], matches); @@ -199,27 +134,14 @@ void BA_Task::optimizeBA(cv::Mat H_pan) continue; } + #ifdef SHOW_MATCH - // 可视化匹配结果 - cv::Mat img_matches; - cv::drawMatches( - _imgVec[i], _FeaPtVec[i], // 第一幅图像及其特征点 - _imgVec[j], _FeaPtVec[j], // 第二幅图像及其特征点 - matches, // 匹配结果 - img_matches, // 输出图像 - cv::Scalar::all(-1), // 匹配线颜色(默认随机颜色) - cv::Scalar::all(-1), // 未匹配点颜色(默认不绘制) - std::vector(), // 掩码(可选,用于筛选匹配) - cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS // 不绘制未匹配的点 - ); - - cv::resize(img_matches, img_matches, cv::Size(1280, 512)); - - // 显示匹配结果 - cv::imshow("Feature Matches", img_matches); - cv::waitKey(0); + // 绘制匹配结果 + drawMatch(i, j, matches, H_map); #endif + + // 添加匹配点对的残差块 for (int m = 0; m < matches.size(); m++) { @@ -230,17 +152,17 @@ void BA_Task::optimizeBA(cv::Mat H_pan) ceres::LossFunction* loss_function = new ceres::HuberLoss(35); - cv::Mat H1 = _origMatrix[i]; + cv::Mat H1 = _origMatrix[i]; cv::Mat H2 = _origMatrix[j]; ceres::CostFunction* cost_function = new ceres::AutoDiffCostFunction( - new HomographyResidual(keypoint_i, keypoint_j,H1,H2)); + new HomographyResidual(keypoint_i, keypoint_j, H1, H2)); problem.AddResidualBlock(cost_function, loss_function, h_list[i], h_list[j]); } nParaCnt += matches.size(); - + } } @@ -258,50 +180,96 @@ void BA_Task::optimizeBA(cv::Mat H_pan) // 求解 ceres::Solve(options, &problem, &summary); - //// 将优化后的参数转换回 cv::Mat - for (int i = 0; i < _currMatrix.size(); i++) - { - std::cout << "------------" << std::endl; - std::cout << _origMatrix[i] << std::endl; - std::cout << _currMatrix[i] << std::endl; - std::cout << "------------" << std::endl; - } + //for (int i = 0; i < _currMatrix.size(); i++) + //{ + // std::cout << "------------" << std::endl; + // std::cout << _origMatrix[i] << std::endl; + // std::cout << _currMatrix[i] << std::endl; + // std::cout << "------------" << std::endl; + //} // 输出结果 std::cout << summary.BriefReport() << std::endl; - - remap(_currMatrix, H_pan, "_currMatrix"); + // 写入缓存 + writeFrameInfo(); +} - cv::waitKey(0); +bool BA_Task::updateCacheH(KeyType Key, cv::Mat H) +{ + auto _t_frame_cache = std::make_shared(); + + if (_cache->get(Key, _t_frame_cache)) + { + // 更新H + memcpy(_t_frame_cache->H, H.data, sizeof(double) * 9); + // 存储 + _cache->set(Key, _t_frame_cache); + return true; + } + + return false; } -void BA_Task::remap(vector> H_Vec, cv::Mat_ H_pan, std::string winname) +int BA_Task::readFrameInfo(vector frameInd) { - cv::Mat image(1500, 1500, CV_8UC3, cv::Scalar(0, 0, 0)); + auto _t_frame_cache = std::make_shared(); - for (size_t i = 0; i < _imgVec.size(); i++) + for (size_t i = 0; i < frameInd.size(); i++) { - cv::Mat imagetmp(1500, 1500, CV_8UC3, cv::Scalar(0, 0, 0)); - cv::warpPerspective(_imgVec[i], imagetmp, H_pan * H_Vec[i], imagetmp.size()); - cv::Mat mask = cv::Mat::ones(_imgVec[i].size(), CV_8UC1) * 255; - cv::Mat warped_mask; - cv::warpPerspective(mask, warped_mask, H_pan * H_Vec[i], image.size()); - imagetmp.copyTo(image, warped_mask); - } + KeyType key = frameInd[i]; + if (_cache->get(key, _t_frame_cache)) + { + // 记录key + _frameInd.push_back(key); - imshow(winname, image); - cv::waitKey(1); + // 特征点 + vector keypoints(_t_frame_cache->_pt, _t_frame_cache->_pt + _t_frame_cache->ptNum); + _FeaPtVec.push_back(keypoints); + // 描述子 + cv::Mat descriptors(_t_frame_cache->ptNum, FEA_DES_SIZE, CV_32FC1, _t_frame_cache->_desp); + _FeaDespVec.push_back(descriptors); + // 原始外参 + _paraVec.push_back(_t_frame_cache->_para); + + // 初始H + cv::Mat H = cv::Mat(3, 3, CV_64FC1, _t_frame_cache->H); + _origMatrix.push_back(H.clone()); + _currMatrix.push_back(H.clone()); + + + // 缓存包围多边形 + _polygon.push_back(warpRectWithH(H, cv::Size(_t_frame_cache->_frame_info.u32Width, _t_frame_cache->_frame_info.u32Height))); + + +#ifdef SHOW_MATCH + // 读取图像 + cv::Mat img = cv::Mat(_t_frame_cache->_frame_info.u32Height, _t_frame_cache->_frame_info.u32Width,CV_8UC1, _t_frame_cache->_data); + _imgVec.push_back(img.clone()); +#endif + } + } + return 0; } +int BA_Task::writeFrameInfo() +{ + for (size_t i = 0; i < _currMatrix.size(); i++) + { + auto Key = _frameInd[i]; + // 更新缓存 + updateCacheH(Key, _currMatrix[i]); + } -//#define SHOW_MATCH -SINT32 BA_Task::CalMatchMat(float fiou_thre) + return 0; +} + +SINT32 BA_Task::CalMatchMat() { - _IOUMat = cv::Mat::zeros(_polygon.size(),_polygon.size(),CV_32FC1); + _IOUMat = cv::Mat::zeros(_polygon.size(), _polygon.size(), CV_32FC1); _MatchMat = cv::Mat::zeros(_polygon.size(), _polygon.size(), CV_32SC1); @@ -315,29 +283,79 @@ SINT32 BA_Task::CalMatchMat(float fiou_thre) { if (i == j) { - _IOUMat.at(i,j) = 1; + _IOUMat.at(i, j) = 1; continue; } vector poly_j = _polygon[j]; - float fiou = computeQuadrilateralIOU(poly_i,poly_j); - _IOUMat.at(i,j) = fiou; - _IOUMat.at(j,i) = fiou;//是对称矩阵 - + float fiou = computeQuadrilateralIOU(poly_i, poly_j); + _IOUMat.at(i, j) = fiou; + _IOUMat.at(j, i) = fiou;//是对称矩阵 + } } return 0; + } +void BA_Task::drawMatch(int i, int j, std::vector matches, cv::Mat H_map) +{ + cv::Mat image(1000, 1000, CV_8UC3, cv::Scalar(0, 0, 0)); + cv::Mat imagetmp(1000, 1000, CV_8UC3, cv::Scalar(0, 0, 0)); + vector> tmpPoly; + tmpPoly.push_back(_polygon[i]); + tmpPoly.push_back(_polygon[j]); + + cv::warpPerspective(_imgVec[i], imagetmp, H_map * _origMatrix[i], imagetmp.size()); + + // 生成遮罩(全白图像,表示有效区域) + cv::Mat mask1 = cv::Mat::ones(_imgVec[i].size(), CV_8UC1) * 255; + cv::Mat warped_mask1; + cv::warpPerspective(mask1, warped_mask1, H_map * _origMatrix[i], image.size()); + + imagetmp.copyTo(image, warped_mask1); + + cv::warpPerspective(_imgVec[j], imagetmp, H_map * _origMatrix[j], imagetmp.size()); + cv::Mat mask2 = cv::Mat::ones(_imgVec[i].size(), CV_8UC1) * 255; + cv::Mat warped_mask2; + cv::warpPerspective(mask2, warped_mask2, H_map * _origMatrix[j], image.size()); + + imagetmp.copyTo(image, warped_mask2); + drawPolygons(image, tmpPoly); + // 显示绘制结果 + cv::imshow("Polygons", image); + cv::waitKey(1); + + + // 可视化匹配结果 + cv::Mat img_matches; + cv::drawMatches( + _imgVec[i], _FeaPtVec[i], // 第一幅图像及其特征点 + _imgVec[j], _FeaPtVec[j], // 第二幅图像及其特征点 + matches, // 匹配结果 + img_matches, // 输出图像 + cv::Scalar::all(-1), // 匹配线颜色(默认随机颜色) + cv::Scalar::all(-1), // 未匹配点颜色(默认不绘制) + std::vector(), // 掩码(可选,用于筛选匹配) + cv::DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS // 不绘制未匹配的点 + ); + + cv::resize(img_matches, img_matches, cv::Size(1280, 512)); + + // 显示匹配结果 + cv::imshow("Feature Matches", img_matches); + cv::waitKey(0); + +} // 函数:绘制多边形 -void drawPolygons(cv::Mat& image, const std::vector>& polygons) +void drawPolygons(cv::Mat& image, const std::vector>& polygons) { // 定义颜色列表 std::vector colors = { diff --git a/stitch/src/Arith_BATask.h b/stitch/src/Arith_BATask.h index 48646dc..3dd4d0a 100644 --- a/stitch/src/Arith_BATask.h +++ b/stitch/src/Arith_BATask.h @@ -9,39 +9,50 @@ * 创建日期:2025/01/15 * 包含关系: *****************************************************************************************/ + #pragma once -#include "StitchStruct.h" -#include -#include -#include "Arith_GeoSolver.h" + +#include "FileCache.h" #include "Arith_FeaMatch.h" -using cv::Mat_; -class BA_Task +//#define SHOW_MATCH + + +class BA_Task { public: - BA_Task(GeoSolver* pGeoTrans); + BA_Task(FileCache* cache); ~BA_Task(); - // 加入优化帧 - SINT32 addFrame(GD_VIDEO_FRAME_S img, FrameInfo para); - // BA优化 - void optimizeBA(cv::Mat H_pan); + // 优化指定帧,并更新H到缓存中,H_map用于优化过程可视化 + void OptFrame(vector frameInd, cv::Mat H_map); - // 使用地理系H矩阵和全景图H重投影所有帧 - void remap(vector>H_Vec, cv::Mat_ H_pan, std::string winname); + // 更新缓存中的帧H矩阵,并存储 + bool updateCacheH(KeyType Key, cv::Mat H); private: - SINT32 CalMatchMat(float fiou_thre);//计算匹配性矩阵(以IOU约束) -private: - GeoSolver* _GeoStitcher;//外参计算 + // 从缓存读取指定帧信息(不需要图像) + int readFrameInfo(vector frameInd); + + // 输出优化结果到cache + int writeFrameInfo(); + + SINT32 CalMatchMat();//计算匹配性矩阵 + + // 调试图像 + vector _imgVec;//图像缓存 + + vector _frameInd;//帧索引,BA模块按照线性存储,完成后利用索引更新实际帧。注意传入的索引有可能是空的,需要处理 + + FeatureMatcher* _FeaMatcher;//特征匹配 -private: + FileCache* _cache; + Mat_ _MatchMat;//配准点邻接表 Mat_ _IOUMat;//交汇邻接表 @@ -49,17 +60,17 @@ private: vector> _currMatrix;//当前H矩阵 - - //超大空间,考虑文件cache todo! -private: - vector _imgVec;//图像缓存 + vector> _polygon;//帧包围四边形 vector> _FeaPtVec;//特征点缓存 vector _FeaDespVec;//特征点描述子 vector _paraVec; - vector> _polygon;//帧包围四边形 + +private: + + // 调试:绘制匹配关系 + void drawMatch(int i, int j, std::vector match,cv::Mat H_map); }; - void drawPolygons(cv::Mat& image, const std::vector>& polygons); \ No newline at end of file diff --git a/stitch/src/Arith_FeaMatch.cpp b/stitch/src/Arith_FeaMatch.cpp index 22328d9..30e719e 100644 --- a/stitch/src/Arith_FeaMatch.cpp +++ b/stitch/src/Arith_FeaMatch.cpp @@ -33,6 +33,7 @@ void FeatureMatcher::matchFeatures(cv::Mat& descriptors1, cv::Mat& descriptors2, void FeatureMatcher::matchFeatures_WithH(vector keypoints1, cv::Mat& descriptors1, vector keypoints2, cv::Mat& descriptors2, cv::Mat H1, cv::Mat H2, std::vector& matches) { std::vector _matches; + if (matcherType_ == FLANN) { flannMatcher_->match(descriptors1, descriptors2, _matches); diff --git a/stitch/src/Arith_VideoStitch.cpp b/stitch/src/Arith_VideoStitch.cpp index 7922b06..eb5a5f5 100644 --- a/stitch/src/Arith_VideoStitch.cpp +++ b/stitch/src/Arith_VideoStitch.cpp @@ -25,11 +25,11 @@ VideoStitch::VideoStitch(SINT32 nWidth, SINT32 nHeight) { _GeoSolver = new GeoSolver(); - _BATask = new BA_Task(_GeoSolver); - _FeaMatcher = new FeatureMatcher(DetectorType::SIFT, MatcherType::FLANN); - _cache = new FileCache(50,"./cache"); + _cache = new FileCache(20,"./cache"); + + _BATask = new BA_Task(_cache); _panPara = { 0 }; @@ -39,7 +39,6 @@ VideoStitch::VideoStitch(SINT32 nWidth, SINT32 nHeight) VideoStitch::~VideoStitch() { delete _GeoSolver; - delete _BATask; delete _cache; } @@ -83,8 +82,6 @@ PanInfo VideoStitch::Init(FrameInfo info) { _panPara = InitMap(info); - //_BATask->setPanPara(_panPara); - _pan = cv::Mat::zeros(_panPara.m_pan_height, _panPara.m_pan_width, CV_8UC1); return _panPara; @@ -166,17 +163,9 @@ BYTE8 VideoStitch::GeoStitch(GD_VIDEO_FRAME_S img, FrameInfo para) return 0; } -SINT32 VideoStitch::BAStitch(GD_VIDEO_FRAME_S img, FrameInfo para) -{ - SINT32 nFrameCnt = _BATask->addFrame(img,para); - return 0; -} -SINT32 VideoStitch::BAOpt() -{ - _BATask->optimizeBA(getAffineFromGeo2Pan(_panPara)); - return 0; -} + + SINT32 VideoStitch::ReceiveFrame(GD_VIDEO_FRAME_S img, FrameInfo para) { @@ -206,6 +195,9 @@ SINT32 VideoStitch::ReceiveFrame(GD_VIDEO_FRAME_S img, FrameInfo para) _FeaMatcher->extractFeatures(cv::Mat(img.u32Height, img.u32Width,CV_8UC1, _t_frame_cache->_data), keypoints, descriptors); size_t keyNum = MIN(keypoints.size(), FEA_NUM_MAX); + + _t_frame_cache->ptNum = keyNum; + // 保存特征点 memcpy(_t_frame_cache->_pt, keypoints.data(), sizeof(cv::KeyPoint) * keyNum); @@ -230,20 +222,15 @@ SINT32 VideoStitch::ProcessFrame() { vector vec; + for (size_t i = 10; i < 300; i+=10) + { + vec.push_back(i); + } - vec.push_back(10); - vec.push_back(20); - //vec.push_back(50); - //vec.push_back(70); - vec.push_back(120); - vec.push_back(220); - //vec.push_back(320); - //vec.push_back(420); - //vec.push_back(520); + _BATask->OptFrame(vec, _H_pan); mapFrame(vec); - return SINT32(); } @@ -289,11 +276,6 @@ void VideoStitch::mapFrame(vector frameInd) } -void VideoStitch::OptFrame(vector frameInd) -{ - - -} GD_VIDEO_FRAME_S VideoStitch::ExportPanAddr() diff --git a/stitch/src/Arith_VideoStitch.h b/stitch/src/Arith_VideoStitch.h index 4284d5c..9154512 100644 --- a/stitch/src/Arith_VideoStitch.h +++ b/stitch/src/Arith_VideoStitch.h @@ -27,15 +27,11 @@ public: // 投影显示 void mapFrame(vector frameInd); - // 优化帧 - void OptFrame(vector frameInd); + public: - SINT32 BAStitch(GD_VIDEO_FRAME_S img, FrameInfo para); - SINT32 BAOpt(); - GD_VIDEO_FRAME_S ExportPanAddr(); private: @@ -53,6 +49,7 @@ private: BA_Task* _BATask;//BA + PanInfo _panPara;//全景图配置 cv::Mat _H_pan;//全景图投影矩阵:从地理系到全景地图 diff --git a/stitch/src/FileCache.h b/stitch/src/FileCache.h index 81f0730..b3b03f4 100644 --- a/stitch/src/FileCache.h +++ b/stitch/src/FileCache.h @@ -12,6 +12,11 @@ // using KeyType = int; +// 通用文件缓存类:HASH部分目前没有针对不同类型的数据进行处理,多个键值一样的数据缓存会文件覆盖 + +// todo:落盘部分增加异步写入任务,提高性能 + + template class FileCache { diff --git a/stitch/src/StitchStruct.h b/stitch/src/StitchStruct.h index ae6a95c..80c68f6 100644 --- a/stitch/src/StitchStruct.h +++ b/stitch/src/StitchStruct.h @@ -51,8 +51,9 @@ struct FrameCache FrameInfo _para; GD_VIDEO_FRAME_S _frame_info; BYTE8 _data[IMG_CACHE_SIZE]; + + SINT32 ptNum; cv::KeyPoint _pt[FEA_NUM_MAX]; FLOAT32 _desp[FEA_NUM_MAX * FEA_DES_SIZE]; - DOUBLE64 H[9];// H矩阵 }; \ No newline at end of file