添加融合流程到框架中

main
wangchongwu 5 months ago
parent 68327492bf
commit c5abb82899

@ -9,4 +9,12 @@
- 2 20250205
上述开发计划存在问题,拼接算法应是后台服务,应当生成标准产品,而不随着显示更改逻辑,这里考虑生成谷歌瓦片,并通过流传输到显示端,由显控处理显示逻辑。
上述开发计划存在问题,拼接算法应是后台服务,应当生成标准产品,而不随着显示更改逻辑,这里考虑生成谷歌瓦片,并通过流传输到显示端,由显控处理显示逻辑。
- 20250213
已初步完成地理快拼、BA、谷歌瓦片输出等核心功能开发能够输出符合谷歌标准的256瓦片。整理以下遗留问题
【1】全景图的分辨率和尺寸应当根据硬件水平自适应目前是人工指定的
【2】长时间推扫导致成像区域离开预设的全景范围如何自适应处理。
【3】一定要提供边扫描边输出瓦片能力

@ -0,0 +1,19 @@
1. 主要目的
针对光电吊舱产品单帧视场覆盖小,侦察效率低的问题,在全景拼接技术的基础上设计态势融合识别的设想。
2.主要功能
2.1 扫描视场全景栅格
提供扫描场景下基于地理位置的实时快拼能力处理频率不低于25Hz。后台自动根据外参精度进行精拼接并自动更新快拼成果。
栅格层是整个态势的基础层。且具备空间测量能力。
2.2 地形地貌识别
在凝视视角下对ROI区域进行地形地貌识别叠加道路、水体、森林等识别结果。地形层为矢量层能够开展GIS空间分析。支持追击导航等中级作战应用。
2.3 目标智能识别
扫描视角/凝视视角下进行目标智能识别,将识别结果按照类型叠加在全景栅格上。形成最重要的实时态势。
2.4 协同作战/沙盘更新
支持协同目标信息叠加,动态标识我方及敌方目标位置和行进方向

@ -120,9 +120,8 @@ void ProcessIR()
cv::Mat mat_pan;//全景显示
//FILE* file = fopen("/media/wang/WORK/wangchongwu_gitea_2023/20241219152917_4.xraw","rb");
FILE* file = fopen("D:/wangchongwu_gitea_2023/20241219152917_4.xraw", "rb");
//FILE* file = fopen("/home/wang/data62/729dataset/ir_1280_1024_para40_y16/5.xraw","rb");
FILE* file = fopen("F:/S729/20241219152917_4.xraw", "rb");
GaussianRandom gr(0.0, 1, 0.0);
@ -233,8 +232,8 @@ void ProcessVL()
cv::Mat mat_pan;//全景显示
FILE* file = fopen("D:/wangchongwu_gitea_2023/20241219152643_1.video", "rb");
//FILE* file = fopen("H:/21.video", "rb");
FILE* file = fopen("F:/S729/20241219152643_1.video", "rb");
GaussianRandom gr(0.0, 1, 0.0);

@ -1,6 +1,9 @@
#ifndef FEATURE_MATCHER_H
#define FEATURE_MATCHER_H
#pragma once
#include <opencv2/opencv.hpp>
#include <vector>
#include <stdexcept>

