|
|
|
|
#include "StdAfx.h"
|
|
|
|
|
#include "GCPGeoCorrect.h"
|
|
|
|
|
|
|
|
|
|
#include "MapPrj.h"
|
|
|
|
|
|
|
|
|
|
#include <omp.h>
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ܣ<EFBFBD><DCA3>ռ<EFBFBD><D5BC>ֱ<EFBFBD><D6B1>ʹ<EFBFBD><CAB9>ƣ<EFBFBD><C6A3><EFBFBD>γ<EFBFBD>ȷֱ<C8B7><D6B1>ʣ<EFBFBD>
|
|
|
|
|
bool CalLonLatResolution(double &LonResolution, double &LatResolution,
|
|
|
|
|
const std::vector<cv::Point2d>& GCP_XY,
|
|
|
|
|
const std::vector<cv::Point2d>& GCP_LonLat)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (GCP_XY.size() < 4 || GCP_LonLat.size() < 4 || GCP_XY.size() != GCP_LonLat.size())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
double Center_Lon = 0.0;
|
|
|
|
|
double Center_Lat = 0.0;
|
|
|
|
|
double Center_x = 0.0;
|
|
|
|
|
double Center_y = 0.0;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>Ŀ
|
|
|
|
|
int count = GCP_XY.size();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < count; i++ )
|
|
|
|
|
{
|
|
|
|
|
// <20><>γ<EFBFBD><CEB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
Center_Lon += GCP_LonLat[i].x / count;
|
|
|
|
|
Center_Lat += GCP_LonLat[i].y / count;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
Center_x += GCP_XY[i].x / count;
|
|
|
|
|
Center_y += GCP_XY[i].y / count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㵽<EFBFBD><E3B5BD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><C4BE><EFBFBD>
|
|
|
|
|
double Resolution = 0;
|
|
|
|
|
for (int i = 1; i < count; i++ )
|
|
|
|
|
{
|
|
|
|
|
double dis = 0;
|
|
|
|
|
CalculateTwoPtsDistance(dis,
|
|
|
|
|
GCP_LonLat[0].x, GCP_LonLat[0].y,
|
|
|
|
|
GCP_LonLat[i].x, GCP_LonLat[i].y,
|
|
|
|
|
3);
|
|
|
|
|
|
|
|
|
|
double L = cv::norm(GCP_XY[i] - GCP_XY[0]);
|
|
|
|
|
|
|
|
|
|
Resolution += (dis / L);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Resolution /= (count - 1);
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD>γ<EFBFBD><CEB3>
|
|
|
|
|
double targetPtLon = Center_Lon;
|
|
|
|
|
double targetPtLat = Center_Lat;
|
|
|
|
|
|
|
|
|
|
// <20>ֱ<EFBFBD><D6B1><EFBFBD>
|
|
|
|
|
CalculatePtCoordinate(targetPtLon, targetPtLat, Center_Lon, Center_Lat, 90, Resolution, 3);
|
|
|
|
|
LonResolution = targetPtLon - Center_Lon;
|
|
|
|
|
CalculatePtCoordinate(targetPtLon, targetPtLat, Center_Lon, Center_Lat, 0, Resolution, 3);
|
|
|
|
|
LatResolution = targetPtLat - Center_Lat;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա任ϵ<E4BBBB><CFB5> : A B prePoints ---> nextPoints
|
|
|
|
|
bool CalLineTransformCoefficient(cv::Mat &A, cv::Mat &B,
|
|
|
|
|
const std::vector<cv::Point2d>& prePoints,
|
|
|
|
|
const std::vector<cv::Point2d>& nextPoints)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ4<D2AA>Ե<EFBFBD>
|
|
|
|
|
int size = 0;
|
|
|
|
|
if (prePoints.size() < 4 || nextPoints.size() < 4 || prePoints.size() != nextPoints.size())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
size = prePoints.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
A.create(3, 1, CV_64FC1);
|
|
|
|
|
A = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
B.create(3, 1, CV_64FC1);
|
|
|
|
|
B = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
cv::Mat W, X, Y;
|
|
|
|
|
W.create(size, 3, CV_64FC1);
|
|
|
|
|
W = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
X.create(size, 1, CV_64FC1);
|
|
|
|
|
X = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
Y.create(size, 1, CV_64FC1);
|
|
|
|
|
Y = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>W X Y<><59>ֵ
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
W.at<double>(i, 0) = 1;
|
|
|
|
|
W.at<double>(i, 1) = prePoints[i].x;
|
|
|
|
|
W.at<double>(i, 2) = prePoints[i].y;
|
|
|
|
|
|
|
|
|
|
X.at<double>(i, 0) = nextPoints[i].x;
|
|
|
|
|
Y.at<double>(i, 0) = nextPoints[i].y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>A B
|
|
|
|
|
// W * A = X
|
|
|
|
|
// W * B = Y
|
|
|
|
|
bool ret1 = cv::solve(W, X, A, CV_SVD); // <20><>A
|
|
|
|
|
bool ret2 = cv::solve(W, Y, B, CV_SVD); // <20><>B
|
|
|
|
|
|
|
|
|
|
if (ret1 == false || ret2 == false)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD><CEB6><EFBFBD>ʽ<EFBFBD>任ϵ<E4BBBB><CFB5> : A B prePoints ---> nextPoints
|
|
|
|
|
bool CalPolynomialCoefficient(cv::Mat &A, cv::Mat &B,
|
|
|
|
|
const std::vector<cv::Point2d>& prePoints,
|
|
|
|
|
const std::vector<cv::Point2d>& nextPoints)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ6<D2AA>Ե<EFBFBD>
|
|
|
|
|
int size = 0;
|
|
|
|
|
if (prePoints.size() < 6 || nextPoints.size() < 6 || prePoints.size() != nextPoints.size())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
size = prePoints.size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
A.create(6, 1, CV_64FC1);
|
|
|
|
|
A = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
B.create(6, 1, CV_64FC1);
|
|
|
|
|
B = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
cv::Mat W, X, Y;
|
|
|
|
|
W.create(size, 6, CV_64FC1);
|
|
|
|
|
W = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
X.create(size, 1, CV_64FC1);
|
|
|
|
|
X = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
Y.create(size, 1, CV_64FC1);
|
|
|
|
|
Y = cv::Scalar(0);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>W X Y<><59>ֵ
|
|
|
|
|
for (int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
W.at<double>(i, 0) = 1;
|
|
|
|
|
W.at<double>(i, 1) = prePoints[i].x;
|
|
|
|
|
W.at<double>(i, 2) = prePoints[i].y;
|
|
|
|
|
W.at<double>(i, 3) = prePoints[i].x * prePoints[i].y;
|
|
|
|
|
W.at<double>(i, 4) = prePoints[i].x * prePoints[i].x;
|
|
|
|
|
W.at<double>(i, 5) = prePoints[i].y * prePoints[i].y;
|
|
|
|
|
|
|
|
|
|
X.at<double>(i, 0) = nextPoints[i].x;
|
|
|
|
|
Y.at<double>(i, 0) = nextPoints[i].y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>A B
|
|
|
|
|
// W * A = X
|
|
|
|
|
// W * B = Y
|
|
|
|
|
bool ret1 = cv::solve(W, X, A, CV_SVD); // <20><>A
|
|
|
|
|
bool ret2 = cv::solve(W, Y, B, CV_SVD); // <20><>B
|
|
|
|
|
|
|
|
|
|
if (ret1 == false || ret2 == false)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>Ӿ<EFBFBD><D3BE><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD>)
|
|
|
|
|
RECT GetMinEncloseRect(const cv::Mat& image)
|
|
|
|
|
{
|
|
|
|
|
RECT minRect;
|
|
|
|
|
minRect.left = -1L;
|
|
|
|
|
minRect.right = -1L;
|
|
|
|
|
minRect.top = -1L;
|
|
|
|
|
minRect.bottom = -1L;
|
|
|
|
|
|
|
|
|
|
if (image.empty() == true)
|
|
|
|
|
{
|
|
|
|
|
return minRect;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
minRect.left = 0L;
|
|
|
|
|
minRect.right = static_cast<LONG>(image.cols - 1);
|
|
|
|
|
minRect.top = 0L;
|
|
|
|
|
minRect.bottom = static_cast<LONG>(image.rows - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int type = image.type();
|
|
|
|
|
|
|
|
|
|
int i = 0, j = 0;
|
|
|
|
|
int temp = 0;
|
|
|
|
|
|
|
|
|
|
if (type == 0) // CV_8UC1
|
|
|
|
|
{
|
|
|
|
|
// left
|
|
|
|
|
for (i = 0; i < image.cols; ++i)
|
|
|
|
|
{
|
|
|
|
|
double count = 0;
|
|
|
|
|
for (j = 0; j < image.rows; ++j)
|
|
|
|
|
{
|
|
|
|
|
temp = image.at<unsigned char>(j, i);
|
|
|
|
|
if (temp > 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == temp)
|
|
|
|
|
{
|
|
|
|
|
minRect.left++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ȫ<><C8AB>
|
|
|
|
|
if (minRect.left == image.cols)
|
|
|
|
|
{
|
|
|
|
|
minRect.left = -1L;
|
|
|
|
|
minRect.right = -1L;
|
|
|
|
|
minRect.top = -1L;
|
|
|
|
|
minRect.bottom = -1L;
|
|
|
|
|
|
|
|
|
|
return minRect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// right
|
|
|
|
|
temp = 0;
|
|
|
|
|
for (i = image.cols - 1; i > -1; --i)
|
|
|
|
|
{
|
|
|
|
|
for (j = 0;j < image.rows; ++j)
|
|
|
|
|
{
|
|
|
|
|
temp = image.at<unsigned char>(j, i);
|
|
|
|
|
|
|
|
|
|
if ( temp > 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == temp)
|
|
|
|
|
{
|
|
|
|
|
minRect.right--;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// top
|
|
|
|
|
temp = 0;
|
|
|
|
|
for (j = 0; j < image.rows; ++j)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < image.cols; ++i)
|
|
|
|
|
{
|
|
|
|
|
temp = image.at<unsigned char>(j, i);
|
|
|
|
|
|
|
|
|
|
if ( temp > 0 )
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == temp)
|
|
|
|
|
{
|
|
|
|
|
minRect.top++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bottom
|
|
|
|
|
temp = 0;
|
|
|
|
|
for ( j = image.rows - 1; j > -1; --j)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < image.cols; ++i)
|
|
|
|
|
{
|
|
|
|
|
temp = image.at<unsigned char>(j, i);
|
|
|
|
|
|
|
|
|
|
if (temp > 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == temp)
|
|
|
|
|
{
|
|
|
|
|
minRect.bottom--;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if(type == 16) // CV_8UC3
|
|
|
|
|
{
|
|
|
|
|
// left
|
|
|
|
|
for (i = 0; i < image.cols; ++i)
|
|
|
|
|
{
|
|
|
|
|
for (j = 0; j < image.rows; ++j)
|
|
|
|
|
{
|
|
|
|
|
temp = image.at<cv::Vec3b>(j, i)[0] + image.at<cv::Vec3b>(j, i)[1] + image.at<cv::Vec3b>(j, i)[2];
|
|
|
|
|
if (temp > 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == temp)
|
|
|
|
|
{
|
|
|
|
|
minRect.left++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ȫ<><C8AB>
|
|
|
|
|
if (minRect.left == image.cols)
|
|
|
|
|
{
|
|
|
|
|
minRect.left = -1L;
|
|
|
|
|
minRect.right = -1L;
|
|
|
|
|
minRect.top = -1L;
|
|
|
|
|
minRect.bottom = -1L;
|
|
|
|
|
|
|
|
|
|
return minRect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// right
|
|
|
|
|
temp = 0;
|
|
|
|
|
for (i = image.cols - 1; i > -1; --i)
|
|
|
|
|
{
|
|
|
|
|
for (j = 0;j < image.rows; ++j)
|
|
|
|
|
{
|
|
|
|
|
temp = image.at<cv::Vec3b>(j, i)[0] + image.at<cv::Vec3b>(j, i)[1] + image.at<cv::Vec3b>(j, i)[2];
|
|
|
|
|
if ( temp > 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == temp)
|
|
|
|
|
{
|
|
|
|
|
minRect.right--;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// top
|
|
|
|
|
temp = 0;
|
|
|
|
|
for (j = 0; j < image.rows; ++j)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < image.cols; ++i)
|
|
|
|
|
{
|
|
|
|
|
temp = image.at<cv::Vec3b>(j, i)[0] + image.at<cv::Vec3b>(j, i)[1] + image.at<cv::Vec3b>(j, i)[2];
|
|
|
|
|
if ( temp > 0 )
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == temp)
|
|
|
|
|
{
|
|
|
|
|
minRect.top++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// bottom
|
|
|
|
|
temp = 0;
|
|
|
|
|
for ( j = image.rows - 1; j > -1; --j)
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < image.cols; ++i)
|
|
|
|
|
{
|
|
|
|
|
temp = image.at<cv::Vec3b>(j, i)[0] + image.at<cv::Vec3b>(j, i)[1] + image.at<cv::Vec3b>(j, i)[2];
|
|
|
|
|
if (temp > 0)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == temp)
|
|
|
|
|
{
|
|
|
|
|
minRect.bottom--;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return minRect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>Ա任
|
|
|
|
|
bool GCPGeoCorrectImgLineTransform( cv::Mat& dstImg, GeoBoundingBox& LBbox, const cv::Mat& srcImg, const std::vector<cv::Point2d>& GCP_XY, const std::vector<cv::Point2d>& GCP_LonLat)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// ָ<><D6B8><EFBFBD><EFBFBD>ֵ<EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (srcImg.empty() == true ||
|
|
|
|
|
GCP_XY.size() < 4 || GCP_LonLat.size() < 4 || GCP_XY.size() != GCP_LonLat.size())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (srcImg.type() != CV_8UC1 && srcImg.type() != CV_8UC3)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>Ŀ
|
|
|
|
|
int count = GCP_XY.size();
|
|
|
|
|
|
|
|
|
|
// <20><>ÿ<EFBFBD><C3BF>GCP<43><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
|
|
|
for(int i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (GCP_XY[i].x < 0 || GCP_XY[i].x > srcImg.cols - 1)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GCP_XY[i].y < 0 || GCP_XY[i].y > srcImg.rows - 1)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GCP_LonLat[i].x < -180.0F || GCP_LonLat[i].x > 180.0F)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GCP_LonLat[i].y < -90.0F || GCP_LonLat[i].y > 90.0F)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ռ<EFBFBD><D5BC>ֱ<EFBFBD><D6B1>ʹ<EFBFBD><CAB9>ƣ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>صľ<D8B5>γ<EFBFBD>ȷֱ<C8B7><D6B1><EFBFBD>
|
|
|
|
|
double deltaLon = 0.0;
|
|
|
|
|
double deltaLat = 0.0;
|
|
|
|
|
if ( false == CalLonLatResolution(deltaLon, deltaLat, GCP_XY, GCP_LonLat) )
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41>B
|
|
|
|
|
cv::Mat A, B;
|
|
|
|
|
if (false == CalLineTransformCoefficient(A, B, GCP_XY, GCP_LonLat))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD>γ<EFBFBD><CEB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
cv::Point2f LeftUp, RightUp, LeftDown, RightDown;
|
|
|
|
|
LeftUp.x = static_cast<float>(A.at<double>(0, 0));
|
|
|
|
|
LeftUp.y = static_cast<float>(B.at<double>(0, 0));
|
|
|
|
|
|
|
|
|
|
RightUp.x = static_cast<float>(A.at<double>(0, 0) + srcImg.cols * A.at<double>(1, 0));
|
|
|
|
|
RightUp.y = static_cast<float>(B.at<double>(0, 0) + srcImg.cols * B.at<double>(1, 0));
|
|
|
|
|
|
|
|
|
|
LeftDown.x = static_cast<float>(A.at<double>(0, 0) + srcImg.rows * A.at<double>(2, 0));
|
|
|
|
|
LeftDown.y = static_cast<float>(B.at<double>(0, 0) + srcImg.rows * B.at<double>(2, 0));
|
|
|
|
|
|
|
|
|
|
RightDown.x = static_cast<float>(A.at<double>(0, 0) + srcImg.cols * A.at<double>(1, 0) + srcImg.rows * A.at<double>(2, 0));
|
|
|
|
|
RightDown.y = static_cast<float>(B.at<double>(0, 0) + srcImg.cols * B.at<double>(1, 0) + srcImg.rows * B.at<double>(2, 0));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ŀ<><C4BF>ͼ<EFBFBD><CDBC><EFBFBD>ı߽<C4B1>
|
|
|
|
|
double Lon_min = 0.0;
|
|
|
|
|
double Lon_max = 0.0;
|
|
|
|
|
double Lat_min = 0.0;
|
|
|
|
|
double Lat_max = 0.0;
|
|
|
|
|
|
|
|
|
|
Lon_min = min(min(min(LeftUp.x, RightUp.x), RightDown.x), LeftDown.x);
|
|
|
|
|
Lon_max = max(max(max(LeftUp.x, RightUp.x), RightDown.x), LeftDown.x);
|
|
|
|
|
Lat_min = min(min(min(LeftUp.y, RightUp.y), RightDown.y), LeftDown.y);
|
|
|
|
|
Lat_max = max(max(max(LeftUp.y, RightUp.y), RightDown.y), LeftDown.y);
|
|
|
|
|
|
|
|
|
|
// Ŀ<><C4BF>ͼ<EFBFBD><CDBC><EFBFBD>ijߴ<C4B3>
|
|
|
|
|
int dstWidth = 0;
|
|
|
|
|
int dstHeight = 0;
|
|
|
|
|
dstWidth = static_cast<int>((Lon_max - Lon_min) / deltaLon);
|
|
|
|
|
dstHeight = static_cast<int>((Lat_max - Lat_min) / deltaLat);
|
|
|
|
|
|
|
|
|
|
if (dstWidth <= 0 || dstHeight <= 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>任
|
|
|
|
|
if (false == CalLineTransformCoefficient(A, B, GCP_LonLat, GCP_XY))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
dstImg = cv::Mat(dstHeight, dstWidth, srcImg.type());
|
|
|
|
|
|
|
|
|
|
if (dstImg.empty() == true)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dstImg = cv::Scalar(0,0,0);
|
|
|
|
|
|
|
|
|
|
// <20><>ͨ<EFBFBD><CDA8>
|
|
|
|
|
if (dstImg.type() == 0)
|
|
|
|
|
{
|
|
|
|
|
#pragma omp parallel for
|
|
|
|
|
for (int x = 0; x < dstImg.cols; x++)
|
|
|
|
|
{
|
|
|
|
|
for (int y = 0; y < dstImg.rows; y++)
|
|
|
|
|
{
|
|
|
|
|
double dst_Lon = 0;
|
|
|
|
|
double dst_Lat = 0;
|
|
|
|
|
|
|
|
|
|
double src_x = 0.0;
|
|
|
|
|
double src_y = 0.0;
|
|
|
|
|
|
|
|
|
|
dst_Lon = Lon_min + x * deltaLon;
|
|
|
|
|
dst_Lat = Lat_max - y * deltaLat;
|
|
|
|
|
|
|
|
|
|
src_x = A.at<double>(0, 0) + (dst_Lon) * A.at<double>(1, 0) + (dst_Lat) * A.at<double>(2, 0);
|
|
|
|
|
src_y = B.at<double>(0, 0) + (dst_Lon) * B.at<double>(1, 0) + (dst_Lat) * B.at<double>(2, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|
|
|
|
int nearest_x = int(src_x + 0.5);
|
|
|
|
|
int nearest_y = int(src_y + 0.5);
|
|
|
|
|
|
|
|
|
|
if ((nearest_x >= 0) && (nearest_y >= 0) && (nearest_x <= (srcImg.cols - 1)) && (nearest_y <= (srcImg.rows - 1)))
|
|
|
|
|
{
|
|
|
|
|
dstImg.at<uchar>(y, x) = srcImg.at<uchar>(nearest_y, nearest_x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // <20><>ͨ<EFBFBD><CDA8>
|
|
|
|
|
{
|
|
|
|
|
#pragma omp parallel for
|
|
|
|
|
for (int x = 0; x < dstImg.cols; x++)
|
|
|
|
|
{
|
|
|
|
|
for (int y = 0; y < dstImg.rows; y++)
|
|
|
|
|
{
|
|
|
|
|
double dst_Lon = 0;
|
|
|
|
|
double dst_Lat = 0;
|
|
|
|
|
|
|
|
|
|
double src_x = 0.0;
|
|
|
|
|
double src_y = 0.0;
|
|
|
|
|
|
|
|
|
|
dst_Lon = Lon_min + x * deltaLon;
|
|
|
|
|
dst_Lat = Lat_max - y * deltaLat;
|
|
|
|
|
|
|
|
|
|
src_x = A.at<double>(0, 0) + (dst_Lon) * A.at<double>(1, 0) + (dst_Lat) * A.at<double>(2, 0);
|
|
|
|
|
src_y = B.at<double>(0, 0) + (dst_Lon) * B.at<double>(1, 0) + (dst_Lat) * B.at<double>(2, 0);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|
|
|
|
int nearest_x = int(src_x + 0.5);
|
|
|
|
|
int nearest_y = int(src_y + 0.5);
|
|
|
|
|
|
|
|
|
|
if ((nearest_x >= 0) && (nearest_y >= 0) && (nearest_x <= (srcImg.cols - 1)) && (nearest_y <= (srcImg.rows - 1)))
|
|
|
|
|
{
|
|
|
|
|
dstImg.at<cv::Vec3b>(y, x) = srcImg.at<cv::Vec3b>(nearest_y, nearest_x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RECT ValidRect = GetMinEncloseRect(dstImg);
|
|
|
|
|
|
|
|
|
|
if (ValidRect.left >= 0 && ValidRect.right >= 0 && ValidRect.right < dstImg.cols && ValidRect.right - ValidRect.left > 0 &&
|
|
|
|
|
ValidRect.top >= 0 && ValidRect.bottom >= 0 && ValidRect.bottom < dstImg.rows && ValidRect.bottom - ValidRect.top > 0)
|
|
|
|
|
{
|
|
|
|
|
dstImg(cv::Range(ValidRect.top, ValidRect.bottom + 1), cv::Range(ValidRect.left, ValidRect.right + 1)).copyTo(dstImg);
|
|
|
|
|
|
|
|
|
|
LBbox.WestLon = Lon_min + ValidRect.left * deltaLon;
|
|
|
|
|
LBbox.EastLon = LBbox.WestLon + dstImg.cols * deltaLon;
|
|
|
|
|
LBbox.NorthLat = Lat_max - ValidRect.top * deltaLat;
|
|
|
|
|
LBbox.SouthLat = LBbox.NorthLat - dstImg.rows * deltaLat;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LBbox.WestLon = Lon_min;
|
|
|
|
|
LBbox.EastLon = Lon_max;
|
|
|
|
|
LBbox.NorthLat = Lat_max;
|
|
|
|
|
LBbox.SouthLat = Lat_min;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ζ<EFBFBD><CEB6><EFBFBD>ʽ<EFBFBD>任
|
|
|
|
|
bool GCPGeoCorrectImgPolynomialTransform( cv::Mat& dstImg, GeoBoundingBox& LBbox, const cv::Mat& srcImg, const std::vector<cv::Point2d>& GCP_XY, const std::vector<cv::Point2d>& GCP_LonLat)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// ָ<><D6B8><EFBFBD><EFBFBD>ֵ<EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (srcImg.empty() == true ||
|
|
|
|
|
GCP_XY.size() < 6 || GCP_LonLat.size() < 6 || GCP_XY.size() != GCP_LonLat.size())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (srcImg.type() != CV_8UC1 && srcImg.type() != CV_8UC3)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>Ŀ
|
|
|
|
|
int count = GCP_XY.size();
|
|
|
|
|
|
|
|
|
|
// <20><>ÿ<EFBFBD><C3BF>GCP<43><50><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
|
|
|
for(int i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (GCP_XY[i].x < 0 || GCP_XY[i].x > srcImg.cols - 1)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GCP_XY[i].y < 0 || GCP_XY[i].y > srcImg.rows - 1)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GCP_LonLat[i].x < -180.0F || GCP_LonLat[i].x > 180.0F)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GCP_LonLat[i].y < -90.0F || GCP_LonLat[i].y > 90.0F)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ռ<EFBFBD><D5BC>ֱ<EFBFBD><D6B1>ʹ<EFBFBD><CAB9>ƣ<EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>صľ<D8B5>γ<EFBFBD>ȷֱ<C8B7><D6B1><EFBFBD>
|
|
|
|
|
double deltaLon = 0.0;
|
|
|
|
|
double deltaLat = 0.0;
|
|
|
|
|
if ( false == CalLonLatResolution(deltaLon, deltaLat, GCP_XY, GCP_LonLat) )
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41>B
|
|
|
|
|
cv::Mat A, B;
|
|
|
|
|
if (!CalPolynomialCoefficient(A, B, GCP_XY, GCP_LonLat))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>ĸ<EFBFBD><C4B8>ǵ<EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA>γ<EFBFBD>Ⱥ<EFBFBD><C8BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
cv::Point2f LeftUp, RightUp, LeftDown, RightDown;
|
|
|
|
|
|
|
|
|
|
LeftUp.x = static_cast<float>(A.at<double>(0, 0));
|
|
|
|
|
LeftUp.y = static_cast<float>(B.at<double>(0, 0));
|
|
|
|
|
|
|
|
|
|
RightUp.x = static_cast<float>(A.at<double>(0, 0) +
|
|
|
|
|
srcImg.cols * A.at<double>(1, 0) +
|
|
|
|
|
srcImg.cols * srcImg.cols * A.at<double>(4, 0));
|
|
|
|
|
RightUp.y = static_cast<float>(B.at<double>(0, 0) +
|
|
|
|
|
srcImg.cols * B.at<double>(1, 0) +
|
|
|
|
|
srcImg.cols * srcImg.cols * B.at<double>(4, 0));
|
|
|
|
|
|
|
|
|
|
LeftDown.x = static_cast<float>(A.at<double>(0, 0) +
|
|
|
|
|
srcImg.rows * A.at<double>(2, 0) +
|
|
|
|
|
srcImg.rows * srcImg.rows * A.at<double>(5, 0));
|
|
|
|
|
LeftDown.y = static_cast<float>(B.at<double>(0, 0) +
|
|
|
|
|
srcImg.rows * B.at<double>(2, 0) +
|
|
|
|
|
srcImg.rows * srcImg.rows * B.at<double>(5, 0));
|
|
|
|
|
|
|
|
|
|
RightDown.x = static_cast<float>(A.at<double>(0, 0) +
|
|
|
|
|
srcImg.cols * A.at<double>(1, 0) +
|
|
|
|
|
srcImg.rows * A.at<double>(2, 0) +
|
|
|
|
|
srcImg.cols * srcImg.rows * A.at<double>(3, 0) +
|
|
|
|
|
srcImg.cols * srcImg.cols * A.at<double>(4, 0) +
|
|
|
|
|
srcImg.rows * srcImg.rows * A.at<double>(5, 0));
|
|
|
|
|
RightDown.y = static_cast<float>(B.at<double>(0, 0) +
|
|
|
|
|
srcImg.cols * B.at<double>(1, 0) +
|
|
|
|
|
srcImg.rows * B.at<double>(2, 0) +
|
|
|
|
|
srcImg.cols * srcImg.rows * B.at<double>(3, 0) +
|
|
|
|
|
srcImg.cols * srcImg.cols * B.at<double>(4, 0) +
|
|
|
|
|
srcImg.rows * srcImg.rows * B.at<double>(5, 0));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ŀ<><C4BF>ͼ<EFBFBD><CDBC><EFBFBD>ı߽<C4B1>
|
|
|
|
|
double Lon_min = 0.0;
|
|
|
|
|
double Lon_max = 0.0;
|
|
|
|
|
double Lat_min = 0.0;
|
|
|
|
|
double Lat_max = 0.0;
|
|
|
|
|
|
|
|
|
|
Lon_min = min(min(min(LeftUp.x, RightUp.x), RightDown.x), LeftDown.x);
|
|
|
|
|
Lon_max = max(max(max(LeftUp.x, RightUp.x), RightDown.x), LeftDown.x);
|
|
|
|
|
Lat_min = min(min(min(LeftUp.y, RightUp.y), RightDown.y), LeftDown.y);
|
|
|
|
|
Lat_max = max(max(max(LeftUp.y, RightUp.y), RightDown.y), LeftDown.y);
|
|
|
|
|
|
|
|
|
|
// Ŀ<><C4BF>ͼ<EFBFBD><CDBC><EFBFBD>ijߴ<C4B3>
|
|
|
|
|
int dstWidth = 0;
|
|
|
|
|
int dstHeight = 0;
|
|
|
|
|
dstWidth = static_cast<int>((Lon_max - Lon_min) / deltaLon);
|
|
|
|
|
dstHeight = static_cast<int>((Lat_max - Lat_min) / deltaLat);
|
|
|
|
|
|
|
|
|
|
if (dstWidth <= 0 || dstHeight <= 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>任
|
|
|
|
|
if (false == CalPolynomialCoefficient(A, B, GCP_LonLat, GCP_XY))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
dstImg = cv::Mat(dstHeight, dstWidth, srcImg.type());
|
|
|
|
|
|
|
|
|
|
if (dstImg.empty() == true)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dstImg = cv::Scalar(0,0,0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><>ͨ<EFBFBD><CDA8>
|
|
|
|
|
if (dstImg.type() == 0)
|
|
|
|
|
{
|
|
|
|
|
#pragma omp parallel for
|
|
|
|
|
for (int x = 0; x < dstImg.cols; x++)
|
|
|
|
|
{
|
|
|
|
|
for (int y = 0; y < dstImg.rows; y++)
|
|
|
|
|
{
|
|
|
|
|
double dst_Lon = 0;
|
|
|
|
|
double dst_Lat = 0;
|
|
|
|
|
|
|
|
|
|
double src_x = 0.0;
|
|
|
|
|
double src_y = 0.0;
|
|
|
|
|
|
|
|
|
|
dst_Lon = Lon_min + x * deltaLon;
|
|
|
|
|
dst_Lat = Lat_max - y * deltaLat;
|
|
|
|
|
|
|
|
|
|
src_x = A.at<double>(0, 0) +
|
|
|
|
|
(dst_Lon) * A.at<double>(1, 0) +
|
|
|
|
|
(dst_Lat) * A.at<double>(2, 0) +
|
|
|
|
|
(dst_Lon) * (dst_Lat) * A.at<double>(3, 0) +
|
|
|
|
|
(dst_Lon) * (dst_Lon) * A.at<double>(4, 0) +
|
|
|
|
|
(dst_Lat) * (dst_Lat) * A.at<double>(5, 0);
|
|
|
|
|
|
|
|
|
|
src_y = B.at<double>(0, 0) +
|
|
|
|
|
(dst_Lon) * B.at<double>(1, 0) +
|
|
|
|
|
(dst_Lat) * B.at<double>(2, 0) +
|
|
|
|
|
(dst_Lon) * (dst_Lat) * B.at<double>(3, 0) +
|
|
|
|
|
(dst_Lon) * (dst_Lon) * B.at<double>(4, 0) +
|
|
|
|
|
(dst_Lat) * (dst_Lat) * B.at<double>(5, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|
|
|
|
int nearest_x = int(src_x + 0.5);
|
|
|
|
|
int nearest_y = int(src_y + 0.5);
|
|
|
|
|
|
|
|
|
|
if ((nearest_x >= 0) && (nearest_y >= 0) && (nearest_x <= (srcImg.cols - 1)) && (nearest_y <= (srcImg.rows - 1)))
|
|
|
|
|
{
|
|
|
|
|
dstImg.at<uchar>(y, x) = srcImg.at<uchar>(nearest_y, nearest_x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else // <20><>ͨ<EFBFBD><CDA8>
|
|
|
|
|
{
|
|
|
|
|
#pragma omp parallel for
|
|
|
|
|
for (int x = 0; x < dstImg.cols; x++)
|
|
|
|
|
{
|
|
|
|
|
for (int y = 0; y < dstImg.rows; y++)
|
|
|
|
|
{
|
|
|
|
|
double dst_Lon = 0;
|
|
|
|
|
double dst_Lat = 0;
|
|
|
|
|
|
|
|
|
|
double src_x = 0.0;
|
|
|
|
|
double src_y = 0.0;
|
|
|
|
|
|
|
|
|
|
dst_Lon = Lon_min + x * deltaLon;
|
|
|
|
|
dst_Lat = Lat_max - y * deltaLat;
|
|
|
|
|
|
|
|
|
|
src_x = A.at<double>(0, 0) +
|
|
|
|
|
(dst_Lon) * A.at<double>(1, 0) +
|
|
|
|
|
(dst_Lat) * A.at<double>(2, 0) +
|
|
|
|
|
(dst_Lon) * (dst_Lat) * A.at<double>(3, 0) +
|
|
|
|
|
(dst_Lon) * (dst_Lon) * A.at<double>(4, 0) +
|
|
|
|
|
(dst_Lat) * (dst_Lat) * A.at<double>(5, 0);
|
|
|
|
|
|
|
|
|
|
src_y = B.at<double>(0, 0) +
|
|
|
|
|
(dst_Lon) * B.at<double>(1, 0) +
|
|
|
|
|
(dst_Lat) * B.at<double>(2, 0) +
|
|
|
|
|
(dst_Lon) * (dst_Lat) * B.at<double>(3, 0) +
|
|
|
|
|
(dst_Lon) * (dst_Lon) * B.at<double>(4, 0) +
|
|
|
|
|
(dst_Lat) * (dst_Lat) * B.at<double>(5, 0);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|
|
|
|
int nearest_x = int(src_x + 0.5);
|
|
|
|
|
int nearest_y = int(src_y + 0.5);
|
|
|
|
|
|
|
|
|
|
if ((nearest_x >= 0) && (nearest_y >= 0) && (nearest_x <= (srcImg.cols - 1)) && (nearest_y <= (srcImg.rows - 1)))
|
|
|
|
|
{
|
|
|
|
|
dstImg.at<cv::Vec3b>(y, x) = srcImg.at<cv::Vec3b>(nearest_y, nearest_x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RECT ValidRect = GetMinEncloseRect(dstImg);
|
|
|
|
|
|
|
|
|
|
if (ValidRect.left >= 0 && ValidRect.right >= 0 && ValidRect.right < dstImg.cols && ValidRect.right - ValidRect.left > 0 &&
|
|
|
|
|
ValidRect.top >= 0 && ValidRect.bottom >= 0 && ValidRect.bottom < dstImg.rows && ValidRect.bottom - ValidRect.top > 0)
|
|
|
|
|
{
|
|
|
|
|
dstImg(cv::Range(ValidRect.top, ValidRect.bottom + 1), cv::Range(ValidRect.left, ValidRect.right + 1)).copyTo(dstImg);
|
|
|
|
|
|
|
|
|
|
LBbox.WestLon = Lon_min + ValidRect.left * deltaLon;
|
|
|
|
|
LBbox.EastLon = LBbox.WestLon + dstImg.cols * deltaLon;
|
|
|
|
|
LBbox.NorthLat = Lat_max - ValidRect.top * deltaLat;
|
|
|
|
|
LBbox.SouthLat = LBbox.NorthLat - dstImg.rows * deltaLat;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LBbox.WestLon = Lon_min;
|
|
|
|
|
LBbox.EastLon = Lon_max;
|
|
|
|
|
LBbox.NorthLat = Lat_max;
|
|
|
|
|
LBbox.SouthLat = Lat_min;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>ܣ<EFBFBD>OpenCVͼ<56><CDBC><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>ļ<EFBFBD><C4BC>ξ<EFBFBD>У<EFBFBD><D0A3>
|
|
|
|
|
//<2F><><EFBFBD>룺 1. srcImg <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
// 2. GCP_XY <20><><EFBFBD>Ƶ㣨<C6B5><E3A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>꣩
|
|
|
|
|
// 3. GCP_LonLat <20><><EFBFBD>Ƶ㣨<C6B5><E3A3A8>γ<EFBFBD><CEB3><EFBFBD><EFBFBD><EFBFBD>꣩
|
|
|
|
|
// 4. type: <20>任<EFBFBD><E4BBBB><EFBFBD><EFBFBD> -1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ 0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<><31><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD><CEB6><EFBFBD>ʽ
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1. dstImg <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
// 2. <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>true<75><65>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>false
|
|
|
|
|
bool GCPGeoCorrectImg( cv::Mat& dstImg, GeoBoundingBox& LBbox, const cv::Mat& srcImg, const std::vector<cv::Point2d>& GCP_XY, const std::vector<cv::Point2d>& GCP_LonLat, int type)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// ָ<><D6B8><EFBFBD><EFBFBD>ֵ<EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (srcImg.empty() == true ||
|
|
|
|
|
GCP_XY.size() < 4 || GCP_LonLat.size() < 4 || GCP_XY.size() != GCP_LonLat.size())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>任<EFBFBD><E4BBBB><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
|
|
|
|
if(type != -1 && type != 0 && type != 1)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (srcImg.type() != CV_8UC1 && srcImg.type() != CV_8UC3)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(type == 0)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD>Ա任
|
|
|
|
|
return GCPGeoCorrectImgLineTransform(dstImg, LBbox, srcImg, GCP_XY, GCP_LonLat);
|
|
|
|
|
}
|
|
|
|
|
else if(type == 1)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD>ζ<EFBFBD><CEB6><EFBFBD>ʽ
|
|
|
|
|
return GCPGeoCorrectImgPolynomialTransform(dstImg, LBbox, srcImg, GCP_XY, GCP_LonLat);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
|
|
|
|
|
int count = GCP_XY.size();
|
|
|
|
|
|
|
|
|
|
if (count >= 9) // <20><>СҪ<D0A1><D2AA>6<EFBFBD><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ9<CEAA><39> <20><><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD>
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD>ζ<EFBFBD><CEB6><EFBFBD>ʽ
|
|
|
|
|
return GCPGeoCorrectImgPolynomialTransform(dstImg, LBbox, srcImg, GCP_XY, GCP_LonLat);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD>Ա任
|
|
|
|
|
return GCPGeoCorrectImgLineTransform(dstImg, LBbox, srcImg, GCP_XY, GCP_LonLat);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD>ڿ<EFBFBD><DABF>Ƶ<EFBFBD><C6B5>ļ<EFBFBD><C4BC><EFBFBD>У<EFBFBD><D0A3>
|
|
|
|
|
//<2F><><EFBFBD>룺 1. srcImg <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
// 2. GCP_xy <20><><EFBFBD>Ƶ㣨<C6B5><E3A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>꣩
|
|
|
|
|
// 3. GCP_XY <20><><EFBFBD>Ƶ㣨<C6B5>ο<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>꣩
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1. dstImg <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
// 2. <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>true<75><65>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>false
|
|
|
|
|
bool CPBasedImgCorrect( cv::Mat &dst, const cv::Mat &src,
|
|
|
|
|
const std::vector<cv::Point2d>& CP_xy, const std::vector<cv::Point2d>& CP_XY)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (src.empty() == true)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (src.type() != 0 && src.type() != 16)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
int imgWidth = src.cols;
|
|
|
|
|
int imgHeight = src.rows;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>Ŀ<EFBFBD><C4BF>֤
|
|
|
|
|
if (CP_xy.size() < 4 || CP_XY.size() < 4 || CP_xy.size() != CP_XY.size())
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>Ŀ
|
|
|
|
|
int size = CP_xy.size();
|
|
|
|
|
|
|
|
|
|
// ÿ<><C3BF>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5><EFBFBD>֤
|
|
|
|
|
for(int i = 0; i < size; i++)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ο<EFBFBD><CEBF><EFBFBD>
|
|
|
|
|
if (CP_xy[i].x < 0 || CP_xy[i].x > imgWidth - 1)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (CP_xy[i].y < 0 || CP_xy[i].y > imgHeight- 1)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>ο<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD>
|
|
|
|
|
if (CP_XY[i].x < 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (CP_XY[i].y < 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41>B
|
|
|
|
|
cv::Mat A, B;
|
|
|
|
|
|
|
|
|
|
if (size >= 6)
|
|
|
|
|
{
|
|
|
|
|
if (false == CalPolynomialCoefficient(A, B, CP_xy, CP_XY))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (false == CalLineTransformCoefficient(A, B, CP_xy, CP_XY))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ĸ<EFBFBD><C4B8>ǵ<EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
cv::Point2f LeftUp, RightUp, LeftDown, RightDown;
|
|
|
|
|
|
|
|
|
|
if (size >= 6)
|
|
|
|
|
{
|
|
|
|
|
LeftUp.x = static_cast<float>(A.at<double>(0, 0));
|
|
|
|
|
LeftUp.y = static_cast<float>(B.at<double>(0, 0));
|
|
|
|
|
|
|
|
|
|
RightUp.x = static_cast<float>(A.at<double>(0, 0) +
|
|
|
|
|
src.cols * A.at<double>(1, 0) +
|
|
|
|
|
src.cols * src.cols * A.at<double>(4, 0));
|
|
|
|
|
RightUp.y = static_cast<float>(B.at<double>(0, 0) +
|
|
|
|
|
src.cols * B.at<double>(1, 0) +
|
|
|
|
|
src.cols * src.cols * B.at<double>(4, 0));
|
|
|
|
|
|
|
|
|
|
LeftDown.x = static_cast<float>(A.at<double>(0, 0) +
|
|
|
|
|
src.rows * A.at<double>(2, 0) +
|
|
|
|
|
src.rows * src.rows * A.at<double>(5, 0));
|
|
|
|
|
LeftDown.y = static_cast<float>(B.at<double>(0, 0) +
|
|
|
|
|
src.rows * B.at<double>(2, 0) +
|
|
|
|
|
src.rows * src.rows * B.at<double>(5, 0));
|
|
|
|
|
|
|
|
|
|
RightDown.x = static_cast<float>(A.at<double>(0, 0) +
|
|
|
|
|
src.cols * A.at<double>(1, 0) +
|
|
|
|
|
src.rows * A.at<double>(2, 0) +
|
|
|
|
|
src.cols * src.rows * A.at<double>(3, 0) +
|
|
|
|
|
src.cols * src.cols * A.at<double>(4, 0) +
|
|
|
|
|
src.rows * src.rows * A.at<double>(5, 0));
|
|
|
|
|
RightDown.y = static_cast<float>(B.at<double>(0, 0) +
|
|
|
|
|
src.cols * B.at<double>(1, 0) +
|
|
|
|
|
src.rows * B.at<double>(2, 0) +
|
|
|
|
|
src.cols * src.rows * B.at<double>(3, 0) +
|
|
|
|
|
src.cols * src.cols * B.at<double>(4, 0) +
|
|
|
|
|
src.rows * src.rows * B.at<double>(5, 0));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LeftUp.x = static_cast<float>(A.at<double>(0, 0));
|
|
|
|
|
LeftUp.y = static_cast<float>(B.at<double>(0, 0));
|
|
|
|
|
|
|
|
|
|
RightUp.x = static_cast<float>(A.at<double>(0, 0) + src.cols * A.at<double>(1, 0));
|
|
|
|
|
RightUp.y = static_cast<float>(B.at<double>(0, 0) + src.cols * B.at<double>(1, 0));
|
|
|
|
|
|
|
|
|
|
LeftDown.x = static_cast<float>(A.at<double>(0, 0) + src.rows * A.at<double>(2, 0));
|
|
|
|
|
LeftDown.y = static_cast<float>(B.at<double>(0, 0) + src.rows * B.at<double>(2, 0));
|
|
|
|
|
|
|
|
|
|
RightDown.x = static_cast<float>(A.at<double>(0, 0) + src.cols * A.at<double>(1, 0) + src.rows * A.at<double>(2, 0));
|
|
|
|
|
RightDown.y = static_cast<float>(B.at<double>(0, 0) + src.cols * B.at<double>(1, 0) + src.rows * B.at<double>(2, 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ŀ<><C4BF>ͼ<EFBFBD><CDBC><EFBFBD>ı߽<C4B1>
|
|
|
|
|
int min_X = 0;
|
|
|
|
|
int max_X = 0;
|
|
|
|
|
int min_Y = 0;
|
|
|
|
|
int max_Y = 0;
|
|
|
|
|
|
|
|
|
|
min_X = static_cast<int>(min(min(min(LeftUp.x, RightUp.x), RightDown.x), LeftDown.x));
|
|
|
|
|
max_X = static_cast<int>(max(max(max(LeftUp.x, RightUp.x), RightDown.x), LeftDown.x));
|
|
|
|
|
min_Y = static_cast<int>(min(min(min(LeftUp.y, RightUp.y), RightDown.y), LeftDown.y));
|
|
|
|
|
max_Y = static_cast<int>(max(max(max(LeftUp.y, RightUp.y), RightDown.y), LeftDown.y));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ŀ<><C4BF>ͼ<EFBFBD><CDBC><EFBFBD>ijߴ<C4B3>
|
|
|
|
|
int dstWidth = 0;
|
|
|
|
|
int dstHeight = 0;
|
|
|
|
|
dstWidth = static_cast<int>(max_X - min_X);
|
|
|
|
|
dstHeight = static_cast<int>(max_Y - min_Y);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>任
|
|
|
|
|
if (size >= 6)
|
|
|
|
|
{
|
|
|
|
|
if (false == CalPolynomialCoefficient(A, B, CP_XY, CP_xy))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (false == CalLineTransformCoefficient(A, B, CP_XY, CP_xy))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
if (src.type() == CV_8UC1)
|
|
|
|
|
{
|
|
|
|
|
dst = cv::Mat(dstHeight, dstWidth, CV_8UC1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dst = cv::Mat(dstHeight, dstWidth, CV_8UC3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dst.empty() == true)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dst = cv::Scalar(0,0,0);
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC><EFBFBD>ز<EFBFBD><D8B2><EFBFBD>
|
|
|
|
|
if (size >= 6) // <20><><EFBFBD>ζ<EFBFBD><CEB6><EFBFBD>ʽ
|
|
|
|
|
{
|
|
|
|
|
if (dst.type() == 0)
|
|
|
|
|
{
|
|
|
|
|
for (int x = min_X; x < max_X; x++)
|
|
|
|
|
{
|
|
|
|
|
for (int y = min_Y; y < max_Y; y++)
|
|
|
|
|
{
|
|
|
|
|
double src_x = 0.0;
|
|
|
|
|
double src_y = 0.0;
|
|
|
|
|
|
|
|
|
|
src_x = A.at<double>(0, 0) +
|
|
|
|
|
x * A.at<double>(1, 0) +
|
|
|
|
|
y * A.at<double>(2, 0) +
|
|
|
|
|
x * y * A.at<double>(3, 0) +
|
|
|
|
|
x * x * A.at<double>(4, 0) +
|
|
|
|
|
y * y * A.at<double>(5, 0);
|
|
|
|
|
|
|
|
|
|
src_y = B.at<double>(0, 0) +
|
|
|
|
|
x * B.at<double>(1, 0) +
|
|
|
|
|
y * B.at<double>(2, 0) +
|
|
|
|
|
x * y * B.at<double>(3, 0) +
|
|
|
|
|
x * x * B.at<double>(4, 0) +
|
|
|
|
|
y * y * B.at<double>(5, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|
|
|
|
int nearest_x = int(src_x + 0.5);
|
|
|
|
|
int nearest_y = int(src_y + 0.5);
|
|
|
|
|
|
|
|
|
|
if ((nearest_x >= 0) && (nearest_y >= 0) && (nearest_x <= (src.cols - 1)) && (nearest_y <= (src.rows - 1)))
|
|
|
|
|
{
|
|
|
|
|
dst.at<uchar>(y - min_Y, x - min_X) = src.at<uchar>(nearest_y, nearest_x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int x = min_X; x < max_X; x++)
|
|
|
|
|
{
|
|
|
|
|
for (int y = min_Y; y < max_Y; y++)
|
|
|
|
|
{
|
|
|
|
|
double src_x = 0.0;
|
|
|
|
|
double src_y = 0.0;
|
|
|
|
|
|
|
|
|
|
src_x = A.at<double>(0, 0) +
|
|
|
|
|
x * A.at<double>(1, 0) +
|
|
|
|
|
y * A.at<double>(2, 0) +
|
|
|
|
|
x * y * A.at<double>(3, 0) +
|
|
|
|
|
x * x * A.at<double>(4, 0) +
|
|
|
|
|
y * y * A.at<double>(5, 0);
|
|
|
|
|
|
|
|
|
|
src_y = B.at<double>(0, 0) +
|
|
|
|
|
x * B.at<double>(1, 0) +
|
|
|
|
|
y * B.at<double>(2, 0) +
|
|
|
|
|
x * y * B.at<double>(3, 0) +
|
|
|
|
|
x * x * B.at<double>(4, 0) +
|
|
|
|
|
y * y * B.at<double>(5, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|
|
|
|
int nearest_x = int(src_x + 0.5);
|
|
|
|
|
int nearest_y = int(src_y + 0.5);
|
|
|
|
|
|
|
|
|
|
if ((nearest_x >= 0) && (nearest_y >= 0) && (nearest_x <= (src.cols - 1)) && (nearest_y <= (src.rows - 1)))
|
|
|
|
|
{
|
|
|
|
|
dst.at<cv::Vec3b>(y - min_Y, x - min_X) = src.at<cv::Vec3b>(nearest_y, nearest_x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // <20><><EFBFBD>Ա任
|
|
|
|
|
{
|
|
|
|
|
if (dst.type() == 0)
|
|
|
|
|
{
|
|
|
|
|
for (int x = min_X; x < max_X; x++)
|
|
|
|
|
{
|
|
|
|
|
for (int y = min_Y; y < max_Y; y++)
|
|
|
|
|
{
|
|
|
|
|
double src_x = 0.0;
|
|
|
|
|
double src_y = 0.0;
|
|
|
|
|
|
|
|
|
|
src_x = A.at<double>(0, 0) + x * A.at<double>(1, 0) + y * A.at<double>(2, 0);
|
|
|
|
|
src_y = B.at<double>(0, 0) + x * B.at<double>(1, 0) + y * B.at<double>(2, 0);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|
|
|
|
int nearest_x = int(src_x + 0.5);
|
|
|
|
|
int nearest_y = int(src_y + 0.5);
|
|
|
|
|
|
|
|
|
|
if ((nearest_x >= 0) && (nearest_y >= 0) && (nearest_x <= (src.cols - 1)) && (nearest_y <= (src.rows - 1)))
|
|
|
|
|
{
|
|
|
|
|
dst.at<uchar>(y - min_Y, x - min_X) = src.at<uchar>(nearest_y, nearest_x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int x = min_X; x < max_X; x++)
|
|
|
|
|
{
|
|
|
|
|
for (int y = min_Y; y < max_Y; y++)
|
|
|
|
|
{
|
|
|
|
|
double src_x = 0.0;
|
|
|
|
|
double src_y = 0.0;
|
|
|
|
|
|
|
|
|
|
src_x = A.at<double>(0, 0) + x * A.at<double>(1, 0) + y * A.at<double>(2, 0);
|
|
|
|
|
src_y = B.at<double>(0, 0) + x * B.at<double>(1, 0) + y * B.at<double>(2, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>
|
|
|
|
|
int nearest_x = int(src_x + 0.5);
|
|
|
|
|
int nearest_y = int(src_y + 0.5);
|
|
|
|
|
|
|
|
|
|
if ((nearest_x >= 0) && (nearest_y >= 0) && (nearest_x <= (src.cols - 1)) && (nearest_y <= (src.rows - 1)))
|
|
|
|
|
{
|
|
|
|
|
dst.at<cv::Vec3b>(y - min_Y, x - min_X) = src.at<cv::Vec3b>(nearest_y, nearest_x);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RECT ValidRect = GetMinEncloseRect(dst);
|
|
|
|
|
|
|
|
|
|
if (ValidRect.left >= 0 && ValidRect.right >= 0 && ValidRect.right < dst.cols && ValidRect.right - ValidRect.left > 0 &&
|
|
|
|
|
ValidRect.top >= 0 && ValidRect.bottom >= 0 && ValidRect.bottom < dst.rows && ValidRect.bottom - ValidRect.top > 0)
|
|
|
|
|
{
|
|
|
|
|
dst = dst(cv::Range(ValidRect.top, ValidRect.bottom), cv::Range(ValidRect.left, ValidRect.right));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>ļ<EFBFBD><C4BC>ξ<EFBFBD>У<EFBFBD><D0A3>
|
|
|
|
|
bool GCPGeoCorrectImg( ImgStru *dstImg,
|
|
|
|
|
const ImgStru *srcImg,
|
|
|
|
|
const std::vector<Point2d>& GCP_XY,
|
|
|
|
|
const std::vector<Point2d>& GCP_LonLat,
|
|
|
|
|
int type)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// ָ<><D6B8><EFBFBD><EFBFBD>ֵ<EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (srcImg == NULL || dstImg == NULL)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (srcImg->ImgWidth <= 0 ||
|
|
|
|
|
srcImg->ImgHeight <= 0 ||
|
|
|
|
|
srcImg->buff == NULL)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srcImg->bitcount != 8 && srcImg->bitcount != 24)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>OpenCV<43>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
cv::Mat src;
|
|
|
|
|
if (srcImg->bitcount == 8)
|
|
|
|
|
{
|
|
|
|
|
src = cv::Mat(srcImg->ImgHeight, srcImg->ImgWidth, CV_8UC1);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
src = cv::Mat(srcImg->ImgHeight, srcImg->ImgWidth, CV_8UC3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (src.empty() == true)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ݸ<EFBFBD><DDB8><EFBFBD>
|
|
|
|
|
int lineByte = srcImg->ImgWidth * srcImg->bitcount / 8;
|
|
|
|
|
unsigned int imgBufSize = static_cast<unsigned int>(srcImg->ImgHeight * lineByte);
|
|
|
|
|
memcpy(src.data, srcImg->buff, imgBufSize);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
cv::Mat dst;
|
|
|
|
|
if (GCPGeoCorrectImg(dst, dstImg->BoundingBox, src, GCP_XY, GCP_LonLat, type) == false)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ݸ<EFBFBD><DDB8><EFBFBD>
|
|
|
|
|
SAFE_DELETE_ARRAY(dstImg->buff);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>Ը<EFBFBD>ֵ
|
|
|
|
|
dstImg->ImgWidth = dst.cols;
|
|
|
|
|
dstImg->ImgHeight = dst.rows;
|
|
|
|
|
dstImg->bitcount = srcImg->bitcount;
|
|
|
|
|
|
|
|
|
|
lineByte = (dst.cols * (dstImg->bitcount / 8));
|
|
|
|
|
imgBufSize = static_cast<unsigned int>(dst.rows * lineByte);
|
|
|
|
|
dstImg->buff = new unsigned char[imgBufSize];
|
|
|
|
|
|
|
|
|
|
if (dstImg->buff == NULL)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memcpy(dstImg->buff, dst.data, imgBufSize);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|