Hi
convert3d (c3d) tool has this nice feature called trim, which finds the smallest rectangular region of non-background voxels. I use quite a lot with masked images. In Slicer, Crop Volume gives a similar functionality, but in a more manual/visual kind of way. Given c3d is based on ITK, I thought maybe Slicer has a similar option too, but couldn’t find it in Simple Filters. Is this feature available?
It is really easy to do this, but I guess it hasn’t come up as a feature request, as it is quite rare that images contain large irrelevant background regions that could be removed by simple thresholding. What kind of images do you have?
Anyway, it’s really simple to do, just copy-paste this into the Python console (image is cropped to region with voxel intensity > 0):
volumeNode = getNode('MRHead')
import vtkSegmentationCorePython as seg
img = slicer.modules.segmentations.logic().CreateOrientedImageDataFromVolumeNode(volumeNode)
img.UnRegister(None)
extent=[0,0,0,0,0,0]
seg.vtkOrientedImageDataResample.CalculateEffectiveExtent(img, extent)
croppedImg = seg.vtkOrientedImageData()
seg.vtkOrientedImageDataResample.CopyImage(img, croppedImg, extent)
slicer.modules.segmentations.logic().CopyOrientedImageDataToVolumeNode(croppedImg, volumeNode)
If you need to set a custom threshold value for cropping then download Slicer nightly build on Wednesday or later and use this code:
volumeNode = getNode('MRHead')
threshold = 20
import vtkSegmentationCorePython as seg
img = slicer.modules.segmentations.logic().CreateOrientedImageDataFromVolumeNode(volumeNode)
img.UnRegister(None)
extent=[0,0,0,0,0,0]
seg.vtkOrientedImageDataResample.CalculateEffectiveExtent(img, extent, threshold)
croppedImg = seg.vtkOrientedImageData()
seg.vtkOrientedImageDataResample.CopyImage(img, croppedImg, extent)
slicer.modules.segmentations.logic().CopyOrientedImageDataToVolumeNode(croppedImg, volumeNode)
Hi Andras,
It worked great, thank you! Once trimmed, may I ask how to pad images as well? Perhaps, add a buffer of few voxels on each side.
I use this on head microCT of mice. I segment all non-cranial elements (there would be limbs, shoulder blade, mandible etc) and usually left with a volume with 50% (if not more) background voxels.
To pad images, adjust the extent after calling CalculateEffectiveExtent
:
volumeNode = getNode('MRHead')
threshold = 20
margin=5
import vtkSegmentationCorePython as seg
img = slicer.modules.segmentations.logic().CreateOrientedImageDataFromVolumeNode(volumeNode)
img.UnRegister(None)
extent=[0,0,0,0,0,0]
seg.vtkOrientedImageDataResample.CalculateEffectiveExtent(img, extent, threshold)
extent=[extent[0]-margin,extent[1]+margin,extent[2]-margin,extent[3]+margin,extent[4]-margin,extent[5]+margin]
croppedImg = seg.vtkOrientedImageData()
seg.vtkOrientedImageDataResample.CopyImage(img, croppedImg, extent)
slicer.modules.segmentations.logic().CopyOrientedImageDataToVolumeNode(croppedImg, volumeNode)
This feature is available in “Split volume” effect (provided by SegmentEditorExtraEffects extension).