图像仿射变换解析

仿射变换

网上关于仿射变换的文章也有一些,有许多文章只讲解了矩阵中的每个值的作用,而没有解释为什么.所以自己也推导一边,方便写这篇博客,也巩固了一下相关知识.

2d仿射矩阵

让我们来看看定义CGAffineTransform(其他语言同样可以适用)

struct CGAffineTransform {
  CGFloat a, b, c, d;
  CGFloat tx, ty;
};

在这里定义成了结构体,要模拟的其实是3*3的矩阵,我在这里建立,至于为什么结构体里只有6个值,等下便可以明白。
[m11 m12 m13]

[m21 m22 m23]

[m31 m32 m33]

变换过程

            [m11 m12 m13]
[x   y  1]* [m21 m22 m23]  =  [x*m11+y*m21+m31    x*m12+y*m22+m32    x*m13+y*m23+m33]
            [m31 m32 m33]

可以看到已经过变幻之后

x映射到xm11+ym21+m31
y映射到xm12+ym22+m32

移动

令m11=1 m21=0 那么 x映射到 x+m31点 所以m31就是CGAffineTransform中的tx.同理等到m32是ty.

缩放

令m21=0,m31=0 那么x映射到x*m11点 这样便实现了缩放,当m11大于1时为方法,反之缩小.

旋转

旋转相对而言比较复杂一些,需要三角函数的知识.也是很多博客中没有介绍的部分.我们进行一下简单的推倒.
我们对任意的单位向量进行旋转,假设(x1,y1)为旋转前的单位向量.其与x正轴的夹脚为theta.那么该单位向量可以表示为(cos(theta),sin(theta))
我们对其逆时针旋转△theta,那么现在该单位向量可以表示为(cos(theta+△theta),sin(theta+△theta))
运用三角函数可以得到旋转后的向量为(cos(theta)cos(△theta)-sin(theta)sin(△theta),sin(theta)cos(△theta)+cos(theta)sin(△theta))

也就是x1=cos(theta)映射到cos(theta)cos(△theta)-sin(theta)sin(△theta)=x1cos(△theta)-y1sin(△theta);
所以只需要令
m11=cos(△theta),m21=-sin(△theta) ,m31=0
m12 =sin(△theta),m22 = cos(△theta),m32 =0
这样就是旋转

3d变换

3d变换的推倒思路一致,这里不再冗余,不过在3d旋转中要用到欧拉角的概念,我这里直接引用一张图片来表示

这张图表现了3d旋转的矩阵值。如果你把某些值做一个替换,就会发现其退化为2d矩阵。其实就是2d变化是个3d变化的特例。留给读者自己思考

posted @ 2016-05-27 16:02  钱鸿强  阅读(976)  评论(0编辑  收藏  举报