diff --git a/stitch/src/Arith_GeoSolver.cpp b/stitch/src/Arith_GeoSolver.cpp index 41f92be..00131ac 100644 --- a/stitch/src/Arith_GeoSolver.cpp +++ b/stitch/src/Arith_GeoSolver.cpp @@ -201,8 +201,8 @@ Proj GeoSolver::AnlayseTform(FrameInfo info) } - -cv::Mat GeoSolver::findHomography(FrameInfo info) +// 检验H的计算 +cv::Mat GeoSolver::findHomography2(FrameInfo info) { Proj _proj = AnlayseTform(info); @@ -231,6 +231,32 @@ cv::Mat GeoSolver::findHomography(FrameInfo info) } +// 根据R和t,解析H +cv::Mat GeoSolver::findHomography(FrameInfo info) +{ + Proj _proj = AnlayseTform(info); + TForm tform = _proj.tf_p2g; + + double R[9] = { 0 }; + double T[3] = { 0 }; + + memcpy(R, tform.R.data, sizeof(double) * 9); + memcpy(T, tform.T.data, sizeof(double) * 3); + + + + Mat H = (Mat_(3, 3) << (R[0] + T[0] * R[6]), (R[1] + T[0] * R[7]), (R[2] + T[0] * R[8]), + (R[3] + T[1] * R[6]), (R[4] + T[1] * R[7]), (R[5] + T[1] * R[8]), + R[6], R[7], R[8]); + + // 归一化 + H = H / H.at(2, 2); + + + return H; +} + + // 计算多边形的面积 double polygonArea(const vector& points) { diff --git a/stitch/src/Arith_GeoSolver.h b/stitch/src/Arith_GeoSolver.h index ac134ee..8046b06 100644 --- a/stitch/src/Arith_GeoSolver.h +++ b/stitch/src/Arith_GeoSolver.h @@ -42,6 +42,9 @@ public: // 建立全景图与归一化地理系的H矩阵 cv::Mat findHomography(FrameInfo info); + // 解析出H + cv::Mat findHomography2(FrameInfo info); + // 设置起始拼接点外参 void SetOriginPoint(FrameInfo info); diff --git a/stitch/src/Arith_VideoStitch.cpp b/stitch/src/Arith_VideoStitch.cpp index 3de7597..d855e98 100644 --- a/stitch/src/Arith_VideoStitch.cpp +++ b/stitch/src/Arith_VideoStitch.cpp @@ -153,6 +153,8 @@ BYTE8 VideoStitch::GeoStitch(GD_VIDEO_FRAME_S img, FrameInfo para) // uv2Geo H cv::Mat H1 = _GeoSolver->findHomography(para); + cv::Mat H2 = _GeoSolver->findHomography2(para); + cv::Mat H = _H_pan * H1; // 利用H投影当前帧到全景 diff --git a/stitch/src/GoogleTile.cpp b/stitch/src/GoogleTile.cpp index 1526747..2478653 100644 --- a/stitch/src/GoogleTile.cpp +++ b/stitch/src/GoogleTile.cpp @@ -8,6 +8,8 @@ using std::string; +#define M_PI 3.1415926 + googleTile::googleTile() { @@ -58,111 +60,27 @@ void googleTile::ExportGeoPng(cv::Mat _pan, TileInfo info, std::string dir, std: void googleTile::ExportTile(cv::Mat _pan, TileInfo info, std::string dir, std::string name) { - + // 计算四至的瓦片编号 + TileIndex westNorth = LatLonToTile(info.west, info.north, 10); + int a = 0; } - - -cv::Point2f googleTile::latLonToGlobal(double lat, double lon) +TileIndex googleTile::LatLonToTile(double latitude, double longitude, int zoomLevel) { - double tileSize = 256.0; - double n = std::pow(2.0, zoom_); - double x = (lon + 180.0) / 360.0 * tileSize * n; - double latRad = lat * CV_PI / 180.0; - double y = (1 - std::log(std::tan(latRad) + 1 / std::cos(latRad)) / CV_PI) / 2 * tileSize * n; - return cv::Point2f(static_cast(x), static_cast(y)); -} + // 将纬度转换为墨卡托投影 + double latRad = latitude * M_PI / 180.0; + double sinLat = sin(latRad); -std::pair googleTile::globalToLatLon(const cv::Point2f& pt) -{ - double tileSize = 256.0; - double n = std::pow(2.0, zoom_); - double lon = pt.x / (tileSize * n) * 360.0 - 180.0; - double latRad = std::atan(std::sinh(CV_PI * (1 - 2 * pt.y / (tileSize * n)))); - double lat = latRad * 180.0 / CV_PI; - return std::make_pair(lat, lon); -} + // 计算经度的瓦片编号(0-2^zoomLevel) + int xTile = static_cast((longitude + 180.0) / 360.0 * pow(2.0, zoomLevel)); -cv::Mat googleTile::computeHomography() -{ - std::vector srcPts; - std::vector dstPts; + // 计算纬度的瓦片编号(0-2^zoomLevel) + int yTile = static_cast((1.0 - log((1.0 + sinLat) / (1.0 - sinLat)) / (2.0 * M_PI)) / 2.0 * pow(2.0, zoomLevel)); - for (const auto& corner : geoCorners_) - { - srcPts.push_back(latLonToGlobal(corner.first, corner.second)); - } + return TileIndex{ xTile, yTile, zoomLevel }; +} - dstPts.push_back(cv::Point2f(0.0f, 0.0f)); - dstPts.push_back(cv::Point2f(static_cast(image_.cols), 0.0f)); - dstPts.push_back(cv::Point2f(static_cast(image_.cols), static_cast(image_.rows))); - dstPts.push_back(cv::Point2f(0.0f, static_cast(image_.rows))); - return cv::getPerspectiveTransform(srcPts, dstPts); -} -void googleTile::generateTiles() -{ - //std::filesystem::create_directories(outputDir_); - //cv::Mat H = computeHomography(); - - //std::vector globalCorners; - //for (const auto& corner : geoCorners_) - //{ - // globalCorners.push_back(latLonToGlobal(corner.first, corner.second)); - //} - - //float minX = globalCorners[0].x, maxX = globalCorners[0].x; - //float minY = globalCorners[0].y, maxY = globalCorners[0].y; - - //for (const auto& p : globalCorners) - //{ - // minX = std::min(minX, p.x); - // maxX = std::max(maxX, p.x); - // minY = std::min(minY, p.y); - // maxY = std::max(maxY, p.y); - //} - - //int tileSize = 256; - //int xTileMin = static_cast(std::floor(minX / tileSize)); - //int xTileMax = static_cast(std::floor(maxX / tileSize)); - //int yTileMin = static_cast(std::floor(minY / tileSize)); - //int yTileMax = static_cast(std::floor(maxY / tileSize)); - - //std::vector tileInfos; - - //for (int tx = xTileMin; tx <= xTileMax; tx++) - //{ - // for (int ty = yTileMin; ty <= yTileMax; ty++) - // { - // std::vector tileGlobalPts = { - // {cv::Point2f(tx * tileSize, ty * tileSize)}, - // {cv::Point2f((tx + 1) * tileSize, ty * tileSize)}, - // {cv::Point2f((tx + 1) * tileSize, (ty + 1) * tileSize)}, - // {cv::Point2f(tx * tileSize, (ty + 1) * tileSize)} }; - - // std::vector tileImgPts; - // cv::perspectiveTransform(tileGlobalPts, tileImgPts, H); - - // //cv::Mat tileTransform = cv::getPerspectiveTransform(tileImgPts, { - // // {0, 0}, {tileSize, 0}, {tileSize, tileSize}, {0, tileSize} }); - - // cv::Mat tileImg; - // //cv::warpPerspective(image_, tileImg, tileTransform, cv::Size(tileSize, tileSize)); - - // std::string tileDir = outputDir_ + "/" + std::to_string(zoom_) + "/" + std::to_string(tx); - // std::filesystem::create_directories(tileDir); - // std::string tilePath = tileDir + "/" + std::to_string(ty) + ".png"; - - // cv::imwrite(tilePath, tileImg); - // tileInfos.push_back({ tx, ty, globalToLatLon({cv::Point2f(tx * tileSize, ty * tileSize)}).first, - // globalToLatLon({cv::Point2f((tx + 1) * tileSize, (ty + 1) * tileSize)}).first, - // globalToLatLon({cv::Point2f((tx + 1) * tileSize, (ty + 1) * tileSize)}).second, - // globalToLatLon({cv::Point2f(tx * tileSize, ty * tileSize)}).second }); - // } - //} - - //generateKML(tileInfos); -} diff --git a/stitch/src/GoogleTile.h b/stitch/src/GoogleTile.h index 6b08436..a325c6f 100644 --- a/stitch/src/GoogleTile.h +++ b/stitch/src/GoogleTile.h @@ -5,10 +5,16 @@ #include #include -struct TileInfo +struct TileIndex { int x; int y; + int z; +}; + +struct TileInfo +{ + TileIndex ind; double north; double south; double east; @@ -30,18 +36,12 @@ public: void ExportTile(cv::Mat _pan, TileInfo info, std::string dir, std::string name); public: - - void generateTiles(); + TileIndex LatLonToTile(double latitude, double longitude, int zoomLevel); private: - cv::Mat image_; - std::vector> geoCorners_; // 左上、右上、右下、左下 - int zoom_; + int zoom_; - cv::Point2f latLonToGlobal(double lat, double lon); - std::pair globalToLatLon(const cv::Point2f& pt); - cv::Mat computeHomography(); };