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
223 lines
5.1 KiB
Python
223 lines
5.1 KiB
Python
import numpy as np
|
|
import pytest
|
|
|
|
from supervision.detection.core import Detections
|
|
|
|
|
|
@pytest.fixture
|
|
def detections_50_50():
|
|
return Detections(
|
|
xyxy=np.array([[10, 10, 50, 50]], dtype=np.float32),
|
|
confidence=np.array([0.9]),
|
|
class_id=np.array([0]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def targets_50_50():
|
|
return Detections(
|
|
xyxy=np.array([[10, 10, 50, 50]], dtype=np.float32),
|
|
class_id=np.array([0]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def dummy_prediction():
|
|
return Detections(
|
|
xyxy=np.array([[10, 10, 20, 20]], dtype=np.float32),
|
|
confidence=np.array([0.8]),
|
|
class_id=np.array([0]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def predictions_no_overlap():
|
|
return Detections(
|
|
xyxy=np.array([[10, 10, 20, 20]], dtype=np.float32),
|
|
confidence=np.array([0.9]),
|
|
class_id=np.array([0]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def targets_no_overlap():
|
|
return Detections(
|
|
xyxy=np.array([[100, 100, 110, 110]], dtype=np.float32),
|
|
class_id=np.array([0]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def targets_two_objects_class_0():
|
|
return Detections(
|
|
xyxy=np.array(
|
|
[
|
|
[10, 10, 50, 50],
|
|
[100, 100, 110, 110],
|
|
],
|
|
dtype=np.float32,
|
|
),
|
|
class_id=np.array([0, 0]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def predictions_multiple_classes():
|
|
return Detections(
|
|
xyxy=np.array(
|
|
[
|
|
[10, 10, 50, 50], # class 0, matches target
|
|
[60, 60, 100, 100], # class 1, matches target
|
|
[120, 120, 130, 130], # class 1, false positive
|
|
],
|
|
dtype=np.float32,
|
|
),
|
|
confidence=np.array([0.9, 0.8, 0.7]),
|
|
class_id=np.array([0, 1, 1]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def targets_multiple_classes():
|
|
return Detections(
|
|
xyxy=np.array(
|
|
[
|
|
[10, 10, 50, 50], # class 0
|
|
[60, 60, 100, 100], # class 1
|
|
],
|
|
dtype=np.float32,
|
|
),
|
|
class_id=np.array([0, 1]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def predictions_iou_064():
|
|
return Detections(
|
|
xyxy=np.array([[15, 15, 55, 55]], dtype=np.float32),
|
|
confidence=np.array([0.9]),
|
|
class_id=np.array([0]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def targets_iou_064():
|
|
return Detections(
|
|
xyxy=np.array([[10, 10, 60, 60]], dtype=np.float32),
|
|
class_id=np.array([0]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def predictions_confidence_ranking():
|
|
return Detections(
|
|
xyxy=np.array(
|
|
[
|
|
[10, 10, 50, 50],
|
|
[11, 11, 49, 49],
|
|
],
|
|
dtype=np.float32,
|
|
),
|
|
confidence=np.array([0.6, 0.9]),
|
|
class_id=np.array([0, 0]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def prediction_class_1():
|
|
return Detections(
|
|
xyxy=np.array([[60, 60, 100, 100]], dtype=np.float32),
|
|
confidence=np.array([0.8]),
|
|
class_id=np.array([1]),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def target_class_1():
|
|
return Detections(
|
|
xyxy=np.array([[60, 60, 100, 100]], dtype=np.float32),
|
|
class_id=np.array([1]),
|
|
)
|
|
|
|
|
|
def _yolo_dataset_factory(
|
|
tmp_path,
|
|
num_images: int = 20,
|
|
classes: list[str] | None = None,
|
|
objects_per_image_range: tuple[int, int] = (1, 3),
|
|
):
|
|
"""
|
|
Factory function to create synthetic YOLO-format datasets with custom parameters.
|
|
|
|
Args:
|
|
tmp_path: Pytest tmp_path fixture
|
|
num_images: Number of images to generate
|
|
classes: List of class names
|
|
objects_per_image_range: Range of objects per image as (min, max)
|
|
|
|
Returns:
|
|
dict with dataset paths and metadata
|
|
"""
|
|
from tests.helpers import create_yolo_dataset
|
|
|
|
if classes is None:
|
|
classes = ["dog", "cat", "person"]
|
|
|
|
return create_yolo_dataset(
|
|
dataset_dir=str(tmp_path / "yolo_dataset"),
|
|
num_images=num_images,
|
|
image_size=(640, 640, 3),
|
|
classes=classes,
|
|
objects_per_image_range=objects_per_image_range,
|
|
seed=42,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def yolo_dataset_structure(tmp_path):
|
|
"""
|
|
Synthetic YOLO-format dataset for testing confusion matrix and detection metrics.
|
|
|
|
Configuration:
|
|
- 20 images
|
|
- 640x640 resolution
|
|
- 3 classes: ["dog", "cat", "person"]
|
|
- 1-3 objects per image
|
|
|
|
Use this for tests that need multi-class scenarios (3+ classes).
|
|
|
|
Returns:
|
|
dict with dataset paths and metadata
|
|
"""
|
|
return _yolo_dataset_factory(
|
|
tmp_path,
|
|
num_images=20,
|
|
classes=["dog", "cat", "person"],
|
|
objects_per_image_range=(1, 3),
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def yolo_dataset_two_classes(tmp_path):
|
|
"""
|
|
Synthetic YOLO-format dataset for testing mAR and binary classification metrics.
|
|
|
|
Configuration:
|
|
- 15 images
|
|
- 640x640 resolution
|
|
- 2 classes: ["class_0", "class_1"]
|
|
- 2-4 objects per image
|
|
|
|
Use this for tests that specifically need 2-class scenarios or depend on
|
|
specific class distributions (e.g., mAR @ K per-image limiting tests).
|
|
|
|
Returns:
|
|
dict with dataset paths and metadata
|
|
"""
|
|
return _yolo_dataset_factory(
|
|
tmp_path,
|
|
num_images=15,
|
|
classes=["class_0", "class_1"],
|
|
objects_per_image_range=(2, 4),
|
|
)
|