美文网首页
图像几何变换之图像旋转(Python实现)

图像几何变换之图像旋转(Python实现)

作者: Youngblaze | 来源:发表于2020-04-27 09:02 被阅读0次

    图像几何变换之图像旋转

    原理

    旋转变化——极坐标表示

    设点P0(x0,y0)旋转θ角后对应点为P(x,y)。

    对于两点坐标可以这样表示:

    x0=R*cosα

    y0=R*sinα

    x=R*cos(α-θ)= x0 *cosθ + y0 *sinθ

    y=R*sin(α-θ)= -x0 *sinθ+ y0 *cosθ
    以矩阵形式表示为:

    1.png
    下面我们来看看更通常一点的做法:以图像的中心为圆心进行旋转。
    这里涉及到一个坐标系的转换问题。如图:
    2.png
    在矩阵中我们的坐标系通常是AD和AB方向的,而传统的笛卡尔直角坐标系是以矩阵中心建立坐标系的。
    令图像表示为M×N的矩阵,对于点A而言,两坐标系中的坐标分别是(0,0)和(-N/2,M/2)
    矩阵中点(x',y')转换为笛卡尔坐标系(x,y)的转换关系为: 3.png
    逆变换:
    4.png
    于是得到图像中心旋转的步骤:
    • 转换为笛卡尔坐标系
    • 将图像上的点旋转α°
    • 将旋转后的点再转换为矩阵坐标
    5.png
    6.png

    代码

    #encoding:UTF-8
    from PIL import Image
    import math
    import matplotlib.pyplot as plt
    
    def rotate(image,degree,crop=False):
        im = Image.open(image)
        radius = math.pi * degree / 180
        width, height = im.size
        if not crop:
            X1 = math.ceil(abs(0.5 * height * math.cos(radius) + 0.5 * width * math.sin(radius)))
            X2 = math.ceil(abs(0.5 * height * math.cos(radius) - 0.5 * width * math.sin(radius)))
            Y1 = math.ceil(abs(-0.5 * height * math.sin(radius) + 0.5 * width * math.cos(radius)))
            Y2 = math.ceil(abs(-0.5 * height * math.sin(radius) - 0.5 * width * math.cos(radius)))
            H = int(2 * max(Y1, Y2))
            W = int(2 * max(X1, X2))
            dstwidth = W + 1
            dstheight = H + 1
        if crop:
            dstheight = height
            dstwidth = width
        im_new = Image.new('RGB', (dstwidth, dstheight), (255, 255, 255))
        for i in range(dstwidth):
            for j in range(dstheight):
                new_i = int(
                    (i - 0.5 * dstwidth) * math.cos(radius) - (j - 0.5 * dstheight) * math.sin(radius) + 0.5 * width)
                new_j = int(
                    (i - 0.5 * dstwidth) * math.sin(radius) + (j - 0.5 * dstheight) * math.cos(radius) + 0.5 * height)
                if new_i >= 0 and new_i < width and new_j >= 0 and new_j < height:
                    im_new.putpixel((i, j), im.getpixel((new_i, new_j)))
        # im_new.show()
        sub = plt.subplot(1, 2, 1)
        sub.set_title("Src Img")
        plt.imshow(im)
        sub = plt.subplot(1, 2, 2)
        sub.set_title("Dst->Src & Nearest")
        plt.imshow(im_new)
        plt.show()
    

    结果图像

    Figure_1.png
    Figure_2.png

    相关文章

      网友评论

          本文标题:图像几何变换之图像旋转(Python实现)

          本文链接:https://www.haomeiwen.com/subject/mevewhtx.html