FJ_*_*asi 4 python numpy image
我有一个形状为(7,4,100,100)的numpy数组,这意味着我有7个深度为4的100x100图像。我想将这些图像旋转90度。我试过了:
rotated= numpy.rot90(array, 1)
Run Code Online (Sandbox Code Playgroud)
但是它将数组的形状更改为(4,7,100,100),这是不希望的。有什么解决办法吗?
一种不使用np.rot90顺时针方向旋转的解决方案是交换最后两个轴,然后翻转最后一个轴 -
img.swapaxes(-2,-1)[...,::-1]
Run Code Online (Sandbox Code Playgroud)
对于逆时针旋转,翻转倒数第二个轴 -
img.swapaxes(-2,-1)[...,::-1,:]
Run Code Online (Sandbox Code Playgroud)
随着np.rot90,逆时针旋转将是 -
np.rot90(img,axes=(-2,-1))
Run Code Online (Sandbox Code Playgroud)
样品运行 -
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]])
Run Code Online (Sandbox Code Playgroud)
运行时测试
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
Run Code Online (Sandbox Code Playgroud)
因此,对于旋转90度数或倍数,numpy.dot或swapping axes基于旋转的旋转在性能方面似乎相当不错,更重要的是不要执行任何会改变值的插值,否则如 Scipy 的基于旋转的函数所做的那样。
您可以使用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)
Run Code Online (Sandbox Code Playgroud)
如果您注意旋转的图像,则会在左侧看到黑色边框,这是因为Scipy使用插值。因此,实际上图像已更改。但是,如果这对您来说是个问题,则有许多选项可以消除黑色边框。
看到这篇文章。