在 Python 中使用插值统一 ct 扫描体素大小
Unification ct scan voxel size by using interpolation in Python
我在Matlab中使用过interp2
,例如下面的代码,这是@rayryeng在Three dimensional (3D) matrix interpolation in Matlab:
中的回答的一部分
d = size(volume_image)
[X,Y] = meshgrid(1:1/scaleCoeff(2):d(2), 1:1/scaleCoeff(1):d(1));
for ind = z
%Interpolate each slice via interp2
M2D(:,:,ind) = interp2(volume_image(:,:,ind), X, Y);
end
维度示例:
The image size is 512x512 and the number of slices is 133. So:
volume_image(rows, columns, slices in 3D dimenson) : 512x512x133 in 3D dimenson
X: 288x288
Y: 288x288
scaleCoeff(2): 0.5625
scaleCoeff(1): 0.5625
z = 1 up to 133 ,hence z: 1x133
ind: 1 up to 133
M2D(:,:,ind) finally is 288x288x133 in 3D dimenson
Aslo,Matlabs 大小语法:(行、列、第 3 维切片)和 Python 大小语法:(第 3 维切片、行、列)。
但是,将Matlab代码转换为Python代码后出现错误,ValueError: Invalid length for input z for non rectangular grid
:
for ind in range(0, len(z)+1):
M2D[ind, :, :] = interpolate.interp2d(X, Y, volume_image[ind, :, :]) # ValueError: Invalid length for input z for non rectangular grid
怎么了?非常感谢。
在 MATLAB 中,interp2
的参数为:
result = interp2(input_x, input_y, input_z, output_x, output_y)
您只使用了后 3 个参数,前两个参数假定为 input_x = 1:size(input_z,2)
和 input_y = 1:size(input_z,1)
。
在 Python 中,scipy.interpolate.interp2
完全不同:它接受 MATLAB 函数的前 3 个输入参数,returns 一个您可以调用以获取插值的对象:
f = scipy.interpolate.interp2(input_x, input_y, input_z)
result = f(output_x, output_y)
按照文档中的示例,我得到了这样的结果:
from scipy import interpolate
x = np.arange(0, volume_image.shape[2])
y = np.arange(0, volume_image.shape[1])
f = interpolate.interp2d(x, y, volume_image[ind, :, :])
xnew = np.arange(0, volume_image.shape[2], 1/scaleCoeff[0])
ynew = np.arange(0, volume_image.shape[1], 1/scaleCoeff[1])
M2D[ind, :, :] = f(xnew, ynew)
[代码未经测试,如有错误请告知。]
您可能对 scipy.ndimage.zoom
感兴趣。如果您从一个规则网格插值到另一个规则网格,它比 scipy.interpolate.interp2d
更快更容易使用。
示例请参见此答案:
你可能想要这样的东西:
import scipy.ndimage as ndimage
M2D = ndimage.zoom(volume_image, (1, scaleCoeff[0], scaleCoeff[1])
我在Matlab中使用过interp2
,例如下面的代码,这是@rayryeng在Three dimensional (3D) matrix interpolation in Matlab:
d = size(volume_image)
[X,Y] = meshgrid(1:1/scaleCoeff(2):d(2), 1:1/scaleCoeff(1):d(1));
for ind = z
%Interpolate each slice via interp2
M2D(:,:,ind) = interp2(volume_image(:,:,ind), X, Y);
end
维度示例:
The image size is 512x512 and the number of slices is 133. So:
volume_image(rows, columns, slices in 3D dimenson) : 512x512x133 in 3D dimenson
X: 288x288
Y: 288x288
scaleCoeff(2): 0.5625
scaleCoeff(1): 0.5625
z = 1 up to 133 ,hence z: 1x133
ind: 1 up to 133
M2D(:,:,ind) finally is 288x288x133 in 3D dimenson
Aslo,Matlabs 大小语法:(行、列、第 3 维切片)和 Python 大小语法:(第 3 维切片、行、列)。
但是,将Matlab代码转换为Python代码后出现错误,ValueError: Invalid length for input z for non rectangular grid
:
for ind in range(0, len(z)+1):
M2D[ind, :, :] = interpolate.interp2d(X, Y, volume_image[ind, :, :]) # ValueError: Invalid length for input z for non rectangular grid
怎么了?非常感谢。
在 MATLAB 中,interp2
的参数为:
result = interp2(input_x, input_y, input_z, output_x, output_y)
您只使用了后 3 个参数,前两个参数假定为 input_x = 1:size(input_z,2)
和 input_y = 1:size(input_z,1)
。
在 Python 中,scipy.interpolate.interp2
完全不同:它接受 MATLAB 函数的前 3 个输入参数,returns 一个您可以调用以获取插值的对象:
f = scipy.interpolate.interp2(input_x, input_y, input_z)
result = f(output_x, output_y)
按照文档中的示例,我得到了这样的结果:
from scipy import interpolate
x = np.arange(0, volume_image.shape[2])
y = np.arange(0, volume_image.shape[1])
f = interpolate.interp2d(x, y, volume_image[ind, :, :])
xnew = np.arange(0, volume_image.shape[2], 1/scaleCoeff[0])
ynew = np.arange(0, volume_image.shape[1], 1/scaleCoeff[1])
M2D[ind, :, :] = f(xnew, ynew)
[代码未经测试,如有错误请告知。]
您可能对 scipy.ndimage.zoom
感兴趣。如果您从一个规则网格插值到另一个规则网格,它比 scipy.interpolate.interp2d
更快更容易使用。
示例请参见此答案:
你可能想要这样的东西:
import scipy.ndimage as ndimage
M2D = ndimage.zoom(volume_image, (1, scaleCoeff[0], scaleCoeff[1])