图像的几何变换
在图像处理中,我们经常会进行两种类型的操作,一种是像素值的变换,最常见的比如直方图均衡,对比度,颜色的变换,这一类都属于像素值的变换;还有一种是几何变换,比如常见的旋转,平移,仿射变换,透视变换等。
- 像素值变换:这种变换,主要改变像素值的大小,但不会改变像素的坐标
- 几何变换:这种变换,会改变像素原有的坐标关系,但一般不会改变像素值
接下来,我们就来看看图像常见的一些几何变换
当我们讨论几何变换的时候,我们首先需要建立一个坐标系,最常见的就是笛卡尔坐标系,以二维空间为例,笛卡尔坐标系,以相互垂直的两个坐标轴进行表示,我们的图像一般也是用笛卡尔坐标系来表示,我们看到的图像都是水平方向和垂直方向相互垂直的一个矩形,所以图像也是建立在笛卡尔坐标系下的,而且图像的原点也是两个坐标轴相交的点,只不过在图像上,两个坐标轴的交点是在图像的四个角上,我们一般就以图像的左上角作为原点。所以图像一般可以表示成:
f ( x , y ) , 0 ≤ x ≤ N , 0 ≤ y ≤ M f(x, y), \quad 0 \leq x \leq N, \quad 0 \leq y \leq M f(x,y),0≤x≤N,0≤y≤M
上面的式子表示了一个有 M 行 N 列的图像。
那么,几何变换,也就是坐标系的变换,简单来说,就是从一个坐标系,变换到另一个坐标系下。所以几何变换,一般会涉及到两个坐标系,一个称为原坐标系,一个称为目标坐标系。可以表示成如下所示:
x ′ = g ( x ) y ′ = h ( y ) \begin{matrix} x' = g(x)\\ y' = h(y) \end{matrix} x′=g(x)y′=h(y)
上面的 x ′ , y ′ x', y' x′,y′ 表示目标坐标系,而 x , y x, y x,y 表示原有的坐标系, g , h g, h g,h 分别表示变换关系,一般是一个线性函数,如果写成矩阵,就如下所示:
[ x ′ y ′ ] = A [ x y ] \begin{bmatrix} x' \\ y' \end{bmatrix} = \mathbf{A} \begin{bmatrix} x \\ y \end{bmatrix} [x′y′]=A[xy]
借助矩阵的表达形式,我们来看看几种常见的几何变换,图像最常见的几种几何变换有缩放,旋转,平移等
图像缩放
图像的缩放就是我们常说的 scale 变换:
x ′ = a x y ′ = b y \begin{matrix} x' = ax\\ y' = by \end{matrix} x′=axy′=by
如果写成矩阵形式,可以表示成:
[ x ′ y ′ ] = [ a 0 0 b ] [ x y ] \begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} a & 0 \\ 0 & b \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} [x′y′]=[a00b][xy]
图像旋转
图像的旋转也是常见的一种几何变换,图像的旋转可以表示成:
x ′ = x cos ( θ ) − y sin ( θ ) y ′ = x sin ( θ ) + y cos ( θ ) \begin{matrix} x' = x \cos(\theta) - y \sin(\theta) \\ y' = x \sin(\theta) + y \cos(\theta) \end{matrix} x′=xcos(θ)−ysin(θ)y′=xsin(θ)+ycos(θ)
显然,这个也可以表示成矩阵形式:
[ x ′ y ′ ] = [ cos ( θ ) − sin ( θ ) sin ( θ ) cos ( θ ) ] [ x y ] \begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} \cos(\theta) & -\sin(\theta) \\ \sin(\theta) & \cos(\theta) \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} [x′y′]=[cos(θ)sin(θ)−sin(θ)cos(θ)][xy]
图像平移
图像的平移,也是常见的一种变换,
x ′ = x + t x y ′ = y + t y \begin{matrix} x' = x + t_x\\ y' = y + t_y \end{matrix} x′=x+txy′=y+ty
想必大家注意到,上面这个表达式,无法用一个 $ 2 \times 2$ 的矩阵来表示,为了能将运算用矩阵运算统一起来,我们引入齐次坐标系,在齐次坐标系下,所有的几何变换都可以用矩阵进行表示。
齐次坐标
齐次坐标就是在原有的坐标的基础上再增加一个维度,如果是二维的坐标,我们就用三维的齐次坐标来表示:
[ x ′ y ′ ] ⇒ [ x ′ y ′ 1 ] \begin{bmatrix} x' \\ y' \end{bmatrix} \Rightarrow \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} [x′y′]⇒⎣⎡x′y′1⎦⎤
引入齐次坐标之后,图像的平移也可以纳入矩阵的运算当中:
- 平移
[ x ′ y ′ 1 ] = [ 1 0 t x 0 1 t y 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} ⎣⎡x′y′1⎦⎤=⎣⎡100010txty1⎦⎤⎣⎡xy1⎦⎤
而前面介绍的缩放和旋转也可以用齐次坐标来表示:
- 缩放:
[ x ′ y ′ 1 ] = [ a 0 0 0 b 0 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} a & 0 & 0 \\ 0 & b & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} ⎣⎡x′y′1⎦⎤=⎣⎡a000b0001⎦⎤⎣⎡xy1⎦⎤
- 旋转
[ x ′ y ′ 1 ] = [ cos ( θ ) − sin ( θ ) 0 sin ( θ ) cos ( θ ) 0 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} \cos(\theta) & -\sin(\theta) & 0 \\ \sin(\theta) & \cos(\theta) & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} ⎣⎡x′y′1⎦⎤=⎣⎡cos(θ)sin(θ)0−sin(θ)cos(θ)0001⎦⎤⎣⎡xy1⎦⎤
这几个矩阵联合起来,就构成了我们常说的缩放,旋转,平移。除了这几个常见的几何变换,还有一个称为 shear 的变换,就是在水平方向或者垂直方向产生错切的变换:
- 错切
x ′ = x + a y y ′ = b x + y \begin{matrix} x' = x + ay\\ y' = bx + y \end{matrix} x′=x+ayy′=bx+y
其矩阵形式可以表示为:
[ x ′ y ′ 1 ] = [ 1 a 0 b 1 0 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} 1 & a & 0 \\ b & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} ⎣⎡x′y′1⎦⎤=⎣⎡1b0a10001⎦⎤⎣⎡xy1⎦⎤
当 b=0, a>1 的时候,会发生水平方向的错切,当 a=0, b>1 的时候,会发生垂直方向的错切,如果 a>1, b>1 那么两个方向都会发生错切。
介绍完这几种基础的线性变换,我们再来看看我们常见的几种变换,仿射变换和透射变换
变换的自由度
前面介绍的几种基础的变换,我们看看每种变换都有几个自由度,所谓自由度,可以理解成这种变换需要几个参数来刻画。
- 平移,平移需要两个自由度,分别表示水平方向的平移量和垂直方向的平移量
- 旋转,旋转需要一个自由度,就是旋转角度
- 缩放,缩放有两个自由度,分别表示水平方向的缩放量和垂直方向的缩放量
- 错切,错切也有两个自由度,分别表示水平方向的错切和垂直方向的错切
仿射变换
仿射变换是我们常见的一种变换,可以理解成是上面几种基础变换的组合得到的,仿射变换可以表示成如下的矩阵形式:
[ x ′ y ′ 1 ] = [ a 1 a 2 a 3 a 4 a 5 a 6 0 0 1 ] [ x y 1 ] \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} a_1 & a_2 & a_3 \\ a_4 & a_5 & a_6 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} ⎣⎡x′y′1⎦⎤=⎣⎡a1a40a2a50a3a61⎦⎤⎣⎡xy1⎦⎤
仿射变换满足如下的几个性质:
- 直线经过仿射变换之后,依然是直线
- 平行线经过仿射变换之后,依然是平行线
- 保持线段之间的比例关系不变
要满足上面的约束:
x ′ = a 1 x + a 2 y + a 3 y ′ = a 4 x + a 5 y + a 6 \begin{matrix} x' = a_1 x + a_2 y + a_3 \\ y' = a_4 x + a_5 y + a_6 \end{matrix} x′=a1x+a2y+a3y′=a4x+a5y+a6
需要有 6 个参数,所以仿射变换的自由度是 6,需要三对不共线的点来确定。
透视变换
透视变换也是一种常见的变换,透视变换,又称为投影变换,主要是用来描述物体或者图像从一个平面投影到另外一个平面的情况,我们看前面的几种基础变换以及仿射变换,可以发现,无论上面的参数怎么变化,图像都是在同一个平面里,如果想将图像变换到另外一个平面,上面介绍的几种变换是无法做到的。透视变换用来描述透视投影,主要用来描述小孔成像原理。在透视图像中,平行线不再是平行的了,而是会在无穷远处相交于一点。在齐次坐标系中,投影前后的点满足如下关系:
[ x ′ y ′ w ′ ] = [ a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 a 9 ] [ x y w ] \begin{bmatrix} x' \\ y' \\ w' \end{bmatrix} = \begin{bmatrix} a_1 & a_2 & a_3 \\ a_4 & a_5 & a_6 \\ a_7 & a_8 & a_9 \end{bmatrix} \begin{bmatrix} x \\ y \\ w \end{bmatrix} ⎣⎡x′y′w′⎦⎤=⎣⎡a1a4a7a2a5a8a3a6a9⎦⎤⎣⎡xyw⎦⎤
令: $ u = x/w, v=y/w$,上式可以表示成:
[ x ′ y ′ w ′ ] = w [ a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 a 9 ] [ u v 1 ] \begin{bmatrix} x' \\ y' \\ w' \end{bmatrix} = w \begin{bmatrix} a_1 & a_2 & a_3 \\ a_4 & a_5 & a_6 \\ a_7 & a_8 & a_9 \end{bmatrix} \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} ⎣⎡x′y′w′⎦⎤=w⎣⎡a1a4a7a2a5a8a3a6a9⎦⎤⎣⎡uv1⎦⎤
同理,令: $ u’ = x’/w’, v’=y’/w’ $,上式可以表示成:
w ′ [ u ′ v ′ 1 ] = w [ a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 a 9 ] [ u v 1 ] w' \begin{bmatrix} u' \\ v' \\ 1 \end{bmatrix} = w \begin{bmatrix} a_1 & a_2 & a_3 \\ a_4 & a_5 & a_6 \\ a_7 & a_8 & a_9 \end{bmatrix} \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} w′⎣⎡u′v′1⎦⎤=w⎣⎡a1a4a7a2a5a8a3a6a9⎦⎤⎣⎡uv1⎦⎤
将右边的 w w w 移到左边,令 k = w ′ / w k = w'/w k=w′/w,可以得到:
k [ u ′ v ′ 1 ] = [ a 1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 a 9 ] [ u v 1 ] k \begin{bmatrix} u' \\ v' \\ 1 \end{bmatrix} = \begin{bmatrix} a_1 & a_2 & a_3 \\ a_4 & a_5 & a_6 \\ a_7 & a_8 & a_9 \end{bmatrix} \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} k⎣⎡u′v′1⎦⎤=⎣⎡a1a4a7a2a5a8a3a6a9⎦⎤⎣⎡uv1⎦⎤
将尺度因子 k k k 忽略掉,可以得到如下的两个式子:
u
′
=
a
1
u
+
a
2
v
+
a
3
a
7
u
+
a
8
v
+
a
9
u' = \frac{a_1 u + a_2 v + a_3}{a_7 u + a_8 v + a_9}
u′=a7u+a8v+a9a1u+a2v+a3
v
′
=
a
4
u
+
a
5
v
+
a
6
a
7
u
+
a
8
v
+
a
9
v' = \frac{a_4 u + a_5 v + a_6}{a_7 u + a_8 v + a_9}
v′=a7u+a8v+a9a4u+a5v+a6
透视变换满足如下的性质:
- 直线变换之后依然是直线
- 平行线变换之后不再是平行线
- 线段之间的比例关系也不再保持
u , v u, v u,v 是变换前的坐标系, u ′ , v ′ u', v' u′,v′ 是变换后的坐标,上面的式子看起来有 9 个变量,其实可以将 a 9 a_9 a9 消掉,所以最后有 8 个变量,换句话说,透视变换需要 8 个参数确定,也就是有 8 个自由度。为了确定这 8 个变量,需要 4 对坐标点。将上面的矩阵经过简单的组合,可以写成如下的形式:
[ u ′ v ′ 1 ] = [ T 1 2 × 2 T 2 2 × 1 T 3 1 × 2 a 9 ] [ u v 1 ] \begin{bmatrix} u' \\ v' \\ 1 \end{bmatrix} = \begin{bmatrix} T_{1}^{2 \times 2} & T_{2}^{2 \times 1} \\ T_{3}^{1 \times 2} & a_9 \end{bmatrix} \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} ⎣⎡u′v′1⎦⎤=[T12×2T31×2T22×1a9]⎣⎡uv1⎦⎤
可以看到,前面两行就类似仿射变换,最后一行可以看成是投影约束。
参考
CMU 计算摄影课
http://graphics.cs.cmu.edu/courses/15-463/