|  |  |  |  | #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; | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 |