Matplotlib如何将图像文件旋转X度?

11

如何在matplotlib中旋转图像文件并绘制它?

我知道可以使用PIL打开并旋转它,但这似乎对于这个简单的功能来说太过繁琐,我可能找不到。

我在这里找到了这段代码,但似乎无法运行:

from matplotlib import pyplot, image, transforms

img = image.imread('filename.png')

pyplot.ion()
fig = pyplot.figure()
ax = fig.add_subplot(111)

for degree in range(360):
    pyplot.clf()
    tr = transforms.Affine2D().rotate_deg(degree)

    ax.imshow(img, transform=tr)
    fig.canvas.draw()
5个回答

18
似乎自从这个问题被提出以来,matplotlib已经有了进展,并且现在可以本地支持图像的仿射变换,而不需要用户回退到低级别的图像处理例程。
现在以一个示例的形式记录在https://matplotlib.org/gallery/images_contours_and_fields/affine_image.html中。
基本上,这需要指定适当的转换关键字参数。原始问题中提供的代码将更新如下:
import matplotlib.pyplot as plt
from matplotlib import transforms

img = plt.imread('filename.png')

fig = plt.figure()
ax = fig.add_subplot(111)

tr = transforms.Affine2D().rotate_deg(rotation_in_degrees)

ax.imshow(img, transform=tr + ax.transData)
plt.show()

17

您可以使用scipy.ndimage中的rotate函数:

import scipy.misc
from scipy import ndimage
import matplotlib.pyplot as plt

img = scipy.misc.lena()  
# img = scipy.misc.face()  # lena is not included in scipy 0.19.1
plt.figure(figsize=(12, 2))

for degree in range(5):
    plt.subplot(151+degree)
    rotated_img = ndimage.rotate(img, degree*60)
    plt.imshow(rotated_img, cmap=plt.cm.gray)
    plt.axis('off')

plt.show()

这将围绕图像中心进行旋转(请参见文档)。

lena

编辑:

如果您希望进行某种动画(我不知道您将如何使用旋转图像,所以我只能猜测),也许最好使用某种游戏/图形库,例如Pygame。在这里,您可以使用pygame.transform.rotate将图像旋转一定角度(由于基础的SDL支持),并将旋转后的图像贴到屏幕上以获得更好的性能。

尝试这个(使用一张名为lena.jpg的图片),以获得平滑旋转的图像:

import pygame

pygame.init()
screen = pygame.display.set_mode([400, 400])
pygame.display.set_caption('Rotating image example')
clock = pygame.time.Clock()

img = pygame.image.load('lena.jpg').convert()

img_rect = img.get_rect(center = screen.get_rect().center)
degree = 0

while degree < 360:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

    # rotate image
    rot_img = pygame.transform.rotate(img, degree)
    img_rect = rot_img.get_rect(center = img_rect.center)

    # copy image to screen
    screen.fill((0, 0, 0))
    screen.blit(rot_img, img_rect)
    pygame.display.flip()

    clock.tick(60)
    degree += 1

pygame.quit()

这给我在轮廓线上产生了奇怪的线条,我正在使用 alpha png 图像。此外,在循环中处理 360 个值时速度非常慢,需要花费 90 秒。我需要多次旋转这张图片。 - f.rodrigues
你想要制作一个旋转的动画图片吗?从你的问题中,我理解到你想要将其旋转后展示给用户。在这种情况下,Matplotlib可能不是正确的库来实现这个功能,你最好使用Pygame(查看pygame.transform.rotate),它基于SDL,应该在旋转等动画方面提供更好的性能。 - adrianus
我正在制作的程序显示了有关车辆(速度、轨迹等)的一系列信息,这些信息是通过GPS获取的,包括方位角。我想在顶部角落显示一个小汽车图像,就像指南针一样。我考虑使用pygame,但它没有大多数matplotlib处理动态数据的好功能。 - f.rodrigues

4

另一个选择可能是使用numpyrot90函数。思路是将图像转换为numpy数组,然后旋转数组所需的次数。以下是一个例子:

import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
import numpy as np

with cbook.get_sample_data('ada.png') as image_file:
    image = plt.imread(image_file)
image_arr = np.array(image)

#plt.show() To view the image

for _ in range(3):#3 to turn the image 90 degrees three times = 270 degrees
    image_arr = np.rot90(image_arr)

plt.imshow(image_arr, aspect="auto", extent=(-14,-4,-2,40), zorder = 2, interpolation="nearest")

plt.show()

然而,这仅限于将图像旋转90度(90的倍数)。


3
您可以使用我在这里找到的以下代码:

如何通过90度旋转matplotlib图形?

import matplotlib.pyplot as plt
import scipy

img = scipy.misc.lena()
tr = scipy.ndimage.rotate(img, 45)
plt.imshow(tr)

注意:lena()函数已在0.17版本中移除。 - Tommaso Di Noto

2
我觉得下面的解决方案十分直观。它使用Pillow库读取图像,然后使用内置的旋转函数来旋转图像。 图像逆时针旋转并存储在新变量中。 最后,我们可以使用matplotlib创建和显示绘图。
from PIL import Image
import matplotlib.pyplot as plt

im = Image.open(path-to-file)
im = im.rotate(90) # Rotates counter clock-wise.
implot = plt.imshow(im)
plt.show()

你好,欢迎来到SO!虽然这段代码可能回答了问题,但提供关于它如何以及为什么解决问题的额外上下文会提高答案的长期价值。请阅读tour如何撰写优秀答案? - Tomer Shetah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接