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

Function box_giou

monai/data/box_utils.py:863–924  ·  view source on GitHub ↗

Compute the generalized intersection over union (GIoU) of two sets of boxes. The two inputs can have different shapes and the func return an NxM matrix, (in contrary to :func:`~monai.data.box_utils.box_pair_giou` , which requires the inputs to have the same shape and returns ``N`` v

(boxes1: NdarrayOrTensor, boxes2: NdarrayOrTensor)

Source from the content-addressed store, hash-verified

861
862
863def box_giou(boxes1: NdarrayOrTensor, boxes2: NdarrayOrTensor) -> NdarrayOrTensor:
864 """
865 Compute the generalized intersection over union (GIoU) of two sets of boxes.
866 The two inputs can have different shapes and the func return an NxM matrix,
867 (in contrary to :func:`~monai.data.box_utils.box_pair_giou` , which requires the inputs to have the same
868 shape and returns ``N`` values).
869
870 Args:
871 boxes1: bounding boxes, Nx4 or Nx6 torch tensor or ndarray. The box mode is assumed to be ``StandardMode``
872 boxes2: bounding boxes, Mx4 or Mx6 torch tensor or ndarray. The box mode is assumed to be ``StandardMode``
873
874 Returns:
875 An array/tensor matching the container type of ``boxes1`` (NumPy ndarray or Torch tensor), always
876 floating-point with size ``(N, M)``:
877 - if ``boxes1`` has a floating-point dtype, the same dtype is used.
878 - if ``boxes1`` has an integer dtype, the result is returned as ``torch.float32``.
879
880 Reference:
881 https://giou.stanford.edu/GIoU.pdf
882
883 """
884
885 if not isinstance(boxes1, type(boxes2)):
886 warnings.warn(f"boxes1 is {type(boxes1)}, while boxes2 is {type(boxes2)}. The result will be {type(boxes1)}.")
887
888 # convert numpy to tensor if needed
889 boxes1_t, *_ = convert_data_type(boxes1, torch.Tensor)
890 boxes2_t, *_ = convert_data_type(boxes2, torch.Tensor)
891
892 spatial_dims = get_spatial_dims(boxes=boxes1_t)
893
894 # we do computation with compute_dtype to avoid overflow
895 box_dtype = boxes1_t.dtype
896
897 inter, union = _box_inter_union(boxes1_t, boxes2_t, compute_dtype=COMPUTE_DTYPE)
898 iou = inter / (union + torch.finfo(COMPUTE_DTYPE).eps) # (N,M)
899
900 # Enclosure
901 # get the left top and right bottom points for the NxM combinations
902 lt = torch.min(boxes1_t[:, None, :spatial_dims], boxes2_t[:, :spatial_dims]).to(
903 dtype=COMPUTE_DTYPE
904 ) # (N,M,spatial_dims) left top
905 rb = torch.max(boxes1_t[:, None, spatial_dims:], boxes2_t[:, spatial_dims:]).to(
906 dtype=COMPUTE_DTYPE
907 ) # (N,M,spatial_dims) right bottom
908
909 # compute size for the enclosure region for the NxM combinations
910 wh = (rb - lt + TO_REMOVE).clamp(min=0) # (N,M,spatial_dims)
911 enclosure = torch.prod(wh, dim=-1, keepdim=False) # (N,M)
912
913 # GIoU
914 giou_t = iou - (enclosure - union) / (enclosure + torch.finfo(COMPUTE_DTYPE).eps)
915 if not box_dtype.is_floating_point:
916 box_dtype = COMPUTE_DTYPE
917 giou_t = giou_t.to(dtype=box_dtype)
918
919 if torch.isnan(giou_t).any() or torch.isinf(giou_t).any():
920 raise ValueError("Box GIoU is NaN or Inf.")

Callers

nothing calls this directly

Calls 4

convert_data_typeFunction · 0.90
convert_to_dst_typeFunction · 0.90
get_spatial_dimsFunction · 0.85
_box_inter_unionFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…