Ë
    ¼Ó^jŒ  ã                  ót   — d dl mZ d dlZd dlmZmZ d dlmZ d dlm	Z	 d dl
Zd dlmZ d dlmZ  G d„ d	«      Zy)
é    )ÚannotationsN)ÚdefaultdictÚdeque)Údeepcopy)Úcast)Ú
Detections)ÚSupervisionWarningsc                  ó2   — e Zd ZdZddd„Zd	d„Zd
d„Zdd„Zy)ÚDetectionsSmootheru·
  
    A utility class for smoothing detections over multiple frames in video tracking.
    It maintains a history of detections for each track and provides smoothed
    predictions based on these histories.

    <video controls>
        <source
            src="https://media.roboflow.com/supervision-detection-smoothing.mp4"
            type="video/mp4">
    </video>

    !!! warning

        - `DetectionsSmoother` requires the `tracker_id` for each detection. Refer to
          [Roboflow Trackers](/latest/trackers/) for
          information on integrating tracking into your inference pipeline.
        - This class is not compatible with segmentation models.
        - When detections in a frame disagree on confidence presence â€” some tracks
          carry confidence scores and others do not â€” `confidence` is set to `None`
          for all smoothed detections in that frame.

    Example:
        ```pycon
        >>> import numpy as np
        >>> import supervision as sv
        >>> smoother = sv.DetectionsSmoother(length=3)
        >>> detections_1 = sv.Detections(
        ...     xyxy=np.array([[0, 0, 10, 10]]),
        ...     confidence=np.array([0.5]),
        ...     tracker_id=np.array([1])
        ... )
        >>> detections_2 = sv.Detections(
        ...     xyxy=np.array([[2, 2, 12, 12]]),
        ...     confidence=np.array([0.7]),
        ...     tracker_id=np.array([1])
        ... )
        >>> smoothed = smoother.update_with_detections(detections_1)
        >>> smoothed.xyxy
        array([[ 0.,  0., 10., 10.]])
        >>> smoothed = smoother.update_with_detections(detections_2)
        >>> smoothed.xyxy
        array([[ 1.,  1., 11., 11.]])
        >>> smoothed.confidence
        array([0.6])

        ```


        ```python
        import supervision as sv

        from ultralytics import YOLO

        video_info = sv.VideoInfo.from_video_path(video_path="<SOURCE_FILE_PATH>")
        frame_generator = sv.get_video_frames_generator(
            source_path="<SOURCE_FILE_PATH>")

        model = YOLO("<MODEL_PATH>")
        tracker = sv.ByteTrack(frame_rate=video_info.fps)
        smoother = sv.DetectionsSmoother()

        box_annotator = sv.BoxAnnotator()

        with sv.VideoSink("<TARGET_FILE_PATH>", video_info=video_info) as sink:
            for frame in frame_generator:
                result = model(frame)[0]
                detections = sv.Detections.from_ultralytics(result)
                detections = tracker.update_with_detections(detections)
                detections = smoother.update_with_detections(detections)

                annotated_frame = box_annotator.annotate(frame.copy(), detections)
                sink.write_frame(annotated_frame)
        ```
    c                ó,   ‡— t        ˆfd„«      | _        y)z�
        Args:
            length: The maximum number of frames to consider for smoothing
                detections. Defaults to 5.
        c                 ó   •— t        ‰ ¬«      S )N)Úmaxlen)r   )Úlengths   €úo/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/supervision/detection/tools/smoother.pyú<lambda>z-DetectionsSmoother.__init__.<locals>.<lambda>a   s   ø€ ”E Ô(€ ó    N)r   Útracks)Úselfr   s    `r   Ú__init__zDetectionsSmoother.__init__Z   s   ø€ ô CNÛ(óC
ˆ�r   c                ó–  — |j                   €t        j                  dt        ¬«       |S t	        t        |«      «      D ]K  }|j                   |   }t        |«      }| j                  |   j                  t        t        ||   «      «       ŒM | j                  j                  «       D ]/  }||j                   vsŒ| j                  |   j                  d«       Œ1 t        | j                  j                  «       «      D ]8  }t        | j                  |   D �cg c]  }|du ‘Œ c}«      sŒ,| j                  |= Œ: | j                  «       S c c}w )zŸ
        Updates the smoother with a new set of detections from a frame.

        Args:
            detections: The detections to add to the smoother.
        NzŠSmoothing skipped. DetectionsSmoother requires tracker_id. Refer to https://supervision.roboflow.com/latest/trackers for more information.)Úcategory)Ú
tracker_idÚwarningsÚwarnr	   ÚrangeÚlenÚintr   Úappendr   r   ÚkeysÚlistÚallÚget_smoothed_detections)r   Ú
detectionsÚdetection_idxÚtracker_id_valuer   Útrack_idÚds          r   Úupdate_with_detectionsz)DetectionsSmoother.update_with_detectionsd   s/  € ð × Ñ Ð(Ü�M‰Mðô -õ	ð Ðä"¤3 z£?Ó3ò 	XˆMØ)×4Ñ4°]ÑCÐÜÐ-Ó.ˆJà�K‰K˜
Ñ#×*Ñ*¬4´
¸JÀ}Ñ<UÓ+VÕWð		Xð Ÿ™×(Ñ(Ó*ò 	3ˆHØ˜z×4Ñ4Ò4Ø—‘˜HÑ%×,Ñ,¨TÕ2ð	3ô ˜TŸ[™[×-Ñ-Ó/Ó0ò 	*ˆHÜ t§{¡{°8Ñ'<Ö= !�A˜’IÒ=Õ>Ø—K‘K Ñ)ð	*ð ×+Ñ+Ó-Ð-ùò >s   ÄE
c                óè  — | j                   j                  |d«      }|€y|D �cg c]  }|€Œ|‘Œ	 }}t        |«      dk(  ryt        |d   «      }t	        j
                  |D �cg c]  }|j                  ‘Œ c}d¬«      |_        |D �cg c]  }|j                  €Œ|j                  ‘Œ }}|r1t	        j
                  t	        j                  |«      d¬«      |_        |S d|_        |S c c}w c c}w c c}w )aE  Return the smoothed `Detections` for a single track.

        Averages `xyxy` over all valid (non-`None`) frames in the track window.
        `confidence` is averaged only over frames that carry it; frames with
        `confidence=None` are excluded. Returns `None` when the track is unknown
        or its entire window is empty.

        Args:
            track_id: The tracker ID whose smoothed detection to retrieve.

        Returns:
            Smoothed `Detections` for the track, or `None` if the track is
            unknown or all frames in its window are empty.
        Nr   )Úaxis)	r   Úgetr   r   ÚnpÚmeanÚxyxyÚ
confidenceÚarray)r   r&   Útrackr'   ÚvalidÚretÚconfidencess          r   Ú	get_trackzDetectionsSmoother.get_track…   sÙ   € ð —‘—‘ ¨$Ó/ˆØˆ=Øà.3Ö"E¨°q±}¢1Ð"EˆÐ"EÜˆu‹:˜Š?Øä�u˜Q‘xÓ ˆÜ—7‘7¨EÖ2 q˜AŸF›FÒ2¸Ô;ˆŒð .3ÖO¨°a·l±lÑ6N�q—|“|ÐOˆÐOÙCNœŸ™¤§¡¨+Ó!6¸QÔ?ˆŒàˆ
ð UYˆŒàˆ
ùò #Fùò
 3ùò Ps   ¤C%¬C%Á"C*ÂC/ÂC/c                ó@  — g }| j                   D ]'  }| j                  |«      }|€Œ|j                  |«       Œ) |r t        d„ |D «       «      r|D ]	  }d |_        Œ t        j                  |«      }t        |«      dk(  r t        j                  g t        ¬«      |_        |S )Nc              3  ó8   K  — | ]  }|j                   d u –— Œ y ­w)N)r/   )Ú.0r'   s     r   ú	<genexpr>z=DetectionsSmoother.get_smoothed_detections.<locals>.<genexpr>°   s   è ø€ Ò%W¸q a§l¡l°dÔ&:Ñ%Wùs   ‚r   )Údtype)r   r5   r   Úanyr/   r   Úmerger   r,   r0   r   r   )r   Útracked_detectionsr&   r1   r'   r#   s         r   r"   z*DetectionsSmoother.get_smoothed_detections¦   sž   € ØÐØŸ™ò 	1ˆHØ—N‘N 8Ó,ˆEØÑ Ø"×)Ñ)¨%Õ0ð	1ñ ¤#Ñ%WÐDVÔ%WÔ"WØ'ò $�Ø#�•ð$ô  ×%Ñ%Ð&8Ó9ˆ
Üˆz‹?˜aÒÜ$&§H¡H¨R´sÔ$;ˆJÔ!àÐr   N)é   )r   r   ÚreturnÚNone)r#   r   r?   r   )r&   r   r?   zDetections | None)r?   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r(   r5   r"   © r   r   r   r      s   „ ñIôV
ó.óBôBr   r   )Ú
__future__r   r   Úcollectionsr   r   Úcopyr   Útypingr   Únumpyr,   Úsupervision.detection.corer   Úsupervision.utils.internalr	   r   rE   r   r   ú<module>rM      s)   ðÝ "ã ß *Ý Ý ã å 1Ý :÷jò jr   