将多维NumPy数组中的图像旋转90度

13

我有一个形状为(7,4,100,100)的numpy数组,这意味着我有7张深度为4的100x100图像。我想将这些图像旋转90度。

我已经尝试过:

rotated= numpy.rot90(array, 1)

但它会改变数组的形状为(4,7,100,100),这并不是所期望的结果。有什么解决方案吗?


抱歉,应该是rot90()函数。我已经编辑了问题。此外,我尝试了numpy.rot90(array,(2,3)),但是它会报错:TypeError: unsupported operand type(s) for %: 'tuple' and 'int'。 - FJ_Abbasi
你已经得到了我纠正、解释和工作的答案,但由于看起来你喜欢给试图帮助你的人投反对票,所以我删除了我的答案。找其他愿意帮助你的人吧!@Divakar,你也能删除你的答案吗? - user2261062
@SembeiNorimaki 不要认为 OP 已经投了反对票。OP 的个人资料显示没有投票记录。 - Divakar
@SembeiNorimaki,老兄,我没有给你的答案投反对票! - FJ_Abbasi
我向那个给我点踩的人要求解释,你说答案并没有回答我的问题。 - user2261062
@SembeiNorimaki 是的,但那不是downvoting的解释,因为我没有这样做 :) 尽管看起来是这样,但我在那时还没有看到你的downvoting评论。 - FJ_Abbasi
3个回答

15

不使用np.rot90进行顺时针旋转的一个解决方案是交换最后两个轴,然后翻转最后一个轴-

img.swapaxes(-2,-1)[...,::-1]

逆时针旋转时,翻转倒数第二个轴 -

img.swapaxes(-2,-1)[...,::-1,:]

使用np.rot90函数进行逆时针旋转,对应的角度为-

np.rot90(img,axes=(-2,-1))

运行示例 -

In [39]: img = np.random.randint(0,255,(7,4,3,5))

In [40]: out_CW = img.swapaxes(-2,-1)[...,::-1] # Clockwise

In [41]: out_CCW = img.swapaxes(-2,-1)[...,::-1,:] # Counter-Clockwise

In [42]: img[0,0,:,:]
Out[42]: 
array([[142, 181, 141,  81,  42],
       [  1, 126, 145, 242, 118],
       [112, 115, 128,   0, 151]])

In [43]: out_CW[0,0,:,:]
Out[43]: 
array([[112,   1, 142],
       [115, 126, 181],
       [128, 145, 141],
       [  0, 242,  81],
       [151, 118,  42]])

In [44]: out_CCW[0,0,:,:]
Out[44]: 
array([[ 42, 118, 151],
       [ 81, 242,   0],
       [141, 145, 128],
       [181, 126, 115],
       [142,   1, 112]])

运行时测试

In [41]: img = np.random.randint(0,255,(800,600))

# @Manel Fornos's Scipy based rotate func
In [42]: %timeit rotate(img, 90)
10 loops, best of 3: 60.8 ms per loop

In [43]: %timeit np.rot90(img,axes=(-2,-1))
100000 loops, best of 3: 4.19 µs per loop

In [44]: %timeit img.swapaxes(-2,-1)[...,::-1,:]
1000000 loops, best of 3: 480 ns per loop

因此,在旋转 90 度或其倍数时,numpy.dot 或基于 swapping axes 的方法在性能方面似乎相当不错,更重要的是,它们不执行任何插值操作,否则会像 Scipy 的旋转函数一样改变值。


1
如何使用swapaxes旋转180度? - FJ_Abbasi
1
@FJ_Abbasi 使用 out = img[...,::-1,::-1] - Divakar

11

另一个选项

你可以使用scipy.ndimage.rotate,我认为它比numpy.rot90更有用。

例如,

from scipy.ndimage import rotate
from scipy.misc import imread, imshow

img = imread('raven.jpg')

rotate_img = rotate(img, 90)

imshow(rotate_img)

输入图像描述 输入图像描述

更新(使用内插法时需小心)

如果你注意到旋转后的图像左侧有黑色边框,这是因为Scipy使用了内插法。所以,实际上图像已经被改变了。然而,如果这对你是个问题,那么有许多选项可以去除黑色边框。

请看这个帖子


谢谢,太棒了!解决了我的问题: rotate_img = rotate(array, 90, axes=(2,3)) - FJ_Abbasi
@FahadJahangir 我很高兴我能帮到你 :) - mforpe
1
@FahadJahangir 注意,这会进行插值。因此,值将被更改,并且左侧会有一条黑线。尝试使用 img = np.random.randint(0,255,(3,5)),然后 rot1 = rotate(img, 90),查看 imgrot1。对于Manel-这可能值得在帖子中提及,以使OP和未来的读者受益。 - Divakar
FYI,对于90/180/270旋转和翻转来说,这需要更多的计算资源。 - VoteCoffee

1

逆时针旋转三次:np.rot90(image, 3)。

如果实现已经优化,并且我们在这里指定的是90度的增量而不是循环计数器,那么它可能会慢三倍,也可能不会。


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