BinaryErodeImageFilter erodes the entire foreground

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.

Hello @kliron,

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')

Hi @zivy
Here is an example example.nrrd (1.3 MB)
label map image.

The image has 496 voxels with the value 1.

If I run the erosion:

f = sitk.BinaryErodeImageFilter()
f.SetKernelType(sitk.sitkBall)
f.SetKernelRadius(1)
f.SetBackgroundValue(0)
f.SetForegroundValue(1)
eroded_img = f.Execute(img)

Then all voxels in eroded_img have the value 0.

Hello @kliron,

Thanks for sharing the data.

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!