from contextlib import ExitStack as DoesNotRaise import pytest from supervision import Detections from typing import Optional, Union, List import numpy as np from test.utils import mock_detections PREDICTIONS = np.array([ [ 2254, 906, 2447, 1353, 0.90538, 0], [ 2049, 1133, 2226, 1371, 0.59002, 56], [ 727, 1224, 838, 1601, 0.51119, 39], [ 808, 1214, 910, 1564, 0.45287, 39], [ 6, 52, 1131, 2133, 0.45057, 72], [ 299, 1225, 512, 1663, 0.45029, 39], [ 529, 874, 645, 945, 0.31101, 39], [ 8, 47, 1935, 2135, 0.28192, 72], [ 2265, 813, 2328, 901, 0.2714, 62] ], dtype=np.float32) DETECTIONS = Detections( xyxy=PREDICTIONS[:, :4], confidence=PREDICTIONS[:, 4], class_id=PREDICTIONS[:, 5].astype(int) ) @pytest.mark.parametrize( 'detections, index, expected_result, exception', [ ( DETECTIONS, DETECTIONS.class_id == 0, mock_detections( xyxy=[[2254, 906, 2447, 1353]], confidence=[0.90538], class_id=[0] ), DoesNotRaise() ), # take only detections with class_id = 0 ( DETECTIONS, DETECTIONS.confidence > 0.5, mock_detections( xyxy=[ [2254, 906, 2447, 1353], [2049, 1133, 2226, 1371], [727, 1224, 838, 1601] ], confidence=[0.90538, 0.59002, 0.51119], class_id=[0, 56, 39] ), DoesNotRaise() ), # take only detections with confidence > 0.5 ( DETECTIONS, np.array([True, True, True, True, True, True, True, True, True], dtype=bool), DETECTIONS, DoesNotRaise() ), # take all detections ( DETECTIONS, np.array([False, False, False, False, False, False, False, False, False], dtype=bool), Detections( xyxy=np.empty((0, 4), dtype=np.float32), confidence=np.array([], dtype=np.float32), class_id=np.array([], dtype=int) ), DoesNotRaise() ), # take no detections ( DETECTIONS, [0, 2], mock_detections( xyxy=[ [2254, 906, 2447, 1353], [727, 1224, 838, 1601] ], confidence=[0.90538, 0.51119], class_id=[0, 39] ), DoesNotRaise() ), # take only first and third detection using List[int] index ( DETECTIONS, np.array([0, 2]), mock_detections( xyxy=[ [2254, 906, 2447, 1353], [727, 1224, 838, 1601] ], confidence=[0.90538, 0.51119], class_id=[0, 39] ), DoesNotRaise() ), # take only first and third detection using np.ndarray index ( DETECTIONS, 0, mock_detections( xyxy=[[2254, 906, 2447, 1353]], confidence=[0.90538], class_id=[0] ), DoesNotRaise() ), # take only first detection by index ( DETECTIONS, slice(1, 3), mock_detections( xyxy=[ [2049, 1133, 2226, 1371], [727, 1224, 838, 1601] ], confidence=[0.59002, 0.51119], class_id=[56, 39] ), DoesNotRaise() ), # take only first detection by index slice (1, 3) ( DETECTIONS, 10, None, pytest.raises(IndexError) ), # index out of range ( DETECTIONS, [0, 2, 10], None, pytest.raises(IndexError) ), # index out of range ( DETECTIONS, np.array([0, 2, 10]), None, pytest.raises(IndexError) ), ( DETECTIONS, np.array([True, True, True, True, True, True, True, True, True, True, True]), None, pytest.raises(IndexError) ) ] ) def test_getitem( detections: Detections, index: Union[int, slice, List[int], np.ndarray], expected_result: Optional[Detections], exception: Exception ) -> None: with exception: result = detections[index] assert result == expected_result @pytest.mark.parametrize( 'detections_list, expected_result, exception', [ ( [], Detections.empty(), DoesNotRaise() ), # empty detections list ( [ Detections.empty() ], Detections.empty(), DoesNotRaise() ), # single empty detections ( [ mock_detections(xyxy=[[10, 10, 20, 20]]) ], mock_detections(xyxy=[[10, 10, 20, 20]]), DoesNotRaise() ), # single detection with xyxy field ( [ mock_detections(xyxy=[[10, 10, 20, 20]]), Detections.empty() ], mock_detections(xyxy=[[10, 10, 20, 20]]), DoesNotRaise() ), # single detection with xyxy field + empty detection ( [ mock_detections(xyxy=[[10, 10, 20, 20]]), mock_detections(xyxy=[[20, 20, 30, 30]]) ], mock_detections( xyxy=[ [10, 10, 20, 20], [20, 20, 30, 30] ]), DoesNotRaise() ), # two detections with xyxy field ( [ mock_detections( xyxy=[[10, 10, 20, 20]], class_id=[0]), mock_detections( xyxy=[[20, 20, 30, 30]]) ], mock_detections( xyxy=[ [10, 10, 20, 20], [20, 20, 30, 30] ]), DoesNotRaise() ), # detection with xyxy, class_id fields + detection with xyxy field ( [ mock_detections( xyxy=[[10, 10, 20, 20]], class_id=[0]), mock_detections( xyxy=[[20, 20, 30, 30]], class_id=[1]), ], mock_detections( xyxy=[ [10, 10, 20, 20], [20, 20, 30, 30] ], class_id=[0, 1] ), DoesNotRaise() ), # two detections with xyxy, class_id fields ] ) def test_merge( detections_list: List[Detections], expected_result: Optional[Detections], exception: Exception ) -> None: with exception: result = Detections.merge(detections_list=detections_list) assert result == expected_result