Ë
    ¼Ó^j©Ž  ã                  ó†  — d dl m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
Zd dlmZ d dlmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlm Z   e e!«      Z" G d„ de«      Z# G d„ de#«      Z$ G d„ de#«      Z% G d„ de#«      Z& G d„ de&«      Z' G d„ de&«      Z( G d„ de&«      Z)e'Z* G d„ d«      Z+y)é    )Úannotations)ÚABCÚabstractmethod)ÚSequence)ÚcastN)Ú	pad_boxesÚspread_out_boxes)Ú	ImageType)ÚColor)Údraw_rounded_rectangle)ÚRect)Ú	KeyPoints)ÚSKELETONS_BY_VERTEX_COUNT)Ú!ensure_cv2_image_for_class_method)Ú_get_loggerc                  ó   — e Zd Zedd„«       Zy)ÚBaseKeyPointAnnotatorc                 ó   — y ©N© )ÚselfÚsceneÚ
key_pointss      úl/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/supervision/key_points/annotators.pyÚannotatezBaseKeyPointAnnotator.annotate   s   € àó    N©r   r
   r   r   Úreturnr
   )Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r      s   „ Øòó ñr   r   c                  óN   — e Zd ZdZej
                  df	 	 	 	 	 dd„Zedd„«       Zy)ÚVertexAnnotatorz®
    A class that specializes in drawing skeleton vertices on images. It uses
    specified key points to determine the locations where the vertices should be
    drawn.
    é   c                ó    — || _         || _        y)z¦
        Args:
            color: The color to use for annotating key points.
            radius: The radius of the circles used to represent the key points.
        N)ÚcolorÚradius)r   r&   r'   s      r   Ú__init__zVertexAnnotator.__init__%   s   € ð ˆŒ
Øˆ�r   c           	     óÒ  — t        |t        j                  «      sJ ‚t        |«      dk(  r|S t	        |j
                  «      D ]¢  \  }}t	        |«      D ]�  \  }\  }}t        j                  ||fd«      rŒ"|j                  �|j                  ||f   sŒ@t        j                  |t        |«      t        |«      f| j                  | j                  j                  «       d¬«       Œ‘ Œ¤ |S )ak  
        Annotates the given scene with skeleton vertices based on the provided key
        points. It draws circles at each key point location. Anchors marked as
        not visible via ``key_points.visible`` are skipped.

        Args:
            scene: The image where skeleton vertices will be drawn. `ImageType` is a
                flexible type, accepting either `numpy.ndarray` or `PIL.Image.Image`.
            key_points: A collection of key points where each key point consists of x
                and y coordinates.

        Returns:
            The annotated image, matching the type of `scene` (`numpy.ndarray`
                or `PIL.Image.Image`)

        Example:
            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> image = np.zeros((800, 800, 3), dtype=np.uint8)
            >>> key_points = sv.KeyPoints(
            ...     xy=np.array(
            ...         [[[400, 200], [300, 500], [500, 500]]],
            ...         dtype=np.float32,
            ...     ),
            ...     class_id=np.array([0]),
            ...     visible=np.array([[True, True, True]]),
            ... )
            >>> annotator = sv.VertexAnnotator(
            ...     color=sv.Color.ROBOFLOW, radius=10
            ... )
            >>> result = annotator.annotate(image.copy(), key_points)

            ```
        r   éÿÿÿÿ)ÚimgÚcenterr'   r&   Ú	thickness)Ú
isinstanceÚnpÚndarrayÚlenÚ	enumerateÚxyÚallcloseÚvisibleÚcv2ÚcircleÚintr'   r&   Úas_bgr)r   r   r   Údetection_indexr3   Úpoint_indexÚxÚys           r   r   zVertexAnnotator.annotate2   sÚ   € ôJ ˜%¤§¡Ô,Ð,Ð,Üˆz‹?˜aÒØˆLä#,¨Z¯]©]Ó#;ò 	ÑˆO˜RÜ'0°£}ò Ñ#�™V˜a Ü—;‘;  1˜v qÔ)Øà×&Ñ&Ð2Ø&×.Ñ.¨ÀÐ/KÒLàÜ—
‘
ØÜ ›F¤C¨£FÐ+ØŸ;™;ØŸ*™*×+Ñ+Ó-Ø öñð	ð" ˆr   N)r&   r   r'   r8   r   ÚNoner   ©	r   r    r!   Ú__doc__r   ÚROBOFLOWr(   r   r   r   r   r   r#   r#      sH   „ ñð —~‘~Øðàðð ðð 
ó	ð 'ò9ó 'ñ9r   r#   c                  óT   — e Zd ZdZej
                  ddf	 	 	 	 	 	 	 dd„Zedd„«       Zy)ÚEdgeAnnotatorz¨
    A class that specializes in drawing skeleton edges on images using specified key
    points. It connects key points with lines to form the skeleton structure.
    é   Nc                ó.   — || _         || _        || _        y)a$  
        Args:
            color: The color to use for the edges.
            thickness: The thickness of the edges.
            edges: The edges to draw. If set to ``None``, will attempt to
                auto-detect the skeleton by vertex count. A
                ``Sequence[tuple[int, int]]`` applies a single skeleton to
                every instance. A ``dict[int, Sequence[tuple[int, int]]]``
                maps ``class_id`` to skeleton edges, enabling correct
                rendering for datasets with multiple skeleton types.
        N)r&   r-   Úedges)r   r&   r-   rF   s       r   r(   zEdgeAnnotator.__init__u   s   € ð& ˆŒ
Ø"ˆŒØˆ�
r   c                ó  — t        |t        j                  «      sJ ‚t        |«      dk(  r|S t	        |j
                  «      D �]Å  \  }}t        | j                  t        «      r`|j                  �t        |j                  |   «      nd}|€t        d«      ‚|| j                  vrt        d|› d�«      ‚| j                  |   }n[| j                  r| j                  }nBt        j                  t        |«      «      }|s t        j                  dt        |«      «       ŒÚ|}|D ]å  \  }}	|dz
  }
