• 图像处理:坐标变换


            在计算机图像学中常常涉及到对图像的进行各种变换,包括平移、旋转、缩放、剪切等操作,它们被称为坐标变换或仿射变换。本篇文章将由浅到深,详细地讨论关于图像坐标变换的原理。

    1、二维坐标变换

            在本篇文章中,我们重点来讨论二维图像和三维图像的坐标变换。为了更好去理解三维坐标变换,我们先讨论二维坐标变换。

    1.1、二维平移(Translation)

            在图(1)中,把 P P P点分别向 x x x y y y方向平移 t x t_x tx t y t_y ty个单位:

    image-20220805092519563
    图1:点P经过平移后得到点P'

            点 P P P经过上述的平移之后,得到 P ′ P' P
    P ′ = p + t = ( x + t x , y + t y ) . (1) P'=p+t=(x+t_x,y+t_y).\tag{1} P=p+t=(x+tx,y+ty).(1)
            如果我们将点 P ′ P' P的坐标用矩阵的方式来表示,则可以得到:
    P ′ = [ x + t x y + t y ] (2) P'=

    [x+txy+ty]" role="presentation" style="position: relative;">[x+txy+ty]
    \tag{2} P=[x+txy+ty](2)

            我们是否可以将式子(2)拆开成为原坐标向量和平移变换矩阵的乘法?然而,根据线性代数的基础知识可知,无法将(2)进行拆分。(读者可以动手试一试,看能不能拆开。至于为什么要拆开,我们将在后面讨论)

            为了将式子(2)拆开,我们就必须引入齐次坐标。齐次坐标无非就是将二维的矩阵变为三维,并在第三维用数字1来填充:

    P ′ = [ x + t x y + t y 1 ] (3) P'=

    [x+txy+ty1]" role="presentation" style="position: relative;">[x+txy+ty1]
    \tag{3} P= x+txy+ty1 (3)

            此时我们就可以拆开式子(3)用矩阵和向量的乘法来表示:

    P ′ = [ x + t x y + t y 1 ] = [ 1 0 t x 0 1 t y 0 0 1 ] ⋅ [ x y 1 ] (4) P'=

    [x+txy+ty1]" role="presentation" style="position: relative;">[x+txy+ty1]
    =
    [10tx01ty001]" role="presentation" style="position: relative;">[10tx01ty001]
    ·
    [xy1]" role="presentation" style="position: relative;">[xy1]
    \tag{4} P= x+txy+ty1 = 100010txty1 xy1 (4)

            为了更加简便,我们将(4)继续化简:

    = [ I t 0 1 ] ⋅ [ x y 1 ] (5) =

    [It01]" role="presentation" style="position: relative;">[It01]
    ·
    [xy1]" role="presentation" style="position: relative;">[xy1]
    \tag{5} =[I0t1] xy1 (5)
            其中 I I I为单位矩阵, t t t为平移的向量 [ t x , t y ] T [t_x,t_y]^T [tx,ty]T。任意一点坐标 [ x , y , 1 ] T [x,y,1]^T [x,y,1]T左乘平移矩阵就可以得到平移后的位置 P ′ P' P

    1.2、二维缩放(Scale)

            在图(2)中,我们沿 P P P点的 x , y x,y x,y轴分别缩放 S x 、 S y S_x、S_y SxSy倍:

    image-20220805092557806
    图2:对P点进行缩放

            在图(2)中,我们为了与平移的矩阵形式统一也采用了齐次坐标,则 P ′ P' P坐标的向量形式:

    p ′ → [ S x x S y y 1 ] (6) p'\to

    [SxxSyy1]" role="presentation" style="position: relative;">[SxxSyy1]
    \tag{6} p SxxSyy1 (6)

            将(6)拆分为坐标向量和缩放矩阵的乘法:

    = [ S x 0 0 0 S y 0 0 0 1 ] ⋅ [ x y 1 ] = [ S ′ 0 0 1 ] ⋅ [ x y 1 ]   = S ⋅ [ x y 1 ] . (7) =

    [Sx000Sy0001]" role="presentation" style="position: relative;">[Sx000Sy0001]
    ·
    [xy1]" role="presentation" style="position: relative;">[xy1]
    \\ =
    [S001]" role="presentation" style="position: relative;">[S001]
    ·
    [xy1]" role="presentation" style="position: relative;">[xy1]
    \quad\quad\, \\= S·
    [xy1]" role="presentation" style="position: relative;">[xy1]
    \quad\quad\quad\quad\quad .\tag{7} = Sx000Sy0001 xy1 =[S001] xy1 =S xy1 .(7)

            其中 S S S为缩放矩阵, P P P点的位置向量左乘缩放矩阵 S S S便可得到缩放后的点 P ′ P' P

    1.3、三维旋转(Rotation)

            如图(3)所示,我们将 O P OP OP向量旋转 β \beta β角度到 O P ′ OP' OP

    img
    图3:P点旋转至点P’

            根据三角函数关系以及极坐标系的机制,我们可以将 P P P P ′ P' P表示为:
    P ( x , y ) = { x = r ⋅ c o s α y = r ⋅ s i n α P ′ ( x ′ , y ′ ) = { x ′ = r ⋅ c o s ( α + β ) y ′ = r ⋅ s i n ( α + β ) (8) P(x,y)=

    {x=r·cosαy=r·sinα" role="presentation" style="position: relative;">{x=r·cosαy=r·sinα
    \\ \\ P'(x',y')=
    {x=r·cos(α+β)y=r·sin(α+β)" role="presentation" style="position: relative;">{x=r·cos(α+β)y=r·sin(α+β)
    \tag{8} P(x,y)={x=rcosαy=rsinαP(x,y)={x=rcos(α+β)y=rsin(α+β)(8)

            在(8)中, r r r就是向量 ∣ O P ∣ |OP| OP的长度。

            我们将式子(8)的 P ′ ( x ′ , y ′ ) P'(x',y') P(x,y)展开:

    { x ′ = r ⋅ c o s α   c o s β − r ⋅ s i n α   s i n β = x c o s β − y s i n β y ′ = r ⋅ s i n α   c o s β + r ⋅ c o s α   s i n β = x s i n β + y c o s β (9)

    {x=r·cosαcosβr·sinαsinβ=xcosβysinβy=r·sinαcosβ+r·cosαsinβ=xsinβ+ycosβ" role="presentation" style="position: relative;">{x=r·cosαcosβr·sinαsinβ=xcosβysinβy=r·sinαcosβ+r·cosαsinβ=xsinβ+ycosβ
    \tag{9} {x=rcosαcosβrsinαsinβ=xcosβysinβy=rsinαcosβ+rcosαsinβ=xsinβ+ycosβ(9)

            将上述表达式用矩阵来表示:

    [ x ′ y ′ 1 ] = [ c o s β − s i n β 0 s i n c o s β 0 0 0 1 ] ⋅ [ x y 1 ] (10)

    [xy1]" role="presentation" style="position: relative;">[xy1]
    =
    [cosβsinβ0sincosβ0001]" role="presentation" style="position: relative;">[cosβsinβ0sincosβ0001]
    ·
    [xy1]" role="presentation" style="position: relative;">[xy1]
    \tag{10} xy1 = cosβsin0sinβcosβ0001 xy1 (10)

            这就是二维旋转的基本形式,中间的矩阵即二维旋转的旋转矩阵,坐标向量左乘该矩阵后,即得到这个向量旋转 β \beta β角度后的新坐标。

            读者可能会注意到,上述的旋转只是二维坐标围绕着坐标原点进行旋转,那关于任意点旋转应该如何表示?其实关于任意点的旋转操作可以拆分为以下步骤:①将旋转点移动到坐标原点;②按绕原点的旋转规律进行旋转;③再将旋转点移回原处。

    img
    图4:任意点的二维旋转可拆分为平移+旋转

    2、三维坐标变换

    2.1、三维平移(Translation)

            图(5)中,点 P P P x 、 y 、 z x、y、z xyz三个方向分别平移 T x 、 T y 、 T z T_x、T_y、T_z TxTyTz个单位:

    image-20220805092644806
    图5:点P的三维平移操作

            点 P P P的平移向量为:
    T ′ = [ T x T y T z ] (11) T'=

    [TxTyTz]" role="presentation" style="position: relative;">[TxTyTz]
    \tag{11} T= TxTyTz (11)
            为了拆分平移操作为向量和矩阵的乘法,我们仍然引入了齐次坐标。那么 P ′ P' P可表示为:

    P ′ → [ I T ′ 0 1 ] 4 × 4 ⋅ [ x y z 1 ] →   T ⋅ [ x y z 1 ] (12) P'\to

    [IT01]" role="presentation" style="position: relative;">[IT01]
    _{4×4} ·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    \to\,T·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    \tag{12} P[I0T1]4×4 xyz1 T xyz1 (12)

            (12)便是三维坐标的平移操作,其中 T T T为平移矩阵。

    2.2、三维缩放(Scale)

            三维坐标的缩放与二维类似,当点 P P P x 、 y 、 z x、y、z xyz三个方向分别缩放 S x 、 S y 、 S z S_x、S_y、S_z SxSySz倍时, P ′ P' P坐标的向量形式为:

    P ′ → [ S x x S y y S z z 1 ] (13) P'\to

    [SxxSyySzz1]" role="presentation" style="position: relative;">[SxxSyySzz1]
    \tag{13} P SxxSyySzz1 (13)

            将(12)进行拆分:

    = [ S x 0 0 0 0 S y 0 0 0 0 S z 0 0 0 0 1 ] ⋅ [ x y z 1 ] = [ S ′ 0 0 1 ] ⋅ [ x y z 1 ]   = S ⋅ [ x y z 1 ]   (14) =

    [Sx0000Sy0000Sz00001]" role="presentation" style="position: relative;">[Sx0000Sy0000Sz00001]
    ·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    \\ =
    [S001]" role="presentation" style="position: relative;">[S001]
    ·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    \quad\quad\quad\quad\, \\= S·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    \quad\quad\quad\quad\quad\quad\quad\, \tag{14} = Sx0000Sy0000Sz00001 xyz1 =[S001] xyz1 =S xyz1 (14)

            (14)中的 S S S就是缩放矩阵,任意三维坐标左乘 S S S就可以得到缩放之后的新坐标 P ’ P’ P

    2.3、三维旋转(Rotation)

            在三维旋转中,我们遵守右手准则,即 x x x指向右方, y y y指向上方, z z z指向前方,如图(6)所示:

    img
    图6:右手坐标系

            三维旋转可借助二维旋转来理解,由于三维空间中可以任意轴旋转,为方便分析与使用,在本节我们考虑绕X、Y、Z轴的旋转。

    2.3.1、绕X轴旋转

            绕 X X X轴旋转,则把图(6)中的整个坐标系向右旋转,让 X X X轴指向前方。绕 X X X轴旋转,则不用考虑 X X X轴的坐标变化,三维坐标变为了二维坐标, Y O Z YOZ YOZ就构成了一个二维平面( O O O为坐标原点):

    img
    图7:绕X轴旋转的右手坐标系

            根据图(7)可知, Y Y Y轴就是原来的 X X X轴, Z Z Z轴也就是原来的 Y Y Y轴,因此根据二维坐标的旋转可得:
    P ( x , y , z ) = { x = x y = r ⋅ c o s α z = r ⋅ s i n α P ′ ( x ′ , y ′ , z ′ ) = { x ′ = x y ′ = r ⋅ c o s ( α + β ) = r c o s α   c o s β − r s i n α   s i n β z ′ = r ⋅ s i n ( α + β ) = r s i n α   c o s β + r c o s α   s i n β (15) P(x,y,z)=

    {x=xy=r·cosαz=r·sinα" role="presentation" style="position: relative;">{x=xy=r·cosαz=r·sinα
    \\ \\ P'(x',y',z')=
    {x=xy=r·cos(α+β)=rcosαcosβrsinαsinβz=r·sin(α+β)=rsinαcosβ+rcosαsinβ" role="presentation" style="position: relative;">{x=xy=r·cos(α+β)=rcosαcosβrsinαsinβz=r·sin(α+β)=rsinαcosβ+rcosαsinβ
    \tag{15} P(x,y,z)= x=xy=rcosαz=rsinαP(x,y,z)= x=xy=rcos(α+β)=rcosαcosβrsinαsinβz=rsin(α+β)=rsinαcosβ+rcosαsinβ(15)
            (15)的矩阵形式:

    [ x ′ y ′ z ′ 1 ] = [ 1 0 0 0 0 c o s β − s i n β 0 0 s i n β c o s β 0 0 0 0 1 ] ⋅ [ x y z 1 ] = R ⋅ [ x y z 1 ] (16)

    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    =
    [10000cosβsinβ00sinβcosβ00001]" role="presentation" style="position: relative;">[10000cosβsinβ00sinβcosβ00001]
    ·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    =R·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    \tag{16} xyz1 = 10000cosβsinβ00sinβcosβ00001 xyz1 =R xyz1 (16)

            注意:为了与平移的矩阵形式相同,旋转矩阵也采用了齐次坐标。

    2.3.2、绕Y轴旋转

            绕 Y Y Y轴旋转,则把图(6)中的整个坐标系向左旋转,让 Y Y Y轴指向前方。绕 Y Y Y轴旋转,则不用考虑 Y Y Y轴的坐标变化,三维坐标变为了二维坐标, Z O X ZOX ZOX就构成了一个二维平面( O O O为坐标原点):

    img
    图8:绕Y轴旋转的右手坐标系

            根据图(8)可知, Z Z Z轴就是原来的 X X X轴, X X X轴也就是原来的 Y Y Y轴,因此根据二维坐标的旋转可得:

    P ( x , y , z ) = { x = r ⋅ s i n α y = y z = r ⋅ c o s α P ′ ( x ′ , y ′ , z ′ ) = { x ′ = r ⋅ s i n ( α + β ) = r s i n α   c o s β + r c o s α   s i n β y ′ = y z ′ = r ⋅ c o s ( α + β ) = r c o s α   c o s β − r s i n α   s i n β = { x ′ = x c o s β + z s i n β y ′ = y z ′ = − x s i n β + z c o s β (17) P(x,y,z)=

    {x=r·sinαy=yz=r·cosα" role="presentation" style="position: relative;">{x=r·sinαy=yz=r·cosα
    \\ \\ P'(x',y',z')=
    {x=r·sin(α+β)=rsinαcosβ+rcosαsinβy=yz=r·cos(α+β)=rcosαcosβrsinαsinβ" role="presentation" style="position: relative;">{x=r·sin(α+β)=rsinαcosβ+rcosαsinβy=yz=r·cos(α+β)=rcosαcosβrsinαsinβ
    \\ \\=
    {x=xcosβ+zsinβy=yz=xsinβ+zcosβ" role="presentation" style="position: relative;">{x=xcosβ+zsinβy=yz=xsinβ+zcosβ
    \tag{17} P(x,y,z)= x=rsinαy=yz=rcosαP(x,y,z)= x=rsin(α+β)=rsinαcosβ+rcosαsinβy=yz=rcos(α+β)=rcosαcosβrsinαsinβ= x=xcosβ+zsinβy=yz=xsinβ+zcosβ(17)

            用矩阵形式来表示式子(16):

    [ x ′ y ′ z ′ 1 ] = [ c o s β 0 s i n β 0 0 1 0 0 − s i n β 0 c o s β 0 0 0 0 1 ] ⋅ [ x y z 1 ] = R ⋅ [ x y z 1 ] (18)

    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    =
    [cosβ0sinβ00100sinβ0cosβ00001]" role="presentation" style="position: relative;">[cosβ0sinβ00100sinβ0cosβ00001]
    ·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    =R·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    \tag{18} xyz1 = cosβ0sinβ00100sinβ0cosβ00001 xyz1 =R xyz1 (18)

    2.3.3、绕Z轴旋转

            绕 Z Z Z轴旋转,则让 Z Z Z轴指向前方。绕 Z Z Z轴旋转,则不用考虑 Z Z Z轴的坐标变化,三维坐标变为了二维坐标, X O Y XOY XOY就构成了一个二维平面( O O O为坐标原点):

    img
    图9:绕Z轴旋转的右手坐标系

            根据图(8)可知,绕 Z Z Z轴旋转,其实就是二维坐标绕原点旋转,因此可推出:

    P ( x , y , z ) = { x = r ⋅ c o s α y = r ⋅ s i n α z = z P ′ ( x ′ , y ′ , z ′ ) = { x ′ = r ⋅ c o s ( α + β ) = r c o s α   c o s β − r s i n α   s i n β y ′ = r ⋅ s i n ( α + β ) = r s i n α   c o s β + r c o s α   s i n β z ′ = z = { x ′ = x c o s β − y s i n β y ′ = = x s i n β + y c o s β z ′ = z (19) P(x,y,z)=

    {x=r·cosαy=r·sinαz=z" role="presentation" style="position: relative;">{x=r·cosαy=r·sinαz=z
    \\ \\ P'(x',y',z')=
    {x=r·cos(α+β)=rcosαcosβrsinαsinβy=r·sin(α+β)=rsinαcosβ+rcosαsinβz=z" role="presentation" style="position: relative;">{x=r·cos(α+β)=rcosαcosβrsinαsinβy=r·sin(α+β)=rsinαcosβ+rcosαsinβz=z
    \\ \\ =
    {x=xcosβysinβy==xsinβ+ycosβz=z" role="presentation" style="position: relative;">{x=xcosβysinβy==xsinβ+ycosβz=z
    \tag{19} P(x,y,z)= x=rcosαy=rsinαz=zP(x,y,z)= x=rcos(α+β)=rcosαcosβrsinαsinβy=rsin(α+β)=rsinαcosβ+rcosαsinβz=z= x=xcosβysinβy==xsinβ+ycosβz=z(19)

            (19)用矩阵表示:

    [ x ′ y ′ z ′ 1 ] = [ c o s β − s i n β 0 0 s i n β c o s β 0 0 0 0 1 0 0 0 0 1 ] ⋅ [ x y z 1 ] = R ⋅ [ x y z 1 ] (20)

    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    =
    [cosβsinβ00sinβcosβ0000100001]" role="presentation" style="position: relative;">[cosβsinβ00sinβcosβ0000100001]
    ·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    =R·
    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    \tag{20} xyz1 = cosβsinβ00sinβcosβ0000100001 xyz1 =R xyz1 (20)

    3、注意

    3.1、为什么要用齐次坐标?

            在图像处理中,我们往往不是单一地对某一坐标进行变换操作,而是会对大量的坐标进行一系列的变换操作。如果直接使用表达式的形式来进行变换操作也是可行的,但是这其中涉及大量的计算,而叠加各种变换系数后的表达式将变得十分臃肿且会降低程序的计算效率。

            解决办法就是将各种变换操作用一个单独的矩阵来进行表示,列如:
    R ⋅ S ⋅ T ⋅ [ x y z 1 ] (21) R·S·T·

    [xyz1]" role="presentation" style="position: relative;">[xyz1]
    \tag{21} RST xyz1 (21)
            (21)表示对三维坐标先进行平移,然后缩放,最后再旋转等一系列操作,其中 R R R是旋转矩阵, S S S是缩放矩阵, T T T是平移矩阵。

            采用矩阵形式来表达变换操作有如下好处:①可以更简便地表示变换操作;②矩阵形式非常利于计算机处理,可以加快计算效率。

            正是基于以上的原因,所以我们需要将变换操作都统一用矩阵的形式来表示。

            读者可以发现:无论是二维坐标的平移还是三维坐标的平移都无法直接用矩阵形式来表示,这也是为什么我们要引入齐次坐标的原因。二维坐标通过引入齐次坐标变成三维坐标,从而可以很轻松地使用矩阵形式来表示平移操作;三维坐标则通过引入齐次坐标变为四维坐标,用四维坐标方式来描述三维的平移操作。

    3.2、在三维坐标中,如何用矩阵形式来表示绕X、Y、Z的负方向进行旋转?

            在2.3节中,从 ( α + β ) (\alpha+\beta) (α+β)可以看出,我们只考虑了向正方向进行旋转,想要考虑负方向的旋转则只需要 − β -\beta β即可,可以表示为 ( α − β ) (\alpha-\beta) (αβ),然后再化解表达式,求出沿负方向的变换矩阵。

    4、总结

            我们在讨论二维坐标变换的基本原理之后,将二维坐标变换的理论迁移到三维坐标变换,并深入讨论关于三维坐标变换的基础原理。我们细致地解释了用变换矩阵的形式来代替变换表达式以及引入齐次坐标的原因。在最后,我们探讨了如何用矩阵形式来表示沿坐标轴的负方向进行旋转变换。

    参考资料

    1、2.2 坐标转换基础_哔哩哔哩_bilibili

    2、3维旋转矩阵推导与助记 - 哔哩哔哩 (bilibili.com)

    3、旋转变换(一)旋转矩阵 - 莫水千流 - 博客园 (cnblogs.com)

    4、齐次坐标_子胤的博客-CSDN博客_齐次坐标

  • 相关阅读:
    What Is SSH Protocol ?
    [网络工程师]-防火墙-ACL
    MySQL 的执行原理(一)
    部署若依springboot-vue前后端分离项目(Nginx反向代理 2022)
    Charles
    Linux图形界面与字符界面切换
    C专家编程 第1章 C:穿越时空的迷雾 1.8 ANSI C标准的结构
    Springboot接入ChatGPT
    Windows 程序安装与更新方案: Clowd.Squirrel
    vue-饼形图-详细
  • 原文地址:https://blog.csdn.net/qq_35149975/article/details/126171415