o
    eXx                     @  s   d dl mZ d dlmZmZ d dlmZmZmZm	Z	m
Z
mZmZ d dlZd dlmZmZmZmZmZ d dlmZ dddZd ddZd!ddZd"ddZd#ddZd$ddZeG dd dZdS )%    )annotations)astuple	dataclass)AnyDictIteratorListOptionalTupleUnionN)calculate_masks_centroidsextract_ultralytics_masksnon_max_suppressionprocess_roboflow_resultxywh_to_xyxy)Positionxyxyr   nintreturnNonec                 C  s*   t | tjo| j|dfk}|stdd S )N   z,xyxy must be 2d np.ndarray with (n, 4) shape
isinstancenpndarrayshape
ValueError)r   r   is_valid r   I/var/www/myenv/lib/python3.10/site-packages/supervision/detection/core.py_validate_xyxy   s   r!   maskc                 C  s@   | d u pt | tjot| jdko| jd |k}|stdd S )N   r   z/mask must be 3d np.ndarray with (n, H, W) shape)r   r   r   lenr   r   )r"   r   r   r   r   r    _validate_mask   s   &r%   c                 C  s.   t jdt jd}| |}t|tstdd S )N)   r&   r#   dtypez/Callback function must return sv.Detection type)r   zerosuint8r   
Detectionsr   )callbacktmp_imgresr   r   r    validate_inference_callback    s
   
r/   class_idc                 C  0   | d u pt | tjo| j|fk}|stdd S )Nz6class_id must be None or 1d np.ndarray with (n,) shaper   )r0   r   r   r   r   r    _validate_class_id'      r2   
confidencec                 C  r1   )Nz8confidence must be None or 1d np.ndarray with (n,) shaper   )r4   r   r   r   r   r    _validate_confidence/   r3   r5   
tracker_idc                 C  r1   )Nz8tracker_id must be None or 1d np.ndarray with (n,) shaper   )r6   r   r   r   r   r    _validate_tracker_id7   r3   r7   c                   @  sf  e Zd ZU dZded< dZded< dZded< dZded< dZded	< d
d Z	dd Z
dMddZdNddZedOddZedOddZedOddZedOddZedOddZedPd!d"ZedOd#d$ZedQd&d'ZedRd*d+Ze	dSdTd/d0ZedOd1d2ZedOd3d4ZedUd7d8ZdVd;d<ZdWd?d@ZedXdAdBZedXdCdDZ	FdYdZdKdLZ dS )[r+   a  
    Data class containing information about the detections in a video frame.

    Attributes:
        xyxy (np.ndarray): An array of shape `(n, 4)` containing
            the bounding boxes coordinates in format `[x1, y1, x2, y2]`
        mask: (Optional[np.ndarray]): An array of shape
            `(n, H, W)` containing the segmentation masks.
        confidence (Optional[np.ndarray]): An array of shape
            `(n,)` containing the confidence scores of the detections.
        class_id (Optional[np.ndarray]): An array of shape
            `(n,)` containing the class ids of the detections.
        tracker_id (Optional[np.ndarray]): An array of shape
            `(n,)` containing the tracker ids of the detections.
    
np.ndarrayr   NzOptional[np.ndarray]r"   r4   r0   r6   c                 C  sT   t | j}t| j|d t| j|d t| j|d t| j|d t	| j
|d d S )N)r   r   )r"   r   )r0   r   )r4   r   )r6   r   )r$   r   r!   r%   r"   r2   r0   r5   r4   r7   r6   )selfr   r   r   r    __post_init__W   s   
zDetections.__post_init__c                 C  s
   t | jS )zL
        Returns the number of detections in the Detections object.
        )r$   r   r9   r   r   r    __len___   s   
