Files
wehub-resource-sync 9194ef5abd
Docs/Test Workflow / Test docs build (push) Failing after 0s
Check links & references / links-check (push) Failing after 1s
Pytest/Test Workflow / Import Test and Pytest Run (ubuntu-latest, 3.10) (push) Failing after 0s
Pytest/Test Workflow / Import Test and Pytest Run (ubuntu-latest, 3.11) (push) Failing after 0s
PR Conflict Labeler / main (push) Failing after 2s
Pytest/Test Workflow / Import Test and Pytest Run (ubuntu-latest, 3.12) (push) Failing after 2s
Pytest/Test Workflow / Import Test and Pytest Run (ubuntu-latest, 3.13) (push) Failing after 0s
Pytest/Test Workflow / Build this Package (push) Failing after 5s
Pytest/Test Workflow / Import Test and Pytest Run (macos-latest, 3.10) (push) Has been cancelled
Pytest/Test Workflow / Import Test and Pytest Run (macos-latest, 3.11) (push) Has been cancelled
Pytest/Test Workflow / Import Test and Pytest Run (macos-latest, 3.12) (push) Has been cancelled
Pytest/Test Workflow / Import Test and Pytest Run (macos-latest, 3.13) (push) Has been cancelled
Pytest/Test Workflow / Import Test and Pytest Run (windows-latest, 3.10) (push) Has been cancelled
Pytest/Test Workflow / Import Test and Pytest Run (windows-latest, 3.11) (push) Has been cancelled
Pytest/Test Workflow / Import Test and Pytest Run (windows-latest, 3.12) (push) Has been cancelled
Pytest/Test Workflow / Import Test and Pytest Run (windows-latest, 3.13) (push) Has been cancelled
Pytest/Test Workflow / testing-guardian (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:06:10 +08:00

63 lines
2.2 KiB
Python

"""Tests for supervision.metrics.utils.object_size — mask pixel-count path."""
from __future__ import annotations
import numpy as np
import pytest
from supervision.metrics.utils.object_size import (
SIZE_THRESHOLDS,
ObjectSizeCategory,
get_mask_size_category,
)
def _reference_mask_size_category(mask: np.ndarray) -> np.ndarray:
"""Reference categorization using a plain ``np.sum`` area."""
areas = np.sum(mask, axis=(1, 2))
result = np.full(areas.shape, ObjectSizeCategory.ANY.value)
sm, lg = SIZE_THRESHOLDS
result[areas < sm] = ObjectSizeCategory.SMALL.value
result[(areas >= sm) & (areas < lg)] = ObjectSizeCategory.MEDIUM.value
result[areas >= lg] = ObjectSizeCategory.LARGE.value
return result
class TestGetMaskSizeCategory:
"""Verify the count_nonzero-based mask area categorization."""
@pytest.mark.parametrize(
("n", "h", "w", "seed"),
[
pytest.param(0, 8, 8, 1, id="empty"),
pytest.param(1, 40, 40, 2, id="single"),
pytest.param(6, 64, 64, 3, id="batch"),
pytest.param(4, 200, 200, 4, id="across-thresholds"),
],
)
def test_matches_sum_based_reference(
self, n: int, h: int, w: int, seed: int
) -> None:
"""Categories match a plain ``np.sum(axis=(1, 2))`` reference."""
rng = np.random.default_rng(seed)
mask = rng.random((n, h, w)) < rng.random()
np.testing.assert_array_equal(
get_mask_size_category(mask), _reference_mask_size_category(mask)
)
def test_threshold_boundaries(self) -> None:
"""Pixel counts on each SMALL/MEDIUM/LARGE boundary land in the right bin."""
sm, lg = SIZE_THRESHOLDS
mask = np.zeros((3, 100, 100), dtype=bool)
mask[0].flat[: sm - 1] = True # below SMALL threshold -> SMALL
mask[1].flat[:sm] = True # exactly SMALL threshold -> MEDIUM
mask[2].flat[:lg] = True # exactly LARGE threshold -> LARGE
np.testing.assert_array_equal(
get_mask_size_category(mask),
[
ObjectSizeCategory.SMALL.value,
ObjectSizeCategory.MEDIUM.value,
ObjectSizeCategory.LARGE.value,
],
)