@ -0,0 +1,60 @@
#include "Arith_FusionMap.h"
#include "Arith_Utils.h"
MapFusion::MapFusion(FileCache<FrameCache>* cache)
{
_cache = cache;
}
MapFusion::~MapFusion()
{
}
void MapFusion::DirectMap(vector<KeyType> frameInd, cv::Mat mapH, cv::Mat pan, cv::Mat pan_mask)
{
pan.setTo(0);
// 从文件缓存获取帧
auto _t_frame_cache = std::make_shared<FrameCache>();
for (size_t i = 0; i < frameInd.size(); i++)
{
KeyType key = frameInd[i];
bool flag = _cache->get(key, _t_frame_cache);
if (!flag)
{
continue;
}
// 读取当前H
cv::Mat H1 = cv::Mat(3, 3, CV_64FC1, _t_frame_cache->H);
// 与全景图的H相乘
cv::Mat H = mapH * H1;
// 利用H投影当前帧到全景
cv::Mat imagetmp(pan.size(), CV_8UC3, cv::Scalar(0, 0, 0));
// 获取图像数据
cv::Mat src = getRGBAMatFromGDFrame(_t_frame_cache->_frame_info, _t_frame_cache->_data);
cv::warpPerspective(src, imagetmp, H, imagetmp.size(), cv::INTER_LINEAR, cv::BORDER_TRANSPARENT);
cv::Mat mask = cv::Mat::ones(cv::Size(src.cols - 200, src.rows - 200), CV_8UC1) * 255;
cv::Mat warped_mask;
cv::warpPerspective(mask, warped_mask, H, imagetmp.size(), cv::INTER_LINEAR);
imagetmp.copyTo(pan, warped_mask);
// 保存遮罩
warped_mask.copyTo(pan_mask, warped_mask);
//imshow("mask", pan_mask);
//waitKey(1);
}
}
void MapFusion::FusionMap(vector<KeyType> frameInd, cv::Mat mapH, cv::Mat pan, cv::Mat pan_mask)
{
}

@ -0,0 +1,37 @@
/*********版权所有C2025武汉高德红外股份有限公司***************************************
* Arith_FusionMap.h
*
*
*
* V0.5
* 04046wcw
* 2025/02/13
*
*****************************************************************************************/
#pragma once
#ifndef FUSION_MAP_H
#define FUSION_MAP_H
#include "FileCache.h"
class MapFusion
{
public:
MapFusion(FileCache<FrameCache>* cache);
~MapFusion();
public:
void DirectMap(vector<KeyType> frameInd, cv::Mat mapH, cv::Mat pan, cv::Mat pan_mask); //直接投影
void FusionMap(vector<KeyType> frameInd, cv::Mat mapH, cv::Mat pan, cv::Mat pan_mask);//融合投影
private:
FileCache<FrameCache>* _cache;
};
#endif

@ -39,10 +39,10 @@ public:
GeoSolver();
~GeoSolver();
// 建立全景图与归一化地理系的H矩阵
// 建立全景图与归一化地理系的H矩阵解析出H
cv::Mat findHomography(FrameInfo info);
// 解析出H
// 测试
cv::Mat findHomography2(FrameInfo info);
// 设置起始拼接点外参
@ -54,9 +54,10 @@ public:
// 计算局部地理系下目标的经纬度
PointBLH getBLHFromGeo(cv::Point2f ptInGeo);
// 经纬度转换为局部地理系坐
// 经纬度转换为局部地理系坐
cv::Point2f getGeoFromBLH(PointBLH ptPos);
private:
// 计算当前帧像方-地理坐标系R t反投影关系
Proj AnlayseTform(FrameInfo info);