zDetections.__len__r   `Iterator[Tuple[np.ndarray, Optional[np.ndarray], Optional[float], Optional[int], Optional[int]]]c                 c  s    t t| jD ]5}| j| | jdur| j| nd| jdur#| j| nd| jdur.| j| nd| jdur9| j| ndfV  qdS )z
        Iterates over the Detections object and yield a tuple of
        `(xyxy, mask, confidence, class_id, tracker_id)` for each detection.
        N)ranger$   r   r"   r4   r0   r6   )r9   ir   r   r    __iter__e   s   zDetections.__iter__otherc                 C  s   t t| j|jt| jd u o|jd u t| j|jgt| jd u o%|jd u t| j|jgt| jd u o8|jd u t| j|jgt| jd u oK|jd u t| j|jggS N)	allr   array_equalr   anyr"   r0   r4   r6   )r9   rA   r   r   r    __eq__}   s0   zDetections.__eq__c                 C  sR   |j d    }| |ddddf |dddf |dddf tdS )a  
        Creates a Detections instance from a
        [YOLOv5](https://github.com/ultralytics/yolov5) inference result.

        Args:
            yolov5_results (yolov5.models.common.Detections):
                The output Detections instance from YOLOv5

        Returns:
            Detections: A new Detections object.

        Example:
            ```python
            >>> import cv2
            >>> import torch
            >>> import supervision as sv

            >>> image = cv2.imread(SOURCE_IMAGE_PATH)
            >>> model = torch.hub.load('ultralytics/yolov5', 'yolov5s')
            >>> result = model(image)
            >>> detections = sv.Detections.from_yolov5(result)
            ```
        r   Nr      r   r4   r0   )predcpunumpyastyper   )clsyolov5_resultsyolov5_detections_predictionsr   r   r    from_yolov5   s   zDetections.from_yolov5c                 C  sd   | |j j  |j j  |j j  tt||j j	dur.|j j	   dS ddS )a  
        Creates a Detections instance from a
            [YOLOv8](https://github.com/ultralytics/ultralytics) inference result.

        Args:
            ultralytics_results (ultralytics.yolo.engine.results.Results):
                The output Results instance from YOLOv8

        Returns:
            Detections: A new Detections object.

        Example:
            ```python
            >>> import cv2
            >>> from ultralytics import YOLO, FastSAM, SAM, RTDETR
            >>> import supervision as sv

            >>> image = cv2.imread(SOURCE_IMAGE_PATH)
            >>> model = YOLO('yolov8s.pt')
            >>> model = SAM('sam_b.pt')
            >>> model = SAM('mobile_sam.pt')
            >>> model = FastSAM('FastSAM-s.pt')
            >>> model = RTDETR('rtdetr-l.pt')
            >>> # model inferences
            >>> result = model(image)[0]
            >>> # if tracker is enabled
            >>> result = model.track(image)[0]
            >>> detections = sv.Detections.from_ultralytics(result)
            ```
        Nr   r4   r0   r"   r6   )
boxesr   rJ   rK   confrM   rL   r   r   id)rM   ultralytics_resultsr   r   r    from_ultralytics   s   !zDetections.from_ultralyticsc                 C  s@   t |jjjd dkr|  S | |jj|jj|jjt	dS )a  
        Creates a Detections instance from a
        [YOLO-NAS](https://github.com/Deci-AI/super-gradients/blob/master/YOLONAS.md)
        inference result.

        Args:
            yolo_nas_results (ImageDetectionPrediction):
                The output Results instance from YOLO-NAS
                ImageDetectionPrediction is coming from
                'super_gradients.training.models.prediction_results'

        Returns:
            Detections: A new Detections object.

        Example:
            ```python
            >>> import cv2
            >>> from super_gradients.training import models
            >>> import supervision as sv

            >>> image = cv2.imread(SOURCE_IMAGE_PATH)
            >>> model = models.get('yolo_nas_l', pretrained_weights="coco")
            >>> result = list(model.predict(image, conf=0.35))[0]
            >>> detections = sv.Detections.from_yolo_nas(result)
            ```
        r   rH   )
r   asarray
predictionbboxes_xyxyr   emptyr4   labelsrL   r   )rM   yolo_nas_resultsr   r   r    from_yolo_nas   s   zDetections.from_yolo_nasc                 C  s`   t |jd jd dkr|  S | t |jd t |jd t |jd t	t
dS )a  
        Creates a Detections instance from a
        [DeepSparse](https://github.com/neuralmagic/deepsparse)
        inference result.

        Args:
            deepsparse_results (deepsparse.yolo.schemas.YOLOOutput):
                The output Results instance from DeepSparse.

        Returns:
            Detections: A new Detections object.

        Example:
            ```python
            >>> from deepsparse import Pipeline
            >>> import supervision as sv

            >>> yolo_pipeline = Pipeline.create(
            ...     task="yolo",
            ...     model_path = "zoo:cv/detection/yolov5-l/pytorch/"             ...                  "ultralytics/coco/pruned80_quant-none"
            >>> pipeline_outputs = yolo_pipeline(SOURCE_IMAGE_PATH,
            ...                         iou_thres=0.6, conf_thres=0.001)
            >>> detections = sv.Detections.from_deepsparse(result)
            ```
        r   rH   )r   rW   rR   r   rZ   arrayscoresr[   rL   floatr   )rM   deepsparse_resultsr   r   r    from_deepsparse  s   zDetections.from_deepsparsec                 C  s8   | |j j  |j j  |j j  tdS )a  
        Creates a Detections instance from
        a [mmdetection](https://github.com/open-mmlab/mmdetection) inference result.
        Also supported for [mmyolo](https://github.com/open-mmlab/mmyolo)

        Args:
            mmdet_results (mmdet.structures.DetDataSample):
                The output Results instance from MMDetection.

        Returns:
            Detections: A new Detections object.

        Example:
            ```python
            >>> import cv2
            >>> import supervision as sv
            >>> from mmdet.apis import DetInferencer

            >>> inferencer = DetInferencer(model_name, checkpoint, device)
            >>> mmdet_result = inferencer(SOURCE_IMAGE_PATH, out_dir='./output',
            ...                           return_datasamples=True)["predictions"][0]
            >>> detections = sv.Detections.from_mmdet(mmdet_result)
            ```
        rH   )pred_instancesbboxesrJ   rK   r_   r[   rL   r   )rM   mmdet_resultsr   r   r    from_mmdetection2  s
   zDetections.from_mmdetectiontransformers_resultsdictc                 C  s8   | |d    |d    |d    tdS )z
        Creates a Detections instance from object detection
        [transformer](https://github.com/huggingface/transformers) inference result.

        Returns:
            Detections: A new Detections object.
        rR   r_   r[   rH   )rJ   rK   rL   r   )rM   rg   r   r   r    from_transformersS  s
   
