|
|
|
@ -27,7 +27,7 @@ VideoStitch::VideoStitch(SINT32 nWidth, SINT32 nHeight)
|
|
|
|
|
|
|
|
|
|
_FeaMatcher = new FeatureMatcher(DetectorType::SIFT, MatcherType::FLANN);
|
|
|
|
|
|
|
|
|
|
_cache = new FileCache<FrameCache>(20,"./cache");
|
|
|
|
|
_cache = new FileCache<FrameCache>(100,"./cache");
|
|
|
|
|
|
|
|
|
|
_BATask = new BA_Task(_cache);
|
|
|
|
|
|
|
|
|
@ -53,17 +53,17 @@ PanInfo VideoStitch::InitMap(FrameInfo info)
|
|
|
|
|
|
|
|
|
|
// 全景图初始化
|
|
|
|
|
PanInfo panPara = { 0 };
|
|
|
|
|
panPara.m_pan_width = 1000;//全景宽
|
|
|
|
|
panPara.m_pan_height = 1000;//全景高
|
|
|
|
|
panPara.scale = 0.5;//比例尺,1m = ?pix
|
|
|
|
|
panPara.m_pan_width = 1500;//全景宽
|
|
|
|
|
panPara.m_pan_height = 1500;//全景高
|
|
|
|
|
panPara.scale = 0.6;//比例尺,1m = ?pix
|
|
|
|
|
|
|
|
|
|
// 直接无平移解算
|
|
|
|
|
cv::Mat H_0 = getAffineFromGeo2Pan(panPara);
|
|
|
|
|
auto cur = warpPointWithH(H_0, ct_geo);
|
|
|
|
|
|
|
|
|
|
// 计算平移到全景图固定点的平移量,从此处开始拼接
|
|
|
|
|
int planX = 200;
|
|
|
|
|
int planY = 200;
|
|
|
|
|
int planX = 500;
|
|
|
|
|
int planY = 500;
|
|
|
|
|
|
|
|
|
|
panPara.map_shiftX = planX - (cur.x);//平移X
|
|
|
|
|
panPara.map_shiftY = planY - (cur.y);//平移Y
|
|
|
|
@ -82,7 +82,12 @@ PanInfo VideoStitch::Init(FrameInfo info)
|
|
|
|
|
{
|
|
|
|
|
_panPara = InitMap(info);
|
|
|
|
|
|
|
|
|
|
_panImage = cv::Mat::zeros(_panPara.m_pan_height, _panPara.m_pan_width, CV_8UC3);
|
|
|
|
|
_panImage = cv::Mat::zeros(_panPara.m_pan_height, _panPara.m_pan_width, CV_8UC4);
|
|
|
|
|
|
|
|
|
|
_panMask = cv::Mat::zeros(_panPara.m_pan_height, _panPara.m_pan_width, CV_8UC1);
|
|
|
|
|
|
|
|
|
|
//auto p1 = getBLHFromPan(cv::Point2f(7420, 2800), _H_pan);
|
|
|
|
|
//auto p2 = getPanXYFromBLH(p1, _H_pan);
|
|
|
|
|
|
|
|
|
|
return _panPara;
|
|
|
|
|
}
|
|
|
|
@ -143,7 +148,7 @@ PanInfo VideoStitch::Init(FrameInfo info)
|
|
|
|
|
|
|
|
|
|
BYTE8 VideoStitch::GeoStitch(GD_VIDEO_FRAME_S img, FrameInfo para)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat src = getRGBMatFromGDFrame(img,img.u64VirAddr[0]);
|
|
|
|
|
cv::Mat src = getRGBAMatFromGDFrame(img,img.u64VirAddr[0]);
|
|
|
|
|
|
|
|
|
|
// uv2Geo H
|
|
|
|
|
cv::Mat H1 = _GeoSolver->findHomography(para);
|
|
|
|
@ -153,11 +158,11 @@ BYTE8 VideoStitch::GeoStitch(GD_VIDEO_FRAME_S img, FrameInfo para)
|
|
|
|
|
// 利用H投影当前帧到全景
|
|
|
|
|
cv::Mat imagetmp(_panImage.size(), CV_8UC3, cv::Scalar(0, 0, 0));
|
|
|
|
|
|
|
|
|
|
cv::warpPerspective(src, imagetmp, H, imagetmp.size());
|
|
|
|
|
cv::warpPerspective(src, imagetmp, H, imagetmp.size(), cv::INTER_LINEAR, cv::BORDER_TRANSPARENT);
|
|
|
|
|
|
|
|
|
|
cv::Mat mask = cv::Mat::ones(src.size(), CV_8UC1) * 255;
|
|
|
|
|
cv::Mat warped_mask;
|
|
|
|
|
cv::warpPerspective(mask, warped_mask, H, imagetmp.size());
|
|
|
|
|
cv::warpPerspective(mask, warped_mask, H, imagetmp.size(), cv::INTER_LINEAR);
|
|
|
|
|
imagetmp.copyTo(_panImage, warped_mask);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
@ -200,7 +205,7 @@ SINT32 VideoStitch::ReceiveFrame(GD_VIDEO_FRAME_S img, FrameInfo para)
|
|
|
|
|
cv::Mat descriptors;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cv::Mat src = getRGBMatFromGDFrame(img, img.u64VirAddr[0]);
|
|
|
|
|
cv::Mat src = getRGBAMatFromGDFrame(img, img.u64VirAddr[0]);
|
|
|
|
|
_FeaMatcher->extractFeatures(src, keypoints, descriptors);
|
|
|
|
|
|
|
|
|
|
size_t keyNum = MIN(keypoints.size(), FEA_NUM_MAX);
|
|
|
|
@ -238,35 +243,31 @@ SINT32 VideoStitch::ProcessFrame()
|
|
|
|
|
vector<KeyType> vec_opt;
|
|
|
|
|
|
|
|
|
|
// 优化所有帧
|
|
|
|
|
_BATask->OptFrame(_recvFrameKey, _H_pan);
|
|
|
|
|
//_BATask->OptFrame(_recvFrameKey, _H_pan);
|
|
|
|
|
|
|
|
|
|
// 重投影所有帧到全景
|
|
|
|
|
mapFrame(_recvFrameKey);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 正反算验证
|
|
|
|
|
// auto _t_frame_cache = std::make_shared<FrameCache>();
|
|
|
|
|
//bool flag = _cache->get(10, _t_frame_cache);
|
|
|
|
|
|
|
|
|
|
auto _t_frame_cache = std::make_shared<FrameCache>();
|
|
|
|
|
bool flag = _cache->get(10, _t_frame_cache);
|
|
|
|
|
// 读取当前H
|
|
|
|
|
cv::Mat H1 = cv::Mat(3, 3, CV_64FC1, _t_frame_cache->H);
|
|
|
|
|
|
|
|
|
|
// 与全景图的H相乘
|
|
|
|
|
cv::Mat H = _H_pan * H1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cv::Point2f p_GEO = CalGeoInfo(warpPointWithH(H, cv::Point2f(0, 0)), _H_pan);
|
|
|
|
|
|
|
|
|
|
//// 读取当前H
|
|
|
|
|
//cv::Mat H1 = cv::Mat(3, 3, CV_64FC1, _t_frame_cache->H);
|
|
|
|
|
|
|
|
|
|
//// 与全景图的H相乘
|
|
|
|
|
//cv::Mat H = _H_pan * H1;
|
|
|
|
|
|
|
|
|
|
PointBLH BLHpT = _GeoSolver->getBLH(H1, cv::Point2f(640, 512));
|
|
|
|
|
|
|
|
|
|
//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(255);
|
|
|
|
|
_panImage.setTo(0);
|
|
|
|
|
|
|
|
|
|
// 从文件缓存获取帧
|
|
|
|
|
auto _t_frame_cache = std::make_shared<FrameCache>();
|
|
|
|
@ -290,20 +291,82 @@ void VideoStitch::mapFrame(vector<KeyType> frameInd)
|
|
|
|
|
cv::Mat imagetmp(_panImage.size(), CV_8UC3, cv::Scalar(0, 0, 0));
|
|
|
|
|
|
|
|
|
|
// 获取图像数据
|
|
|
|
|
cv::Mat src = getRGBMatFromGDFrame(_t_frame_cache->_frame_info, _t_frame_cache->_data);
|
|
|
|
|
cv::Mat src = getRGBAMatFromGDFrame(_t_frame_cache->_frame_info, _t_frame_cache->_data);
|
|
|
|
|
|
|
|
|
|
cv::warpPerspective(src, imagetmp, H, imagetmp.size());
|
|
|
|
|
cv::warpPerspective(src, imagetmp, H, imagetmp.size(), cv::INTER_LINEAR, cv::BORDER_TRANSPARENT);
|
|
|
|
|
|
|
|
|
|
cv::Mat mask = cv::Mat::ones(src.size(), CV_8UC1) * 255;
|
|
|
|
|
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::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)
|
|
|
|
|
{
|
|
|
|
|
// 计算全景图的坐标范围
|
|
|
|
|
auto P1 = getBLHFromPan(cv::Point2f(0, 0), _H_pan);
|
|
|
|
|
auto P2 = getBLHFromPan(cv::Point2f(_panImage.cols, 0), _H_pan);
|
|
|
|
|
|
|
|
|
|
auto P3 = getBLHFromPan(cv::Point2f(_panImage.cols, _panImage.rows), _H_pan);
|
|
|
|
|
auto P4 = getBLHFromPan(cv::Point2f(0, _panImage.rows), _H_pan);
|
|
|
|
|
|
|
|
|
|
auto minL = min(min(min(P1.L, P2.L), P3.L), P4.L);
|
|
|
|
|
auto maxL = max(max(max(P1.L, P2.L), P3.L), P4.L);
|
|
|
|
|
|
|
|
|
|
auto minB = min(min(min(P1.B, P2.B), P3.B), P4.B);
|
|
|
|
|
auto maxB = max(max(max(P1.B, P2.B), P3.B), P4.B);
|
|
|
|
|
|
|
|
|
|
TileInfo info = { 0 };
|
|
|
|
|
|
|
|
|
|
info.north = maxB;
|
|
|
|
|
info.south = minB;
|
|
|
|
|
info.east = minL;
|
|
|
|
|
info.west = maxL;
|
|
|
|
|
|
|
|
|
|
// 输出谷歌地图产品
|
|
|
|
|
_googleProduct.ExportGeoPng(_panImage, info, dir, name);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool VideoStitch::ExportGoogleTile(std::string dir, std::string name)
|
|
|
|
|
{
|
|
|
|
|
// 计算全景图的坐标范围
|
|
|
|
|
auto P1 = getBLHFromPan(cv::Point2f(0, 0), _H_pan);
|
|
|
|
|
auto P2 = getBLHFromPan(cv::Point2f(_panImage.cols, 0), _H_pan);
|
|
|
|
|
|
|
|
|
|
auto P3 = getBLHFromPan(cv::Point2f(_panImage.cols, _panImage.rows), _H_pan);
|
|
|
|
|
auto P4 = getBLHFromPan(cv::Point2f(0, _panImage.rows), _H_pan);
|
|
|
|
|
|
|
|
|
|
auto minL = min(min(min(P1.L, P2.L), P3.L), P4.L);
|
|
|
|
|
auto maxL = max(max(max(P1.L, P2.L), P3.L), P4.L);
|
|
|
|
|
|
|
|
|
|
auto minB = min(min(min(P1.B, P2.B), P3.B), P4.B);
|
|
|
|
|
auto maxB = max(max(max(P1.B, P2.B), P3.B), P4.B);
|
|
|
|
|
|
|
|
|
|
TileInfo info = { 0 };
|
|
|
|
|
|
|
|
|
|
info.north = maxB;
|
|
|
|
|
info.south = minB;
|
|
|
|
|
info.east = minL;
|
|
|
|
|
info.west = maxL;
|
|
|
|
|
|
|
|
|
|
_googleProduct.ExportTile(_panImage, info, dir, name);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GD_VIDEO_FRAME_S VideoStitch::ExportPanAddr()
|
|
|
|
@ -318,14 +381,23 @@ GD_VIDEO_FRAME_S VideoStitch::ExportPanAddr()
|
|
|
|
|
return pan_out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Point2f VideoStitch::CalGeoInfo(cv::Point2f ptInPan, cv::Mat _H_panPara)
|
|
|
|
|
PointBLH VideoStitch::getBLHFromPan(cv::Point2f ptInPan, cv::Mat _H_panPara)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat H_inv = _H_panPara.inv();
|
|
|
|
|
|
|
|
|
|
// 解算到局部地理系
|
|
|
|
|
cv::Point2f ptInGeo = warpPointWithH(H_inv,ptInPan);
|
|
|
|
|
|
|
|
|
|
return _GeoSolver->getBLHFromGeo(ptInGeo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Point2f VideoStitch::getPanXYFromBLH(PointBLH ptInBLH, cv::Mat _H_panPara)
|
|
|
|
|
{
|
|
|
|
|
// 经纬度转局部地理系
|
|
|
|
|
cv::Point2f ptGeo = _GeoSolver->getGeoFromBLH(ptInBLH);
|
|
|
|
|
|
|
|
|
|
return ptInGeo;
|
|
|
|
|
// 投影到全景图
|
|
|
|
|
return warpPointWithH(_H_panPara, ptGeo);;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Mat VideoStitch::getAffineFromGeo2Pan(PanInfo _pan)
|
|
|
|
|