Повернуть массив NumPy 2D

У меня есть набор изображений в оттенках серого в виде 2D массивов numpy.

Мне нужно повернуть изображения около одной точки (внутри них) разных, плавающих углов. Вращение не должно быть на месте, и я позволю (конечно, если я хорошо объяснил до сих пор) для интерполяции.

Я хотел бы остаться в numpy, так как мне нужно выполнить численные операции над результатом, но я также могу (если это невозможно) разрешить шаг in / out; например, я попытался использовать PIL, а именно Изображение.поворот (тета), но не понимаю, как применить это к моим массивам и как вернуть массив.

Спасибо за Ваш вклад.

3 ответов


см. комментарий cgohlke Nov 10 ' 11 в 18: 34:

считают scipy.ndimage.интерполяция.shift () и rotate () для интерполированных переводов и вращений 2D массивов numpy.


основные операции описаны в Википедии матрица преобразования страница-я не буду пытаться сделать ascii matrix art здесь, но выход P' = R*P, где P' - выходная точка, R-матрица преобразования 2x2, содержащая синус и косинус угла поворота, а P-входная точка. Если вы хотите вращаться о чем-то, кроме начала координат, то сдвиньте начало координат до вращения: P' = T + R*(P-T), где T-координата перевода. Основной матричные операции не выполняют интерполяцию, поэтому, если вы не используете numpy-based библиотека обработки изображений, вы захотите сделать обратное преобразование: для каждой (целочисленной) выходной координаты найдите (с плавающей точкой) координату точки, которая будет повернута в нее, и интерполируйте значение этой входной точки из окружающих пикселей.


Я хотел бы взять помощь выше и решить это на примере:

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

из которых выход будет похож:

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