Project-MONAI / MONAI

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

Add option to skip resizing for RestoreLabeld Transform #6380

Open AHarouni opened 1 year ago

AHarouni commented 1 year ago

Is your feature request related to a problem? Please describe. RestoreLabeld transform in monai label app does multiple operations: 1- restore resizing 2 - restore cropping 3- undo spacing 4- undo slicing

currently it is all or none. I need to select operations to do

Describe the solution you'd like Please options to disable the resizing. may be options to skip restore cropping and spacing as well. user can always use restore transform to restore the spacing

Describe alternatives you've considered I have copped the transform and created my own transform to disable the resizing

ctongh commented 7 months ago

Solution Description

As @AHarouni said, I noticed that the RestoreLabeld transform currently performs a combined restoration, including resizing, cropping, spacing, and slicing. However, the current implementation is all or none, so I propose an improved solution.

I have made modifications to the RestoreLabeld transform by introducing four new parameters for more flexible which restoration operations should be executed:

  1. resize: Used to enable or disable resizing restoration.
  2. spacing: Used to enable or disable undoing spacing.
  3. fetch_2d_sliced: Used to enable or disable Fetch2DSliced restoration.
  4. spatial_crop_guidance: Used to enable or disable SpatialCropGuidance restoration.

This design allows users to selectively enable or disable each restoration operation as needed, providing greater flexibility.

Example Code

Take resize as an example

# This is the modified portion of the code, with the addition of new parameters
def __init(
    self, 
     # ... (original code)
    resize: bool = True,
    spacing: bool = True,
    fetch_2d_sliced: bool = True,
    spatial_crop_guidance: bool = True,
) -> None:
    # ... (original code)

def __call__(self, data: Any) -> dict:
        d = dict(data)
        meta_dict: dict = d[f"{self.ref_image}_{self.meta_key_postfix}"]

        for key, mode, align_corners, meta_key in self.key_iterator(d, self.mode, self.align_corners, self.meta_keys):
            image = d[key]

            # Undo Resize
            if self.resize:
                current_shape = image.shape
                cropped_shape = meta_dict[self.cropped_shape_key]
                if np.any(np.not_equal(current_shape, cropped_shape)):
                    resizer = Resize(spatial_size=cropped_shape[1:], mode=mode)
                    image = resizer(image, mode=mode, align_corners=align_corners)

             # ... (original code)

            d[key] = image

            meta_key = meta_key or f"{key}_{self.meta_key_postfix}"
            meta = d.get(meta_key)
            if meta is None:
                meta = dict()
                d[meta_key] = meta
            meta["affine"] = meta_dict["original_affine"]
        return d

Additional context

Happy and new to contribute ! 😊

KumoLiu commented 7 months ago

Welcome the contribution, please refer to the Contribution Guide.