Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotating images by 90 degrees for a multidimensional NumPy array

I have a numpy array of shape (7,4,100,100) which means that I have 7 images of 100x100 with depth 4. I want to rotate these images at 90 degrees. I have tried:

rotated= numpy.rot90(array, 1)

but it changes the shape of the array to (4,7,100,100) which is not desired. Any solution for that?

like image 419
FJ_Abbasi Avatar asked May 09 '17 08:05

FJ_Abbasi


People also ask

How do I rotate a NumPy array by 90 degrees?

The numpy. rot90() method performs rotation of an array by 90 degrees in the plane specified by axis(0 or 1). Parameters : array : [array_like]i.e. array having two or more dimensions.

How do you rotate an image 90 degrees in Python?

rotate() function is used to rotate an image by an angle in Python.

How do I rotate an image in NumPy?

Rotate image with NumPy: np. The NumPy function that rotates ndarray is np. rot90() . Specify the original ndarray as the first argument and the number of times to rotate 90 degrees as the second argument.

How do I rotate a NumPy 3d array?

Using numpy. rot90() , you can rotate the NumPy array ndarray by 90/180/270 degrees.


2 Answers

One solution without using np.rot90 to rotate in clockwise direction would be to swap the last two axes and then flip the last one -

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

For counter-clockwise rotation, flip the second last axis -

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

With np.rot90, the counter-clockwise rotation would be -

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

Sample run -

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]])

Runtime test

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

Thus, for rotating by 90 degrees or multiples of it, numpy.dot or swapping axes based ones seem pretty good in terms of performance and also more importantly do not perform any interpolation that would change the values otherwise as done by Scipy's rotate based function.

like image 70
Divakar Avatar answered Sep 17 '22 04:09

Divakar


Another option

You could use scipy.ndimage.rotate, i think that it's more useful than numpy.rot90

For example,

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

img = imread('raven.jpg')

rotate_img = rotate(img, 90)

imshow(rotate_img)

enter image description here enter image description here

Updated (Beware with interpolation)

If you pay attention at the rotated image you will observe a black border on the left, this is because Scipy use interpolation. So, actually the image has been changed. However, if that is a problem for you there are many options able to remove the black borders.

See this post.

like image 43
mforezdev Avatar answered Sep 20 '22 04:09

mforezdev