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
You can also use PyTorch + TorchIO. The following is the resampling of a 3D array with gaussian interpolation (the zoom function is adapted from the code that my supervisor wrote for me):
def zoom(
label_stack: Sequence[Sequence[SupportsFloat]],
spacing: Sequence[Union[SupportsInt, SupportsFloat]],
) -> np.ndarray:
spacing = np.asanyarray(spacing)
target = tuple(1 / spacing)
# Resample the array with respect to spacing parameters
arr4d = np.expand_dims(label_stack, 0)
transform = tio.Resample(target, image_interpolation="gaussian")
transformed = transform(arr4d)
result = np.squeeze(transformed)
# Perform an arbitrary gaussian to smoothen the surface.
# Achieves a more smooth surface
sigma = (round(spacing[0] * 0.25), 7, 7)
gaussian_3d = gaussian_filter(result, sigma=sigma)
# Binary thresholding
highpass_threshold = np.median(gaussian_3d[gaussian_3d > 0.09])
thresh = threshold_array(gaussian_3d, highpass=highpass_threshold)
return thresh
def threshold_array(
array: np.ndarray,
lowpass: Union[Union[SupportsInt, SupportsFloat], None] = None,
highpass: Union[Union[SupportsInt, SupportsFloat], None] = None,
) -> np.ndarray:
if lowpass and highpass:
msg = "Defition of both lowpass and highpass is illogical"
raise ValueError(msg)
if not lowpass and not highpass:
msg = "Either lowpass or highpass has to be defined"
raise ValueError(msg)
array = np.asanyarray(array)
filtered = np.zeros_like(array, dtype=np.int8)
if lowpass:
filtered[array < lowpass] = 1
if highpass:
filtered[array > highpass] = 1
return filtered
The images array is z-x-y, and zoom has been designed accordingly.
Spacing is defined by the user. Spacing has to be a sequence that has the same length as the shape of the image numpy array. The interpolated image will have the shape as spacing * "old shape".
I wish there was cubic method for the interpolation in the Resample function. I tried with gaussian + thresholding, but haven't gotten any great results. Better than whatever I could muster with SciPy though.
Please credit when used.