Project-MONAI / MONAI

AI Toolkit for Healthcare Imaging
https://monai.io/
Apache License 2.0
5.5k stars 1.01k forks source link

Cannot use non-`nearest` interpolation methods with `Invertd` #7836

Open joshuacwnewton opened 2 weeks ago

joshuacwnewton commented 2 weeks ago

Is your feature request related to a problem? Please describe.

We have a model that produces a "soft" (i.e. not binary) segmentation output.

In our preprocessing steps for the input image, we use Spacingd with mode=2 to resample the image to the expected resolution of the model. For the postprocessing of the output segmentation, we use Invertd to reverse the preprocessing. However, it seems that we only have two options:

  1. nearest_interp=True: Uses nearest interpolation. This produces a choppy, non-smooth output:

    image

  2. nearest_interp=False: Uses mode=2 interpolation. This is recommended by the MONAI tutorials to produce a "smooth" output.

    image

    However, re-using spline interpolation isn't ideal for soft segmentations, as it produces values outside of the typical "soft" range ([0, 1]). We could clip the intensity range to [0, 1], however this creates an unnatural ring of "1.0" values around the perimeter (shown in the darkest red in the figure above).

Describe the solution you'd like

The solution I'd like is pretty straightforward: If we look at how nearest_interp currently works, we can see that inside of monai.transforms.post.dictionary, it's a simple call to convert_applied_interp_mode:

https://github.com/Project-MONAI/MONAI/blob/4029c422f1da84cdf5e4ce546dbff33245cbe025/monai/transforms/post/dictionary.py#L695-L698

If I go into my local copy of monai and manually change mode for the above call to be, say, 'bilinear' instead, then I get the desired output (smooth output within the range [0, 1]):

Screenshot from 2024-06-10 15-40-40

I think that if nearest_interp was gradually deprecated in support of a more general parameter interp, we could then supply any kind of interpolation method (e.g. 'nearest', 'bilinear', etc.) to override the default interpolation mode, which would help us achieve the results we're looking for. (nearest_interp could even be kept as a synonym for interp='nearest' to avoid a breaking API change.)

Describe alternatives you've considered

I considered using bilinear for the forward transform, too. While this produces a correct-looking output image, it produces a lower quality input image.

I have also tried modifying the transform stack that I supply to Invertd. However, I receive an error in doing so, because get_most_recent_transform sets check=True by default, and the inverse transforms do not match the forward transforms.