You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1418 lines
31 KiB
C++

2 years ago
#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;
}
}