2D图形变换原理浅析

来源:互联网 发布:淘宝天猫店铺怎么申请 编辑:程序博客网 时间:2024/05/18 14:14

转载请注明出处:http://blog.csdn.net/hjf_huangjinfu/article/details/77640727


        本文简述一下2D图形变换的概念和原理。


基础概念

矩阵乘法

m行n列的矩阵,表示为m*n,如果2个矩阵相乘,矩阵A[m1*n1]和矩阵B[m2*n2]相乘,必须满足条件n1==m2,相乘的结果矩阵为C[m1*n2]。

参考链接:https://baike.baidu.com/item/%E7%9F%A9%E9%98%B5%E4%B9%98%E6%B3%95/5446029?fr=aladdin


齐次坐标

简单来说就是使用n+1维的向量,表示n维空间的点。比如,使用(2,3,1)来表示(2/1,3/1)=(2,3),用(4,6,2)来表示(4/2,6/2)=(2,3)。

参考链接:https://baike.baidu.com/item/%E9%BD%90%E6%AC%A1%E5%9D%90%E6%A0%87/511284?fr=aladdin



备注:

使用下文使用二维数组代表矩阵,比如 [[a,b], [c,d]] =



1、组合变换

假如有一个图像,需要进行一系列变换(先不管具体的变换),比如变换A(平移)、B(缩放)、C(旋转),那么可以把这3个变换组合成一个组合变换,变换矩阵为ABC。

改变换可以同时让图像进行 平移、缩放和旋转的变换。



2、平移

概念

所谓平移,就是图形整体移动,微观上看每一个点的话,有如下的变化:



推导变换矩阵

[x, y] ->[x+c0, y+c1],c0和c1是不变的常量。


如果变换矩阵A,是一个2*2矩阵,假设A=[[a,b],[c,d]],那么有:

[x,y]A = [ax+cy, bx+dy]

ax+cy=x+c0,bx+dy=y+c1

又因为cy和bx不是常量,所以A不能满足平移变换。


如果引入齐次坐标,对上述变换做进一步推导,则有

[x, y] -> [x, y, 1]  -> [x+c0, y+c1, 1]  -> [x+0*y+c0, 0*x+y+c1, 1]。

上述变换可以由一个1*3矩阵和3*3矩阵相乘得到,所以:

如果A为[[a, b, c], [d, e, f], [g, h, i]],则有:

ax+dy+h = x+0*y+c0

bx+ey+i = 0*x+y+c1

cx+fy+g=1

所以可以算出A为[[1,0,0], [0,1,0], [c0,c1,1]]



3、缩放

概念

缩放跟平移有点区别,平移是整体移动固定距离,而缩放除了缩放系数之外,还要一个基准点,也就是,基于某个点,缩放多少倍。




上图可以看出,基于不同的基准点缩放,结果会不一样,这样的话,如何统一处理所有缩放,就是一个问题。

幸运的是,我们可以先对它做平移的预处理,然后做缩放变换,最后再还原之前的位置,也就是入下图所示:





推导变换矩阵

如果基准点为[0, 0](坐标系原点),缩放系数为2,那么有如下变换结果

[x, y] ->[s*x, s* y],s为缩放系数。


如果变换矩阵A,是一个2*2矩阵,假设A=[[a,b],[c,d]],那么有:

[x,y]A = [ax+cy, bx+dy]

ax+cy=s*x,bx+dy=s*y

所以可以算出,A为[[s,0], [0,s]]



又因为平移变换矩阵是3*3矩阵,而缩放矩阵是2*2矩阵,所以再次使用齐次坐标,把缩放矩阵变为A1=[[s,0,0], [0,s,0], [0,0,1]]

如果基准点是[px, py],平移基准点到坐标系原点的矩阵为A2=[[1,0,0], [0,1,0],[ -px,-py,1]]

缩放后还原到原来位置的矩阵为A3=[[1,0,0], [0,1,0], [px,py,1]]

那么整个流程的变换矩阵为A2A1A3=[[s,0,0], [0,s,0], [(1-s)*px, (1-s)*py, 1]]





4、旋转

概念

旋转跟缩放有点类似,都需要一个基准点。所以处理方法一样,都是先平移基准点到原点,然后做旋转,最后再还原。



绕基准点逆时针旋转a度,称为旋转a度。


推导变换矩阵

如果基准点为[0, 0](坐标系原点),初始角度为B,旋转角度为A,那么有如下变换结果

首先点[x,y] = [r*cosB, r*sinB],r为点[x,y]到基准点距离。

则有,[r*cosB, r*sinB] -> [r*cos(A+B), r*sin(A+B)] -> [r*(cosA*cosB-sinA*sinB), r*(sinA*cosB+cosA*sinB)]。另r=1,则有

变换矩阵M=[[a,b], [c,d]],

[cosB, sinB]M = [cosA*cosB-sinA*sinB, sinA*cosB+cosA*sinB]

所以有:

a*cosB+c*sinB = cosA*cosB-sinA*sinB

b*cosB+d*sinB = sinA*cosB+cosA*sinB

所以可以算出M=[[cosA, sinA], [-sinA,cosA]],结合齐次坐标,转换M为3*3矩阵后,M=[[cosA,sinA,0], [-sinA,cosA,0], [0,0,1]]


如果基准点为[px, py],再结合前后的平移变换(参考缩放变换),可以计算出,整体得变换矩阵为

[[cosA, sinA,0], [-sinA,cosA,0], [(1-cosA)*px+sinA*py, (1-cosA)*py-sinA*px, 1]]





5、扭曲

概念

扭曲就是x和y坐标分别进行不同程度的变换,如下图所示:





推导变换矩阵

x不变,y随着x变:

[x, y] -> [x, y + s*x],s为扭曲率。

假设变换矩阵M=[[a,b], [c,d]],那么

a*x+c*y = x

b*x+d*y = s*x + y

所以可以计算出M为[[1,s], [0,1]],转换为齐次坐标后,M=[[1,s,0], [0,1,0], [0,0,1]]


y不变,x随着y变:

[x, y] -> [x + s*y, y],s为扭曲率。

假设变换矩阵M=[[a,b], [c,d]],那么

a*x+c*y = x + s*y

b*x+d*y = y

所以可以计算出M为[[1,0], [s,1]],转换为齐次坐标后,M=[[1,0,0], [s,1,0], [0,0,1]]


综上所述,如果sx表示x随着y的变化率,sy表示y随着x的变化率,则有M=[[1,sy,0], [sx,1,0], [0,0,1]]







原创粉丝点击