zDetections.from_transformersc                 C  s@   | |d j j  |d j  |d j  tdS )a  
        Create a Detections object from the
        [Detectron2](https://github.com/facebookresearch/detectron2) inference result.

        Args:
            detectron2_results: The output of a
                Detectron2 model containing instances with prediction data.

        Returns:
            (Detections): A Detections object containing the bounding boxes,
                class IDs, and confidences of the predictions.

        Example:
            ```python
            >>> import cv2
            >>> from detectron2.engine import DefaultPredictor
            >>> from detectron2.config import get_cfg
            >>> import supervision as sv

            >>> image = cv2.imread(SOURCE_IMAGE_PATH)
            >>> cfg = get_cfg()
            >>> cfg.merge_from_file("path/to/config.yaml")
            >>> cfg.MODEL.WEIGHTS = "path/to/model_weights.pth"
            >>> predictor = DefaultPredictor(cfg)
            >>> result = predictor(image)
            >>> detections = sv.Detections.from_detectron2(result)
            ```
        	instancesrH   )
pred_boxestensorrJ   rK   r_   pred_classesrL   r   )rM   detectron2_resultsr   r   r    from_detectron2c  s   zDetections.from_detectron2roboflow_resultc                 C  sB   t |d\}}}}}t|jd dkr|  S | |||||dS )aB  
        Create a Detections object from the [Roboflow](https://roboflow.com/)
            API inference result.

        Args:
            roboflow_result (dict): The result from the
                Roboflow API containing predictions.

        Returns:
            (Detections): A Detections object containing the bounding boxes, class IDs,
                and confidences of the predictions.

        Example:
            ```python
            >>> import supervision as sv

            >>> roboflow_result = {
            ...     "predictions": [
            ...         {
            ...             "x": 0.5,
            ...             "y": 0.5,
            ...             "width": 0.2,
            ...             "height": 0.3,
            ...             "class_id": 0,
            ...             "class": "person",
            ...             "confidence": 0.9
            ...         },
            ...         # ... more predictions ...
            ...     ]
            ... }

            >>> detections = sv.Detections.from_roboflow(roboflow_result)
            ```
        )rp   r   rQ   )r   r   rW   r   rZ   )rM   rp   r   r4   r0   maskstrackersr   r   r    from_roboflow  s   $zDetections.from_roboflow
