地理H的计算改为R和t的解析

main
wangchongwu 5 months ago
parent cda013b9d0
commit 65f705aabe

@ -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_<double>(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<double>(2, 2);
return H;
}
// 计算多边形的面积
double polygonArea(const vector<cv::Point2f>& points)
{

@ -42,6 +42,9 @@ public:
// 建立全景图与归一化地理系的H矩阵
cv::Mat findHomography(FrameInfo info);
// 解析出H
cv::Mat findHomography2(FrameInfo info);
// 设置起始拼接点外参
void SetOriginPoint(FrameInfo info);

@ -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投影当前帧到全景

@ -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<float>(x), static_cast<float>(y));
}
// 将纬度转换为墨卡托投影
double latRad = latitude * M_PI / 180.0;
double sinLat = sin(latRad);
std::pair<double, double> 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<int>((longitude + 180.0) / 360.0 * pow(2.0, zoomLevel));
cv::Mat googleTile::computeHomography()
{
std::vector<cv::Point2f> srcPts;
std::vector<cv::Point2f> dstPts;
// 计算纬度的瓦片编号0-2^zoomLevel
int yTile = static_cast<int>((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<float>(image_.cols), 0.0f));
dstPts.push_back(cv::Point2f(static_cast<float>(image_.cols), static_cast<float>(image_.rows)));
dstPts.push_back(cv::Point2f(0.0f, static_cast<float>(image_.rows)));
return cv::getPerspectiveTransform(srcPts, dstPts);
}
void googleTile::generateTiles()
{
//std::filesystem::create_directories(outputDir_);
//cv::Mat H = computeHomography();
//std::vector<cv::Point2f> 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<int>(std::floor(minX / tileSize));
//int xTileMax = static_cast<int>(std::floor(maxX / tileSize));
//int yTileMin = static_cast<int>(std::floor(minY / tileSize));
//int yTileMax = static_cast<int>(std::floor(maxY / tileSize));
//std::vector<TileInfo> tileInfos;
//for (int tx = xTileMin; tx <= xTileMax; tx++)
//{
// for (int ty = yTileMin; ty <= yTileMax; ty++)
// {
// std::vector<cv::Point2f> 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<cv::Point2f> 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);
}

@ -5,10 +5,16 @@
#include <string>
#include <vector>
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<std::pair<double, double>> geoCorners_; // 左上、右上、右下、左下
int zoom_;
int zoom_;
cv::Point2f latLonToGlobal(double lat, double lon);
std::pair<double, double> globalToLatLon(const cv::Point2f& pt);
cv::Mat computeHomography();
};

Loading…
Cancel
Save