
    ^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    , <*F1I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"abz<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"21"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'?'?'Ba'GMN`NfNfMgghijj066q91==9:L:R:RST:U9VV`amasas`ttuvww( 066rzz6N$V,G
 
(C$V,G;;56:::CL
&&/C
&&/C
 
HhX	F 'sS3./39sSy01 C4#:&,39% a1f%,,RZZ8Q!V$++BJJ7u}u$v~%&'" D 11BKK4EETXHYYJ
**RVV
C''?.44Ra8?!?Q?BJJWKXXj$++bjj2I3OK	XXj$++bjj2I3OK	(3K	XXj$++bjj2I3OK	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$6N["[[ [r   