I have a 3D labelmap image with the values 1 for foreground and 0 for background. I want to erode 1-2 voxels from the edge of the foreground. This is my code:
f = sitk.BinaryErodeImageFilter()
f.SetKernelType(sitk.sitkBall)
f.SetKernelRadius(1)
f.SetBackgroundValue(0)
f.SetForegroundValue(1)
new_img = f.Execute(img)
new_img is all zeros (while img has 496 voxels labeled as 1). What am I doing wrong? I have tried with kernels other than sitkBall with similar results.
Code looks good. If you can provided a Minimal Working Example (MWE) illustrating the issue that would help.
Below is a MWE, but it works as expected:
import SimpleITK as sitk
img = sitk.Image([64]*3, sitk.sitkUInt8)
img[10:20,10:20,10:20] = 1
f = sitk.BinaryErodeImageFilter()
f.SetKernelType(sitk.sitkBall)
f.SetKernelRadius(1)
f.SetBackgroundValue(0)
f.SetForegroundValue(1)
new_img = f.Execute(img)
#multiply images by 255 so that the foreground is visible
#in Fiji without modifying window/level
sitk.Show(img*255, 'orig')
sitk.Show(new_img*255,'erroded')
It looks like it is an “issue/feature” with the segmentation, it is just 2 voxels wide in all locations and the erosion gets rid of everything. Possibly try thinning, BinaryThinningImageFilter, the result is a skeleton (1 voxel wide representation).
Thank you @zivy
I suspected it should be an issue with the images themselves as I got normal results with other images and the same code. I think I will have to use higher resolution images to segment the structure of interest and then resample on the lower resolution ones or figure a way to avoid the erosion altogether. Or maybe go with BinaryThinningImageFilter as you suggest. Thanks again!