如何使用旋转矩阵绕中心旋转Numpy 3D数组?
3D Numpy数组绕中心旋转的问题及解决
我有一个shape=(50, 50, 50)的3D numpy数组,希望借助旋转矩阵R绕其中心旋转。尝试使用scipy.ndimage.affine_transform实现,但遇到了异常情况,也欢迎更好的方案。
复现代码
import random import numpy as np import scipy from PIL import Image R = np.array([ [ 0.299297976, -0.817653322, -0.491796468], [-0.425077904, -0.575710904, 0.698473858], [-0.854242060, 0, -0.519875469], ]) print('Is R really orthogonal:', np.allclose(np.dot(R, R.T), np.identity(3))) # True # 初始化随机数据 a = (50 + np.random.rand(50, 50, 50)*200).astype(np.uint8) print(a.shape) # (50, 50, 50) Image.fromarray(a[:, :, 25]).show() b = scipy.ndimage.affine_transform(a, R, offset=0) Image.fromarray(b[:, :, 25]).show() c = scipy.ndimage.affine_transform(a, R, offset=(50, 50, 50)) Image.fromarray(c[:, :, 25]).show()
异常情况
- 偏移设为
0时,数组并未绕中心旋转 - 偏移设为
50时,矩阵操作不仅实现旋转,还伴随扭曲/剪切效果
问题
我忽略了什么?
编辑: 已找到正确解法,以下是适配原3D问题的代码:
import random import numpy as np import scipy from PIL import Image R = np.array([ [ 0.299297976, -0.817653322, -0.491796468, 0.], [-0.425077904, -0.575710904, 0.698473858, 0.], [-0.854242060, 0., -0.519875469, 0.], [ 0., 0., 0., 1.], ]) N = 50 # 平移矩阵:将坐标原点移至数组中心 shift = np.array( [ [1, 0, 0, N / 2], [0, 1, 0, N / 2], [0, 0, 1, N / 2], [0, 0, 0, 1], ] ) # 逆平移矩阵:将原点移回原位置 unshift = np.array( [ [1, 0, 0, -N / 2], [0, 1, 0, -N / 2], [0, 0, 1, -N / 2], [0, 0, 0, 1], ] ) print('Is R orthogonal:', np.allclose(np.dot(R, R.T), np.identity(4))) # True a = (50 + np.random.rand(N, N, N)*200).astype(np.uint8) print(a.shape) # (50, 50, 50) Image.fromarray(a[:, :, N//2]).show() # 组合变换:先平移原点到中心,再旋转,最后移回原点 b = scipy.ndimage.affine_transform(a, shift @ R @ unshift, offset=0) Image.fromarray(b[:, :, N//2]).show()
效果说明
- 原始效果:偏移0时切片内容偏离中心;偏移50时切片出现扭曲
- 修正后效果:切片内容绕中心正常旋转,无扭曲变形
内容的提问来源于stack exchange,提问作者johndodo
相关产品推荐
相关产品推荐

