diff --git a/API_MANUAL.md b/API_MANUAL.md new file mode 100644 index 0000000..e8e37b0 --- /dev/null +++ b/API_MANUAL.md @@ -0,0 +1,103 @@ +# 航拍拼接模块接口说明 + +本模块用于吊舱的扫描全景图拼接,包含前视和下视两个模式。前视与下视投影面和效果均不同。二者接口大部分相同。 + + + +## 前视接口 + +### 1.依赖 +本模块依赖ceres优化库(包含gflag、glog)以及cuda支持,opencv 410支持。 +除cuda库外,其余库均以vc17动态库文件形式提供。 + + +### 2.接口 + +```C++ +static API_FrontStitch* Create(std::string cachedir = "./cache"); +``` + +模块创建接口,其中默认参数为使用cache路径,cache是用于拼接图优化的预留功能,当前版本暂未使用,可以不做设置 + +```C++ +static void Destroy(API_FrontStitch* obj); +``` +模块析构接口,使用完毕后释放内存。 + +```C++ +virtual FPanInfo Init(FrameInfo info, ScanRange stAzRange, ScanRange stPtRange) = 0; +``` +初始化接口,请使用拼接时刻的内外参信息以及扫描区间进行初始化,其中方位扫描区间和俯仰扫描区域均为伺服坐标系。程序内部会转换为大地坐标进行初始化,并将拼接图中心置为扫描中心。 + +```C++ + virtual BYTE8 Run(GD_VIDEO_FRAME_S img, FrameInfo para) = 0; +``` +运行拼接流程,在该过程中程序自动将当前图像重新投影到全景图上,可以通过访问全景图内存进行实时显示。 + + +```C++ + virtual GD_VIDEO_FRAME_S ExportPanAddr() = 0; +``` +获取全景图接口,其中GD_VIDEO_FRAME_S是高德研发中心通用帧接口,内部维护了图像类型和指针等信息。具体参见GD_VIDEO_FRAME_S接口说明 + + +```C++ + virtual SINT32 OptAndOutCurrPan() = 0; +``` +全景投影完毕后,可以调用该接口进行优化,主要是精细对齐帧以及拼接缝消除等,暂未实现。 + + + +## 下视接口 +### 1.依赖 +本模块依赖opencv 410。 + + +### 2.接口 + + +```C++ +static API_FrontStitch* Create(std::string cachedir = "./cache"); +``` + +模块创建接口,其中默认参数为使用cache路径,cache是用于拼接图优化的预留功能,当前版本暂未使用,可以不做设置 + +```C++ +static void Destroy(API_FrontStitch* obj); +``` +模块析构接口,使用完毕后释放内存。 + +```C++ +virtual FPanInfo Init(FrameInfo info, ScanRange stAzRange, ScanRange stPtRange) = 0; +``` +初始化接口,请使用拼接时刻的内外参信息以及扫描区间进行初始化,其中方位扫描区间和俯仰扫描区域均为伺服坐标系。程序内部会转换为大地坐标进行初始化,并将拼接图中心置为扫描中心。 + + +```C++ + virtual void SetOutput(std::string name, std::string outdir) = 0; +``` +设置输出路径,下视模块按照通用谷歌瓦片生成标准256*256瓦片,提前设置好输出文件夹 + +```C++ + virtual void SetConfig(UPanConfig config) = 0; +``` +设置运行参数。 + + + +```C++ + virtual BYTE8 Run(GD_VIDEO_FRAME_S img, FrameInfo para) = 0; +``` +运行拼接流程,在该过程中程序自动将当前图像重新投影到全景图上,可以通过访问全景图内存进行实时显示。 + + +```C++ + virtual GD_VIDEO_FRAME_S ExportPanAddr() = 0; +``` +获取全景图接口,其中GD_VIDEO_FRAME_S是高德研发中心通用帧接口,内部维护了图像类型和指针等信息。具体参见GD_VIDEO_FRAME_S接口说明 + + +```C++ + virtual SINT32 OptAndOutCurrPan() = 0; +``` +全景投影完毕后,可以调用该接口进行优化,主要是精细对齐帧以及拼接缝消除等,暂未实现。 \ No newline at end of file diff --git a/main.cpp b/main.cpp index 2ace5ce..b4197fe 100644 --- a/main.cpp +++ b/main.cpp @@ -222,7 +222,7 @@ void ProcessIR(string filePath, string outname) void ProcessVL(string filePath,string outname) { auto stitcher = API_UnderStitch::Create(); - stitcher->SetOutput(outname, "D:/google_tiles"); + stitcher->SetOutput(outname, "google_tiles"); GD_VIDEO_FRAME_S frame = { 0 };//输入帧 @@ -232,7 +232,7 @@ void ProcessVL(string filePath,string outname) FILE* file = fopen(filePath.c_str(), "rb"); - + cv::VideoWriter output; GaussianRandom gr(0.0, 1, 0.0); int i = 0; @@ -290,12 +290,12 @@ void ProcessVL(string filePath,string outname) mat_pan = cv::Mat(pan.u32Height, pan.u32Width, CV_8UC4, pan.u64VirAddr[0]); - //output.open("D:/output.mp4", VideoWriter::fourcc('H', '2', '6', '4'), 25, Size(pan.u32Width, pan.u32Height), true); - //if (!output.isOpened()) - //{ - // cout << "打开视频失败" << endl; - // return; - //} + output.open("D:/output.mp4", VideoWriter::fourcc('H', '2', '6', '4'), 25, Size(pan.u32Width, pan.u32Height), true); + if (!output.isOpened()) + { + cout << "打开视频失败" << endl; + return; + } } else { @@ -318,7 +318,7 @@ void ProcessVL(string filePath,string outname) cout << "time:" << tm.getTimeMilli() << endl; - //output.write(mat_pan); + output.write(mat_pan); // 接收帧 //auto a = stitcher->ReceiveFrame(frame, info); @@ -329,6 +329,8 @@ void ProcessVL(string filePath,string outname) cv::resize(mat_pan, res, cv::Size(pan.u32Width / 4, pan.u32Height / 4)); imshow("pan_opt", res); + output.release(); + waitKey(1); i = i + 1; @@ -371,7 +373,7 @@ void ProcessFrontVL(string filePath) SINT32 nVLFrameSize = 1.5 * IMAGE_WIDTH_VL * IMAGE_HEIGHT_VL + IMAGE_WIDTH_VL * PARA_IR_LINE; - + cv::VideoWriter output; int i = 0; while (!feof(file)) @@ -409,9 +411,9 @@ void ProcessFrontVL(string filePath) info.craft.stAtt.fRoll += gr.generate(); - //cv::Mat mat_src(IMAGE_HEIGHT_VL * 1.5, IMAGE_WIDTH_VL, CV_8UC1, pFrameVL); - //cv::Mat IMG; - //cv::cvtColor(mat_src, IMG, cv::COLOR_YUV2BGR_NV12); + cv::Mat mat_src(IMAGE_HEIGHT_VL * 1.5, IMAGE_WIDTH_VL, CV_8UC1, pFrameVL); + cv::Mat IMG; + cv::cvtColor(mat_src, IMG, cv::COLOR_YUV2BGR_NV12); //imshow("src", IMG); //waitKey(1); @@ -423,11 +425,19 @@ void ProcessFrontVL(string filePath) if (i == 0) { - stitcher->Init(info, ScanRange{0,100}, ScanRange{ 56,90 }); + stitcher->Init(info, ScanRange{-10,100}, ScanRange{ 56,90 }); pan = stitcher->ExportPanAddr(); mat_pan = cv::Mat(pan.u32Height, pan.u32Width, CV_8UC3, pan.u64VirAddr[0]); + + + output.open("F:/output.mp4", VideoWriter::fourcc('H', '2', '6', '4'), 5, Size(pan.u32Width/4, pan.u32Height/4), true); + if (!output.isOpened()) + { + cout << "打开视频失败" << endl; + return; + } } else { @@ -454,10 +464,21 @@ void ProcessFrontVL(string filePath) } + // 定义大图的 ROI(左上角区域) + cv::Mat roi = mat_pan(cv::Rect(0, 0, frame.u32Width, frame.u32Height)); + + // 将小图复制到 ROI + IMG.copyTo(roi); + + cv::Mat res; cv::resize(mat_pan, res, cv::Size(pan.u32Width / 4, pan.u32Height / 4)); imshow("pan_opt", res); + output << res; + + + waitKey(1); i = i + 1; } @@ -468,6 +489,8 @@ void ProcessFrontVL(string filePath) cv::resize(mat_pan, res, cv::Size(pan.u32Width / 4, pan.u32Height / 4)); imshow("pan_opt", res); + output.release(); + waitKey(0); @@ -477,12 +500,12 @@ void ProcessFrontVL(string filePath) int main(int, char**) { //ProcessIR("H:/ir_1280_1024_para40_y16/20241219155238_20.xraw", "20241219155238_20"); - //ProcessVL("H:/vl_1920_1080_para40_y8/22.video","22"); + //ProcessVL("/home/wang/22.video","22"); //ProcessVL("H:/vl_1920_1080_para40_y8/20241219153557_11.video", "20241219152643_1"); //ProcessVL("H:/vl_1920_1080_para40_y8/20241219152917_4.video", "20241219152917_4"); //ProcessVL("H:/vl_1920_1080_para40_y8/20241219153515_10.video", "20241219153515_10"); // - //ProcessVL("H:/vl_1920_1080_para40_y8/1.video", "1"); + ProcessVL("H:/vl_1920_1080_para40_y8/1.video", "1"); - ProcessFrontVL("H:/vl_1920_1080_para40_y8/20241219152917_4.video"); + //ProcessFrontVL("H:/vl_1920_1080_para40_y8/1.video"); } \ No newline at end of file diff --git a/stitch/src/Arith_BATask.h b/stitch/src/Arith_BATask.h index 6abd27d..f38142a 100644 --- a/stitch/src/Arith_BATask.h +++ b/stitch/src/Arith_BATask.h @@ -16,7 +16,7 @@ #include "Arith_FeaMatch.h" -#define SHOW_MATCH +//#define SHOW_MATCH class BA_Task diff --git a/stitch/src/Arith_UnderStitch.cpp b/stitch/src/Arith_UnderStitch.cpp index 76b54b0..f35dee9 100644 --- a/stitch/src/Arith_UnderStitch.cpp +++ b/stitch/src/Arith_UnderStitch.cpp @@ -62,9 +62,9 @@ UPanInfo UnderStitch::InitMap(FrameInfo info) // 全景图初始化 UPanInfo panPara = { 0 }; - panPara.m_pan_width = MIN(info.nWidth * 5,2000);//全景宽 - panPara.m_pan_height = MIN(info.nWidth * 5,2000);//全景高 - panPara.scale = gsd / 2;//比例尺,1m = ?pix + panPara.m_pan_width = MIN(info.nWidth * 5,3000);//全景宽 + panPara.m_pan_height = MIN(info.nWidth * 5,3000);//全景高 + panPara.scale = gsd / 9;//比例尺,1m = ?pix // 直接无平移解算