Ë
    ëÓ^jþ!  ã                  óX   — d Z ddlmZ ddlZddgZdd„Zdd„Zdd„Zdd	„Z		 	 	 	 	 	 dd
„Z
y)zAKeypoint utility functions shared by inference and visualization.é    )ÚannotationsNÚschemas_semantically_equalÚ&precision_cholesky_to_pixel_covariancec                ó,   — t        | «      xr | d   dk(  S )a‹  Return True if *schema* uses a background-first layout.

    A background-first schema has a leading slot with zero keypoints that
    acts as a background/no-keypoint sentinel, e.g. ``[0, 17]`` where slot 0
    is background and slot 1 is person with 17 keypoints.  Active-first
    schemas omit that slot entirely, e.g. ``[17]``.

    Args:
        schema: Keypoints-per-class list.

    Returns:
        ``True`` when ``schema`` is non-empty and its first element is zero.

    Examples:
        >>> _is_bg_first_schema([0, 17])
        True
        >>> _is_bg_first_schema([17])
        False
        >>> _is_bg_first_schema([])
        False
    r   )Úbool©Úschemas    úe/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/utilities/keypoints.pyÚ_is_bg_first_schemar      s   € ô, �‹<Ò*˜F 1™I¨™NÐ*ó    c                ó8   — t        | «      r| dd S t        | «      S )a¸  Strip the leading background slot from a bg-first schema.

    Always returns a new list. A no-op (copy) when *schema* is already
    active-first or empty. Only the first leading zero slot is removed;
    schemas with multiple leading zeros (e.g. ``[0, 0, 17]``) retain all
    but the first.

    Args:
        schema: Keypoints-per-class list.

    Returns:
        Schema with the leading zero-keypoint slot removed when bg-first,
        or a copy of *schema* otherwise.

    Examples:
        >>> _to_active_first([0, 17])
        [17]
        >>> _to_active_first([17])
        [17]
        >>> _to_active_first([0, 17, 4])
        [17, 4]
        >>> _to_active_first([0])
        []
    é   N©r   Úlistr   s    r
   Ú_to_active_firstr   +   s"   € ô2 ˜6Ô"Ø�a�bˆzÐÜ�‹<Ðr   c                óP   — t        | «      s| st        | «      S dgt        | «      z   S )a»  Prepend a background slot to an active-first schema.

    A no-op when *schema* already starts with a zero-keypoint slot or is empty.

    Args:
        schema: Keypoints-per-class list.

    Returns:
        Schema with a leading ``0`` prepended when not already bg-first.

    Examples:
        >>> _to_bg_first([17])
        [0, 17]
        >>> _to_bg_first([0, 17])
        [0, 17]
        >>> _to_bg_first([17, 4])
        [0, 17, 4]
    r   r   r   s    r
   Ú_to_bg_firstr   I   s)   € ô& ˜6Ô"©&Ü�F‹|ÐØˆ3”�f“ÑÐr   c                ó0   — t        | «      t        |«      k(  S )as  Return True if *a* and *b* represent the same keypoint structure.

    Two schemas are semantically equal when they encode identical active
    keypoint counts per class after stripping any leading background slot.
    This allows ``[0, 17]`` (bg-first) and ``[17]`` (active-first) to
    compare equal.

    Args:
        a: First keypoints-per-class list.
        b: Second keypoints-per-class list.

    Returns:
        ``True`` when both schemas reduce to the same active-first form.

    Note:
        A schema of ``[0]`` (one detection-only background slot) is semantically
        equal to ``[]`` (no schema) because both reduce to an empty active-first
        form.  Callers that need to distinguish "no schema" from "bg-first with no
        active slots" should compare ``to_active_first(a)`` directly or check
        ``bool(schema)`` before calling this function.

        Use this function for user-facing validation where representational form
        does not matter.  Use exact ``!=`` comparison when preserving
        representational form is required (e.g. auto-align in checkpoint loading).

    Examples:
        >>> schemas_semantically_equal([0, 17], [17])
        True
        >>> schemas_semantically_equal([17], [17])
        True
        >>> schemas_semantically_equal([0, 17], [0, 33])
        False
        >>> schemas_semantically_equal([0], [])
        True
    )r   )ÚaÚbs     r
   r   r   a   s   € ôH ˜AÓÔ"2°1Ó"5Ñ5Ð5r   c                ó.  — | j                   dk7  s| j                  d   dk7  rt        d| j                  › d�«      ‚|j                  | j                  d   dfk7  r)t        d| j                  d   › d|j                  › d�«      ‚| j                  t        j
                  d¬	«      }|d
   }|d   }|d   }t	        j                  |«      j                  d¬«      }t	        j                  |«      }t	        j                  |«      }t	        j                  ddd¬«      5  d||z  |z  |z  z  }	|	||z  ||z  z   z  }
|	| |z  z  dz   }|	||z  z  }|dd…dd…f   j                  t        j
                  «      }|dd…dd…f   j                  t        j
                  «      }||z  |