|	dz
  }||
   }||   }t        j                  |d«      st        j                  |d«      rŒG|j                   �#|j                   ||
f   r|j                   ||f   sŒvt#        j$                  |t        |d   «      t        |d   «      ft        |d   «      t        |d   «      f| j&                  j)                  «       | j*                  ¬«       Œç �ŒÈ |S )	až	  
        Annotates the given scene by drawing lines between specified key points to form
        edges. Edges where either endpoint is marked as not visible via
        ``key_points.visible`` are skipped.

        Args:
            scene: The image where skeleton edges will be drawn. `ImageType` is a
                flexible type, accepting either `numpy.ndarray` or `PIL.Image.Image`.
            key_points: A collection of key points where each key point consists of x
                and y coordinates.

        Returns:
            The annotated image, matching the type of `scene` (`numpy.ndarray`
                or `PIL.Image.Image`)

        Example:
            Single-skeleton example:

            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> image = np.zeros((800, 800, 3), dtype=np.uint8)
            >>> key_points = sv.KeyPoints(
            ...     xy=np.array(
            ...         [[[400, 200], [300, 500], [500, 500]]],
            ...         dtype=np.float32,
            ...     ),
            ...     class_id=np.array([0]),
            ...     visible=np.array([[True, True, True]]),
            ... )
            >>> annotator = sv.EdgeAnnotator(
            ...     color=sv.Color.ROBOFLOW,
            ...     thickness=3,
            ...     edges=[(1, 2), (1, 3)],
            ... )
            >>> result = annotator.annotate(image.copy(), key_points)

            ```

            Multi-skeleton example with per-class edges:

            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> image = np.zeros((800, 800, 3), dtype=np.uint8)
            >>> key_points = sv.KeyPoints(
            ...     xy=np.array(
            ...         [[[400, 200], [300, 500], [500, 500]],
            ...          [[700, 300], [650, 500], [0, 0]]],
            ...         dtype=np.float32,
            ...     ),
            ...     class_id=np.array([0, 1]),
            ...     visible=np.array(
            ...         [[True, True, True],
            ...          [True, True, False]],
            ...     ),
            ... )
            >>> annotator = sv.EdgeAnnotator(
            ...     color=sv.Color.ROBOFLOW,
            ...     thickness=3,
            ...     edges={0: [(1, 2), (1, 3)], 1: [(1, 2)]},
            ... )
            >>> result = annotator.annotate(image.copy(), key_points)

            ```
        r   NzGedges is a dict but class_id is None; KeyPoints must have class_id set.zNo edges defined for class_id=ú.z"No skeleton found with %d verticesé   )r+   Úpt1Úpt2r&   r-   )r.   r/   r0   r1   r2   r3   rF   ÚdictÚclass_idr8   Ú
ValueErrorr   ÚgetÚloggerÚwarningr4   r5   r6   Úliner&   r9   r-   )r   r   r   r:   r3   rM   rF   Ú
_looked_upÚclass_aÚclass_bÚidx_aÚidx_bÚxy_aÚxy_bs                 r   r   zEdgeAnnotator.annotateŒ   sö  € ôH ˜%¤§¡Ô,Ð,Ð,Üˆz‹?˜aÒØˆLä#,¨Z¯]©]Ó#;ó ,	ÑˆO˜RÜ˜$Ÿ*™*¤dÔ+ð "×*Ñ*Ð6ô ˜
×+Ñ+¨OÑ<Ô=àð ð
 Ð#Ü$ð<óð ð  4§:¡:Ñ-Ü$Ð'EÀhÀZÈqÐ%QÓRÐRØŸ
™
 8Ñ,‘Ø—’ØŸ
™
‘ä6×:Ñ:¼3¸r»7ÓC�
Ù!Ü—N‘NÐ#GÌÈRËÔQØØ"�à$)ò Ñ �˜Ø !™�Ø !™�Ø˜%‘y�Ø˜%‘y�Ü—;‘;˜t QÔ'¬2¯;©;°t¸QÔ+?ØØ×%Ñ%Ð1à&×.Ñ.¨ÀÐ/EÒFØ)×1Ñ1°/À5Ð2HÒIà ä—‘ØÜ˜T !™W›¤s¨4°©7£|Ð4Ü˜T !™W›¤s¨4°©7£|Ð4ØŸ*™*×+Ñ+Ó-Ø"Ÿn™nöòð1,	ð\ ˆr   )r&   r   r-   r8   rF   zGSequence[tuple[int, int]] | dict[int, Sequence[tuple[int, int]]] | Noner   r>   r   r?   r   r   r   rC   rC   o   sZ   „ ñð —~‘~Øð ðàðð ðð
 Tðð 
óð. 'òuó 'ñur   rC   c                  ó˜   — e Zd ZdZdej
                  ej                  ej                  fdf	 	 	 	 	 	 	 dd„Zd	d„Z		 	 	 	 d