sam_result
List[dict]c                 C  sl   t |dd dd}tdd |D }tdd |D }t|jd dkr+|  S t|d	}| ||d
S )a  
        Creates a Detections instance from
        [Segment Anything Model](https://github.com/facebookresearch/segment-anything)
        inference result.

        Args:
            sam_result (List[dict]): The output Results instance from SAM

        Returns:
            Detections: A new Detections object.

        Example:
            ```python
            >>> import supervision as sv
            >>> from segment_anything import (
            ...     sam_model_registry,
            ...     SamAutomaticMaskGenerator
            ... )

            >>> sam_model_reg = sam_model_registry[MODEL_TYPE]
            >>> sam = sam_model_reg(checkpoint=CHECKPOINT_PATH).to(device=DEVICE)
            >>> mask_generator = SamAutomaticMaskGenerator(sam)
            >>> sam_result = mask_generator.generate(IMAGE)
            >>> detections = sv.Detections.from_sam(sam_result=sam_result)
            ```
        c                 S  s   | d S )Narear   )xr   r   r    <lambda>  s    z%Detections.from_sam.<locals>.<lambda>T)keyreversec                 S     g | ]}|d  qS )bboxr   .0r"   r   r   r    
<listcomp>      z'Detections.from_sam.<locals>.<listcomp>c                 S  r{   )segmentationr   r}   r   r   r    r     r   r   )
boxes_xywh)r   r"   )sortedr   r^   rW   r   rZ   r   )rM   rt   sorted_generated_masksxywhr"   r   r   r   r    from_sam  s   

zDetections.from_samazure_result	class_mapOptional[Dict[int, str]]c                 C  s>  d|v rt d|d d  g g g }}}|du }|ri }dd | D }|d d D ]V}|d	 }|d
 }	|d }
|d }|
|d  }||d  }|	D ]5}|d }|d }||d}|rl|du rlt|}|||< |dur||
|||g || || qNq.t|dkrt S | t|t|t|dS )a
  
        Creates a Detections instance from [Azure Image Analysis 4.0](
        https://learn.microsoft.com/en-us/azure/ai-services/computer-vision/
        concept-object-detection-40).

        Args:
            azure_result (dict): The result from Azure Image Analysis. It should
                contain detected objects and their bounding box coordinates.
            class_map (Optional[Dict[int, str]]): A mapping ofclass IDs (int) to class
                names (str). If None, a new mapping is created dynamically.

        Returns:
            Detections: A new Detections object.

        Example:
            ```python
            >>> import requests
            >>> import supervision as sv

            >>> image = open(input, "rb").read()

            >>> endpoint = "https://.cognitiveservices.azure.com/"
            >>> subscription_key = "..."

            >>> headers = {
            ...    "Content-Type": "application/octet-stream",
            ...    "Ocp-Apim-Subscription-Key": subscription_key
            ... }

            >>> response = requests.post(endpoint,
            ...     headers=self.headers,
            ...     data=image
            ... ).json()

            >>> detections = sv.Detections.from_azure_analyze_image(response)
            ```
        errorzAzure API returned an error messageNc                 S  s   i | ]\}}||qS r   r   )r~   ry   valuer   r   r    
<dictcomp>      z7Detections.from_azure_analyze_image.<locals>.<dictcomp>objectsResultvaluesboundingBoxtagsrw   ywhr4   namer   )r   r0   r4   )	r   itemsgetr$   appendr+   rZ   r   r^   )rM   r   r   r   confidences	class_idsis_dynamic_mapping	detectionr|   r   x0y0x1y1tagr4   
class_namer0   r   r   r    from_azure_analyze_image  sH   )

