经常要使用到图像的仿射变换和透视变换,今天简单贴一个代码,方便以后复制。
仿射变化:
1、直接通过中心和旋转角度计算变换矩阵
2、通过对应三个点的输入计算变换矩阵
透视变换:
通过对应四个点的输入计算变换矩阵
代码:
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main() {
Mat src = imread("D:/images/wrap.jpg");
Mat gray, binary, dst_0, dst_1, rst;
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
vector<vector<Point>>con;
findContours(binary, con, RETR_TREE, CHAIN_APPROX_SIMPLE);
cout << "con = " << con.size() << endl;
Point2f P[4];
RotatedRect minRect;
for (int i = 0; i < con.size(); i++) {
// drawContours(src, con[i], i, (255, 0, 0),2, 8);
minRect = minAreaRect(con[i]);
minRect.points(P);
}
for (int j = 0; j<4; j++)
{
line(src, P[j], P[(j + 1) % 4], Scalar(0, 0, 255), 2, 8); //绘制最小外接矩形每条边
}
//仿射变换——1
Mat M0 = getRotationMatrix2D(minRect.center, minRect.angle, 1);
//仿射变换——2
Point2f srcPoints2[3];
Point2f dstPoints2[3];
srcPoints2[0] = Point2i(0, 0);
srcPoints2[1] = Point2i(0, src.rows);
srcPoints2[2] = Point2i(src.cols, 0);
dstPoints2[0] = Point2i(src.cols, 0);
dstPoints2[1] = Point2i(src.cols, src.rows);
dstPoints2[2] = Point2i(0, 0);
Mat M2 = getAffineTransform(srcPoints2, dstPoints2);
warpAffine(src, dst_0, M0, Size(src.cols, src.rows), INTER_LINEAR);
warpAffine(src, dst_1, M2, Size(src.cols, src.rows), INTER_LINEAR);
//透视变换
Point2f srcPoints[4];//原图中的四点 ,一个包含三维点(x,y)的数组,其中x、y是浮点型数
Point2f dstPoints[4];//目标图中的四点
srcPoints[0] = Point2f(0, 0);
srcPoints[1] = Point2f(0, src.rows);
srcPoints[2] = Point2f(src.cols, 0);
srcPoints[3] = Point2f(src.cols, src.rows);
//映射后的四个坐标值
dstPoints[0] = Point2f(src.cols*0.1, src.rows*0.1);
dstPoints[1] = Point2f(0, src.rows);
dstPoints[2] = Point2f(src.cols, 0);
dstPoints[3] = Point2f(src.cols*0.7, src.rows*0.8);
Mat M1 = getPerspectiveTransform(srcPoints, dstPoints);//由四个点对计算透视变换矩阵
warpPerspective(src, rst, M1, src.size());
imshow("src", src);
imshow("binary", binary);
imshow("dst_0", dst_0);
imshow("dst_1", dst_1);
imshow("rst", rst);
waitKey(0);
return 0;
}