d„Z
	 	 	 	 dd„Zy)Ú_BaseVertexEllipseAnnotatorz¾Private base for ellipse-based keypoint annotators.

    Handles sigma/color validation, sorting, covariance extraction and
    eigendecomposition shared by all VertexEllipse* variants.
    ©ç      ð?ç       @g      @Nc                ó4  ‡— t        |t        t        f«      r|fn|Št        |t        «      r|fn|}t	        ‰«      dk(  rt        d«      ‚t        d„ ‰D «       «      rt        d«      ‚|�|dk  rt        d«      ‚t	        |«      t	        ‰«      k7  r$t        dt	        |«      › dt	        ‰«      › d�«      ‚t        t        t	        ‰«      «      ˆfd	„d
¬«      }|D �cg c]  }‰|   ‘Œ	 c}| _	        |D �cg c]  }||   ‘Œ	 c}| _
        || _        y c c}w c c}w )Nr   z%sigma must contain at least one valuec              3  ó&   K  — | ]	  }|d k  –— Œ y­w)r   Nr   )Ú.0Úss     r   ú	<genexpr>z7_BaseVertexEllipseAnnotator.__init__.<locals>.<genexpr>  s   è ø€ Ò)˜!ˆq�A�vÑ)ùs   ‚z!All sigma values must be positivez'max_axis must be positive when providedzcolor length (z) must match sigma length (ú)c                ó   •— ‰|    S r   r   )ÚiÚ	sigma_seqs    €r   ú<lambda>z6_BaseVertexEllipseAnnotator.__init__.<locals>.<lambda>$  s   ø€ °¸1±€ r   T)ÚkeyÚreverse)r.   r8   Úfloatr   r1   rN   ÚanyÚsortedÚrangeÚsigmar&   Úmax_axis)r   ro   r&   rp   Ú	color_seqÚsorted_indicesrf   rg   s          @r   r(   z$_BaseVertexEllipseAnnotator.__init__  s  ø€ ô # 5¬3´¨,Ô7ˆU‰H¸Uð 	ô 2<¸EÄ5Ô1I e¡XÈuˆ	äˆy‹>˜QÒÜÐDÓEÐEÜÑ)˜yÔ)Ô)ÜÐ@ÓAÐAØÐ H°¢MÜÐFÓGÐGÜˆy‹>œS ›^Ò+ÜØ ¤ Y£Ð 0ð 1!Ü!$ Y£Ð 0°ð3óð ô
  Ü”#�i“.Ó!Ó'=Àtô
ˆð -;Ö; q�i “lÒ;ˆŒ
Ø,:Ö; q�i “lÒ;ˆŒ
Ø ˆ�ùò <ùÚ;s   ÃDÃ4Dc                óˆ  — |j                   j                  d«      }|€t        d«      ‚t        t        j
                  t        j                     t        j                  |t        j                  ¬«      «      }g |j                  j                  d d ¢d‘d‘­}|j                  |k7  rt        d|› d|j                  › d�«      ‚|S )NÚ
covariancezBkey_points.data must contain 'covariance' with shape (N, K, 2, 2).©ÚdtyperD   zExpected covariance shape z, got rH   )ÚdatarO   rN   r   ÚnptÚNDArrayr/   Úfloat32Úasarrayr3   Úshape)r   r   ÚcovariancesÚcovariances_arrayÚexpected_shapes        r   Ú_get_covariancesz,_BaseVertexEllipseAnnotator._get_covariances*  sÄ   € Ø —o‘o×)Ñ)¨,Ó7ˆØÐÜØTóð ô !Ü�K‰KœŸ
™
Ñ#¤R§Z¡Z°Ä2Ç:Á:Ô%Nó
Ðð :˜:Ÿ=™=×.Ñ.¨r°Ð2Ð9°AÐ9°qÑ9ˆØ×"Ñ" nÒ4ÜØ,¨^Ð,<ð =Ø(×.Ñ.Ð/¨qð2óð ð !Ð r   c                óÚ  — t        j                  |«      j                  «       sy	 t         j                  j	                  |j                  t         j                  «      «      \  }}t        j                  |«      j                  «       rt        j                  |dk  «      ryt        j                  |«      ddd…   }||   |dd…|f   fS # t         j                  j                  $ r Y yw xY w)zIEigendecompose a 2x2 covariance, returning sorted (eigenvalues, vectors).Nr   r*   )
r/   ÚisfiniteÚallÚlinalgÚeighÚastypeÚfloat64ÚLinAlgErrorrl   Úargsort)r   rt   ÚeigenvaluesÚeigenvectorsÚorders        r   Ú_decompose_covariancez1_BaseVertexEllipseAnnotator._decompose_covariance;  s¿   € ô �{‰{˜:Ó&×*Ñ*Ô,Øð	Ü(*¯	©	¯©°z×7HÑ7HÌÏÉÓ7TÓ(UÑ%ˆK˜ô �{‰{˜;Ó'×+Ñ+Ô-´·±¸ÀqÑ8HÔ1IØÜ—
‘
˜;Ó'©¨"¨Ñ-ˆØ˜5Ñ! <²°5°Ñ#9Ð9Ð9øô �y‰y×$Ñ$ò 	Ùð	ús   ¦?C
 Ã
C*Ã)C*c                ó   — | j                  |«      }| j                  D �cg c]  }g ‘Œ c}}t        |j                  «      D �]„  \  }}t        |«      D �]o  \  }\  }}	t	        j
                  ||	fd«      rŒ#|j                  �|j                  ||f   sŒA|||f   }
