
    ^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]]#; 	OR'0} #Va;;1vq)&&2&../KL

FC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]]#; ,	OR$**d+ "**6 
++O<= 
 #$<  4::-$'EhZq%QRR

8,

6::3r7C
!NN#GRQ"$)  !!%y%y;;tQ'2;;tQ+?%%1&../EF)11/52HI T!Ws47|4T!Ws47|4**++-"nn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)_BaseVertexEllipseAnnotatorzPrivate 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     )!qAv)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    #53,7UHU 	 2<E51IeXu	y>QDEE)y))@AAHMFGGy>S^+ Y 0 1!!$Y 03 
  #i.!'=t
 -;;qil;
,:;qi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     oo)),7T  !KK

#RZZ2::%N
 ::==..r29A9q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     {{:&**,	(*		z7H7H7T(U%K {{;'++-q8H1I

;'"-5!<5#999 yy$$ 		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 $AR$ 	 $-Z]]#; 	OR'0} #Va;;1vq)&&2&../KL(+)EF
 $ : :: F (,9)\JJrzz,t*<l4>PQR  (E!H-1:3tzz4::;V1W 
-I~u 277;#77D}}0!zz$>AuT!W~.AuT!W~.$L 9%,,ueU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||UYY)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__       & 	uEH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 :eVU!%  ,,.  [[
	 	ua$,,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||UYY)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     $ 	uEH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 :eVU!%  ,,."nn [[
	 r   )
ro   r   r&   r   r-   r8   rp   r   r   r>   r   r   r   s   @r   r   r     sr     *9*/++u||UYY)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{{2A1-2\\"**-E	..z: '	=E>C &=:eVU%B7bAg#X
#X
BBOQ/BOQ/BOQ/BOQ/E>Ue^YYue2::>CYYue2::>C!#R!4JJv.	y)y)e^fun4e^fun47q.BG>9 C--0#&#8T[["H&5hhu||~RZZ@eU5[ 89&q!RZZ'78G,sW}<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    
 FE *9*/++u||UYY)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26<RO"66tzz<PO#'#;#;$  <( @%%1%--ad3 [[A*beAh-RU1X7""6*!!/!"45!!/!"45&&';A'>?@	@2 Lxx &)j%A	 "FE **##'#6#6'- + 	
  Td.?.?@*;7K+43D3D2DED8;
OT;9
 	4D%S* #^^J/"00	 KKVS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8qCF88 fd# 8  v% #B8*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     fd#6{l* (V 6--9N">  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   