图像旋转

    xiaoxiao2022-06-28  24

    图像的旋转

    1.  基本概念

    1.1 基本公式

    从图中我们可以得到如下关系:

    r = (X – X0)/cos(α) = (Y0-Y)/sin(α)

    Xn   = r*cos(θ + α) + X0                    

             =r*cos(θ)*cos(α) – r*sin(θ)*sin(α) + X0

             =((X – X0)/cos(α)) * cos(θ)*cos(α) – ((Y0-Y)/sin(α)) * sin(θ)*sin(α) + X0

             = (X – X0) * cos(θ) + (Y – Y0) * sin(θ)+ X0

    Yn   = -r*sin(θ + α) + Y0

             =-r*sin(θ) * cos(α) – r*cos(θ)*sin(α) + Y0

             = -(X-X0)sin(θ) + (Y-Y0)*cos(θ) + Y0

    整理得到公式1

    Xn  = (X – X0) * cos(θ) + (Y – Y0) * sin(θ) + X0

    Yn  = -(X-X0)*sin(θ) + (Y-Y0)*cos(θ) + Y0

    反过来可得公式2

    X    = (Xn – X0) * cos(θ) - (Yn – Y0) * sin(θ) + X0

    Y     = (Xn-X0) * sin(θ) + (Yn-Y0) * cos(θ) + Y0

    由此得到旋转前后像素的坐标关系。可通过公式1来计算任意一个旋转前的像素在旋转后的图像中的坐标位置;利用公式2计算任意一个旋转后的像素在旋转前的图像中的坐标位置。

    其中:θ,逆时针方向旋转角度

             (X0,Y0)旋转中心

             (X,Y)为像素在旋转前的坐标

             (Xn,Yn)为旋转后该像素的坐标

    按照基本公式来旋转,计算量巨大。

    1.2 基于刚体旋转而得到的快速算法

    为了提高旋转的运算速度,基于旋转图像是刚体运动的特点,可简化运算量。

    我们考察图3,试图用A’, QL’,QR’来表示Q’。显然两个红三角形是全等的。

    因此有公式4

             Xn = XR’ + (XL’ – XA’)

             Yn = YR’ + (YL’ – YA’)

    公式4说明,利用某一行和某一列的旋转坐标就可以计算所有像素的旋转后坐标,一般我们选AB图像的第一行,AC为图像的第一列。

    例如,如果一个图像的大小是1080p(水平1920,垂直1080),图像的左上角为坐标原点,逆时针旋转θ角。

    我们可以用公式四公式一计算原始图像坐标(X,Y)的像素旋转后的新坐标(Xn,Yn)。

    1)        按照公式一计算出:

    a)        原始图像第一行X, (0…1919), Y=0,对应的旋转后坐标XR’(即:Xn): H(X,0)= { H(0,0)…H(1919,0) }YR’(即:Yn): V(X,0)= { V(0,0)…V(1919,0) }

    b)        原始图像第一列X= 0Y:0…1079)对应的旋转后坐标XL’(即:Xn) : H(0,Y) = { H(0,0)…H(0,1079) }YL’(即:Yn): V(0,Y) = { V(0,0)…V(0,1079) }

    c)        XA’ = H(0,0)YA’ = V(0,0)

    2)        按照公式4,原始图像的任意一点(XY),旋转后的坐标为:

    a)        Xn = H(X,0) + ( H(0,Y) – H(0,0))

    b)        Yn = V(X,0) + ( V(0,Y) – V(0,0))

    我们可以用公式四公式二计算旋转后图像任意一个像素(Xn,Yn)在原始图像中的坐标(X,Y)。

    3)        按照公式二计算出:

    a)        旋转后图像第一行Xn, (0…1919), Yn=0,对应的在原始图像中的坐标XR’(即:X): H(Xn,0) = { H(0,0)…H(1919,0) }YR’(即:Y): V(Xn,0)= { V(0,0)…V(1919,0) }

    b)        旋转后图像第一列Xn= 0Yn:0…1079)对应在原始图像中的坐标XL’(即:X) : H(0,Yn) = { H(0,0)…H(0,1079) }YL’(即:Y): V(0,Yn)= { V(0,0)…V(0,1079) }

    c)        XA’ = H(0,0)YA’ = V(0,0)

    4)        按照公式4,旋转后图像任意一点(XnYn),在原始图像中的坐标为:

    a)        X = H(Xn,0) + ( H(0,Yn) – H(0,0))

    b)        Y = V(Xn,0) + ( V(0,Yn) –V(0,0) )

     

    显然,我们只需计算第一行和第一列的对应关系就可以。通过简单的计算来获得任意像素的对应关系。从而提高的运算效率。

     

    1.3    三步法

    如果旋转中心为坐标原点,及X0=Y0=0,则公式二简化为:

    Xn = X * cos(θ) - Y *sin(θ)

    Yn= X * sin(θ) + Y*cos(θ)

    写成矩阵形式,即公式五:

                        

                                 

    注意一个三角函数公式:   tan(θ)= (1 - cos(θ))/sin(θ) = sin(θ)/(1+cos(θ))。将这个代入上式即可验证这个关系。

    由公式五,我们可以把一次旋转看作通过三次错切变换来完成。也即三步法。

                                          fig4: rotating 90deg, 30deg

    1.4 一些特殊角度的旋转

    2.  关于算法的实现问题

    4

    2.1 近邻法与双线性插值法

    将一个图像顺时针旋转一个角度,如图4所示。红色为显示屏幕点阵。黑色为原始图像经过顺时针旋转一个角度的图像。其对应关系由公式12给出。

    显然公式12的计算结果是分数坐标,这在图4中也可以看出,如旋转后的像素(红1),在原始图像中不是一个整数坐标,而是一个分数坐标,那么(红1)像素值如何得到呢?

    近邻法:取距离最近的原始图像中的像素值,及黑1像素值。

    双线性法:由相邻的4个像素(黑0156)插值而来。计算方法如图5

    5

     

    第一步在x方向上插值,得f(x,0)f(x,1):

             f(x,0) = (1-x)*f(0,0) + x*f(1,0)

             f(x,1) = (1-x)*f(0,1) + x*f(1,1)

    第二步在y方向上插值,得到结果f(x,y):

             f(x,y) = (1-y)*f(x,0) + y*f(x,1)

     

    转载请注明原文地址: https://ju.6miu.com/read-1124530.html

    最新回复(0)