赞
踩
本文经过参考多个文章整理而成,感谢各位博主的无私分享。
图像(2维平面)到图像(2维平面)的四种变换包括:等距变换,相似变换,仿射变换,投影变换。对图像的几何变换本质上是一种线性变换,其数学本质为 I n e w = T I o l d I_{new}=T{I_{old}} Inew=TIold,即通过变换矩阵 T T T将原图上的点的位置 I o l d I_{old} Iold 变换到新的位置,从而得到新的图像 I n e w I_{new} Inew。
执行一般的二维空间变换包括如下三步:
2D平面变换示意图
eometry Transformation 几何变换
Homogeneous coordinate 齐次坐标:使用N+1维坐标来表示N维坐标,例如在2D笛卡尔坐标系中加上额外变量w来形成2D齐次坐标系。齐次坐标具有规模不变性,同一点可以被无数个齐次坐标表达. 齐次坐标转化为笛卡尔坐标可以通过同除最后一项得到。
仿射变换其实是另外两种简单变换的叠加:一个是线性变换,一个是平移变换。统一平移变换和线性变换的一种变换我们起了个名字叫“仿射变换”。这个新的变换就不再单纯的是两个线性空间的映射了,而是变成了两个仿射空间的映射关系。为了更好地理解仿射变换,首先就要知道线性变换以及它的不足。在未说明的情况下,下面使用的是卡迪尔坐标系。
所谓线性变换是指两个线性空间的映射,一个变换
L
:
A
→
B
{\mathcal{L}:\mathcal{A}\to\mathcal{B}}
L:A→B是线性变换,必须满足两个条件,也就是我们经常说的线性条件:
举个例子说明一下。假设
L
L
L是一个二维绕原点旋转变换,
u
u
u和
v
v
v是旋转角度。我们知道“一次性旋转
u
+
v
u+v
u+v度”和“先旋转
u
u
u度再旋转
v
v
v读”达到的效果是一样的;同样地,“一次性旋转
α
u
{\alpha}u
αu度”和“旋转
α
\alpha
α次
u
u
u度”也是一样的。
线性变换可以用矩阵来表示。假设
p
=
(
x
,
y
)
T
p=(x,y)^{T}
p=(x,y)T是二维空间中的点,
T
T
T是一线性变换,那么存在一个矩阵
A
A
A,使得
p
′
=
(
x
′
,
y
′
)
T
=
T
(
p
)
=
A
p
p'=(x',y')^{T}=T(p)=Ap
p′=(x′,y′)T=T(p)=Ap。上面的旋转变换
R
R
R,以及缩放
S
S
S变换都有相应的变换矩阵
[
x
′
y
′
]
=
R
(
p
)
=
[
c
o
s
(
θ
)
−
s
i
n
(
θ
)
s
i
n
(
θ
)
c
o
s
(
θ
)
]
[
x
y
]
\left[ {
[
x
′
y
′
]
=
S
(
p
)
=
[
S
x
0
0
S
y
]
[
x
y
]
\left[ {
但是在笛卡尔坐标系中,平移变换却不能用矩阵来表示。一个平移变换 T T T具有如下的形式
[
x
′
y
′
]
=
T
(
p
)
=
I
[
x
y
]
+
[
t
x
t
y
]
\left[ {
我们可以很容易地验证,平移变换
T
T
T是不能写成两个矩阵乘积形式的。使用齐次坐标系很好的解决了这个问题(可能还有其它的原因)。齐次坐标系统其实是用高维坐标来表示一个低维的点,就好比我们用
(
x
,
1
)
(x,1)
(x,1)来表示一个长度值一样,其实用一个
x
x
x就可以了,但是用高一维的表示,在有的时候会带来便利。一个N维的卡迪尔坐标系中的一个点
p
=
(
x
1
,
x
2
,
.
.
.
,
x
N
)
p=(x_1,x_2,...,x_N)
p=(x1,x2,...,xN),在齐次坐标系中有无数的
N
+
1
N+1
N+1维点与之对应,这些点可以描述为
p
H
=
(
ω
x
1
,
ω
x
2
,
.
.
.
,
ω
x
N
,
ω
)
p_H=(\omega x_1,\omega x_2,...,\omega x_N,\omega)
pH=(ωx1,ωx2,...,ωxN,ω),
ω
\omega
ω取不同的值,我们变得到齐次坐标系中不同的点。当把这些点映射到
ω
=
1
\omega=1
ω=1平面(不改变
x
i
x_i
xi之间比例),我们又降维得到对应的卡迪尔坐标系中的点。在OpenGL中我们是用
(
x
,
y
,
z
,
1
)
(
ω
=
1
)
(x,y,z,1)(\omega=1)
(x,y,z,1)(ω=1)来表示一点三维的点,显然这个点与卡迪尔坐标系中的点
(
x
,
y
,
z
)
(x,y,z)
(x,y,z)是一一对应的。在计算的过程中,会出现第四个分量不为
ω
≠
1
\omega \neq 1
ω=1的情况,这时我们也总是同除以
ω
\omega
ω使齐次坐标正规化。
现在回来让我们看看使用齐次坐标时,对应的线性变换是什么形式。假设
p
=
(
x
,
y
,
1
)
T
p=(x,y,1)^{T}
p=(x,y,1)T是二维点对应的齐次坐标,与上面使用卡迪尔坐标系类似,我们可以得到相应的线性变换如旋转变换
R
R
R和缩放变换
S
S
S的矩阵表示:
[
x
′
y
′
1
]
=
R
(
p
)
=
[
c
o
s
(
θ
)
−
s
i
n
(
θ
)
0
s
i
n
(
θ
)
c
o
s
(
θ
)
0
0
0
1
]
[
x
y
1
]
\left[ {
[
x
′
y
′
1
]
=
S
(
p
)
=
[
S
x
0
0
0
S
y
0
0
0
1
]
[
x
y
1
]
\left[ {
容易验证, ( x ′ , y ′ ) (x', y') (x′,y′)的值并没有变化。但是使用齐次坐标后,平移操作便也可以使用矩阵来表示了(如下),平移量出现在变换矩阵的最右侧。
[
x
′
y
′
1
]
=
T
(
p
)
=
[
1
0
t
x
0
1
t
y
0
0
1
]
[
x
y
1
]
\left[ {
最后,我们给出仿射变换稍微正式点的定义。一个仿射变换 T T T,可以表示成一个线性变换 A A A后平移 t t t: T ( p ) = A p + t T(p)=Ap+t T(p)=Ap+t,其中 p p p是待变换的点齐次坐标表示。 T T T可以表示成如下的形式:
T
=
[
a
11
a
12
a
13
t
1
a
21
a
22
a
23
t
2
a
31
a
32
a
33
t
3
0
0
0
1
]
\bf{T}=\left[ {
其中,
A
=
[
a
11
a
12
a
13
a
21
a
22
a
23
a
31
a
32
a
33
]
\bf{A}=\left[ {
可以知道:仿射变换保持了二维图形的“平直性”和“平行性”。仿射变换可以通过一系列的变换的复合来实现,包括平移,缩放,翻转,旋转和剪切。
opencv中相应的函数是:
void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
Parameters:
可以使用opencv中自带的Mat getRotationMatrix2D(Point2f center, double angle, double scale)
函数获得变换矩阵M,
它得到的矩阵是:
(顺时针)
(逆时针)
其中 α = s c a l e ∗ c o s ( a n g l e ) , β = s c a l e ∗ s i n ( a n g l e ) , ( c e n t e r . x , c e n t e r . y ) α = scale * cos(angle) , β = scale * sin(angle) , (center.x , center.y) α=scale∗cos(angle),β=scale∗sin(angle),(center.x,center.y) 表示旋转轴心。
opencv中还有一个函数:Mat getAffineTransform(InputArray src, InputArray dst)
它通过三组点对就可以获得它们之间的仿射变换,如果我们在一组图像变换中知道变换后的三组点,那么我们就可以利用该函数求得变换矩阵,然后对整张图片进行仿射变换。
仿射变换之所以重要,另一个重要的原因是仿射变换后不改变点的共线/共面性,而且还保持比例,这对图形系统尤其重要。例如,根据这个性质,如果我们要变换一个三角形,只需要对三个定点 v 1 v1 v1, v 2 v2 v2, v 3 v3 v3进行变换T就可以了,对于原先边 v 1 v 2 v1v2 v1v2上的点,变换后一定还在边后 T ( v 1 ) T ( v 2 ) T(v1)T(v2) T(v1)T(v2)上。
总结一下,仿射变换是线性变换后进行平移变换(其实也是齐次空间的线性变换),使用齐次坐标使得仿射变换可以以统一的矩阵形式进行表示。
还有一种与仿射变换经常混淆的变换为透视变换,透视变换需要四组点对才能确定变换矩阵,由于仿射变换保持“平直性”与“平行性”,因此只需要三组点对,而透视变换没有这种约束,故需要四组点对。
透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。通用的变换公式为:
u
u
u,
v
v
v是原始图片左边,对应得到变换后的图片坐标
x
x
x,
y
y
y,其中
。
变换矩阵可以拆成4部分,表示线性变换,比如scaling,shearing和ratotion。用于平移,产生透视变换。所以可以理解成仿射等是透视变换的特殊形式。经过透视变换之后的图片通常不是平行四边形(除非映射视平面和原来平面平行的情况)。
重写之前的变换公式可以得到:
所以,已知变换对应的几个点就可以求取变换公式。反之,特定的变换公式也能新的变换后的图片。简单的看一个正方形到四边形的变换:
变换的4组对应点可以表示成:
根据变换公式得到:
定义几个辅助变量:
都为0时变换平面与原来是平行的,可以得到:
不为0时,得到:
求解出的变换矩阵就可以将一个正方形变换到四边形。反之,四边形变换到正方形也是一样的。于是,我们通过两次变换:四边形变换到正方形+正方形变换到四边形就可以将任意一个四边形变换到另一个四边形。
主要作用:对图像进行透视变换,就是变形。
C++: void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
参数详解:
图像的变换
https://blog.csdn.net/liangjiubujiu/article/details/80424287
仿射变换与齐次坐标
https://blog.csdn.net/liangjiubujiu/article/details/80628506
仿射变换矩阵
https://blog.csdn.net/liangjiubujiu/article/details/80918428
matlab 二维空间变换
https://blog.csdn.net/liangjiubujiu/article/details/80607161
图像投影/单应性变换/直射
https://blog.csdn.net/liangjiubujiu/article/details/80412175
图像的等距变换,相似变换,仿射变换,射影变换及其matlab实现
https://blog.csdn.net/liangjiubujiu/article/details/80616870
仿射变换详解 warpAffine
https://blog.csdn.net/q123456789098/article/details/53330484
写于关雎
新浪微博:https://weibo.com/tianzhejia
CSDN博客:https://blog.csdn.net/qq_35605018
博客网站:http://www.zhijiadeboke.xyz
GitHub:https://github.com/ZhijiaTian
QQ邮箱:2461824656@qq.com
126邮箱:tianzhejia@126.com
Outlook邮箱:tianzhejia@outlook.com
以上均可与本人取得联系,欢迎探讨。^ v ^
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。