Матрица вращения для 4D Tensor - PullRequest
0 голосов
/ 16 мая 2019

У меня есть тензор с формой 8,24,24,24, который представляет трехмерную вокселизированную картинку с 8 каналами. Теперь я должен повернуть это, чтобы получить все 24 перестановки. Поскольку данные очень большие, я хочу вращаться на лету. Для этого, я думаю, наиболее эффективным способом является умножение на матрицу вращения.

Я должен сказать, что я абсолютно не знаю, кто вычислять тензор, который я могу использовать, чтобы вращать 4D-тензор или лучше изображение каждого канала без цикла for.

Я нашел вращение вектора только в 3D-пространстве или с помощью предопределенной команды. Но кто мне вращать целый тензор?

x = np.arange(27).reshape(3,3,3)
np.rot90(x)

array([[[ 6,  7,  8],
       [15, 16, 17],
       [24, 25, 26]],

      [[ 3,  4,  5],
       [12, 13, 14],
       [21, 22, 23]],

      [[ 0,  1,  2],
       [ 9, 10, 11],
       [18, 19, 20]]])

Я обнаружил, что вращение в 3D - это не что иное, как вращение в 2D с указанной осью. Для этого можно использовать, например, это:

r = [[1,0,0],[0,0,-1],[0,1,0]]
np.matmul(x,r)

array([[[  0,   2,  -1],
       [  3,   5,  -4],
       [  6,   8,  -7]],

      [[  9,  11, -10],
       [ 12,  14, -13],
       [ 15,  17, -16]],

      [[ 18,  20, -19],
       [ 21,  23, -22],
       [ 24,  26, -25]]])

Но результат совершенно другой. Я что-то не так понял?

Кроме того: на самом деле я использую следующее:

def calc_rot(data):
        t1 = []
        n1 = data
        for i in range(4):
            n1 = np.rot90(n1, axes=(2, 1))
            t1.append(n1)
            n2 = np.copy(n1)
            for j in range(3):
                n2 = np.rot90(n2, axes=(3, 2))
                t1.append(n2)
        for k in [0, 2, 4, 6, 8, 10, 12, 14]:
            t1.append(np.rot90(t1[k], axes=(3, 1)))
        return t1

def calc_rot2(data):
        t1 = []
        n1 = data
        for i in range(4):
            n1 = n1.swapaxes(2,1)[:,:,::-1,:]
            t1.append(n1)
            n2 = np.copy(n1)
            for j in range(3):
                n2 = n2.swapaxes(3,2)[:,:,::-1,:]
                t1.append(n2)
        for k in [0, 2, 4, 6, 8, 10, 12, 14]:
            t1.append(t1[k].swapaxes(3,1)[:,:,::-1,:])
        return t1

Оба делают то же самое. Swapaxes кажется немного быстрее. Но я думаю, что в общем случае тензор / матричное умножение должно быть быстрее. Верно?

...