Detection#

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

Compute the PASCAL VOC mean average precision (mAP) of detections over a set of images.

mAP, ap = mean_average_precision(pred_boxes, pred_labels, pred_scores, gt_boxes, gt_labels, n_classes) takes one tensor per image in each list. It returns the mean over the scored classes of their 11-point interpolated AP as a 0-d tensor, and a dict of the per-class APs. Both are fractions in \([0, 1]\), or -1.0 where there is no object to score.

Convention:
  • 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 mAP 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]) – per-image predicted boxes, each with shape (N, 4).

  • pred_labels (List[Tensor]) – per-image predicted class labels, each with shape (N,).

  • pred_scores (List[Tensor]) – per-image confidence scores, each with shape (N,).

  • gt_boxes (List[Tensor]) – per-image ground-truth boxes, each with shape (M, 4).

  • gt_labels (List[Tensor]) – per-image ground-truth class labels, each with shape (M,).

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

  • threshold (float, optional) – the IoU a detection must exceed to be a true positive. Default: 0.5

Return type:

Tuple[Tensor, Dict[int, float]]

Returns:

the mAP and a dict mapping each foreground class id, 1 to n_classes - 1, to its AP.

See also

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})
Reference:

Adapted from sgrvinod/a-PyTorch-Tutorial-to-Object-Detection.

kornia.metrics.mean_iou_bbox(boxes_1, boxes_2, box_format='xyxy')[source]#

Compute the IoU of every pair of boxes from two sets.

iou = mean_iou_bbox(boxes_1, boxes_2) takes boxes of shape (B1, 4) and (B2, 4) and returns the IoU of each box of the first set with each box of the second, as fractions in \([0, 1]\). Despite the name, nothing is averaged.

Convention:
  • 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.

  • Swapping the two sets transposes the result.

Parameters:
  • boxes_1 (Tensor) – the first set of boxes, with shape (B1, 4).

  • boxes_2 (Tensor) – the second set of boxes, with shape (B2, 4).

  • box_format (str, optional) – 'xyxy' for (x1, y1, x2, y2) with the top-left and bottom-right corners, 'xywh' for (x, y, w, h) with the top-left corner, or 'cxcywh' for (cx, cy, w, h) with the center. Default: "xyxy"

Return type:

Tensor

Returns:

the IoU matrix with shape (B1, B2).

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.

See also

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]])