Skip to content

instance_segmentation

Point-mask instance-segmentation metrics: per-scene instance matches and their average precision.

Classes:

  • InstanceMatches –

    One scene of predicted instance masks reduced against its ground truth (the output of instance_matches).

Functions:

  • instance_matches –

    Reduce one scene's instance predictions to the compact match record scored by instance_average_precision.

  • instance_average_precision –

    Point-mask instance-segmentation average precision (AP) of matched instance predictions.

InstanceMatches [source]

Bases: TypedDict

One scene of predicted instance masks reduced against its ground truth (the output of instance_matches).

Holds per-instance counts and pairwise intersections only, nothing mask-sized: \(K\) predictions, \(I\) ground-truth instances (ordered by ascending id) and \(M\) same-class (prediction, instance) pairs with a nonzero intersection.

Attributes:

  • pred_labels (Tensor) –

    Per-prediction class, shape \((K,)\).

  • pred_scores (Tensor) –

    Per-prediction confidence score, shape \((K,)\).

  • pred_counts (Tensor) –

    Per-prediction point count, shape \((K,)\).

  • pred_void (Tensor) –

    Per-prediction count of void points (ignored label or no instance), shape \((K,)\).

  • gt_labels (Tensor) –

    Per-instance class, shape \((I,)\).

  • gt_counts (Tensor) –

    Per-instance point count, shape \((I,)\).

  • pair_pred (Tensor) –

    Prediction index of each overlapping pair, shape \((M,)\).

  • pair_gt (Tensor) –

    Instance index of each overlapping pair, shape \((M,)\).

  • pair_inter (Tensor) –

    Number of points shared by each overlapping pair, shape \((M,)\).

instance_matches [source]

instance_matches(
    pred_masks: Tensor,
    pred_labels: Tensor,
    pred_scores: Tensor,
    gt_instance: Tensor,
    gt_label: Tensor,
    *,
    ignore_index: int = -1,
) -> InstanceMatches

Reduce one scene's instance predictions to the compact match record scored by instance_average_precision.

Predicted masks are dense \((K, N)\) booleans: a few hundred masks over a \(\sim 50\text{k}\)-point scene is only tens of MB and intersections reduce to bincounts, while index lists would be ragged and no smaller. The returned record holds per-instance counts and pairwise intersections only, so nothing mask-sized outlives the call and a whole validation split can be accumulated scene by scene.

Ground truth instances are the unique gt_instance ids among points with a non-negative id and a valid semantic label; points whose gt_label equals ignore_index are void, and predictions overlapping them are excused accordingly during scoring. Each instance must carry a single semantic label. Intersections are recorded for same-class (prediction, instance) pairs only.

Parameters:

  • pred_masks (Tensor) –

    Per-instance point masks, shape \((K, N)\) bool.

  • pred_labels (Tensor) –

    Per-instance class indices, shape \((K,)\).

  • pred_scores (Tensor) –

    Per-instance confidences, shape \((K,)\).

  • gt_instance (Tensor) –

    Per-point ground-truth instance ids, shape \((N,)\); negative marks no instance.

  • gt_label (Tensor) –

    Per-point semantic labels in the instance-class space, shape \((N,)\).

  • ignore_index (int, default: -1 ) –

    Semantic label marking void points.

Returns:

  • InstanceMatches –

    The InstanceMatches record of the scene, as CPU tensors.

Example
>>> masks = torch.tensor([[True, True, True, True]])
>>> match = instance_matches(
...     masks, torch.tensor([0]), torch.tensor([0.9]), torch.tensor([0, 0, 1, -1]), torch.tensor([0, 0, 0, -1])
... )
>>> match["gt_counts"].tolist(), match["pair_inter"].tolist(), match["pred_void"].tolist()
([2, 1], [2, 1], [1])

instance_average_precision [source]

