diff --git a/monai/transforms/croppad/array.py b/monai/transforms/croppad/array.py index 7c8d7b6a19..06650a28b8 100644 --- a/monai/transforms/croppad/array.py +++ b/monai/transforms/croppad/array.py @@ -824,7 +824,7 @@ def __init__( select_fn: Callable = is_positive, channel_indices: IndexSelection | None = None, margin: Sequence[int] | int = 0, - allow_smaller: bool = True, + allow_smaller: bool = False, return_coords: bool = False, k_divisible: Sequence[int] | int = 1, mode: str = PytorchPadMode.CONSTANT, @@ -837,9 +837,9 @@ def __init__( channel_indices: if defined, select foreground only on the specified channels of image. if None, select foreground on the whole image. margin: add margin value to spatial dims of the bounding box, if only 1 value provided, use it for all dims. - allow_smaller: when computing box size with `margin`, whether allow the image size to be smaller - than box size, default to `True`. if the margined size is larger than image size, will pad with - specified `mode`. + allow_smaller: when computing box size with `margin`, whether to allow the final box edges to be outside of + the image edges (the image is smaller than the box). If `True`, part of a padded output box might be outside + of the original image, if `False`, the image edges will be used as the box edges. return_coords: whether return the coordinates of spatial bounding box for foreground. k_divisible: make each spatial dimension to be divisible by k, default to 1. if `k_divisible` is an int, the same `k` be applied to all the input spatial dimensions. diff --git a/monai/transforms/croppad/dictionary.py b/monai/transforms/croppad/dictionary.py index 6dc8f10c32..6b908dda8c 100644 --- a/monai/transforms/croppad/dictionary.py +++ b/monai/transforms/croppad/dictionary.py @@ -729,7 +729,7 @@ def __init__( select_fn: Callable = is_positive, channel_indices: IndexSelection | None = None, margin: Sequence[int] | int = 0, - allow_smaller: bool = True, + allow_smaller: bool = False, k_divisible: Sequence[int] | int = 1, mode: SequenceStr = PytorchPadMode.CONSTANT, start_coord_key: str = "foreground_start_coord", @@ -747,9 +747,9 @@ def __init__( channel_indices: if defined, select foreground only on the specified channels of image. if None, select foreground on the whole image. margin: add margin value to spatial dims of the bounding box, if only 1 value provided, use it for all dims. - allow_smaller: when computing box size with `margin`, whether allow the image size to be smaller - than box size, default to `True`. if the margined size is larger than image size, will pad with - specified `mode`. + allow_smaller: when computing box size with `margin`, whether to allow the final box edges to be outside of + the image edges (the image is smaller than the box). If `True`, part of a padded output box might be outside + of the original image, if `False`, the image edges will be used as the box edges. k_divisible: make each spatial dimension to be divisible by k, default to 1. if `k_divisible` is an int, the same `k` be applied to all the input spatial dimensions. mode: available modes for numpy array:{``"constant"``, ``"edge"``, ``"linear_ramp"``, ``"maximum"``, diff --git a/monai/transforms/utils.py b/monai/transforms/utils.py index c01f44635b..9b24d7038a 100644 --- a/monai/transforms/utils.py +++ b/monai/transforms/utils.py @@ -950,7 +950,7 @@ def generate_spatial_bounding_box( select_fn: Callable = is_positive, channel_indices: IndexSelection | None = None, margin: Sequence[int] | int = 0, - allow_smaller: bool = True, + allow_smaller: bool = False, ) -> tuple[list[int], list[int]]: """ Generate the spatial bounding box of foreground in the image with start-end positions (inclusive). @@ -961,7 +961,6 @@ def generate_spatial_bounding_box( [1st_spatial_dim_start, 2nd_spatial_dim_start, ..., Nth_spatial_dim_start], [1st_spatial_dim_end, 2nd_spatial_dim_end, ..., Nth_spatial_dim_end] - If `allow_smaller`, the bounding boxes edges are aligned with the input image edges. This function returns [0, 0, ...], [0, 0, ...] if there's no positive intensity. Args: @@ -970,8 +969,10 @@ def generate_spatial_bounding_box( channel_indices: if defined, select foreground only on the specified channels of image. if None, select foreground on the whole image. margin: add margin value to spatial dims of the bounding box, if only 1 value provided, use it for all dims. - allow_smaller: when computing box size with `margin`, whether allow the image size to be smaller - than box size, default to `True`. + allow_smaller: when computing box size with `margin`, whether to allow the final box edges to be outside of + the image edges (the image is smaller than the box). If `False`, the bounding boxes edges are aligned + with the input image edges, default to `False`. + """ check_non_lazy_pending_ops(img, name="generate_spatial_bounding_box") spatial_size = img.shape[1:] @@ -998,7 +999,7 @@ def generate_spatial_bounding_box( arg_max = where(dt == dt.max())[0] min_d = arg_max[0] - margin[di] max_d = arg_max[-1] + margin[di] + 1 - if allow_smaller: + if not allow_smaller: min_d = max(min_d, 0) max_d = min(max_d, spatial_size[di]) diff --git a/tests/test_crop_foreground.py b/tests/test_crop_foreground.py index 4435b128ba..fdc4ac0488 100644 --- a/tests/test_crop_foreground.py +++ b/tests/test_crop_foreground.py @@ -63,7 +63,7 @@ TESTS.append( [ - {"select_fn": lambda x: x > 0, "channel_indices": None, "margin": [2, 1], "allow_smaller": True}, + {"select_fn": lambda x: x > 0, "channel_indices": None, "margin": [2, 1], "allow_smaller": False}, p([[[0, 0, 0, 0, 0], [0, 1, 2, 1, 0], [0, 2, 3, 2, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]), p([[[0, 0, 0, 0, 0], [0, 1, 2, 1, 0], [0, 2, 3, 2, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]), True, @@ -72,7 +72,7 @@ TESTS.append( [ - {"select_fn": lambda x: x > 0, "channel_indices": None, "margin": [2, 1], "allow_smaller": False}, + {"select_fn": lambda x: x > 0, "channel_indices": None, "margin": [2, 1], "allow_smaller": True}, p([[[0, 0, 0, 0, 0], [0, 1, 2, 1, 0], [0, 2, 3, 2, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]), p([[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 1, 2, 1, 0], [0, 2, 3, 2, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]]), True, diff --git a/tests/test_crop_foregroundd.py b/tests/test_crop_foregroundd.py index 776776f6c5..6f5910e64c 100644 --- a/tests/test_crop_foregroundd.py +++ b/tests/test_crop_foregroundd.py @@ -88,7 +88,7 @@ "select_fn": lambda x: x > 0, "channel_indices": None, "margin": [2, 1], - "allow_smaller": True, + "allow_smaller": False, }, { "img": p( @@ -107,7 +107,7 @@ "select_fn": lambda x: x > 0, "channel_indices": None, "margin": [2, 1], - "allow_smaller": False, + "allow_smaller": True, }, { "img": p( diff --git a/tests/test_generate_spatial_bounding_box.py b/tests/test_generate_spatial_bounding_box.py index a67e7d0175..36b7d3c812 100644 --- a/tests/test_generate_spatial_bounding_box.py +++ b/tests/test_generate_spatial_bounding_box.py @@ -82,7 +82,7 @@ "select_fn": lambda x: x > 0, "channel_indices": None, "margin": [2, 1], - "allow_smaller": False, + "allow_smaller": True, }, ([-1, 0], [6, 5]), ] @@ -96,7 +96,7 @@ "select_fn": lambda x: x > 0, "channel_indices": None, "margin": [2, 1], - "allow_smaller": True, + "allow_smaller": False, }, ([0, 0], [5, 5]), ]