-
-
Save fepegar/b723d15de620cd2a3a4dbd71e491b59d to your computer and use it in GitHub Desktop.
Do you mean for visualization or to apply elastic deformations to 3D images?
For the former, I'd user 3D Slicer and VTK.
For the latter, TorchIO: https://torchio.readthedocs.io/transforms/augmentation.html#randomelasticdeformation
I mean, to apply 3D deformation to 3d images (e.g., CT scans). I am a radiologist working on deep learning in kidney tumours. I have been looking for efficient spline-based deformations of the tumour as data-augmentation. People have developed elaborate elastic / deep-learning based pipeline but afaik a simple solution with splines would be quicker and logical. I haven't found an implementation yet.
You can use TorchIO, as I mentioned above.
Hi, thanks for this.
How possible is it to apply deformations only around a label/mask in a subject using the randomelacticdeformation method?
Example:
mri = tio.ScalarImage('')
label = tio.LabelMap('')
subject = tio.Subject(mri=sample, seg=label)
subject.plot()
transform = tio.RandomElasticDeformation()
new_image = transform(subject)
Hi, thanks for this.
How possible is it to apply deformations only around a label/mask in a subject using the randomelacticdeformation method? Example:
mri = tio.ScalarImage('') label = tio.LabelMap('') subject = tio.Subject(mri=sample, seg=label) subject.plot() transform = tio.RandomElasticDeformation() new_image = transform(subject)
Interesting! Here's an attempt, not perfect but might be good enough for your purposes:
import SimpleITK as sitk
import torch
import torchio as tio
size = 256
grid_spacing = 15
grid = sitk.GridSource(
outputPixelType=sitk.sitkFloat32,
size=(size, size, size),
sigma=(0.5, 0.5, 0.5),
gridSpacing=(grid_spacing, grid_spacing, grid_spacing),
gridOffset=(0, 0, 0),
spacing=(1, 1, 1),
) * -1
image = tio.ScalarImage.from_sitk(grid)
mask_tensor = torch.zeros_like(image.data, dtype=torch.bool)
mask_tensor[:, 50:150, 30:180, 50:200] = True
mask = tio.LabelMap(tensor=mask_tensor, affine=image.affine)
crop = tio.CropOrPad((100, 150, 150), mask_name="mask")
subject = tio.Subject(
image=image,
mask=mask,
)
roi = crop(subject)
elastic = tio.RandomElasticDeformation(
locked_borders=2,
max_displacement=20,
)
torch.manual_seed(0)
deformed = elastic(roi.image)
resample = tio.Resample(target=image)
resampled = resample(deformed)
result_tensor = image.data
result_tensor[mask_tensor] = resampled.data[mask_tensor]
result = tio.ScalarImage(tensor=result_tensor, affine=image.affine)
result.plot(figsize=(9, 3))
Hi, thanks for this.
How possible is it to apply deformations only around a label/mask in a subject using the randomelacticdeformation method? Example:mri = tio.ScalarImage('') label = tio.LabelMap('') subject = tio.Subject(mri=sample, seg=label) subject.plot() transform = tio.RandomElasticDeformation() new_image = transform(subject)
Interesting! Here's an attempt, not perfect but might be good enough for your purposes:
import SimpleITK as sitk import torch import torchio as tio size = 256 grid_spacing = 15 grid = sitk.GridSource( outputPixelType=sitk.sitkFloat32, size=(size, size, size), sigma=(0.5, 0.5, 0.5), gridSpacing=(grid_spacing, grid_spacing, grid_spacing), gridOffset=(0, 0, 0), spacing=(1, 1, 1), ) * -1 image = tio.ScalarImage.from_sitk(grid) mask_tensor = torch.zeros_like(image.data, dtype=torch.bool) mask_tensor[:, 50:150, 30:180, 50:200] = True mask = tio.LabelMap(tensor=mask_tensor, affine=image.affine) crop = tio.CropOrPad((100, 150, 150), mask_name="mask") subject = tio.Subject( image=image, mask=mask, ) roi = crop(subject) elastic = tio.RandomElasticDeformation( locked_borders=2, max_displacement=20, ) torch.manual_seed(0) deformed = elastic(roi.image) resample = tio.Resample(target=image) resampled = resample(deformed) result_tensor = image.data result_tensor[mask_tensor] = resampled.data[mask_tensor] result = tio.ScalarImage(tensor=result_tensor, affine=image.affine) result.plot(figsize=(9, 3))
Thanks for the snippet. Its a great starting point:
Hi, This is really good. Do you have any tips to share to extend it to 3D spatial coordinates?