instance_average_precision(
    matches: Sequence[InstanceMatches],
    *,
    iou_threshold: Union[float, Sequence[float]] = ...,
    average: Literal["macro"] = ...,
    num_classes: Optional[int] = ...,
    class_names: Optional[Sequence[str]] = ...,
    min_points: int = ...,
) -> float
instance_average_precision(
    matches: Sequence[InstanceMatches],
    *,
    iou_threshold: Union[float, Sequence[float]] = ...,
    average: Literal["none"],
    num_classes: Optional[int] = ...,
    class_names: None = ...,
    min_points: int = ...,
) -> Tensor
instance_average_precision(
    matches: Sequence[InstanceMatches],
    *,
    iou_threshold: Union[float, Sequence[float]] = ...,
    average: Literal["none"],
    num_classes: Optional[int] = ...,
    class_names: Sequence[str],
    min_points: int = ...,
) -> Dict[str, float]
instance_average_precision(
    matches: Sequence[InstanceMatches],
    *,
    iou_threshold: Union[float, Sequence[float]] = (
        0.5,
        0.55,
        0.6,
        0.65,
        0.7,
        0.75,
        0.8,
        0.85,
        0.9,
    ),
    average: Literal["macro", "none"] = "macro",
    num_classes: Optional[int] = None,
    class_names: Optional[Sequence[str]] = None,
    min_points: int = 100,
) -> Union[float, Tensor, Dict[str, float]]

Point-mask instance-segmentation average precision (AP) of matched instance predictions.

Follows the standard indoor instance-segmentation protocol (the ScanNet benchmark): per class and IoU threshold, ground-truth instances greedily consume overlapping predicted masks above the threshold, duplicates on a matched instance count as false positives with the lower score, and an unmatched prediction whose void / small-instance point fraction exceeds the threshold is excused. The AP integrates the score-swept precision-recall curve with centered recall steps, and is averaged over the IoU thresholds: the default sweep \(0.5, 0.55, \ldots, 0.9\) is the benchmark's headline AP, iou_threshold=0.5 and 0.25 its AP50 and AP25. A class is scored when it has ground truth.

Parameters:

  • matches (Sequence[InstanceMatches]) –

    The instance_matches record of every evaluated scene.

  • iou_threshold (Union[float, Sequence[float]], default: (0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9) ) –

    IoU a match must exceed, or a sequence of them to average the AP over.

  • average (Literal['macro', 'none'], default: 'macro' ) –

    "macro" returns the mean AP (mAP) over the scored classes; "none" returns the per-class AP.

  • num_classes (Optional[int], default: None ) –

    Number of instance classes, i.e. the length of the average="none" output; defaults to the number of class_names, else to the largest class index met plus one.

  • class_names (Optional[Sequence[str]], default: None ) –

    Name of each class index; with average="none" the per-class AP comes back as a {name: ap} dict instead of a tensor.

  • min_points (int, default: 100 ) –

    Minimum point count for a prediction or ground-truth instance to be scored; smaller ground-truth instances count as ignore regions.

Returns:

  • Union[float, Tensor, Dict[str, float]] –

    The mAP as a float with average="macro" (\(0\) when no class is scored), or the per-class AP, shape

  • Union[float, Tensor, Dict[str, float]] –

    \((C,)\) float64, with average="none" (a {name: ap} dict when class_names is given), holding NaN

  • Union[float, Tensor, Dict[str, float]] –

    for the classes without ground truth.

Shape
  • output: scalar, or \((C,)\) with average="none"
Example
>>> masks = torch.tensor([[True, True, True, False], [False, False, False, True]])
>>> match = instance_matches(
...     masks,
...     torch.tensor([0, 1]),
...     torch.tensor([0.9, 0.8]),
...     torch.tensor([0, 0, 0, 1]),
...     torch.tensor([0, 0, 0, 1]),
... )
>>> instance_average_precision([match], min_points=1)
1.0
>>> instance_average_precision([match], iou_threshold=0.5, average="none", class_names=["chair", "table"], min_points=1)
{'chair': 1.0, 'table': 1.0}