Looks like a good solution to me. I have done similar things when working with 4D XYZC images. This approach is really asking for a reusable solution something like a python function decorator to operate slice_by_slice. Here is what I came up with:
def slicing_decorator(func):
"""
A function decorator which extracts image slices of N-1 dimensions and calls func on each slice. The resulting
images are then concatenated together with JoinSeries.
:param func: A function which take a SimpleITK Image as it's first argument
:return: The result of running func on each slice of image.
"""
@wraps(func)
def slice_by_slice(image, *args, **kwargs):
size = list(image.GetSize())
number_of_slices = size[-1]
extract_size = size
extract_index = [0]*image.GetDimension()
img_list = []
extract_size[-1] = 0
extractor = sitk.ExtractImageFilter()
extractor.SetSize(extract_size)
for slice_idx in range(0, number_of_slices):
extract_index[-1] = slice_idx
extractor.SetIndex(extract_index)
img_list.append(func(extractor.Execute(image), *args, **kwargs))
return sitk.JoinSeries(img_list, image.GetOrigin()[-1], image.GetSpacing()[-1])
return slice_by_slice
@slicing_decorator
def my_algo(image):
print("Executing image of size: {0}".format(image.GetSize()))
return sitk.SmoothingRecursiveGaussian(image)