旋转是图像处理的常用技巧。今天介绍一下旋转,平移以及尺度放缩的基本原理。
点的旋转
给定一个点P(x,y),以及一个角度
θ
\theta
θ,求逆时针旋转
θ
\theta
θ之后新的点坐标
P
′
P'
P′的位置。
我们用极坐标表示P
x
=
R
c
o
s
ϕ
x = Rcos\phi
x=Rcosϕ
y
=
R
s
i
n
ϕ
y = R sin\phi
y=Rsinϕ
逆时针旋转
t
h
e
t
a
theta
theta之后,
x
′
=
R
c
o
s
(
θ
+
ϕ
)
;
y
′
=
R
s
i
n
(
θ
+
ϕ
)
x' = Rcos(\theta + \phi); y' = Rsin(\theta+\phi)
x′=Rcos(θ+ϕ);y′=Rsin(θ+ϕ)
把cos和sin拆开。
x
′
=
R
(
c
o
s
θ
c
o
s
ϕ
−
s
i
n
θ
s
i
n
ϕ
)
=
x
c
o
s
θ
−
y
s
i
n
θ
x' =R(cos\theta cos\phi - sin\theta sin\phi)\\ = xcos\theta - ysin\theta
x′=R(cosθcosϕ−sinθsinϕ)=xcosθ−ysinθ
y
′
=
R
(
s
i
n
θ
c
o
s
ϕ
+
c
o
s
θ
s
i
n
ϕ
)
=
x
s
i
n
θ
+
y
c
o
s
θ
y' = R(sin\theta cos\phi + cos\theta sin\phi)\\ =xsin\theta + ycos\theta
y′=R(sinθcosϕ+cosθsinϕ)=xsinθ+ycosθ
然后写成矩阵形式
[
x
′
y
′
]
=
[
c
o
s
θ
−
s
i
n
θ
s
i
n
θ
c
o
s
θ
]
[
x
y
]
\left[ \begin{matrix} x' \\ y' \end{matrix} \right] = \left[ \begin{matrix} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{matrix} \right] \left[ \begin{matrix} x \\ y \end{matrix} \right]
[x′y′]=[cosθsinθ−sinθcosθ][xy]
齐次坐标
图像的仿射变换是要在齐次坐标系下进行的。齐次坐标能把旋转,缩放以及平移都用相同大小的矩阵表示,而且他们的组合是线性且可逆的。
范式如下:
[
x
′
,
y
′
,
1
]
T
=
A
[
x
,
y
,
1
]
T
[x',y',1]^T = A[x,y,1]^T
[x′,y′,1]T=A[x,y,1]T
-
旋转矩阵
A = [ c o s θ − s i n θ 0 s i n θ c o s θ 0 0 0 1 ] A = \left[ \begin{matrix} cos\theta & -sin\theta & 0 \\ sin\theta & cos\theta & 0 \\ 0 & 0 & 1 \end{matrix} \right] A=⎣⎡cosθsinθ0−sinθcosθ0001⎦⎤ -
平移矩阵
A = [ 1 0 t x 0 1 t y 0 0 1 ] A=\left[ \begin{matrix} 1&0&t_x \\ 0&1&t_y \\ 0&0&1 \end{matrix} \right] A=⎣⎡100010txty1⎦⎤ -
缩放矩阵
A = [ s x 0 0 0 s y 0 0 0 1 ] A=\left[ \begin{matrix} s_x &0&0 \\ 0&s_y&0 \\ 0&0&1 \end{matrix} \right] A=⎣⎡sx000sy0001⎦⎤
使用这些矩阵,我们就能获得每个坐标在仿射变换之后的位置。
如果我们想让一张图片围绕中心旋转。我们应该把中心点移到原点坐标上,然后旋转,然后在平移回去。
OpenCV中的仿射API
- cv2.getRotationMatrix2D(center, angle, scale)
- cv2.warpAffine(image, A, (width, height))
第一个函数用来获得仿射矩阵。你可以设置这个三个自由度。angle用角度值(不是弧度制)
第二个函数是做仿射变换。其中A就是仿射矩阵。
另外numpy中有角度转弧度的函数 np.radians 以及弧度转角度的函数 np.rad2deg
其他参考
推荐看
旋转变换(一)旋转矩阵