MCPcopy Create free account
hub / github.com/Project-MONAI/MONAI / spatial_crop_boxes

Function spatial_crop_boxes

monai/data/box_utils.py:1011–1065  ·  view source on GitHub ↗

This function generate the new boxes when the corresponding image is cropped to the given ROI. When ``remove_empty=True``, it makes sure the bounding boxes are within the new cropped image. Args: boxes: bounding boxes, Nx4 or Nx6 torch tensor or ndarray. The box mode is assumed

(
    boxes: NdarrayTensor,
    roi_start: Sequence[int] | NdarrayOrTensor,
    roi_end: Sequence[int] | NdarrayOrTensor,
    remove_empty: bool = True,
)

Source from the content-addressed store, hash-verified

1009
1010
1011def spatial_crop_boxes(
1012 boxes: NdarrayTensor,
1013 roi_start: Sequence[int] | NdarrayOrTensor,
1014 roi_end: Sequence[int] | NdarrayOrTensor,
1015 remove_empty: bool = True,
1016) -> tuple[NdarrayTensor, NdarrayOrTensor]:
1017 """
1018 This function generate the new boxes when the corresponding image is cropped to the given ROI.
1019 When ``remove_empty=True``, it makes sure the bounding boxes are within the new cropped image.
1020
1021 Args:
1022 boxes: bounding boxes, Nx4 or Nx6 torch tensor or ndarray. The box mode is assumed to be ``StandardMode``
1023 roi_start: voxel coordinates for start of the crop ROI, negative values allowed.
1024 roi_end: voxel coordinates for end of the crop ROI, negative values allowed.
1025 remove_empty: whether to remove the boxes that are actually empty
1026
1027 Returns:
1028 - cropped boxes, boxes[keep], does not share memory with original boxes
1029 - ``keep``, it indicates whether each box in ``boxes`` are kept when ``remove_empty=True``.
1030 """
1031
1032 # convert numpy to tensor if needed
1033 boxes_t = convert_data_type(boxes, torch.Tensor)[0].clone()
1034
1035 # convert to float32 since torch.clamp_ does not support float16
1036 boxes_t = boxes_t.to(dtype=COMPUTE_DTYPE)
1037
1038 roi_start_t = convert_to_dst_type(src=roi_start, dst=boxes_t, wrap_sequence=True)[0].to(torch.int16)
1039 roi_end_t = convert_to_dst_type(src=roi_end, dst=boxes_t, wrap_sequence=True)[0].to(torch.int16)
1040 roi_end_t = torch.maximum(roi_end_t, roi_start_t)
1041
1042 # makes sure the bounding boxes are within the patch
1043 spatial_dims = get_spatial_dims(boxes=boxes, spatial_size=roi_end)
1044 for axis in range(spatial_dims):
1045 boxes_t[:, axis] = boxes_t[:, axis].clamp(min=roi_start_t[axis], max=roi_end_t[axis] - TO_REMOVE)
1046 boxes_t[:, axis + spatial_dims] = boxes_t[:, axis + spatial_dims].clamp(
1047 min=roi_start_t[axis], max=roi_end_t[axis] - TO_REMOVE
1048 )
1049 boxes_t[:, axis] -= roi_start_t[axis]
1050 boxes_t[:, axis + spatial_dims] -= roi_start_t[axis]
1051
1052 # remove the boxes that are actually empty
1053 if remove_empty:
1054 keep_t = boxes_t[:, spatial_dims] >= boxes_t[:, 0] + 1 - TO_REMOVE
1055 for axis in range(1, spatial_dims):
1056 keep_t = keep_t & (boxes_t[:, axis + spatial_dims] >= boxes_t[:, axis] + 1 - TO_REMOVE)
1057 boxes_t = boxes_t[keep_t]
1058 else:
1059 keep_t = torch.full_like(boxes_t[:, 0], fill_value=True, dtype=torch.bool)
1060
1061 # convert tensor back to numpy if needed
1062 boxes_keep, *_ = convert_to_dst_type(src=boxes_t, dst=boxes)
1063 keep, *_ = convert_to_dst_type(src=keep_t, dst=boxes, dtype=keep_t.dtype)
1064
1065 return boxes_keep, keep
1066
1067
1068def clip_boxes_to_image(

Callers 2

__call__Method · 0.90
clip_boxes_to_imageFunction · 0.85

Calls 4

convert_data_typeFunction · 0.90
convert_to_dst_typeFunction · 0.90
get_spatial_dimsFunction · 0.85
cloneMethod · 0.80

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…