z#Detections.from_azure_analyze_imagec                 C  sx   t |d ddddf jd dkr|  S | |d ddddf |d dddf |d dddf tdS )a  
        Creates a Detections instance from
            [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection)
            inference result.

        Args:
            paddledet_result (List[dict]): The output Results instance from PaddleDet

        Returns:
            Detections: A new Detections object.

        Example:
            ```python
            >>> import supervision as sv
            >>> import paddle
            >>> from ppdet.engine import Trainer
            >>> from ppdet.core.workspace import load_config

            >>> weights = (...)
            >>> config = (...)

            >>> cfg = load_config(config)
            >>> trainer = Trainer(cfg, mode='test')
            >>> trainer.load_weights(weights)

            >>> paddledet_result = trainer.predict([images])[0]

            >>> detections = sv.Detections.from_paddledet(paddledet_result)
            ```
        r|   N      r      rH   )r   rW   r   rZ   rL   r   )rM   paddledet_resultr   r   r    from_paddledet?  s   (!zDetections.from_paddledetc                 C  s0   | t jdt jdt jg t jdt jg tddS )a\  
        Create an empty Detections object with no bounding boxes,
            confidences, or class IDs.

        Returns:
            (Detections): An empty Detections object.

        Example:
            ```python
            >>> from supervision import Detections

            >>> empty_detections = Detections.empty()
            ```
        )r   r   r'   rH   )r   rZ   float32r^   r   )rM   r   r   r    rZ   i  s
   zDetections.emptydetections_listList[Detections]c           	      C  s   t |dkr
t S dd |D }dd t| D \}}}}}ddd}t|}||r2t|nd	}||r=t|nd	}||rHt|nd	}||rSt|nd	}| |||||d
S )a  
        Merge a list of Detections objects into a single Detections object.

        This method takes a list of Detections objects and combines their
        respective fields (`xyxy`, `mask`, `confidence`, `class_id`, and `tracker_id`)
        into a single Detections object. If all elements in a field are not
        `None`, the corresponding field will be stacked.
        Otherwise, the field will be set to `None`.

        Args:
            detections_list (List[Detections]): A list of Detections objects to merge.

        Returns:
            (Detections): A single Detections object containing
                the merged data from the input list.

        Example:
            ```python
            >>> from supervision import Detections

            >>> detections_1 = Detections(...)
            >>> detections_2 = Detections(...)

            >>> merged_detections = Detections.merge([detections_1, detections_2])
            ```
        r   c                 S     g | ]}t |qS r   )r   )r~   r   r   r   r    r     r   z$Detections.merge.<locals>.<listcomp>c                 S  r   r   )list)r~   fieldr   r   r    r     s    	item_list	List[Any]c                 S  s   t dd | D S )Nc                 s  s    | ]}|d uV  qd S rB   r   )r~   rw   r   r   r    	<genexpr>  s    z;Detections.merge.<locals>.__all_not_none.<locals>.<genexpr>)rC   )r   r   r   r    __all_not_none  s   z(Detections.merge.<locals>.__all_not_noneNr   r"   r4   r0   r6   )r   r   )r$   r+   rZ   zipr   vstackhstack)	rM   r   detections_tuples_listr   r"   r4   r0   r6   _Detections__all_not_noner   r   r    merge  s&   

zDetections.mergeanchorr   c                 C  s  |t jkr2t| jdddf | jdddf  d | jdddf | jdddf  d g S |t jkrF| jdu r@tdt	| jdS |t j
krmt| jdddf | jdddf | jdddf  d g S |t jkrt| jdddf | jdddf | jdddf  d g S |t jkrt| jdddf | jdddf  d | jdddf g S |t jkrt| jdddf | jdddf g S |t jkrt| jdddf | jdddf g S |t jkrt| jdddf | jdddf  d | jdddf g S |t jkr8t| jdddf | jdddf g S |t jkrUt| jdddf | jdddf g S t| d)	aQ  
        Calculates and returns the coordinates of a specific anchor point
        within the bounding boxes defined by the `xyxy` attribute. The anchor
        point can be any of the predefined positions in the `Position` enum,
        such as `CENTER`, `CENTER_LEFT`, `BOTTOM_RIGHT`, etc.

        Args:
            anchor (Position): An enum specifying the position of the anchor point
                within the bounding box. Supported positions are defined in the
                `Position` enum.

        Returns:
            np.ndarray: An array of shape `(n, 2)`, where `n` is the number of bounding
                boxes. Each row contains the `[x, y]` coordinates of the specified
                anchor point for the corresponding bounding box.

        Raises:
            ValueError: If the provided `anchor` is not supported.
        Nr   r   r   r#   z>Cannot use `Position.CENTER_OF_MASS` without a detection mask.)rq   z is not supported.)r   CENTERr   r^   r   	transposeCENTER_OF_MASSr"   r   r   CENTER_LEFTCENTER_RIGHTBOTTOM_CENTERBOTTOM_LEFTBOTTOM_RIGHT
TOP_CENTERTOP_LEFT	TOP_RIGHT)r9   r   r   r   r    get_anchors_coordinates  sf   
&&


