如何在各个维度中调整体积图像的大小或形状?

2 投票
1 回答
1646 浏览
提问于 2025-04-18 13:42

我有一个体积图像,存储在一个叫做 vtkImageData 的对象里。我想改变它的尺寸,比如从 [100,100,100] 改成 [120,120,120]。我想在每个方向上分别添加零值,比如在“负X”方向添加5个切片,在“正X”方向添加15个切片,这样总的X方向分辨率就增加了20。

有没有什么vtk的过滤器或者numpy的重塑函数可以让我做到这一点呢?

我为什么要这样做呢?因为我在用python处理一个体积图像。VTK(5.10)里有一个叫 vtkImageDilateErode3D 的形态学操作符,可以让我对这个图像进行膨胀和腐蚀操作。不过,当我对靠近图像边界的体素进行膨胀/腐蚀时,会产生一些伪影。因此,我想在应用这个操作符之前,先“挤出”这个体积。

这里有一些python代码,可以在一定程度上重塑图像,但数据在图像中分布得很乱。也许我可以用更聪明的方式把之前的图像复制到新的数组里?(不过出于性能考虑,我想避免手动复制每一个体素)

def change_vol_resolution(volume, res_adjust=[0,0, 0,0, 0,0]):
    changed_volume = vtk.vtkImageData()
    original_dimensions = volume.GetDimensions()

    changed_dimensions = [original_dimensions[0] + res_adjust[0] + res_adjust[1], original_dimensions[1] + res_adjust[2] + res_adjust[3], original_dimensions[2] + res_adjust[4] + res_adjust[5]]
    changed_volume.SetDimensions(changed_dimensions)

    changed_volume.SetScalarTypeToShort()
    changed_volume.SetNumberOfScalarComponents(volume.GetNumberOfScalarComponents())
    changed_volume.AllocateScalars()

    np_array = numpy_support.vtk_to_numpy(volume.GetPointData().GetScalars())
    np_array_copy = np.copy(np_array)
    np_array_copy.resize(changed_dimensions[0]*changed_dimensions[1]*changed_dimensions[2])

    changed_volume.GetPointData().SetScalars(numpy_support.numpy_to_vtk(np_array_copy,deep=1))

    return changed_volume

更新:我找到一个numpy的函数叫 numpy.pad(),它可以在矩阵的任意维度上添加空的“填充”区域,这正是我想要的功能。

1 个回答

2

因为我没有足够的积分来写评论,所以我只能把这个写成回答。虽然你已经找到了用numpy重塑的方法,但在vtk中有一些过滤器可以完成这个任务(这样你就不需要把图像复制到numpy数组里了)。目前有三个过滤器,它们都是从抽象的 vtkImagePadFiter 继承而来的。你可以查看 vtkImagePadFilter 文档 VTK 5.10

第一个是 vtkImageConstantPad,它用一个常数填充额外的值。我觉得这正是你想要的。你可以查看 vtkImageConstantPad 文档 VTK 5.10

第二个是 vtkImageMirroPad,它通过用原始图像的镜像填充额外的像素来让图像变大。

第三个是 vtkImageWrapPad,它通过取模的方式将现有图像包裹起来,以填充新的像素/体素。

附言:因为我的积分太低,无法添加另外两个过滤器的文档链接,但其实它们很容易找到。

撰写回答