z  }||z  |z  }||z  |z  }ddd«       |t	        j                  «      z  t	        j                  «      z  t	        j                  «      z  }t	        j                  t        j                  «      }t	        j                  g | j                  dd ¢d‘d‘­|t        j                  ¬«      }t	        j                  ||j                  t        j                  «      |«      |d<   t	        j                  ||j                  t        j                  «      |«      |d<   |d   |d<   t	        j                  ||j                  t        j                  «      |«      |d<   |S # 1 sw Y   �ŒZxY w)a.  Convert RF-DETR keypoint precision parameters into pixel covariances.

    The keypoint head predicts lower-triangular precision-Cholesky parameters in
    normalized image coordinates. This helper inverts those precision matrices
    and scales them to pixel coordinates for Supervision covariance annotators.

    Args:
        precision_cholesky: Lower-triangular precision parameters with shape
            ``(N, K, 3)``. Each triplet is ``(log_l11, l21, log_l22)``.
        source_shape: Per-detection ``(height, width)`` rows with shape
            ``(N, 2)``.

    Returns:
        Pixel-space covariance matrices with shape ``(N, K, 2, 2)``.

    Raises:
        ValueError: If ``precision_cholesky`` or ``source_shape`` has an
            incompatible shape.

    Example:
        >>> precision = np.array([[[0.0, 0.0, 0.0]]], dtype=np.float32)
        >>> shape = np.array([[10.0, 20.0]], dtype=np.float32)
        >>> precision_cholesky_to_pixel_covariance(precision, shape)[0, 0]
        array([[400.,   0.],
               [  0., 100.]], dtype=float32)
    é   é   z2precision_cholesky must have shape (N, K, 3), got ú.r   zsource_shape must have shape (z
, 2), got F)Úcopy).r   ).r   ).r   éÿÿÿÿ)ÚaxisÚignore)ÚdivideÚinvalidÚoverg      ð?g        Nr   )Údtype).r   r   ).r   r   ).r   r   ).r   r   )ÚndimÚshapeÚ
ValueErrorÚastypeÚnpÚfloat64ÚisfiniteÚallÚexpÚerrstateÚfloat32ÚnanÚfullÚwhere)Úprecision_choleskyÚsource_shapeÚprecision_cholesky_f64Úlog_l11Úl21Úlog_l22Úfinite_inputÚl11Úl22Úinv_detÚcov00Úcov01Úcov11ÚheightÚwidthÚpx00Úpx01Úpx11Ú
finite_allr.   Úcovariancess                        r
   r   r   ˆ   sç  € ð< ×Ñ !Ò#Ð'9×'?Ñ'?ÀÑ'BÀaÒ'GÜÐMÐN`×NfÑNfÐMgÐghÐiÓjÐjØ×ÑÐ0×6Ñ6°qÑ9¸1Ð=Ò=ÜÐ9Ð:L×:RÑ:RÐSTÑ:UÐ9VÐV`Ðam×asÑasÐ`tÐtuÐvÓwÐwð( 0×6Ñ6´r·z±zÈÐ6ÓNÐØ$ VÑ,€GØ
  Ñ
(€CØ$ VÑ,€Gä—;‘;Ð5Ó6×:Ñ:ÀÐ:ÓC€Lä
�&‰&�‹/€CÜ
�&‰&�‹/€Cô
 
�‰˜H¨h¸XÔ	Fñ 'Ø˜˜s™ S™¨3Ñ.Ñ/ˆØ˜3 ™9 s¨S¡yÑ0Ñ1ˆð ˜C˜4 #™:Ñ&¨Ñ,ˆØ˜3 ™9Ñ%ˆð ša  1 ˜fÑ%×,Ñ,¬R¯Z©ZÓ8ˆØšQ  ! ˜VÑ$×+Ñ+¬B¯J©JÓ7ˆà�u‰}˜uÑ$ˆØ�v‰~ Ñ%ˆØ˜‰ Ñ&ˆ÷'ð" ¤§¡¨DÓ 1Ñ1´B·K±KÀÓ4EÑEÌÏÉÐTXÓHYÑY€JÜ
�*‰*”R—V‘VÓ
€Cä—'‘'Ð?Ð.×4Ñ4°R°aÐ8Ð?¸!Ð?¸QÑ?ÀÌBÏJÉJÔW€KÜŸX™X j°$·+±+¼b¿j¹jÓ2IÈ3ÓO€K�	ÑÜŸX™X j°$·+±+¼b¿j¹jÓ2IÈ3ÓO€K�	ÑØ(¨Ñ3€K�	ÑÜŸX™X j°$·+±+¼b¿j¹jÓ2IÈ3ÓO€K�	ÑØÐ÷3'ñ 'ús   ÄBL
Ì
L)r	   ú	list[int]Úreturnr   )r	   rE   rF   rE   )r   rE   r   rE   rF   r   )r1   ú
np.ndarrayr2   rG   rF   rG   )Ú__doc__Ú
__future__r   Únumpyr'   Ú__all__r   r   r   r   r   © r   r
   ú<module>rM      sX   ðñ Hå "ã ð !Ø,ð€ó+ó2ó<ó0$6ðN[Ø"ð[àð[ð ô[r   