|
|
|
@ -23,7 +23,6 @@ void API_VideoStitch::Destroy(API_VideoStitch * obj)
|
|
|
|
|
VideoStitch::VideoStitch(SINT32 nWidth, SINT32 nHeight)
|
|
|
|
|
{
|
|
|
|
|
_GeoStitcher = new GeoStitcher();
|
|
|
|
|
memset(&_pan, 0, sizeof(GD_VIDEO_FRAME_S));
|
|
|
|
|
|
|
|
|
|
_BATask = new BA_Task(_GeoStitcher);
|
|
|
|
|
|
|
|
|
@ -52,58 +51,85 @@ PanInfo VideoStitch::Init(FrameInfo info)
|
|
|
|
|
return _panPara;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//BYTE8 VideoStitch::GeoStitch(GD_VIDEO_FRAME_S img, FrameInfo para)
|
|
|
|
|
//{
|
|
|
|
|
// Proj t_Proj = _GeoStitcher->AnlayseTform(para);
|
|
|
|
|
//
|
|
|
|
|
// // 计算帧的map四至
|
|
|
|
|
// cv::Point2f leftTop_map = _GeoStitcher->back_project(cv::Point2f(0,0), t_Proj, _panPara);
|
|
|
|
|
// cv::Point2f rightTop_map = _GeoStitcher->back_project(cv::Point2f(img.u32Width,0), t_Proj, _panPara);
|
|
|
|
|
// cv::Point2f rightBottom_map = _GeoStitcher->back_project(cv::Point2f(img.u32Width,img.u32Height), t_Proj, _panPara);
|
|
|
|
|
// cv::Point2f leftBottom_map = _GeoStitcher->back_project(cv::Point2f(0,img.u32Height), t_Proj, _panPara);
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// auto H = _GeoStitcher->findHomography(t_Proj,_panPara);
|
|
|
|
|
// leftTop_map = warpPointWithH(H,cv::Point2f(0,0));
|
|
|
|
|
// rightTop_map = warpPointWithH(H,cv::Point2f(img.u32Width,0));
|
|
|
|
|
// rightBottom_map = warpPointWithH(H,cv::Point2f(img.u32Width,img.u32Height));
|
|
|
|
|
// leftBottom_map = warpPointWithH(H,cv::Point2f(0,img.u32Height));
|
|
|
|
|
//
|
|
|
|
|
// // 计算全景图的范围
|
|
|
|
|
// int right = max(max(max(leftTop_map.x, leftBottom_map.x), rightTop_map.x), rightBottom_map.x);
|
|
|
|
|
// int left = min(min(min(leftTop_map.x, leftBottom_map.x), rightTop_map.x), rightBottom_map.x);
|
|
|
|
|
// int top = min(min(min(leftTop_map.y, leftBottom_map.y), rightTop_map.y), rightBottom_map.y);
|
|
|
|
|
// int bottom = max(max(max(leftTop_map.y, leftBottom_map.y), rightTop_map.y), rightBottom_map.y);
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// int xRange = right - left;
|
|
|
|
|
// int yRnage = bottom - top;
|
|
|
|
|
//
|
|
|
|
|
// //反映射到像素坐标
|
|
|
|
|
// int valid_top = std::max(0, top);
|
|
|
|
|
// int valid_bottom = std::min(_pan.cols, bottom);
|
|
|
|
|
// int valid_left = std::max(0, left);
|
|
|
|
|
// int valid_right = std::min(_pan.rows, right);
|
|
|
|
|
//
|
|
|
|
|
//#pragma omp parallel for
|
|
|
|
|
// for (int i = valid_top; i < valid_bottom; i++)
|
|
|
|
|
// {
|
|
|
|
|
// for (int j = valid_left; j < valid_right; j++)
|
|
|
|
|
// {
|
|
|
|
|
// //转换为pixel坐标
|
|
|
|
|
// cv::Point2f p_img = _GeoStitcher->project(Point2f(j, i), t_Proj, _panPara);
|
|
|
|
|
//
|
|
|
|
|
// p_img = warpPointWithH(H.inv(),Point2f(j, i));
|
|
|
|
|
// if (p_img.x >= 0 && p_img.y >= 0 && p_img.x < img.u32Width && p_img.y < img.u32Height)
|
|
|
|
|
// {
|
|
|
|
|
// _pan.data[i * _pan.rows + j] =
|
|
|
|
|
// FourPointInterpolation(img.u64VirAddr[0], img.u32Width, img.u32Height, p_img.x, p_img.y);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// return 0;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
BYTE8 VideoStitch::GeoStitch(GD_VIDEO_FRAME_S img, FrameInfo para)
|
|
|
|
|
{
|
|
|
|
|
Proj t_Proj = _GeoStitcher->AnlayseTform(para);
|
|
|
|
|
|
|
|
|
|
// 计算帧的map四至
|
|
|
|
|
cv::Point2f leftTop_map = _GeoStitcher->back_project(cv::Point2f(0,0), t_Proj, _panPara);
|
|
|
|
|
cv::Point2f rightTop_map = _GeoStitcher->back_project(cv::Point2f(img.u32Width,0), t_Proj, _panPara);
|
|
|
|
|
cv::Point2f rightBottom_map = _GeoStitcher->back_project(cv::Point2f(img.u32Width,img.u32Height), t_Proj, _panPara);
|
|
|
|
|
cv::Point2f leftBottom_map = _GeoStitcher->back_project(cv::Point2f(0,img.u32Height), t_Proj, _panPara);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto H = _GeoStitcher->findHomography(t_Proj,_panPara);
|
|
|
|
|
leftTop_map = warpPointWithH(H,cv::Point2f(0,0));
|
|
|
|
|
rightTop_map = warpPointWithH(H,cv::Point2f(img.u32Width,0));
|
|
|
|
|
rightBottom_map = warpPointWithH(H,cv::Point2f(img.u32Width,img.u32Height));
|
|
|
|
|
leftBottom_map = warpPointWithH(H,cv::Point2f(0,img.u32Height));
|
|
|
|
|
// uv2Geo H
|
|
|
|
|
cv::Mat H1 = _GeoStitcher->findHomography(t_Proj);
|
|
|
|
|
|
|
|
|
|
// 计算全景图的范围
|
|
|
|
|
int right = max(max(max(leftTop_map.x, leftBottom_map.x), rightTop_map.x), rightBottom_map.x);
|
|
|
|
|
int left = min(min(min(leftTop_map.x, leftBottom_map.x), rightTop_map.x), rightBottom_map.x);
|
|
|
|
|
int top = min(min(min(leftTop_map.y, leftBottom_map.y), rightTop_map.y), rightBottom_map.y);
|
|
|
|
|
int bottom = max(max(max(leftTop_map.y, leftBottom_map.y), rightTop_map.y), rightBottom_map.y);
|
|
|
|
|
// Geo2Pan H
|
|
|
|
|
cv::Mat H2 = getHFromGeo2Pan(_panPara);
|
|
|
|
|
|
|
|
|
|
cv::Mat H = H2 * H1;
|
|
|
|
|
|
|
|
|
|
int xRange = right - left;
|
|
|
|
|
int yRnage = bottom - top;
|
|
|
|
|
// 利用H投影当前帧到全景
|
|
|
|
|
cv::Mat imagetmp(_pan.size(), CV_8UC3, cv::Scalar(0, 0, 0));
|
|
|
|
|
|
|
|
|
|
//反映射到像素坐标
|
|
|
|
|
int valid_top = std::max(0, top);
|
|
|
|
|
int valid_bottom = std::min(_pan.cols, bottom);
|
|
|
|
|
int valid_left = std::max(0, left);
|
|
|
|
|
int valid_right = std::min(_pan.rows, right);
|
|
|
|
|
cv::Mat src(img.u32Height, img.u32Width, CV_8UC1, img.u64VirAddr[0]);
|
|
|
|
|
|
|
|
|
|
#pragma omp parallel for
|
|
|
|
|
for (int i = valid_top; i < valid_bottom; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = valid_left; j < valid_right; j++)
|
|
|
|
|
{
|
|
|
|
|
//转换为pixel坐标
|
|
|
|
|
cv::Point2f p_img = _GeoStitcher->project(Point2f(j, i), t_Proj, _panPara);
|
|
|
|
|
|
|
|
|
|
p_img = warpPointWithH(H.inv(),Point2f(j, i));
|
|
|
|
|
if (p_img.x >= 0 && p_img.y >= 0 && p_img.x < img.u32Width && p_img.y < img.u32Height)
|
|
|
|
|
{
|
|
|
|
|
_pan.data[i * _pan.rows + j] =
|
|
|
|
|
FourPointInterpolation(img.u64VirAddr[0], img.u32Width, img.u32Height, p_img.x, p_img.y);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
cv::warpPerspective(src, imagetmp, H, imagetmp.size());
|
|
|
|
|
|
|
|
|
|
cv::Mat mask = cv::Mat::ones(src.size(), CV_8UC1) * 255;
|
|
|
|
|
cv::Mat warped_mask;
|
|
|
|
|
cv::warpPerspective(mask, warped_mask, H, imagetmp.size());
|
|
|
|
|
imagetmp.copyTo(_pan, warped_mask);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SINT32 VideoStitch::BAStitch(GD_VIDEO_FRAME_S img, FrameInfo para)
|
|
|
|
@ -117,7 +143,7 @@ SINT32 VideoStitch::BAStitch(GD_VIDEO_FRAME_S img, FrameInfo para)
|
|
|
|
|
|
|
|
|
|
SINT32 VideoStitch::BAOpt()
|
|
|
|
|
{
|
|
|
|
|
_BATask->optimizeBA();
|
|
|
|
|
_BATask->optimizeBA(getHFromGeo2Pan(_panPara));
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -145,8 +171,10 @@ SINT32 VideoStitch::ReceiveFrame(GD_VIDEO_FRAME_S img, FrameInfo para)
|
|
|
|
|
|
|
|
|
|
// 深拷贝图像数据
|
|
|
|
|
memcpy(_t_frame_cache->_data,img.u64VirAddr[0],imgSize);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto size = sizeof(_t_frame_cache);
|
|
|
|
|
|
|
|
|
|
// 加入文件缓存
|
|
|
|
|
_cache->set(para.nFrmID,_t_frame_cache);
|
|
|
|
@ -158,26 +186,26 @@ SINT32 VideoStitch::ReceiveFrame(GD_VIDEO_FRAME_S img, FrameInfo para)
|
|
|
|
|
|
|
|
|
|
SINT32 VideoStitch::ProcFrame()
|
|
|
|
|
{
|
|
|
|
|
printf("size:%d\n",_cache->getMemSize());
|
|
|
|
|
std::shared_ptr<FrameCache> loadedFrame1;
|
|
|
|
|
bool bflag1 = _cache->get(30, loadedFrame1);
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<FrameCache> loadedFrame2;
|
|
|
|
|
auto bflag2 = _cache->get(40,loadedFrame2);
|
|
|
|
|
|
|
|
|
|
if (bflag1 && loadedFrame1->_frame_info.u32Height > 0)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat src1(loadedFrame1->_frame_info.u32Height, loadedFrame1->_frame_info.u32Width, CV_8UC1, loadedFrame1->_data);
|
|
|
|
|
imshow("src30",src1);
|
|
|
|
|
waitKey(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bflag2 && loadedFrame2->_frame_info.u32Height > 0)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat src2(loadedFrame2->_frame_info.u32Height, loadedFrame2->_frame_info.u32Width, CV_8UC1, loadedFrame2->_data);
|
|
|
|
|
imshow("src40",src2);
|
|
|
|
|
waitKey(0);
|
|
|
|
|
}
|
|
|
|
|
//printf("size:%d\n",_cache->getMemSize());
|
|
|
|
|
//std::shared_ptr<FrameCache> loadedFrame1;
|
|
|
|
|
// bool bflag1 = _cache->get(30, loadedFrame1);
|
|
|
|
|
|
|
|
|
|
//std::shared_ptr<FrameCache> loadedFrame2;
|
|
|
|
|
//auto bflag2 = _cache->get(40,loadedFrame2);
|
|
|
|
|
|
|
|
|
|
//if (bflag1 && loadedFrame1->_frame_info.u32Height > 0)
|
|
|
|
|
//{
|
|
|
|
|
// cv::Mat src1(loadedFrame1->_frame_info.u32Height, loadedFrame1->_frame_info.u32Width, CV_8UC1, loadedFrame1->_data);
|
|
|
|
|
// imshow("src30",src1);
|
|
|
|
|
// waitKey(1);
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//if (bflag2 && loadedFrame2->_frame_info.u32Height > 0)
|
|
|
|
|
//{
|
|
|
|
|
// cv::Mat src2(loadedFrame2->_frame_info.u32Height, loadedFrame2->_frame_info.u32Width, CV_8UC1, loadedFrame2->_data);
|
|
|
|
|
// imshow("src40",src2);
|
|
|
|
|
// waitKey(0);
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
@ -198,4 +226,13 @@ GD_VIDEO_FRAME_S VideoStitch::ExportPanAddr()
|
|
|
|
|
return pan_out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Mat VideoStitch::getHFromGeo2Pan(PanInfo _pan)
|
|
|
|
|
{
|
|
|
|
|
Mat H = (Mat_<double>(3, 3) << _pan.scale, 0, _pan.map_shiftX,
|
|
|
|
|
0, -_pan.scale, _panPara.m_pan_height + _pan.map_shiftY,
|
|
|
|
|
0, 0, 1
|
|
|
|
|
);
|
|
|
|
|
return H;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|