插值/调整3D数组大小 [英] Interpolate/Resize 3D array

查看:102
本文介绍了插值/调整3D数组大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个3D数组,用于保存来自mri数据集的体素.该模型可以沿一个或多个方向拉伸.例如.体素大小(x,y,z)可以为0.5x0.5x2 mm.现在,我想将3D数组重新采样为一个包含1,1,1毫米体素的数组.为此,我需要使x/y尺寸较小,而z尺寸较大,并对体素值进行插值. 我的问题是:在numpy或scipy中是否有一个简单的函数可以对简单的3d数组进行这种重新采样?

I have a 3D array holding voxels from a mri dataset. The model could be stretched along one or more directions. E.g. the voxel size (x,y,z) could be 0.5x0.5x2 mm. Now I want to resample the 3D array into an array holding 1,1,1 mm voxels. For this I need to make the x/y dimensions smaller and the z dimension bigger and interpolate the voxel values. My question is: Is there a simple function in numpy or scipy for doing such a resampling of a simple 3d array?

从* .nii文件加载模型:

Loading model from *.nii file:

img = nib.load(sFileName)
array = np.array(img.dataobj).astype("uint8") # 3d array with e.g. 0.5,0.5,2 mm
# TODO resample

推荐答案

ndimage.zoom

这可能是最好的方法,

ndimage.zoom

This is probably the best approach, the zoom method is designed for precisely this kind of task.

from scipy.ndimage import zoom
new_array = zoom(array, (0.5, 0.5, 2))

通过指定的系数更改每个尺寸的大小.如果数组的原始形状为(40, 50, 60),则新的形状为(20, 25, 120).

changes the size in each dimension by the specified factor. If the original shape of array was, say, (40, 50, 60), the new one will be (20, 25, 120).

SciPy具有用于信号处理的大量方法.这里最相关的是 decimate resample_poly .我在下面使用后者

SciPy has a large set of methods for signal processing. Most relevant here are decimate and resample_poly. I use the latter below

from scipy.signal import resample_poly
factors = [(1, 2), (1, 2), (2, 1)]
for k in range(3):
    array = resample_poly(array, factors[k][0], factors[k][1], axis=k)

因子(必须为整数)具有上采样和下采样.那就是:

The factors (which must be integers) are of up- and down-sampling. That is:

  • (1,2)表示大小除以2
  • (2,1)表示大小乘以2
  • (2,3)表示向上乘2,然后向下乘3,因此大小乘以2/3

可能的缺点:该过程在每个维度上独立发生,因此与ndimage方法一样,可能不考虑空间结构.

Possible downside: the process happens independently in each dimension, so the spatial structure may not be taken into account as well as by ndimage methods.

这更加实际,但也更加费力,并且没有过滤的好处:直接进行下采样.我们必须为插值器制作一个网格,并在每个方向上使用原始步长.创建插值器后,需要在新的网格上对其进行评估;它的调用方法采用由mgrid准备的另一种网格格式.

This is more hands-on, but also more laborious and without the benefit of filtering: straightforward downsampling. We have to make a grid for the interpolator, using original step sizes in each direction. After the interpolator is created, it needs to be evaluated on a new grid; its call method takes a different kind of grid format, prepared with mgrid.

values = np.random.randint(0, 256, size=(40, 50, 60)).astype(np.uint8)  # example

steps = [0.5, 0.5, 2.0]    # original step sizes
x, y, z = [steps[k] * np.arange(array.shape[k]) for k in range(3)]  # original grid
f = RegularGridInterpolator((x, y, z), values)    # interpolator

dx, dy, dz = 1.0, 1.0, 1.0    # new step sizes
new_grid = np.mgrid[0:x[-1]:dx, 0:y[-1]:dy, 0:z[-1]:dz]   # new grid
new_grid = np.moveaxis(new_grid, (0, 1, 2, 3), (3, 0, 1, 2))  # reorder axes for evaluation
new_values = f(new_grid)

缺点:例如,当尺寸减少2时,实际上会降低所有其他值,这就是简单的下采样.理想情况下,在这种情况下,应该对相邻值进行平均.在信号处理方面,在抽取中,低通滤波优先于下采样.

Downside: e.g., when a dimension is reduced by 2, it will in effect drop every other value, which is simple downsampling. Ideally, one should average neighboring values in this case. In terms of signal processing, low-pass filtering precedes downsampling in decimation.

这篇关于插值/调整3D数组大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