OpenCV中的仿射变换
仿射变换:一个任意的仿射变换都能表示为 乘以一个矩阵 (线性变换) 接着再 加上一个向量 (平移).
通常一个图像有三种变换:
1、旋转
2、平移
3、缩放
通常用2X3的矩阵来表示一个仿射变换:
变
换
矩
阵
A
=
[
a
11
a
12
a
21
a
22
]
变换矩阵A=\begin{bmatrix}a_{11}&a_{12}\\a_{21}&a_{22}\end{bmatrix}
变换矩阵A=[a11a21a12a22]
平
移
变
化
M
=
[
t
x
t
y
]
平移变化M=\begin{bmatrix} t_x\\t_y \end{bmatrix}
平移变化M=[txty]
通常将两个变换合为一个:
仿
射
变
换
矩
阵
T
=
[
a
11
a
12
t
x
a
21
a
22
t
y
]
仿射变换矩阵T=\begin{bmatrix}a_{11}&a_{12}&t_x\\a_{21}&a_{22}&{t_y} \end{bmatrix}
仿射变换矩阵T=[a11a21a12a22txty]
假设原坐标为
(
x
原
,
y
原
)
(x_原,y_原)
(x原,y原)经过仿射变换:
[
x
新
y
新
]
=
[
a
11
a
12
a
21
a
22
]
∗
[
x
原
y
原
]
+
[
t
x
t
y
]
\begin{bmatrix}x_新\\y_新 \end{bmatrix}=\begin{bmatrix} a_{11}&a_{12}\\a_{21}&a_{22}\end{bmatrix}*\begin{bmatrix}x_原\\y_原 \end{bmatrix}+\begin{bmatrix}t_x\\t_y \end{bmatrix}
[x新y新]=[a11a21a12a22]∗[x原y原]+[txty]
以上为仿射变换的分步。
直接使用仿射变换矩阵T:
[
x
新
y
新
]
=
[
a
11
a
12
t
x
a
21
a
22
t
y
]
∗
[
x
原
y
原
1
]
\begin{bmatrix} x_新\\y_新\end{bmatrix}=\begin{bmatrix}a_{11}&a_{12}&t_x\\a_{21}&a_{22}&{t_y} \end{bmatrix}*\begin{bmatrix}x_原\\y_原\\1\end{bmatrix}
[x新y新]=[a11a21a12a22txty]∗⎣⎡x原y原1⎦⎤
下面是几个函数的API:
利用变换前的点和变换后的点求出仿射变换矩阵:
getAffineTransform(
原图像的点的集合,
变换后的图像的点的集合
);
利用旋转角度和缩放比例来求出仿射变换矩阵:
getRotationMatrix2D(
中心点,
旋转角度,
缩放比例
);
最后根据仿射变换矩阵对图像进行操作:
warpAffine(
输入图像,
输出图像,
仿射变换矩阵,
原图像.size()
);
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat test = Mat::zeros(500,500,CV_8UC3);
imshow("test",test);
Point2f p[3];
Point2f q[3];
p[0] = Point2f(200,300);
p[1] = Point2f(400,100);
p[2] = Point2f(70,80);
line(test,p[0],p[1],Scalar(255,255,255),3,8);
line(test,p[0],p[2],Scalar(255,255,255),3,8);
line(test,p[2],p[1],Scalar(255,255,255),3,8);
q[0] = Point2f(300,300);
q[1] = Point2f(500,100);
q[2] = Point2f(170,80);
line(test,q[0],q[1],Scalar(255,255,255),3,8);
line(test,q[0],q[2],Scalar(255,255,255),3,8);
line(test,q[2],q[1],Scalar(255,255,255),3,8);
Mat tr = getAffineTransform(p,q);
cout << tr << endl;
imshow("test",test);
Mat src = imread("/home/dynamicw/Project/C++_Project/opencvtest/src/lesson01/source/map.png");
Mat dst;
Point center = Point(src.cols/2,src.rows/2);
double angle = -50.0;
double scale = 0.6;
tr = getRotationMatrix2D(center,angle,scale);
warpAffine(src,dst,tr,src.size());
imshow("dst",dst);
waitKey(0);
return 0;
}