Hello @rtlim,
Not sure what it is that you were expecting? The linear interpolation does the interpolation across the whole image and those zero values are part of the image content.
Generally speaking, if the most important constraint on the output is not to introduce new values into the resampled image, use nearest neighbor interpolation, per @dzenanz’s advice. Note that this will likely reduce the quality/accuracy of the interpolation.
A compromise of sorts is to combine the two (has its own issues of abrupt discontinuities, but maybe it is good enough for your needs), sample code below:
import SimpleITK as sitk
original_image_size = [128,128]
img = sitk.GaussianSource(sitk.sitkUInt8, original_image_size, [16,16], [64,64])
img_size_scale = 4
ref_img = sitk.Image([img_size_scale*sz for sz in original_image_size], sitk.sitkUInt8)
ref_img.SetSpacing([spc/img_size_scale for spc in img.GetSpacing()])
# Resample using both linear and nearest neighbor, and then combine the two using nearest neighbor near the
# object boundary and linear in its interior.
resampled_img_linear = sitk.Resample(img, ref_img, sitk.Transform(), sitk.sitkLinear, 0, img.GetPixelID())
resampled_img_nn = sitk.Resample(img, ref_img, sitk.Transform(), sitk.sitkNearestNeighbor, 0, img.GetPixelID())
# Create masks for combining the two interpolation results
roi_distance_map = sitk.SignedMaurerDistanceMap(img>0, squaredDistance=False, useImageSpacing=True)
resampled_roi_distance_map = sitk.Resample(roi_distance_map, ref_img, interpolator = sitk.sitkLinear)
offset = 30.0
resampled_img_linear_mask = resampled_roi_distance_map<=-offset
resampled_img_nn_mask = resampled_roi_distance_map>-offset
sitk.Show(img, "original image")
sitk.Show(resampled_img_linear, "linear resampling")
sitk.Show(resampled_img_nn, "nearest neighbor resampling")
sitk.Show(resampled_img_linear*resampled_img_linear_mask + resampled_img_nn*resampled_img_nn_mask, "combination")