Detection#

kornia.metrics.mean_average_precision(pred_boxes, pred_labels, pred_scores, gt_boxes, gt_labels, n_classes, threshold=0.5)[source]#

Calculate the Mean Average Precision (mAP) of detected objects.

Code altered from sgrvinod/a-PyTorch-Tutorial-to-Object-Detection.

Convention:
  • Every argument but n_classes and threshold is a list with one tensor per image. The call raises when the five lists differ in length, when the boxes, labels and scores of an image differ in their number of rows, or when a label lies outside [0, n_classes) or is not a whole number: a floating-point label such as 1.0 counts as class 1, and 1.5 raises. Boxes are exclusive xyxy, the default format of mean_iou_bbox(), which computes the overlaps.

  • Class 0 is background: its objects and detections are never scored, and n_classes counts it, so the classes 1 to n_classes - 1 are scored.

  • The detections of a class are ranked by score over all images at once, so the AP is not a mean of per-image APs. In that order, a detection takes the object of its image and class that it overlaps most; it is a true positive when that IoU is strictly greater than threshold and the object is not taken yet, and a false positive otherwise. A class with objects and no detection has AP 0.

  • A class without objects in any image has no AP: its entry is -1.0 and it stays out of the mean, so neither a larger n_classes nor detections of such a class change the mAP. Without any foreground object the mAP is -1.0 too.

  • The AP is the 11-point interpolated AP of PASCAL VOC2007: the mean, over the recall levels 0, 0.1, ..., 1, of the highest precision at a recall of at least that level.

  • The result is a 0-d tensor and a dict of Python floats, fractions in \([0, 1]\) apart from that -1.0. The tensor takes the floating dtype of the boxes: integer boxes count as float32, and predicted and ground-truth boxes of different dtypes give the promotion of those two floating dtypes (float32 when one set is integer and the other float16). Losses and metrics compares the match rule with the VOC devkit and COCO.

Parameters:
  • pred_boxes (List[Tensor]) – a torch.Tensor list of predicted bounding boxes.

  • pred_labels (List[Tensor]) – a torch.Tensor list of predicted labels in [0, n_classes).

  • pred_scores (List[Tensor]) – a torch.Tensor list of predicted labels’ scores.

  • gt_boxes (List[Tensor]) – a torch.Tensor list of ground truth bounding boxes.

  • gt_labels (List[Tensor]) – a torch.Tensor list of ground truth labels in [0, n_classes).

  • n_classes (int) – the number of classes, background (class 0) included.

  • threshold (float, optional) – count as a positive if the overlap is greater than the threshold. Default: 0.5

Return type:

Tuple[Tensor, Dict[int, float]]

Returns:

the mAP, and a dict mapping each scored class id to its average precision.

Examples

>>> boxes, labels, scores = torch.tensor([[100, 50, 150, 100.]]), torch.tensor([1]), torch.tensor([.7])
>>> gt_boxes, gt_labels = torch.tensor([[100, 50, 150, 100.]]), torch.tensor([1])
>>> mean_average_precision([boxes], [labels], [scores], [gt_boxes], [gt_labels], 2)
(tensor(1.), {1: 1.0})
kornia.metrics.mean_iou_bbox(boxes_1, boxes_2, box_format='xyxy')[source]#

Compute the IoU of the cartesian product of two sets of boxes.

Convention:
  • The result is the IoU of every pair, \((B1, B2)\), each a fraction in \([0, 1]\); despite the name, nothing is averaged, and swapping the two sets transposes it.

  • Boxes are exclusive in every box_format: the area of (x1, y1, x2, y2) is \((x_2 - x_1)(y_2 - y_1)\), with no + 1, as in nms(). A box with a non-positive width or height raises AssertionError, unless the call captures a graph (torch.compile or torch.export), which skips the check and gives such a box an IoU of 0 or NaN. A Boxes gives the same IoU through to_tensor('xyxy'), not through its inclusive 'xyxy_plus' export.

Parameters:
  • boxes_1 (Tensor) – a tensor of bounding boxes in \((B1, 4)\).

  • boxes_2 (Tensor) – a tensor of bounding boxes in \((B2, 4)\).

  • box_format (str, optional) – the bounding box format. Supported formats are: - ‘xyxy’: (x1, y1, x2, y2) where (x1, y1) is top-left and (x2, y2) is bottom-right - ‘xywh’: (x, y, w, h) where (x, y) is top-left, w is width, h is height - ‘cxcywh’: (cx, cy, w, h) where (cx, cy) is center, w is width, h is height Default: ‘xyxy’.

Return type:

Tensor

Returns:

a tensor in dimensions \((B1, B2)\), representing the IoU of each of the boxes in set 1 with each of the boxes in set 2.

Note

Integer (and bool) boxes are computed in float32, so the result is float32 and widths, areas and the union do not wrap around in a narrow integer dtype such as uint8, int8 or int16.

Example

>>> # XYXY format
>>> boxes_1 = torch.tensor([[40, 40, 60, 60], [30, 40, 50, 60]])
>>> boxes_2 = torch.tensor([[40, 50, 60, 70], [30, 40, 40, 50]])
>>> mean_iou_bbox(boxes_1, boxes_2)
tensor([[0.3333, 0.0000],
        [0.1429, 0.2500]])
>>> # XYWH format
>>> boxes_1_xywh = torch.tensor([[40, 40, 20, 20], [30, 40, 20, 20]])
>>> boxes_2_xywh = torch.tensor([[40, 50, 20, 20], [30, 40, 10, 10]])
>>> mean_iou_bbox(boxes_1_xywh, boxes_2_xywh, box_format='xywh')
tensor([[0.3333, 0.0000],
        [0.1429, 0.2500]])
>>> # CXCYWH format
>>> boxes_1_cxcywh = torch.tensor([[50, 50, 20, 20], [40, 50, 20, 20]])
>>> boxes_2_cxcywh = torch.tensor([[50, 60, 20, 20], [35, 45, 10, 10]])
>>> mean_iou_bbox(boxes_1_cxcywh, boxes_2_cxcywh, box_format='cxcywh')
tensor([[0.3333, 0.0000],
        [0.1429, 0.2500]])