parent
8496a66eff
commit
e6751c98fc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,181 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "API_FeaStitch.h"
|
||||
#include "PlatformDefine.h"
|
||||
#include <string.h>
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include <random>
|
||||
|
||||
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<int>(cap.get(cv::CAP_PROP_FRAME_WIDTH));
|
||||
int height = static_cast<int>(cap.get(cv::CAP_PROP_FRAME_HEIGHT));
|
||||
int frame_count = static_cast<int>(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_RGB_PACKED;
|
||||
frame.u32Width = mat_ds2.cols;
|
||||
frame.u32Height = mat_ds2.rows;
|
||||
frame.u64VirAddr[0] = mat_ds2.data;
|
||||
|
||||
if (frmID % 100 != 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()
|
||||
{
|
||||
|
||||
string videoPath = "F:/DJI_202504181507_016/DJI_20250418152649_0005_W.MP4";
|
||||
|
||||
ProcDJVideo(videoPath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
class FeaStitch : public API_FeaStitch
|
||||
{
|
||||
public:
|
||||
FeaStitch();
|
||||
~FeaStitch();
|
||||
|
||||
GenPanInfo Init(GD_VIDEO_FRAME_S img, FrameInfo info);
|
||||
void SetOutput(std::string filename, std::string outdir);
|
||||
SINT32 Run(GD_VIDEO_FRAME_S img, FrameInfo para);
|
||||
GD_VIDEO_FRAME_S ExportPanAddr();
|
||||
cv::Mat ExportPanMat();
|
||||
|
||||
private:
|
||||
void SetBase(cv::Mat& img, FrameInfo& info, EdgeDirection edgeDirection);
|
||||
EdgeDirection isNearEdge(cv::Mat& H);
|
||||
void calculateInitialOffset(EdgeDirection direction, int& offsetX, int& offsetY);
|
||||
float calculateIOU(const cv::Mat& H1, const cv::Mat& H2, const cv::Size& imgSize);
|
||||
bool checkHContinuity(const cv::Mat& prevH, const cv::Mat& currH);
|
||||
|
||||
FeatureMatcher* _FeaMatcher;
|
||||
std::vector<FrameInfo> _paraVec;
|
||||
std::vector<cv::Mat> _imgVec;
|
||||
std::vector<std::vector<cv::KeyPoint>> _keypointsVec;
|
||||
std::vector<cv::Mat> _descriptorsVec;
|
||||
std::vector<cv::Mat> _currMatrix;
|
||||
cv::Mat _panImage;
|
||||
GenPanInfo _panPara;
|
||||
SINT32 _totalFrameCnt;
|
||||
SINT32 _failedFrameCnt; // 连续失败帧计数
|
||||
};
|
@ -0,0 +1,72 @@
|
||||
#ifndef _FEASTITCH_H
|
||||
#define _FEASTITCH_H
|
||||
#include "API_FeaStitch.h"
|
||||
#include "opencv2/opencv.hpp"
|
||||
#include "Arith_BATask.h"
|
||||
#include <map>
|
||||
|
||||
// 定义出界方向枚举
|
||||
enum class EdgeDirection
|
||||
{
|
||||
NONE, // 未出界
|
||||
LEFT, // 左边界
|
||||
RIGHT, // 右边界
|
||||
TOP, // 上边界
|
||||
BOTTOM, // 下边界
|
||||
TOP_LEFT, // 左上角
|
||||
TOP_RIGHT, // 右上角
|
||||
BOTTOM_LEFT,// 左下角
|
||||
BOTTOM_RIGHT// 右下角
|
||||
};
|
||||
|
||||
class FeaStitch :public API_FeaStitch
|
||||
{
|
||||
public:
|
||||
FeaStitch();
|
||||
~FeaStitch();
|
||||
|
||||
GenPanInfo Init(GD_VIDEO_FRAME_S img,FrameInfo info);
|
||||
|
||||
// 当前帧设为拼接基准
|
||||
void SetBase(cv::Mat& img, FrameInfo& info, EdgeDirection edgeDirection = EdgeDirection::NONE);
|
||||
|
||||
|
||||
void SetOutput(std::string filename, std::string outdir);
|
||||
|
||||
SINT32 Run(GD_VIDEO_FRAME_S img, FrameInfo para);
|
||||
|
||||
public:
|
||||
|
||||
GD_VIDEO_FRAME_S ExportPanAddr();
|
||||
|
||||
cv::Mat ExportPanMat();
|
||||
|
||||
FeatureMatcher* _FeaMatcher;//特征匹配
|
||||
|
||||
private:
|
||||
std::vector<FrameInfo> _paraVec; // 帧参数
|
||||
std::vector<cv::Mat> _imgVec; //图像缓存
|
||||
std::vector<std::vector<cv::KeyPoint>> _keypointsVec; // 特征点
|
||||
std::vector<cv::Mat> _descriptorsVec; // 描述子
|
||||
std::vector<cv::Mat_<double>> _currMatrix;//当前H矩阵
|
||||
int _totalFrameCnt;//处理帧计数
|
||||
int _failedFrameCnt;//匹配失败计数
|
||||
|
||||
private:
|
||||
GenPanInfo _panPara;//全景图配置
|
||||
cv::Mat _panImage; //全景图
|
||||
|
||||
// 检测图像是否接近边缘,返回出界方向
|
||||
EdgeDirection isNearEdge(cv::Mat& H);
|
||||
|
||||
// 根据出界方向计算初始偏移量
|
||||
void calculateInitialOffset(EdgeDirection direction, int& offsetX, int& offsetY);
|
||||
|
||||
float calculateIOU(const cv::Mat& H1, const cv::Mat& H2, const cv::Size& imgSize);
|
||||
|
||||
bool checkHContinuity(const cv::Mat& prevH, const cv::Mat& currH);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in new issue