Skip to content

Downsampling Augmentation Transform #3781

Closed

Description

@lyndonboone

Is your feature request related to a problem? Please describe.
Working with augmentation for DL pipelines, it would be nice to have a transform that downsamples the image by a factor (as opposed to a specified tensor shape or voxel size) while preserving the shape of the input to simulate images acquired at a low resolution that have been resampled to a larger shape.

Describe the solution you'd like
An ideal solution would downsample the image by a specified factor, then upsample back to the original shape. Similar to RandomAnisotropy from TorchIO (https://torchio.readthedocs.io/transforms/augmentation.html) except with the capability to do isotropic downsampling.

Describe alternatives you've considered
I can get close to the desired behavior by placing two instances of a Zoom transform one after another, with reciprocal zoom factors and keep_size=False (e.g., Compose([Zoom(zoom=0.5, keep_size=False), Zoom(zoom=2.0, keep_size=False)])); however, this solution doesn't guarantee that the output shape will be the same as the input (although it will likely be close). For example, if the input shape is [192, 256, 256] and the desired downsampling factor is 3, the output shape will be [192, 255, 255].

There may be an alternative solution that I haven't considered. Otherwise, if you think this is worth adding as a new transform (or an adaptation to an existing transform), I'd be more than happy to try to submit a PR.

Activity

  1. wyli commented on Feb 8, 2022

    @wyli
    Contributor

    For the alternative solution, I think you can use ResizeWithPadOrCrop as the final part of the compose to make the shapes consistent

    class ResizeWithPadOrCrop(Transform):

    if the input shape is not known beforehand, perhaps a new transform is needed? would be great to have your PR on this...

  2. lyndonboone commented on Feb 9, 2022

    @lyndonboone
    ContributorAuthor

    Hi @wyli , thanks for the comment.

    Yes, exactly; I was thinking of the case where the input shape is not known beforehand. I'd be happy to submit a PR for a new transform (assuming it isn't more appropriate to adapt an existing transform). What should the new transform be called? Perhaps something with Resolution in the name?

  3. wyli commented on Feb 9, 2022

    @wyli
    Contributor

    great thanks! perhaps the name could be RandReinterpolate?

  4. rijobro commented on Feb 11, 2022

    @rijobro
    Contributor

    We would want a random and non-random version I suppose. @lyndonboone you could calculate the input size at the start of the __call__ method and then create the ResizeWithPadOrCrop accordingly. In this way, you wouldn't need to a priori know the image shape.

  5. ashwinkumargb commented on Jul 29, 2023

    @ashwinkumargb

    Has there been any updates to this? I would be interested in this functionality especially something similar to batchgenerator's SimulateLowResolutionTransform: https://github.com/MIC-DKFZ/batchgenerators/blob/master/batchgenerators/transforms/resample_transforms.py

  6. wyli commented on Jul 29, 2023

    @wyli
    Contributor

    @aaronkujawa has kindly shared his implementations but not yet has the bandwidth to integrate them into monai core https://github.com/aaronkujawa/MONAI/blob/04e24e3e1d6030d70063aedc97884f4cd6eebb75/monai/transforms/spatial/dictionary.py#L2151 I'm labelling this as contribution wanted.

  7. added a commit that references this issue on Aug 1, 2023
    d6bafc9
  8. function2-llx commented on Aug 8, 2023

    @function2-llx
    Contributor

    I've got one question about RandSimulateLowResolution. The nnUNet upsamples the downsampled image with cubic interpolation (according to the supplementary material, Section 4). Currently, there's only linear interpolation available for 3D images.

  9. aaronkujawa commented on Aug 11, 2023

    @aaronkujawa
    Contributor

    I've got one question about RandSimulateLowResolution. The nnUNet upsamples the downsampled image with cubic interpolation (according to the supplementary material, Section 4). Currently, there's only linear interpolation available for 3D images.

    That's true. This transform uses MONAI's Resize transform which is based on torch's interpolate function, which does not offer cubic interpolation in 3D. I guess one could try to replace Resize with MONAI's Resample transform or ResampleToMatch if cubic interpolation is a requirement.

  10. function2-llx commented on Oct 20, 2023

    @function2-llx
    Contributor

    FYI, it seems that the following one will work with 3D cubic interpolation now:

    import numpy as np
    
    from monai import transforms as mt
    
    def main():
    	img = np.random.randn(1, 6, 6, 6)
        zoom = np.array([2, 2, 2])
        affine = mt.Affine(
            scale_params=(1 / zoom).tolist(),
            spatial_size=(np.array(img.shape[1:]) * zoom).astype(np.int32).tolist(),
            mode=3,
            image_only=True,
        )
        zoomed_img = affine(img)
    
    if __name__ == '__main__':
        main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions