TPS 样板条插值算法矫正图像 TPS 具体用法

#TPS用法
TPS在opencv contribute 里面使用的时候需要自己把源码和contrib 一块编译进去
TPS主要的使用步骤是首先确定上下矫正的点 对于弯曲文本将上边沿点拉到同一水平位置,
使用注意事项是上下边沿点最好确定在同一x坐标上 否则会出现矫正后图片畸形的情况

参考代码:

‘’‘using namespace std;
cv::Mat trans_img(cv::Mat src_img, std::vectorcv::Point2f sourcePoints, std::vectorcv::Point2ftargetPoints)
{
auto tps = cv::createThinPlateSplineShapeTransformer();
std::vectorcv::DMatch matches;
for (unsigned int i = 0; i < sourcePoints.size(); i++)
matches.push_back(cv::DMatch(i, i, 0));

tps->estimateTransformation(targetPoints, sourcePoints, matches);

//std::vector transPoints;
//tps->applyTransformation(sourcePoints, transPoints);

cout << "sourcePoints = " << endl << " " << sourcePoints << endl << endl;
cout << "targetPoints = " << endl << " " << targetPoints << endl << endl;
//cout << "transPos = " << endl << " " << transPoints << endl << endl;
cv::Mat res(600, 600, CV_8UC3, cv::Scalar(0, 0, 0));
cv::Mat roi = res(cv::Rect(0, 0, 495, 152));
src_img.copyTo(roi);
cv::Mat re;
tps->warpImage(src_img, re);
return re;

}
int main(char* arg, char** argv)
{
using clock = std::chrono::system_clock;
using ms = std::chrono::milliseconds;

cv::Mat img = cv::imread("F:\\cppcode\\data\\0001682_6.jpg");

if (img.empty())
{
	cout << "read failed" << endl;
}
int imgH = img.rows;
int imgW = img.cols;
int imgC = img.channels();
//int imgC = image.channels;
cout  << imgC << imgH << imgW << endl;

int objH = 20;
int objW = 400;
//cv::Mat outimg(2, 2, CV_8UC3, cv::Scalar(0, 0, 0));
const auto before = clock::now();
std::vector sourcePoints, targetPoints;
sourcePoints.push_back(cv::Point2f(88, 20));
sourcePoints.push_back(cv::Point2f(149, 2));
sourcePoints.push_back(cv::Point2f(210, 0));
sourcePoints.push_back(cv::Point2f(264, 7));
sourcePoints.push_back(cv::Point2f(320, 27));
sourcePoints.push_back(cv::Point2f(75, 84));
sourcePoints.push_back(cv::Point2f(113, 61));
sourcePoints.push_back(cv::Point2f(153, 46));
sourcePoints.push_back(cv::Point2f(203, 40));
sourcePoints.push_back(cv::Point2f(257, 57));
sourcePoints.push_back(cv::Point2f(290, 72));*/
sourcePoints.push_back(cv::Point2f(8, 59));
sourcePoints.push_back(cv::Point2f(90, 42));
sourcePoints.push_back(cv::Point2f(190, 6));
sourcePoints.push_back(cv::Point2f(330, 42));
sourcePoints.push_back(cv::Point2f(443, 72));
sourcePoints.push_back(cv::Point2f(19, 99));
sourcePoints.push_back(cv::Point2f(103, 78));
sourcePoints.push_back(cv::Point2f(196, 52));
sourcePoints.push_back(cv::Point2f(317, 80));
sourcePoints.push_back(cv::Point2f(429, 106));
/*targetPoints.push_back(cv::Point2f(0,2));
targetPoints.push_back(cv::Point2f(85, 2));
targetPoints.push_back(cv::Point2f(183, 2));
targetPoints.push_back(cv::Point2f(336, 2));
targetPoints.push_back(cv::Point2f(448, 2));
targetPoints.push_back(cv::Point2f(0, 60));
targetPoints.push_back(cv::Point2f(85, 60));
targetPoints.push_back(cv::Point2f(183, 60));
targetPoints.push_back(cv::Point2f(336, 60));
targetPoints.push_back(cv::Point2f(446, 60));*/


targetPoints.push_back(cv::Point2f(sourcePoints[0].x,2));
for (int i = 0; i < sourcePoints.size() / 2 -1  ; i++)
{
	float tmpx = sourcePoints[i].x + sqrt((sourcePoints[i + 1].x - sourcePoints[i].x)
		* (sourcePoints[i + 1].x - sourcePoints[i].x) + (sourcePoints[i + 1].y - sourcePoints[i].y)
		* (sourcePoints[i + 1].y - sourcePoints[i].y));
	float tmpy = 2;
	targetPoints.push_back(cv::Point2f(tmpx, tmpy));
}
targetPoints.push_back(cv::Point2f(sourcePoints[sourcePoints.size() / 2 ].x,60));
for (int i = sourcePoints.size()/2 ; i < sourcePoints.size() - 1; i++)
{
	float tmpx = sourcePoints[i].x + sqrt((sourcePoints[i + 1].x - sourcePoints[i].x)
		* (sourcePoints[i + 1].x - sourcePoints[i].x) + (sourcePoints[i + 1].y - sourcePoints[i].y)
		* (sourcePoints[i + 1].y - sourcePoints[i].y));
	float tmpy = 60;
	targetPoints.push_back(cv::Point2f(tmpx, tmpy));
}

cv::Mat res;
res = trans_img(img, sourcePoints, targetPoints);
const auto duration = std::chrono::duration_cast(clock::now() - before);
std::cout << "It took " << duration.count() / 1000.0 << "s" << std::endl;
//plot  source and target dot on the map
for (int i = 0; i < sourcePoints.size(); i++)
{
	cv::circle(img, sourcePoints[i], 1, (255, 255, 255), 3);
	//cv::circle(res, targetPoints[i], 1, (255, 255, 0), 3);
}

//cv::namedWindow("Display window", cv::WINDOW_AUTOSIZE); // Create a window for display.
cv::Mat roi = res(cv::Rect(0, 0, imgW, 60));
cv::imshow("warp result_1.jpg", roi);// Show our image inside it.
cv::imwrite("warp result_1.jpg", roi);
cv::waitKey(0); // Wait for a keystroke in the window

return 0;

}

TPS 样板条插值算法矫正图像 TPS 具体用法_第1张图片在这里插入图片描述

你可能感兴趣的:(cv)