| j                  |
«      }|€Œ\|\  }}t        t	        j                  t	        j                  |d   |d   «      «      «      }t        |«      t        |	«      f}t        t        | j                  | j                  «      «      D ]•  \  }\  }}|t	        j                  |«      z  }| j                  � t	        j                   || j                  «      }t#        dt        |d   «      «      t#        dt        |d   «      «      f}||   j%                  |||||f«       Œ— �Œr �Œ‡ |S c c}w )z?Return ellipse params grouped by sigma level (outermost first).r   )rI   r   )r   r   rI   )r€   ro   r2   r3   r/   r4   r5   r�   rk   ÚdegreesÚarctan2ÚroundÚzipr&   Úsqrtrp   ÚminimumÚmaxÚappend)r   r   r}   Ú_Úlevelsr:   r3   r;   r<   r=   rt   ÚdecompositionrŠ   r‹   Úangler,   Ú	level_idxro   r&   ÚaxesÚaxis_lengthss                        r   Ú_iter_ellipse_paramsz0_BaseVertexEllipseAnnotator._iter_ellipse_paramsJ  sÇ  € ð ×+Ñ+¨JÓ7ˆð Ÿ™Ö$�AŠRÒ$ð 	ô $-¨Z¯]©]Ó#;ó 	ÑˆO˜RÜ'0°£}ó Ñ#�™V˜a Ü—;‘;  1˜v qÔ)Øà×&Ñ&Ð2Ø&×.Ñ.¨ÀÐ/KÒLàØ(¨¸+Ð)EÑF�
Ø $× :Ñ :¸:Ó F�Ø Ð(ØØ,9Ñ)�˜\ÜÜ—J‘JœrŸz™z¨,°tÑ*<¸lÈ4Ñ>PÓQÓRó�ô   ›(¤E¨!£HÐ-�Ü1:¼3¸t¿z¹zÈ4Ï:É:Ó;VÓ1Wò 
Ñ-�I™~  uØ ¤2§7¡7¨;Ó#7Ñ7�DØ—}‘}Ð0Ü!Ÿz™z¨$°·±Ó>˜ä˜Aœu T¨!¡W›~Ó.Ü˜Aœu T¨!¡W›~Ó.ð$�Lð ˜9Ñ%×,Ñ,Ø ¨u°e¸UÐCõò
ò#ð	ð: ˆùò= %s    	G)ro   úfloat | Sequence[float]r&   úColor | Sequence[Color]rp   úfloat | Noner   r>   )r   r   r   únpt.NDArray[np.float32])rt   r¢   r   z>tuple[npt.NDArray[np.float64], npt.NDArray[np.float64]] | None)r   r   r   zHlist[list[tuple[tuple[int, int], tuple[int, int], float, float, Color]]])r   r    r!   r@   r   ÚGREENÚYELLOWÚREDr(   r€   r�   rž   r   r   r   r[   r[     s   „ ñð *9Ø*/¯+©+°u·|±|ÀUÇYÁYÐ)OØ!%ð	!à&ð!ð 'ð!ð ð	!ð
 
ó!ó<!ð":Ø1ð:à	Gó:ð%Ø#ð%à	Qô%r   r[   c                  ó”   ‡ — e Zd ZdZdej
                  ej                  ej                  fddf	 	 	 	 	 	 	 	 	 dˆ fd„Ze	dd„«       Z
ˆ xZS )	ÚVertexEllipseAreaAnnotatora�  
    Draws filled semi-transparent covariance ellipses at multiple sigma levels
    around each keypoint, each ring in a different color.  This produces a
    bullseye-like uncertainty visualization where inner rings represent higher
    probability density.

    !!! warning

        This annotator uses `key_points.data["covariance"]` with shape
        `(N, K, 2, 2)` in pixel coordinates.
    r\   gš™™™™™Ù?Nc                ó8   •— t         ‰| �  |||¬«       || _        y)ae  
        Args:
            sigma: Sigma multipliers for each ring, drawn from outermost to
                innermost.  Accepts a single float or a sequence of floats.
                Defaults to ``(1.0, 2.0, 3.0)``.
            color: The color for each sigma level.  Accepts a single
                ``Color`` or a sequence of colors (one per sigma level).
                Defaults to ``(Color.GREEN, Color.YELLOW, Color.RED)``.
            opacity: Opacity of the overlay mask. Must be between ``0`` and
                ``1``.
            max_axis: Optional cap for ellipse semi-axis lengths in pixels.
        ©ro   r&   rp   N©Úsuperr(   Úopacity©r   ro   r&   r¬   rp   Ú	__class__s        €r   r(   z#VertexEllipseAreaAnnotator.__init__  ó    ø€ ô& 	‰Ñ˜u¨E¸HÐÔEØˆ�r   c                óœ  — t        |t        j                  «      sJ ‚t        |«      dk(  r|S |j	                  «       }| j                  |«      D ]I  }|D ]B  \  }}}}}	t        j                  ||||dd|	j                  «       dt        j                  ¬«	       ŒD ŒK t        j                  || j                  |d| j                  z
  d|¬«       |S )að  
        Draws filled semi-transparent covariance ellipses around each keypoint.

        Args:
            scene: The image to annotate. ``ImageType`` accepts either
                ``numpy.ndarray`` or ``PIL.Image.Image``.
            key_points: Key points with covariance data in
                ``key_points.data["covariance"]``.

        Returns:
            The annotated image, matching the type of ``scene``.

        Example:
            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> image = np.zeros((800, 800, 3), dtype=np.uint8)
            >>> key_points = sv.KeyPoints(
            ...     xy=np.array(
            ...         [[[400, 200], [300, 500], [500, 500]]],
            ...         dtype=np.float32,
            ...     ),
            ...     class_id=np.array([0]),
            ...     visible=np.array([[True, True, True]]),
            ...     data={
            ...         "covariance": np.array(
            ...             [[[[800, 0], [0, 400]],
            ...               [[400, 0], [0, 800]],
            ...               [[600, 0], [0, 600]]]],
            ...             dtype=np.float32,
            ...         )
            ...     },
            ... )
            >>> annotator = sv.VertexEllipseAreaAnnotator(
            ...     sigma=[1.0, 2.0],
            ...     color=[sv.Color.GREEN, sv.Color.RED],
            ... )
            >>> result = annotator.annotate(image.copy(), key_points)

            ```
        r   éh  r*   ©	r+   r,   rœ   rš   Ú
startAngleÚendAngler&   r-   ÚlineTyperI   )Údst)r.   r/   r0   r1   Úcopyrž   r6   Úellipser9   ÚLINE_AAÚaddWeightedr¬   )
r   r   r   ÚoverlayÚlevelr,   r�   rš   Ú_sigmar&   s
             r   r   z#VertexEllipseAreaAnnotator.annotate•  sÄ   € ôV ˜%¤§¡Ô,Ð,Ð,Üˆz‹?˜aÒØˆLà—*‘*“,ˆØ×.Ñ.¨zÓ:ò 	ˆEØ>Cò Ñ:�˜ e¨V°UÜ—‘ØØ!Ø%ØØ Ø ØŸ,™,›.Ø Ü Ÿ[™[ö
ñð	ô 	�‰˜ §¡¨u°a¸$¿,¹,Ñ6FÈÈuÕUØˆr   ©
ro   rŸ   r&   r    r¬   rk   rp   r¡   r   r>   r   ©r   r    r!   r@   r   r£   r¤   r¥   r(   r   r   Ú__classcell__©r®   s   @r   r§   r§   r  sr   ø„ ñ
ð *9Ø*/¯+©+°u·|±|ÀUÇYÁYÐ)OØØ!%ðà&ðð 'ðð ð	ð
 ðð 
õð, 'ò>ó 'ô>r   r§   c                  ó”   ‡ — e Zd ZdZdej
                  ej                  ej                  fddf	 	 	 	 	 	 	 	 	 dˆ fd„Ze	dd„«       Z
ˆ xZS )	ÚVertexEllipseOutlineAnnotatorzø
    Draws stroke-only concentric covariance ellipse rings at multiple sigma
    levels around each keypoint.

    !!! warning

        This annotator uses `key_points.data["covariance"]` with shape
        `(N, K, 2, 2)` in pixel coordinates.
    r\   rD   Nc                ó8   •— t         ‰| �  |||¬«       || _        y)aA  
        Args:
            sigma: Sigma multipliers for each ring, drawn from outermost to
                innermost.  Accepts a single float or a sequence of floats.
                Defaults to ``(1.0, 2.0, 3.0)``.
            color: The color for each sigma level.  Accepts a single
                ``Color`` or a sequence of colors (one per sigma level).
                Defaults to ``(Color.GREEN, Color.YELLOW, Color.RED)``.
            thickness: Line thickness of the ellipse outlines.
            max_axis: Optional cap for ellipse semi-axis lengths in pixels.
        r©   N)r«   r(   r-   )r   ro   r&   r-   rp   r®   s        €r   r(   z&VertexEllipseOutlineAnnotator.__init__â  s    ø€ ô$ 	‰Ñ˜u¨E¸HÐÔEØ"ˆ�r   c                ó,  — t        |t        j                  «      sJ ‚t        |«      dk(  r|S | j	                  |«      D ]S  }|D ]L  \  }}}}}t        j                  ||||dd|j                  «       | j                  t
        j                  ¬«	       ŒN ŒU |S )a  
        Draws stroke-only covariance ellipse outlines around each keypoint.

        Args:
            scene: The image to annotate. ``ImageType`` accepts either
                ``numpy.ndarray`` or ``PIL.Image.Image``.
            key_points: Key points with covariance data in
                ``key_points.data["covariance"]``.

        Returns:
            The annotated image, matching the type of ``scene``.

        Example:
            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> image = np.zeros((800, 800, 3), dtype=np.uint8)
            >>> key_points = sv.KeyPoints(
            ...     xy=np.array(
            ...         [[[400, 200], [300, 500], [500, 500]]],
            ...         dtype=np.float32,
            ...     ),
            ...     class_id=np.array([0]),
            ...     visible=np.array([[True, True, True]]),
            ...     data={
            ...         "covariance": np.array(
            ...             [[[[800, 0], [0, 400]],
            ...               [[400, 0], [0, 800]],
            ...               [[600, 0], [0, 600]]]],
            ...             dtype=np.float32,
            ...         )
            ...     },
            ... )
            >>> annotator = sv.VertexEllipseOutlineAnnotator(
            ...     sigma=[1.0, 2.0],
            ...     color=[sv.Color.GREEN, sv.Color.RED],
            ...     thickness=2,
            ... )
            >>> result = annotator.annotate(image.copy(), key_points)

            ```
        r   r±   r²   )
