detection_metrics / mask_utils.py
sklum's picture
Fix modules
3e2a0ca
raw
history blame
No virus
3.01 kB
# This code is a copy and paste with small modifications of the code:
# https://github.com/rafaelpadilla/review_object_detection_metrics/blob/main/src/evaluators/coco_evaluator.py
from typing import List
import numpy as np
class MaskEvaluator(object):
@staticmethod
def iou(
dt: List[List[float]], gt: List[List[float]], iscrowd: List[bool]
) -> np.ndarray:
"""
Calculate the intersection over union (IoU) between detection bounding boxes (dt) and \
ground truth bounding boxes (gt).
Reference: https://github.com/rafaelpadilla/review_object_detection_metrics
Args:
dt (List[List[float]]): List of detection bounding boxes in the \
format [x, y, width, height].
gt (List[List[float]]): List of ground-truth bounding boxes in the \
format [x, y, width, height].
iscrowd (List[bool]): List indicating if each ground-truth bounding box \
is a crowd region or not.
Returns:
np.ndarray: Array of IoU values of shape (len(dt), len(gt)).
"""
assert len(iscrowd) == len(gt), "iou(iscrowd=) must have the same length as gt"
if len(dt) == 0 or len(gt) == 0:
return []
ious = np.zeros((len(dt), len(gt)), dtype=np.float64)
for g_idx, g in enumerate(gt):
for d_idx, d in enumerate(dt):
ious[d_idx, g_idx] = _jaccard(d, g, iscrowd[g_idx])
return ious
def _jaccard(a: List[float], b: List[float], iscrowd: bool) -> float:
"""
Calculate the Jaccard index (intersection over union) between two bounding boxes.
For "crowd" regions, we use a modified criteria. If a gt object is
marked as "iscrowd", we allow a dt to match any subregion of the gt.
Choosing gt' in the crowd gt that best matches the dt can be done using
gt'=intersect(dt,gt). Since by definition union(gt',dt)=dt, computing
iou(gt,dt,iscrowd) = iou(gt',dt) = area(intersect(gt,dt)) / area(dt)
For crowd gt regions we use this modified criteria above for the iou.
Args:
a (List[float]): Bounding box coordinates in the format [x, y, width, height].
b (List[float]): Bounding box coordinates in the format [x, y, width, height].
iscrowd (bool): Flag indicating if the second bounding box is a crowd region or not.
Returns:
float: Jaccard index between the two bounding boxes.
"""
eps = 4e-12
xa, ya, x2a, y2a = a[0], a[1], a[0] + a[2], a[1] + a[3]
xb, yb, x2b, y2b = b[0], b[1], b[0] + b[2], b[1] + b[3]
# innermost left x
xi = max(xa, xb)
# innermost right x
x2i = min(x2a, x2b)
# same for y
yi = max(ya, yb)
y2i = min(y2a, y2b)
# calculate areas
Aa = max(x2a - xa, 0.) * max(y2a - ya, 0.)
Ab = max(x2b - xb, 0.) * max(y2b - yb, 0.)
Ai = max(x2i - xi, 0.) * max(y2i - yi, 0.)
if iscrowd:
return Ai / (Aa + eps)
return Ai / (Aa + Ab - Ai + eps)