15

I have greyscale images as 2D NumPy arrays. I need to rotate around one point inside them of different float angles. The rotation doesn't need to be in place and I allow interpolation.

I'd like to use NumPy but also allow for step in/out. I tried using PIL Image.rotate(theta) but don't understand how to apply that to my arrays and how to get an array back.

0

3 Answers 3

6

Consider scipy.ndimage.interpolation.shift() and rotate() for interpolated translations and rotations of 2D numpy arrays.

Sign up to request clarification or add additional context in comments.

1 Comment

In SciPy v1.1, I think this is now scipy.ndimage.rotate() rather than scipy.ndimage.interpolation.rotate().
3

The operations are described on Wikipedia's Transformation matrix page. 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 around something other than the origin then shift 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 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.

1 Comment

This would have been the hard way... in case you didn't check cgohlke's solution, I implemented it in 120±13 seconds.
2

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

Output:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.