如何将Numpy 4x4矩阵转为SimpleITK变换对象以重采样图像?
将4×4 Numpy刚性变换矩阵转换为SimpleITK变换对象
核心逻辑
SimpleITK的sitk.Resample接受的变换对象需要明确坐标映射方向(默认是从输出图像空间指向输入图像空间),而4×4齐次变换矩阵通常描述的是输入到输出的坐标变换。因此需要先拆解矩阵的旋转、平移部分,再根据实际需求决定是否取逆,最后封装为对应的SimpleITK变换类。
3D图像场景实现
假设你已读取目标图像,且拥有transform_matrix(4×4 Numpy数组,刚性变换要求旋转矩阵为正交矩阵,最后一行固定为[0,0,0,1]):
import SimpleITK as sitk import numpy as np # 读取图像 image = sitk.ReadImage("your_image_path.nii") # 示例4×4刚性变换矩阵(替换为你实际的矩阵) transform_matrix = np.array([ [0.936, -0.352, 0.0, 10.0], [0.352, 0.936, 0.0, -5.0], [0.0, 0.0, 1.0, 3.0], [0.0, 0.0, 0.0, 1.0] ]) # 1. 提取旋转矩阵和平移向量 rotation_matrix = transform_matrix[:3, :3] translation = transform_matrix[:3, 3] # 2. 创建刚性变换对象(优先用VersorRigid3DTransform,避免欧拉角奇异性) rigid_transform = sitk.VersorRigid3DTransform() # 3. 设置变换参数:SimpleITK要求传入行优先扁平化的矩阵数组 rigid_transform.SetMatrix(rotation_matrix.flatten()) rigid_transform.SetTranslation(translation) # 关键:判断是否需要逆变换 # 如果你的矩阵是「输入图像坐标 → 输出图像坐标」的映射,必须取逆 # 因为Resample需要的是「输出图像坐标 → 输入图像坐标」的映射 inv_transform_matrix = np.linalg.inv(transform_matrix) rigid_transform.SetMatrix(inv_transform_matrix[:3, :3].flatten()) rigid_transform.SetTranslation(inv_transform_matrix[:3, 3]) # 4. 执行重采样(可自定义输出参数,这里默认沿用输入图像的配置) resampled_image = sitk.Resample( image, image.GetSize(), rigid_transform, sitk.sitkLinear, # 插值方式,可替换为sitk.sitkNearestNeighbor等 image.GetOrigin(), image.GetSpacing(), image.GetDirection(), 0.0, # 图像外区域填充值 image.GetPixelID() )
2D图像场景适配
如果是2D图像,标准齐次变换矩阵应为3×3,但如果你误用了4×4矩阵(最后两行是[0,0,1,0]和[0,0,0,1]),可提取前2×2旋转矩阵和前2个平移分量,使用Euler2DTransform:
# 提取2D变换部分 rotation_matrix_2d = transform_matrix[:2, :2] translation_2d = transform_matrix[:2, 3] # 创建2D刚性变换对象 rigid_transform_2d = sitk.Euler2DTransform() rigid_transform_2d.SetMatrix(rotation_matrix_2d.flatten()) rigid_transform_2d.SetTranslation(translation_2d) # 同样根据需求判断是否取逆 inv_matrix_2d = np.linalg.inv(transform_matrix[:3, :3]) # 取前3×3矩阵求逆 rigid_transform_2d.SetMatrix(inv_matrix_2d[:2, :2].flatten()) rigid_transform_2d.SetTranslation(inv_matrix_2d[:2, 2]) # 执行重采样 resampled_image_2d = sitk.Resample(image, rigid_transform_2d)
常见注意事项
- 矩阵存储顺序:SimpleITK的
SetMatrix接受行优先扁平化数组,与Numpy默认存储逻辑一致,无需额外转置。 - 变换方向:这是最容易出错的点,务必明确你的矩阵描述的坐标映射方向,必要时用
np.linalg.inv求逆。 - 变换类选择:3D场景优先用
VersorRigid3DTransform避免欧拉角万向锁问题;若涉及缩放等非刚性仿射变换,改用AffineTransform。
内容的提问来源于stack exchange,提问作者brohan322
相关产品推荐
相关产品推荐