@ -31,6 +31,8 @@ VideoStitch::VideoStitch(SINT32 nWidth, SINT32 nHeight)
_BATask = new BA_Task(_cache);
_fusionTask = new MapFusion(_cache);
_panPara = { 0 };
_totalFrameCnt = 0;
@ -246,70 +248,13 @@ SINT32 VideoStitch::ProcessFrame()
//_BATask->OptFrame(_recvFrameKey, _H_pan);
// 重投影所有帧到全景
mapFrame(_recvFrameKey);
// 正反算验证
// auto _t_frame_cache = std::make_shared<FrameCache>();
//bool flag = _cache->get(10, _t_frame_cache);
_fusionTask->DirectMap(_recvFrameKey, _H_pan, _panImage,_panMask);
//// 读取当前H
//cv::Mat H1 = cv::Mat(3, 3, CV_64FC1, _t_frame_cache->H);
//// 与全景图的H相乘
//cv::Mat H = _H_pan * H1;
//PointBLH res = getBLHFromPan(warpPointWithH(H, cv::Point2f(519, 483)), _H_pan);
//PointBLH BLHpT = _GeoSolver->getBLHFromFrame(H1, cv::Point2f(519, 483));
return 0;
}
void VideoStitch::mapFrame(vector<KeyType> frameInd)
{
_panImage.setTo(0);
// 从文件缓存获取帧
auto _t_frame_cache = std::make_shared<FrameCache>();
for (size_t i = 0; i < frameInd.size(); i++)
{
KeyType key = frameInd[i];
bool flag = _cache->get(key, _t_frame_cache);
if (!flag)
{
continue;
}
// 读取当前H
cv::Mat H1 = cv::Mat(3,3,CV_64FC1,_t_frame_cache->H);
// 与全景图的H相乘
cv::Mat H = _H_pan * H1;
// 利用H投影当前帧到全景
cv::Mat imagetmp(_panImage.size(), CV_8UC3, cv::Scalar(0, 0, 0));
// 获取图像数据
cv::Mat src = getRGBAMatFromGDFrame(_t_frame_cache->_frame_info, _t_frame_cache->_data);
cv::warpPerspective(src, imagetmp, H, imagetmp.size(), cv::INTER_LINEAR, cv::BORDER_TRANSPARENT);
cv::Mat mask = cv::Mat::ones(cv::Size(src.cols - 200,src.rows - 200), CV_8UC1) * 255;
cv::Mat warped_mask;
cv::warpPerspective(mask, warped_mask, H, imagetmp.size(), cv::INTER_LINEAR);
imagetmp.copyTo(_panImage, warped_mask);
// 保存遮罩
warped_mask.copyTo(_panMask, warped_mask);
//imshow("mask", _panMask);
//waitKey(1);
}
}
bool VideoStitch::ExportGeoPng(std::string dir, std::string name)
{
@ -364,7 +309,7 @@ bool VideoStitch::ExportGoogleTile(std::string dir, std::string name)
info.box.south = minB;
info.box.west = minL;
info.box.east = maxL;
info.ind.z = 17;
info.ind.z = 16;
_googleProduct.ExportTile(_panImage, info, dir);
return 0;

@ -6,6 +6,7 @@
#include "Arith_BATask.h"
#include "FileCache.h"
#include "GoogleTile.h"
#include "Arith_FusionMap.h"
class VideoStitch:public API_VideoStitch
{
@ -23,8 +24,6 @@ public:
// 处理帧
SINT32 ProcessFrame();
// 投影到全景图
void mapFrame(vector<KeyType> frameInd);
// 输出地理产品:kml png全景
bool ExportGeoPng(std::string dir, std::string name);
@ -60,6 +59,9 @@ private:
BA_Task* _BATask;//BA
MapFusion* _fusionTask;// 融合模块
PanInfo _panPara;//全景图配置
cv::Mat _H_pan;//全景图投影矩阵:从地理系到全景地图

@ -66,7 +66,7 @@ void googleTile::ExportTile(cv::Mat _pan, TileInfo panInfo, std::string dir)
{
for (size_t j = xStart; j < xEnd; j++)
{
TileIndex id = {j,i,17};
TileIndex id = {j,i,zoom};
TileBox tilebox = GetTileBox(id);
// 填充
@ -126,6 +126,19 @@ void googleTile::ExportTile(cv::Mat _pan, TileInfo panInfo, std::string dir)
}
int googleTile::getZoomLevel(float mp)
{
int nLev = 0;
// 计算单位瓦片的实际覆盖
int meters_cover = TILE_SIZE * mp;
int earthLen = 40075017;
nLev = std::round(std::log2(earthLen / meters_cover));
return nLev;
}
TileIndex googleTile::LatLonToTile(double latitude, double longitude, int zoomLevel)
{
// 将纬度转换为墨卡托投影

@ -31,6 +31,7 @@ struct TileInfo
TileBox box;
};
const int TILE_SIZE = 256;
class googleTile
{
@ -45,10 +46,12 @@ public:
// 输出tile
void ExportTile(cv::Mat _pan, TileInfo info, std::string dir);
public:
TileIndex LatLonToTile(double latitude, double longitude, int zoomLevel);
// 计算给定分辨率最接近的瓦片等级,mp单位 米/像素
int getZoomLevel(float mp);
private:
TileIndex LatLonToTile(double latitude, double longitude, int zoomLevel);
// 瓦片编号对应的信息
TileBox GetTileBox(TileIndex ind);

Loading…
Cancel
Save