from typing import Optional
[docs]
def sample_avg_bbox_size(gt, /) -> float:
"""
Computes the average bounding box size (area) across all annotations in the given Ground Truth.
Parameters:
gt: The Ground Truth object containing images and annotations.
Returns:
float: The average bounding box size (area) across all annotations.
"""
sum_area: float = 0.0
count: int = 0
for anns in gt.annotations.values():
for ann in anns:
sum_area += ann.bbox_coords.area
count += 1
if count == 0:
raise ValueError(f"No annotations found in Ground Truth: {gt.name}")
return sum_area / float(count)
[docs]
def sample_avg_bboxes_per_image(gt, /) -> float:
"""
Computes the average number of bounding boxes per image in the given Ground Truth.
Parameters:
gt: The Ground Truth object containing images and annotations.
Returns:
float: The average number of bounding boxes per image.
"""
image_count: int = len(gt.images)
if image_count == 0:
raise ValueError(f"No images found in Ground Truth: {gt.name}")
total_bboxes: int = sum(len(anns) for anns in gt.annotations.values())
if total_bboxes == 0:
raise ValueError(f"No annotations found in Ground Truth: {gt.name}")
return float(total_bboxes) / float(image_count)
[docs]
def sample_global_avg_bbox_size(gts: list, /) -> float:
"""
Computes the global average bounding box size (area) across all provided Ground Truths.
Parameters:
gts (list): A list of Ground Truth objects.
Returns:
float: The global average bounding box size (area) across all provided Ground Truths.
"""
avgs: list[float] = []
for gt in gts:
avg_size: float = sample_avg_bbox_size(gt)
avgs.append(avg_size)
if not avgs:
raise ValueError("No average bounding box sizes could be computed from the provided Ground Truths.")
return sum(avgs) / float(len(avgs))
[docs]
def sample_global_avg_bboxes_per_image(gts: list, /) -> float:
"""
Computes the global average number of bounding boxes per image across all provided Ground Truths.
Parameters:
gts (list): A list of Ground Truth objects.
Returns:
float: The global average number of bounding boxes per image across all provided Ground Truths.
"""
avgs: list[float] = []
for gt in gts:
avg_count: float = sample_avg_bboxes_per_image(gt)
avgs.append(avg_count)
if not avgs:
raise ValueError("No average bounding boxes per image could be computed from the provided Ground Truths.")
return sum(avgs) / float(len(avgs))
[docs]
def get_min_max_bbox_size(gts: list, /, *, filename: Optional[str] = None) -> tuple[float, float]:
"""
Computes the minimum and maximum bounding box sizes (areas) across all annotations in the provided Ground Truths.
Parameters:
gts (list): A list of Ground Truth objects.
filename (Optional[str]): If provided, only annotations from the specified image filename will be considered. If None, all annotations from all images will be considered.
Returns:
tuple[float, float]: A tuple containing the minimum and maximum bounding box sizes (areas) across the specified annotations.
"""
min_size: float = float('inf')
max_size: float = float('-inf')
annotations: list = []
if filename is not None:
for gt in gts:
anns = gt.annotations[filename]
annotations.extend(anns)
else:
for gt in gts:
for anns in gt.annotations.values():
annotations.extend(anns)
for ann in annotations:
area = ann.bbox_coords.area
if area < min_size:
min_size = area
if area > max_size:
max_size = area
if min_size == float('inf') or max_size == float('-inf'):
raise ValueError("No bounding box sizes could be computed from the provided Ground Truths.")
return (min_size, max_size)