diff --git a/supervision/validators/__init__.py b/supervision/validators/__init__.py index 44cfcb988..1788708e2 100644 --- a/supervision/validators/__init__.py +++ b/supervision/validators/__init__.py @@ -2,6 +2,8 @@ import numpy as np +from supervision.utils.internal import warn_deprecated + def validate_xyxy(xyxy: Any) -> None: expected_shape = "(_, 4)" @@ -15,15 +17,29 @@ def validate_xyxy(xyxy: Any) -> None: def validate_mask(mask: Any, n: int) -> None: + if mask is None: + return + expected_shape = f"({n}, H, W)" actual_shape = str(getattr(mask, "shape", None)) - is_valid = mask is None or ( + actual_dtype = getattr(mask, "dtype", None) + + is_valid_shape = ( isinstance(mask, np.ndarray) and len(mask.shape) == 3 and mask.shape[0] == n ) - if not is_valid: + if not is_valid_shape: raise ValueError( - f"mask must be a 3D np.ndarray with shape {expected_shape}, but got shape " - f"{actual_shape}" + "Mask must be a 3D np.ndarray with shape " + + f"{expected_shape}, but got shape {actual_shape}" + ) + if not np.issubdtype(actual_dtype, bool): + warn_deprecated( + f"A `Detections` object was created with a mask of type {actual_dtype}." + " Masks of type other than `bool` are deprecated and may produce unexpected" + " behavior. Stricter type checking will be introduced in" + " `supervision-0.28.0`. Please use `mask = np.array(..., dtype=bool)` when" + " creating the mask manually. If you did not create the mask manually," + " please report the issue to the `supervision` team." ) diff --git a/test/dataset/formats/test_coco.py b/test/dataset/formats/test_coco.py index 7e269dae4..dc98ad323 100644 --- a/test/dataset/formats/test_coco.py +++ b/test/dataset/formats/test_coco.py @@ -227,7 +227,8 @@ def test_group_coco_annotations_by_image_id( [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], ] - ] + ], + dtype=bool, ), ), DoesNotRaise(), @@ -259,7 +260,8 @@ def test_group_coco_annotations_by_image_id( [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], ] - ] + ], + dtype=bool, ), ), DoesNotRaise(), @@ -304,7 +306,8 @@ def test_group_coco_annotations_by_image_id( [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], ], - ] + ], + dtype=bool, ), ), DoesNotRaise(), @@ -349,7 +352,8 @@ def test_group_coco_annotations_by_image_id( [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], ], - ] + ], + dtype=bool, ), ), DoesNotRaise(), @@ -461,7 +465,8 @@ def test_build_coco_class_index_mapping( [1, 1, 1, 1, 0], [1, 1, 1, 1, 0], ] - ] + ], + dtype=bool, ), ), 0, @@ -490,7 +495,8 @@ def test_build_coco_class_index_mapping( [0, 0, 0, 1, 1], [0, 0, 0, 1, 1], ] - ] + ], + dtype=bool, ), ), 0, @@ -522,7 +528,8 @@ def test_build_coco_class_index_mapping( [1, 1, 0, 0, 1], [1, 1, 1, 1, 1], ] - ] + ], + dtype=bool, ), ), 0, diff --git a/test/utils/test_internal.py b/test/utils/test_internal.py index eee614e6c..d90236619 100644 --- a/test/utils/test_internal.py +++ b/test/utils/test_internal.py @@ -157,7 +157,7 @@ def __private_property(self): xyxy=np.array([[1, 2, 3, 4], [5, 6, 7, 8]]), class_id=np.array([1, 2]), confidence=np.array([0.1, 0.2]), - mask=np.array([[[1]], [[2]]]), + mask=np.array([[[1]], [[2]]], dtype=bool), tracker_id=np.array([1, 2]), data={"key_1": [1, 2], "key_2": [3, 4]}, ),