仿射变换
平移
(1) ( x ^ y ^ 1 ) = ( 1 0 t x 0 1 t y 0 0 1 ) ( x y 1 ) \begin{pmatrix} \hat{x} \\ \hat{y} \\ 1\end{pmatrix}=\begin{pmatrix}1&0&t_x\\0&1&t_y\\0&0&1\end{pmatrix}\begin{pmatrix}x\\y\\1\end{pmatrix}\tag{1} ⎝⎛x^y^1⎠⎞=⎝⎛100010txty1⎠⎞⎝⎛xy1⎠⎞(1)
若 t x > 0 t_x>0 tx>0,向x轴正方向移动;若 t x < 0 t_x<0 tx<0,向x轴负方向移动。
放大和缩小
- ( x , y ) (x,y) (x,y)以(0,0)为中心缩放变换后的坐标为 ( x ^ , y ^ ) (\hat{x},\hat{y}) (x^,y^),则 ( x ^ , y ^ ) = ( s x ∗ x , x y ∗ y ) (\hat{x},\hat{y})=(s_x*x,x_y*y) (x^,y^)=(sx∗x,xy∗y).
通常令 s x = s y s_x=s_y sx=sy,即等比例缩放。
(2) ( x ^ y ^ 1 ) = ( s x 0 0 0 s y 0 0 0 1 ) ( x y 1 ) \begin{pmatrix} \hat{x} \\ \hat{y} \\ 1\end{pmatrix}=\begin{pmatrix}s_x&0&0\\0&s_y&0\\0&0&1\end{pmatrix}\begin{pmatrix}x\\y\\1\end{pmatrix}\tag{2} ⎝⎛x^y^1⎠⎞=⎝⎛sx000sy0001⎠⎞⎝⎛xy1⎠⎞(2) - 若以任意一点 ( x 0 , y 0 ) (x_0,y_0) (x0,y0),则 ( x ^ , y ^ ) = ( x 0 + s x ( x − x 0 ) , y 0 + s y ( y − y 0 ) ) (\hat{x},\hat{y})=(x_0+s_x(x-x_0),y_0+s_y(y-y_0)) (x^,y^)=(x0+sx(x−x0),y0+sy(y−y0)).
(3) ( x ^ y ^ 1 ) = ( 1 0 x 0 0 1 y 0 0 0 1 ) ( s x 0 0 0 s y 0 0 0 1 ) ( 1 0 − x 0 0 1 − y 0 0 0 1 ) ( x y 1 ) \begin{pmatrix} \hat{x} \\ \hat{y} \\ 1\end{pmatrix}=\begin{pmatrix}1&0&x_0\\0&1&y_0\\0&0&1\end{pmatrix} \begin{pmatrix}s_x&0&0\\0&s_y&0\\0&0&1\end{pmatrix} \begin{pmatrix}1&0&-x_0\\0&1&-y_0\\0&0&1\end{pmatrix} \begin{pmatrix}x\\y\\1\end{pmatrix}\tag{3} ⎝⎛x^y^1⎠⎞=⎝⎛100010x0y01⎠⎞⎝⎛sx000sy0001⎠⎞⎝⎛100010−x0−y01⎠⎞⎝⎛xy1⎠⎞(3)
平移矩阵和缩放矩阵相乘
旋转
逆时针旋转 α \alpha α
(4) ( x ^ y ^ 1 ) = ( 1 0 x 0 0 1 y 0 0 0 1 ) ( c o s α s i n α 0 − s i n α c o s α 0 0 0 1 ) ( 1 0 − x 0 0 1 − y 0 0 0 1 ) ( x y 1 ) \begin{pmatrix} \hat{x} \\ \hat{y}\\1\end{pmatrix}=\begin{pmatrix}1&0&x_0\\0&1&y_0\\0&0&1\end{pmatrix} \begin{pmatrix}cos\alpha&sin\alpha&0\\-sin\alpha&cos\alpha&0\\0&0&1\end{pmatrix} \begin{pmatrix}1&0&-x_0\\0&1&-y_0\\0&0&1\end{pmatrix} \begin{pmatrix}x\\y\\1\end{pmatrix}\tag{4} ⎝⎛x^y^1⎠⎞=⎝⎛100010x0y01⎠⎞⎝⎛cosα−sinα0sinαcosα0001⎠⎞⎝⎛100010−x0−y01⎠⎞⎝⎛xy1⎠⎞(4)
顺时针旋转 α \alpha α
(5) ( x ^ y ^ 1 ) = ( 1 0 x 0 0 1 y 0 0 0 1 ) ( c o s α − s i n α 0 s i n α c o s α 0 0 0 1 ) ( 1 0 − x 0 0 1 − y 0 0 0 1 ) ( x y 1 ) \begin{pmatrix} \hat{x} \\ \hat{y}\\1\end{pmatrix}=\begin{pmatrix}1&0&x_0\\0&1&y_0\\0&0&1\end{pmatrix} \begin{pmatrix}cos\alpha&-sin\alpha&0\\sin\alpha&cos\alpha&0\\0&0&1\end{pmatrix} \begin{pmatrix}1&0&-x_0\\0&1&-y_0\\0&0&1\end{pmatrix} \begin{pmatrix}x\\y\\1\end{pmatrix}\tag{5} ⎝⎛x^y^1⎠⎞=⎝⎛100010x0y01⎠⎞⎝⎛cosαsinα0−sinαcosα0001⎠⎞⎝⎛100010−x0−y01⎠⎞⎝⎛xy1⎠⎞(5)
计算仿射矩阵A
- 方程法
cv2.getAffineTransform(src,dst)
import cv2
import numpy as np
src = np.array([[0,0],[200,0],[0,200]],np.float32);
dst = np.array([[0,0],[100,0],[0,100]],np.float32);
A = cv2.getAffineTransform(src,dst)
- 矩阵法
先平移后缩放
import numpy as np
s = np.array([[0.5,0,0],[0,0.5,0],[0,0,1]]); #缩放矩阵
t = np.array([[1,0,100],[0,1,200],[0,0,1]]); #平移矩阵
A=np.dot(t,s)
- 对于等比例缩放和旋转
cv2.getRotationMatrix2D(center,angle,scale)
center 为变换中心的坐标 ,scale为等比例缩放的系数 ,angle为逆时针旋转的角度
如:以(40,50)为中心逆时针旋转30度,缩小0.5倍
import cv2
A=cv2.getRotationMatrix2D((40,50),30,0.5)