&
&
8
.
.8..z"Detections.get_anchors_coordinatesindex(Union[int, slice, List[int], np.ndarray]c                 C  s|   t |tr|g}t| j| | jdur| j| nd| jdur"| j| nd| jdur-| j| nd| jdur:| j| dS ddS )a  
        Get a subset of the Detections object.

        Args:
            index (Union[int, slice, List[int], np.ndarray]):
                The index or indices of the subset of the Detections

        Returns:
            (Detections): A subset of the Detections object.

        Example:
            ```python
            >>> import supervision as sv

            >>> detections = sv.Detections(...)

            >>> first_detection = detections[0]

            >>> first_10_detections = detections[0:10]

            >>> some_detections = detections[[0, 2, 4]]

            >>> class_0_detections = detections[detections.class_id == 0]

            >>> high_confidence_detections = detections[detections.confidence > 0.5]
            ```
        Nr   )r   r   r+   r   r"   r4   r0   r6   )r9   r   r   r   r    __getitem__  s   
zDetections.__getitem__c                 C  s&   | j durtdd | j D S | jS )a  
        Calculate the area of each detection in the set of object detections.
        If masks field is defined property returns are of each mask.
        If only box is given property return area of each box.

        Returns:
          np.ndarray: An array of floats containing the area of each detection
            in the format of `(area_1, area_2, ..., area_n)`,
            where n is the number of detections.
        Nc                 S  s   g | ]}t |qS r   )r   sumr}   r   r   r    r   +  r   z#Detections.area.<locals>.<listcomp>)r"   r   r^   box_arear;   r   r   r    rv     s   
zDetections.areac                 C  sH   | j dddf | j dddf  | j dddf | j dddf   S )a7  
        Calculate the area of each bounding box in the set of object detections.

        Returns:
            np.ndarray: An array of floats containing the area of each bounding
                box in the format of `(area_1, area_2, ..., area_n)`,
                where n is the number of detections.
        Nr#   r   r   r   )r   r;   r   r   r    r   /  s   H
zDetections.box_area      ?F	thresholdr`   class_agnosticboolc                 C  s   t | dkr| S | jdusJ d|r*t| j| jddf}t||d}| | S | jdus3J dt| j| jdd| jddf}t||d}| | S )a  
        Perform non-maximum suppression on the current set of object detections.

        Args:
            threshold (float, optional): The intersection-over-union threshold
                to use for non-maximum suppression. Defaults to 0.5.
            class_agnostic (bool, optional): Whether to perform class-agnostic
                non-maximum suppression. If True, the class_id of each detection
                will be ignored. Defaults to False.

        Returns:
            Detections: A new Detections object containing the subset of detections
                after non-maximum suppression.

        Raises:
            AssertionError: If `confidence` is None and class_agnostic is False.
                If `class_id` is None and class_agnostic is False.
        r   Nz;Detections confidence must be given for NMS to be executed.r   )predictionsiou_thresholdzDetections class_id must be given for NMS to be executed. If you intended to perform class agnostic NMS set class_agnostic=True.)r$   r4   r   r   r   reshaper   r0   )r9   r   r   r   indicesr   r   r    with_nms;  s&   zDetections.with_nms)r   r=   )rA   r+   )r   r+   )rg   rh   r   r+   )rp   rh   r   r+   )rt   ru   r   r+   rB   )r   rh   r   r   r   r+   )r   r   r   r+   )r   r   r   r8   )r   r   r   r+   )r   r8   )r   F)r   r`   r   r   r   r+   )!__name__
__module____qualname____doc____annotations__r"   r4   r0   r6   r:   r<   r@   rF   classmethodrP   rV   r]   rb   rf   ri   ro   rs   r   r   r   rZ   r   r   r   propertyrv   r   r   r   r   r   r    r+   ?   s\   
 

 *$$ '2)V)
4
B(r+   )r   r   r   r   r   r   )r"   r   r   r   r   r   )r   r   )r0   r   r   r   r   r   )r4   r   r   r   r   r   )r6   r   r   r   r   r   )
__future__r   dataclassesr   r   typingr   r   r   r   r	   r
   r   rK   r   supervision.detection.utilsr   r   r   r   r   supervision.geometry.corer   r!   r%   r/   r2   r5   r7   r+   r   r   r   r    <module>   s    $