r.   r/   r0   r1   rž   r6   r¸   r9   r-   r¹   )	r   r   r   r¼   r,   r�   rš   r½   r&   s	            r   r   z&VertexEllipseOutlineAnnotator.annotate÷  sš   € ôX ˜%¤§¡Ô,Ð,Ð,Üˆz‹?˜aÒØˆLà×.Ñ.¨zÓ:ò 	ˆEØ>Cò Ñ:�˜ e¨V°UÜ—‘ØØ!Ø%ØØ Ø ØŸ,™,›.Ø"Ÿn™nÜ Ÿ[™[ö
ñð	ð ˆr   )
ro   rŸ   r&   r    r-   r8   rp   r¡   r   r>   r   r¿   rÁ   s   @r   rÃ   rÃ   ×  sr   ø„ ñð *9Ø*/¯+©+°u·|±|ÀUÇYÁYÐ)OØØ!%ð#à&ð#ð 'ð#ð ð	#ð
 ð#ð 
õ#ð* 'ò=ó 'ô=r   rÃ   c                  ó¤   ‡ — e Zd ZU dZdZded<   dej                  ej                  ej                  fddf	 	 	 	 	 	 	 	 	 d
ˆ fd„Z
edd	„«       Zˆ xZS )ÚVertexEllipseHaloAnnotatora™  
    Draws filled covariance ellipses with a radial fade: full opacity at the
    center, smoothly falling off to zero at the ellipse boundary.  The falloff
    follows a power curve controlled by ``decay``, producing a soft glow that
    is strongest near the keypoint.

    !!! warning

        This annotator uses `key_points.data["covariance"]` with shape
        `(N, K, 2, 2)` in pixel coordinates.
    r^   rk   Ú_DECAYr\   g333333ã?Nc                ó8   •— t         ‰| �  |||¬«       || _        y)al  
        Args:
            sigma: Sigma multipliers for each ring, drawn from outermost to
                innermost.  Accepts a single float or a sequence of floats.
                Defaults to ``(1.0, 2.0, 3.0)``.
            color: The color for each sigma level.  Accepts a single
                ``Color`` or a sequence of colors (one per sigma level).
                Defaults to ``(Color.GREEN, Color.YELLOW, Color.RED)``.
            opacity: Peak opacity at the ellipse center. Must be between ``0``
                and ``1``.
            max_axis: Optional cap for ellipse semi-axis lengths in pixels.
        r©   Nrª   r­   s        €r   r(   z#VertexEllipseHaloAnnotator.__init__G  r¯   r   c                ó<  — t        |t        j                  «      sJ ‚t        |«      dk(  r|S |j                  dd \  }}|j                  t        j                  «      }| j                  |«      D �]ö  }|D �]í  \  }}}	}
}|\  }}|dk(  s|dk(  rŒd}||z   }||z   }|\  }}t        ||z
  d«      }t        ||z   |«      }t        ||z
  d«      }t        ||z   |«      }||k\  s||k\  rŒrt        j                  ||t        j                  ¬«      |z
  }t        j                  ||t        j                  ¬«      |z
  }t        j                  ||«      \  }}t        j                  |	 «      }t        j                  |«      }t        j                  |«      }||z  ||z  z
  }||z  ||z  z   }||z  dz  ||z  dz  z   } | dk  }!t        j                  | «      }"d| |!   z
  | j                   z  |"|!<   |"| j"                  z  }#t        j$                  |j'                  «       t        j                  ¬«      }$|||…||…f   }%|#dd…dd…t        j(                  f   }&|%d|&z
  z  |$|&z  z   |%dd �Œð �Œù t        j*                  ||j                  t        j,                  «      «       |S )aè  
        Draws radially-fading covariance ellipses around each keypoint.

        Args:
            scene: The image to annotate. ``ImageType`` accepts either
                ``numpy.ndarray`` or ``PIL.Image.Image``.
            key_points: Key points with covariance data in
                ``key_points.data["covariance"]``.

        Returns:
            The annotated image, matching the type of ``scene``.

        Example:
            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> image = np.zeros((800, 800, 3), dtype=np.uint8)
            >>> key_points = sv.KeyPoints(
            ...     xy=np.array(
            ...         [[[400, 200], [300, 500], [500, 500]]],
            ...         dtype=np.float32,
            ...     ),
            ...     class_id=np.array([0]),
            ...     visible=np.array([[True, True, True]]),
            ...     data={
            ...         "covariance": np.array(
            ...             [[[[800, 0], [0, 400]],
            ...               [[400, 0], [0, 800]],
            ...               [[600, 0], [0, 600]]]],
            ...             dtype=np.float32,
            ...         )
            ...     },
            ... )
            >>> annotator = sv.VertexEllipseHaloAnnotator(
            ...     sigma=[1.0, 2.0],
            ...     color=[sv.Color.GREEN, sv.Color.RED],
            ... )
            >>> result = annotator.annotate(image.copy(), key_points)

            ```
        r   NrD   ru   r]   rI   )r.   r/   r0   r1   r|   r†   rz   rž   r•   ÚminÚarangeÚmeshgridÚradiansÚcosÚsinÚ
zeros_likerÈ   r¬   Úarrayr9   ÚnewaxisÚcopytoÚuint8)'r   r   r   ÚhÚwÚ	compositer¼   r,   r�   rš   r½   r&   ÚaxÚayÚpadÚ
roi_half_wÚ
roi_half_hÚcxÚcyÚx_minÚx_maxÚy_minÚy_maxÚysÚxsÚgrid_xÚgrid_yÚ	angle_radÚcos_aÚsin_aÚrxÚryÚdist_sqÚinsideÚfalloffÚscaled_alphaÚbgrÚroiÚalpha_3s'                                          r   r   z#VertexEllipseHaloAnnotator.annotate]  s‡  € ôV ˜%¤§¡Ô,Ð,Ð,Üˆz‹?˜aÒØˆLà�{‰{˜2˜Aˆ‰ˆˆ1Ø-2¯\©\¼"¿*¹*Ó-Eˆ	à×.Ñ.¨zÓ:ó '	=ˆEØ>Có &=Ñ:�˜ e¨V°UØ%‘��BØ˜’7˜b AšgØà�Ø #™X�
Ø #™X�
Ø‘��Bä˜B ™O¨QÓ/�Ü˜B ™O¨QÓ/�Ü˜B ™O¨QÓ/�Ü˜B ™O¨QÓ/�Ø˜E’> U¨e¢^Øä—Y‘Y˜u e´2·:±:Ô>ÀÑC�Ü—Y‘Y˜u e´2·:±:Ô>ÀÑC�Ü!#§¡¨R°Ó!4‘�˜äŸJ™J¨ vÓ.�	ÜŸ™˜yÓ)�ÜŸ™˜yÓ)�Ø˜e‘^ f¨u¡nÑ4�Ø˜e‘^ f¨u¡nÑ4�à ™7 q™.¨B°©G¸©>Ñ9�Ø  C™�äŸ-™-¨Ó0�Ø#&¨°©Ñ#8¸T¿[¹[Ñ"H�˜‘à&¨¯©Ñ5�ä—h‘h˜uŸ|™|›~´R·Z±ZÔ@�Ø  e ¨U°5¨[Ð 8Ñ9�Ø&¢qª!¬R¯Z©ZÐ'7Ñ8�Ø  G¡Ñ,¨s°W©}Ñ<�‘A’òM&=ð'	=ôR 	�	‰	�%˜×)Ñ)¬"¯(©(Ó3Ô4Øˆr   r¾   r   )r   r    r!   r@   rÈ   Ú__annotations__r   r£   r¤   r¥   r(   r   r   rÀ   rÁ   s   @r   rÇ   rÇ   8  s€   ø… ñ
ð €FˆEÓð *9Ø*/¯+©+°u·|±|ÀUÇYÁYÐ)OØØ!%ðà&ðð 'ðð ð	ð
 ðð 
õð, 'ò[ó 'ô[r   rÇ   c                  óð   — e Zd ZdZej
                  ej                  dddddf	 	 	 	 	 	 	 	 	 	 	 	 	 dd„Z	 d	 	 	 	 	 	 	 dd	„Ze		 	 	 	 	 	 	 	 	 	 	 	 dd
„«       Z
e		 d	 	 	 	 	 	 	 dd„«       Ze		 	 	 	 	 	 dd„«       Zy)ÚVertexLabelAnnotatorz£
    A class that draws labels of skeleton vertices on images. It uses specified key
    points to determine the locations where the vertices should be drawn.
    g      à?rI   é
   r   Fc                óf   — || _         || _        || _        || _        || _        || _        || _        y)a§  
        Args:
            color: The color to use for each keypoint label. If a list is
                provided, the colors will be used in order for each keypoint.
            text_color: The color to use for the labels. If a list is
                provided, the colors will be used in order for each keypoint.
            text_scale: The scale of the text.
            text_thickness: The thickness of the text.
            text_padding: The padding around the text.
            border_radius: The radius of the rounded corners of the boxes.
                Set to a high value to produce circles.
            smart_position: Spread out the labels to avoid overlap.
        N)Úborder_radiusr&   Ú
text_colorÚ
text_scaleÚtext_thicknessÚtext_paddingÚsmart_position)r   r&   rú   rû   rü   rý   rù   rþ   s           r   r(   zVertexLabelAnnotator.__init__Å  s9   € ð. #0ˆÔØ*/ˆŒ
Ø/9ˆŒØ!+ˆŒØ#1ˆÔØ!-ˆÔØ,ˆÕr   Nc                óÌ  — t        |t        j                  «      sJ ‚t        j                  }|j
                  j                  \  }}}|dk(  r|S g }g }	g }
g }t        |«      D �]:  }|j
                  |   }|j                  �t        |j                  |   «      nd}| j                  |||«      }| j                  | j                  |«      }| j                  | j                  |«      }t        |«      D ]©  }|j                  �|j                  ||f   sŒ!t        j                  ||   d«      rŒ;t        ||   d   «      t        ||   d   «      f}|j!                  |«       |	j!                  ||   «       |
j!                  ||   «       |j!                  ||   «       Œ« �Œ= |s|S t        j"                  t%        ||	«      D ��cg c]/  \  }}| j'                  ||| j(                  | j*                  |¬«      ‘Œ1 c}}«      }t-        || j.                  ¬«      }| j0                  r#t3        |«      }t-        || j.                   ¬«      }t%        |	|
|||«      D ]‰  \  }}}}}t5        |t7        j8                  |«      || j:                  ¬«       t        j<                  |||d   |d   f|| j(                  |j?                  «       | j*                  t        j@                  ¬«       Œ‹ |S c c}}w )	aB  
        Draws labels at skeleton vertex positions on the image. Vertices
        marked not visible via ``key_points.visible`` are skipped.

        Args:
            scene: The image where vertex labels will be drawn. `ImageType` is a
                flexible type, accepting either `numpy.ndarray` or `PIL.Image.Image`.
            key_points: A collection of key points where each key point consists of x
                and y coordinates.
            labels: Labels to display at each keypoint. If ``None``, keypoint
                indices are used. A ``list[str]`` applies the same labels to
                every instance. A ``dict[int, list[str]]`` maps ``class_id``
                to per-class label lists, enabling correct labeling for
                datasets with multiple skeleton types.

        Returns:
            The annotated image, matching the type of `scene` (`numpy.ndarray`
                or `PIL.Image.Image`)

        Example:
            Single-skeleton example:

            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> image = np.zeros((800, 800, 3), dtype=np.uint8)
            >>> key_points = sv.KeyPoints(
            ...     xy=np.array(
            ...         [[[400, 200], [300, 500], [500, 500]]],
            ...         dtype=np.float32,
            ...     ),
            ...     class_id=np.array([0]),
            ...     visible=np.array([[True, True, True]]),
            ... )
            >>> annotator = sv.VertexLabelAnnotator(
            ...     color=sv.Color.ROBOFLOW,
            ...     text_color=sv.Color.WHITE,
            ...     border_radius=5,
            ... )
            >>> result = annotator.annotate(
            ...     scene=image.copy(),
            ...     key_points=key_points,
            ...     labels=["head", "L-foot", "R-foot"],
            ... )

            ```

            Multi-skeleton example with per-class labels:

            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> image = np.zeros((800, 800, 3), dtype=np.uint8)
            >>> key_points = sv.KeyPoints(
            ...     xy=np.array(
            ...         [[[400, 200], [300, 500], [500, 500]],
            ...          [[700, 300], [650, 500], [0, 0]]],
            ...         dtype=np.float32,
            ...     ),
            ...     class_id=np.array([0, 1]),
            ...     visible=np.array(
            ...         [[True, True, True],
            ...          [True, True, False]],
            ...     ),
            ... )
            >>> annotator = sv.VertexLabelAnnotator(
            ...     color=sv.Color.ROBOFLOW,
            ...     text_color=sv.Color.WHITE,
            ...     border_radius=5,
            ... )
            >>> result = annotator.annotate(
            ...     scene=image.copy(),
            ...     key_points=key_points,
            ...     labels={
            ...         0: ["head", "L-foot", "R-foot"],
            ...         1: ["top", "bottom", "pad"],
            ...     },
            ... )

            ```
        r   NrI   )ÚtextÚfontrû   rü   Úcenter_coordinates)ÚxyxyÚpx)r   Úrectr&   rù   é   )r+   r   ÚorgÚfontFaceÚ	fontScaler&   r-   rµ   )!r.   r/   r0   r6   ÚFONT_HERSHEY_SIMPLEXr3   r|   rn   rM   r8   Ú_resolve_labelsÚ_resolve_color_listr&   rú   r5   r4   r–   rÒ   r’   Úget_text_bounding_boxrû   rü   r   rý   rþ   r	   r   r   Ú	from_xyxyrù   ÚputTextr9   r¹   )r   r   r   Úlabelsr  Úskeletons_countÚpoints_countr—   Úall_anchorsÚ
all_labelsÚ
all_colorsÚall_text_colorsrf   r3   rM   Úinstance_labelsÚinstance_colorsÚinstance_text_colorsÚjÚanchorÚlabelr  Úxyxy_paddedr   r&   rú   ÚboxÚ
box_paddeds                               r   r   zVertexLabelAnnotator.annotateä  sí  € ôn ˜%¤§¡Ô,Ð,Ð,Ü×'Ñ'ˆà+5¯=©=×+>Ñ+>Ñ(ˆ˜ qØ˜aÒØˆLà-/ˆØ "ˆ
Ø"$ˆ
Ø')ˆä�Ó'ó 	@ˆAØ—‘˜qÑ!ˆBð 0:×/BÑ/BÐ/N”�J×'Ñ'¨Ñ*Ô+ÐTXð ð #×2Ñ2°6¸<ÈÓRˆOØ"×6Ñ6°t·z±zÀ<ÓPˆOØ#'×#;Ñ#;Ø—‘ ó$Ð ô ˜<Ó(ò @�Ø×%Ñ%Ð1Ø%×-Ñ-¨a°¨dÒ3Ø Ü—[‘[  A¡¨Ô*Øä˜b ™e A™h›-¬¨R°©U°1©X«Ð7�Ø×"Ñ" 6Ô*Ø×!Ñ! /°!Ñ"4Ô5Ø×!Ñ! /°!Ñ"4Ô5Ø×&Ñ&Ð';¸AÑ'>Õ?ò@ð	@ñ2 ØˆLä�x‰xô &)¨°jÓ%A÷	ñ "�F˜Eð ×*Ñ*ØØØ#Ÿ™Ø#'×#6Ñ#6Ø'-ð +õ ó	ó
ˆô   T¨d×.?Ñ.?Ô@ˆà×ÒÜ*¨;Ó7ˆKÜ +°4×3DÑ3DÐ2DÔEˆDä8;Ø˜
 O°T¸;ó9
ò 	Ñ4ˆD�%˜ S¨*ô #ØÜ—^‘^ JÓ/ØØ"×0Ñ0õ	ô �K‰KØØØ˜‘V˜S ™VÐ$ØØŸ/™/Ø ×'Ñ'Ó)Ø×-Ñ-ÜŸ™ö	ð	ð( ˆùóK	s   Ç4K 
c                ó†   — t        j                  | |||¬«      d   \  }}|\  }}||dz  z
  ||dz  z
  ||dz  z   ||dz  z   fS )N)r   r  r	  r-   r   rD   )r6   ÚgetTextSize)	r   r  rû   rü   r  Útext_wÚtext_hÚcenter_xÚcenter_ys	            r   r  z*VertexLabelAnnotator.get_text_bounding_box‹  sr   € ô Ÿ™ØØØ Ø$ô	
ð
 ñ‰ˆ�ð 0Ñˆ�(à�v ‘{Ñ"Ø�v ‘{Ñ"Ø�v ‘{Ñ"Ø�v ‘{Ñ"ð	
ð 	
r   c                ó  — | €"t        |«      D �cg c]  }t        |«      ‘Œ c}S t        | t        «      r&|€t	        d«      ‚|| vrt	        d|› d�«      ‚| |   }n| }t        |«      |k7  rt	        dt        |«      › d|› d�«      ‚|S c c}w )z,Return the label list for a single instance.zHlabels is a dict but class_id is None; KeyPoints must have class_id set.zNo labels defined for class_id=rH   zNumber of labels (ú#) must match number of key points (ú).)rn   Ústrr.   rL   rN   r1   )r  r  rM   r  Úresolveds        r   r  z$VertexLabelAnnotator._resolve_labels¡  s¶   € ð ˆ>Ü$)¨,Ó$7Ö8˜q”C˜•FÒ8Ð8ô �fœdÔ#ØÐÜ ð8óð ð ˜vÑ%Ü Ð#BÀ8À*ÈAÐ!NÓOÐOØ˜hÑ'‰HàˆHäˆx‹=˜LÒ(ÜØ$¤S¨£] Oð 4)Ø)5¨°bð:óð ð ˆùò) 9s   �Bc                ó„   — t        | t        «      r+t        | «      |k7  rt        dt        | «      › d|› d�«      ‚| S | g|z  S )z7Return a per-keypoint color list for a single instance.zNumber of colors (r'  r(  )r.   Úlistr1   rN   )Úcolorsr  s     r   r  z(VertexLabelAnnotator._resolve_color_list¿  sW   € ô �fœdÔ#Ü�6‹{˜lÒ*Ü Ø(¬¨V«¨ð 6-Ø-9¨N¸"ð>óð ð ˆMØˆx˜,Ñ&Ð&r   )r&   úColor | list[Color]rú   r.  rû   rk   rü   r8   rý   r8   rù   r8   rþ   Úboolr   )r   r
   r   r   r  ú'list[str] | dict[int, list[str]] | Noner   r
   )r   r)  r  r8   rû   rk   rü   r8   r  ztuple[int, int]r   ztuple[int, int, int, int])r  r0  r  r8   rM   z
int | Noner   z	list[str])r-  r.  r  r8   r   zlist[Color])r   r    r!   r@   r   rA   ÚWHITEr(   r   Ústaticmethodr  r  r  r   r   r   rö   rö   ¿  s]  „ ñð &+§^¡^Ø*/¯+©+ØØØØØ$ð-à"ð-ð (ð-ð ð	-ð
 ð-ð ð-ð ð-ð ó-ðF ;?ð	eàðeð ðeð 8ð	eð
 
óeðN ð
Øð
àð
ð ð
ð ð	
ð
 ,ð
ð 
#ò
ó ð
ð* ð  $ðØ7ðàðð ðð 
ò	ó ðð: ð'Ø#ð'àð'ð 
ò'ó ñ'r   rö   ),Ú
__future__r   Úabcr   r   Úcollections.abcr   Útypingr   r6   Únumpyr/   Únumpy.typingrx   Ú!supervision.detection.utils.boxesr   r	   Úsupervision.draw.baser
   Úsupervision.draw.colorr   Úsupervision.draw.utilsr   Úsupervision.geometry.corer   Úsupervision.key_points.corer   Ú supervision.key_points.skeletonsr   Úsupervision.utils.conversionr   Úsupervision.utils.loggerr   r   rP   r   r#   rC   r[   r§   rÃ   rÇ   ÚVertexEllipseAnnotatorrö   r   r   r   ú<module>rC     s¿   ðÝ "ç #Ý $Ý ã 
Û Ý ç IÝ +Ý (Ý 9Ý *Ý 1Ý FÝ JÝ 0á	�XÓ	€ô˜Cô ôNÐ+ô NôbSÐ)ô SôljÐ"7ô jôZbÐ!<ô bôJ^Ð$?ô ^ôBAÐ!<ô AðH 4Ð ÷M'ò M'r   