#include #include #include #include #include #include #include "API_FeaStitch.h" #include "PlatformDefine.h" #include #include "opencv2/opencv.hpp" #include void ProcDJVideo(std::string videoPathList) { auto stitcher = API_FeaStitch::Create(); GD_VIDEO_FRAME_S frame = { 0 };//输入帧 GD_VIDEO_FRAME_S pan = { 0 };//输出全景 cv::Mat mat_pan;//全景显示 cv::VideoCapture cap(videoPathList); // Get video properties double fps = cap.get(cv::CAP_PROP_FPS); int width = static_cast(cap.get(cv::CAP_PROP_FRAME_WIDTH)); int height = static_cast(cap.get(cv::CAP_PROP_FRAME_HEIGHT)); int frame_count = static_cast(cap.get(cv::CAP_PROP_FRAME_COUNT)); // dsample int nDownSample = 1; if (width > 3000) { nDownSample = 4; } FrameInfo info = { 0 }; info.nFrmID = 0; info.camInfo.nFocus = 0; info.camInfo.fPixelSize = 0; info.craft.stAtt.fYaw = 0; info.craft.stAtt.fPitch = 0; info.craft.stAtt.fRoll = 0; info.craft.stPos.B = 0; info.craft.stPos.L = 0; info.craft.stPos.H = 0; info.nEvHeight = 0; info.servoInfo.fServoAz = 0; info.servoInfo.fServoPt = 0; info.nWidth = width / nDownSample; info.nHeight = height / nDownSample; cv::Mat mat; // Read a new frame cap >> mat; Mat mat_ds2; cv::resize(mat, mat_ds2, cv::Size(width / nDownSample, height / nDownSample)); frame.enPixelFormat = GD_PIXEL_FORMAT_RGB_PACKED; frame.u32Width = mat_ds2.cols; frame.u32Height = mat_ds2.rows; frame.u64VirAddr[0] = mat_ds2.data; // 初始化 stitcher->Init(frame,info); mat_pan = stitcher->ExportPanMat(); Mat pan_rgb, pan_rgb_ds; cv::cvtColor(mat_pan, pan_rgb, cv::COLOR_BGRA2BGR); cv::resize(pan_rgb, pan_rgb_ds, cv::Size(pan_rgb.cols / 2, pan_rgb.rows / 2)); imshow("pan_rgb", pan_rgb_ds); cv::waitKey(0); cv::VideoWriter output; output.open("D:/DJ_stitchVL.mp4", cv::VideoWriter::fourcc('H', '2', '6', '4'), 5, cv::Size(mat_pan.cols / 3, mat_pan.rows / 3), true); int frmID = 0; while (true) { cv::Mat mat; // Read a new frame cap >> mat; // Check if frame is empty (end of video) if (mat.empty()) { std::cout << "End of video\n"; cap.release(); break; } frmID++; Mat mat_ds2; cv::resize(mat, mat_ds2, cv::Size(width / nDownSample, height / nDownSample)); FrameInfo info = { 0 }; info.nFrmID = frmID; info.nWidth = mat_ds2.cols; info.nHeight = mat_ds2.rows; frame.enPixelFormat = GD_PIXEL_FORMAT_BGR_PACKED; frame.u32Width = mat_ds2.cols; frame.u32Height = mat_ds2.rows; frame.u64VirAddr[0] = mat_ds2.data; if (frmID % 20 != 0) { continue; } cv::TickMeter tm; tm.start(); // 基于外参的快拼 stitcher->Run(frame, info); tm.stop(); printf("cost time:%f\n", tm.getTimeMilli()); Mat pan_rgb, pan_rgb_ds; cv::cvtColor(mat_pan, pan_rgb, cv::COLOR_BGRA2BGR); cv::resize(pan_rgb, pan_rgb_ds, cv::Size(pan_rgb.cols / 2, pan_rgb.rows / 2)); output.write(pan_rgb_ds); imshow("pan_rgb", pan_rgb_ds); if (cv::waitKey(1) == 27) { break; } } output.release(); } using std::string; int main(int argc, char* argv[]) { string videoPath; if (argc == 1) { videoPath = "F:/DJI_202504021349_012/DJI_20250402135211_0001_W.MP4"; } else { videoPath = argv[1]; } //videoPath = "F:/DJI_202504181507_016/DJI_20250418152649_0005_W.MP4"; ProcDJVideo(videoPath); return 0; }