У меня есть тензор с формой 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 кажется немного быстрее. Но я думаю, что в общем случае тензор / матричное умножение должно быть быстрее. Верно?