Rotate numpy 2D array
Solution 1
See the comment of cgohlke Nov 10 '11 at 18:34:
Consider scipy.ndimage.interpolation.shift() and rotate() for interpolated translations and rotations of 2D numpy arrays.
Solution 2
The basic operations are described in the Wikipedia transformation matrix page - I'm not going to try to do ascii matrix art here, but the output P' = R*P where P' is the output point, R is the 2x2 transformation matrix containing sine and cosine of the rotation angle, and P is the input point. If you want to rotate about something other than the origin, then shift the the origin prior to rotation: P' = T + R*(P-T) where T is the translation coordinate. The basic matrix operations don't do interpolation, so if you aren't using a numpy-based image processing library, you'll want to do a reverse transform: for each (integer-valued) output coordinate, find the (floating point) coordinate of the point that would be rotated into it, and interpolate the value of that input point from the surrounding pixels.
Solution 3
I would like take help of above and solve this by an example:
import pandas as pd
import numpy as np
bd = np.matrix([[44., -1., 40., 42., 40., 39., 37., 36., -1.],
[42., -1., 43., 42., 39., 39., 41., 40., 36.],
[37., 37., 37., 35., 38., 37., 37., 33., 34.],
[35., 38., -1., 35., 37., 36., 36., 35., -1.],
[36., 35., 36., 35., 34., 33., 32., 29., 28.],
[38., 37., 35., -1., 30., -1., 29., 30., 32.]])
def rotate45(array):
rot = []
for i in range(len(array)):
rot.append([0] * (len(array)+len(array[0])-1))
for j in range(len(array[i])):
rot[i][int(i + j)] = array[i][j]
return rot
df_bd = pd.DataFrame(data=np.matrix(rotate45(bd.transpose().tolist())))
df_bd = df_bd.transpose()
print df_bd
of which output will be like:
44 0 0 0 0 0 0 0 0
42 -1 0 0 0 0 0 0 0
37 -1 40 0 0 0 0 0 0
35 37 43 42 0 0 0 0 0
36 38 37 42 40 0 0 0 0
38 35 -1 35 39 39 0 0 0
0 37 36 35 38 39 37 0 0
0 0 35 35 37 37 41 36 0
0 0 0 -1 34 36 37 40 -1
0 0 0 0 30 33 36 33 36
0 0 0 0 0 -1 32 35 34
0 0 0 0 0 0 29 29 -1
0 0 0 0 0 0 0 30 28
0 0 0 0 0 0 0 0 32
astabada
My main occupation is to debug cruft I write in my free time. That is, after struggling to stay alive.
Updated on November 13, 2021Comments
-
astabada over 2 years
I have a set of greyscale images as a 2D numpy arrays.
I need to rotate the images about one point (inside them) of different, float angles. The rotation doesn't need to be in place, and I will allow (of course, if I explained well so far) for interpolation.
I'd like to remain in numpy, as I need to perform numerical operations on the result, but I can also (if that's impossible) allow for step in/out; for example I tried using PIL, namely Image.rotate(theta) but don't understand how to apply that to my arrays, and how to get an array back.
Thank you for your input.
-
BlackBear over 12 yearsI changed your 'greyscale' tag to the 'image processing' one. I think it describes better your intentions. Feel free to change it back
-
Josh Bleecher Snyder over 12 yearsYou can do this directly in numpy, but for converting back and forth, see effbot.org/zone/pil-numpy.htm.
-
astabada over 12 yearsThank you for the advice, I just noticed this box!
-
tiago about 7 years@cgohlke your second link has a typo (domain name should be scikit-image.org), as it stands it currently links to a spammer.
-
cgohlke about 7 years
-
-
astabada over 12 yearsThis would have been the hard way... in case you didn't check cgohlke's solution, I implemented it in 120±13 seconds.
-
Nathan almost 6 yearsThanks @Vasco. Are there any functions that preserve the shape while they rotate only the "on" bits?
-
Grayscale almost 6 yearsIn SciPy v1.1, I think this is now scipy.ndimage.rotate() rather than scipy.ndimage.interpolation.rotate().