
    ^jL                    V   d dl mZ d dlZd dlmZmZ d dlmZmZ d dl	m
Z
mZmZ d dlZd dlm	Z d dlmZ d dlmZ d dlmZmZ d d	lmZmZ d d
lmZ d dlmZ  ej>                  e       Z!ee"e#e$e"   e$e%   ejL                  ejN                     ejL                  ejP                     f   Z)e*e)e)f   Z+ee"ejX                  e
   ejL                  ejZ                     e$e
   e#f   Z.eejL                  ejZ                     e$e
   e#f   Z/	 	 	 	 	 	 ddZ0	 	 	 	 ddZ1 ed       G d d             Z2y)    )annotationsN)IterableIterator)	dataclassfield)AnyUnioncast)CLASS_NAME_DATA_FIELD)
Detections)get_data_itemis_data_equal)OverlapMetricbox_non_max_suppression)warn_deprecated)_validate_keypoints_fieldsc                J    | |
| d u xr |d u S t        j                  | |      S N)nparray_equal)firstseconds     f/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/supervision/key_points/core.py_optional_array_equalr   *   s1     }}/4/>>%((    c                   t        | t        t        j                  f      r-t	        t
        t        j                  t        |       g            S t        | t        j                        rD| j                  t        k(  r1t	        t
        t        j                  | j                                     S t        | t        j                        r.| j                  dk(  rt	        t
        | j                  d            S t        | t              rJ| rHt        d | D              r6t	        t
        t        j                  t        j                  |                   S | S )a  Normalise *i* to a 1-D row index for 1-D per-object fields.

    Handles:
    - Python int or np.integer scalar  -> np.array([int(i)])
    - boolean np.ndarray (any shape)   -> np.flatnonzero(i.ravel())
    - non-bool 0-d np.ndarray          -> reshaped to shape (1,)
    - list of bool                     -> np.flatnonzero(np.array(i))
    - slice, list of ints, 1-D ndarray -> returned as-is
    r      c              3  <   K   | ]  }t        |t                y wr   
isinstancebool.0xs     r   	<genexpr>z'_normalize_row_index.<locals>.<genexpr>E   s     (HAt)<(H   )r    intr   integerr
   _NormalizedRowIndexarrayndarraydtyper!   flatnonzeroravelndimreshapelistall)is    r   _normalize_row_indexr4   3   s     !c2::&''3q6();<<!RZZ QWW_'	)BCC!RZZ QVVq['166!TqS(Ha(H%H')DEEHr   F)initc                     e Zd ZU dZded<   dZded<   dZded<   dZded	<   dZd
ed<    e	e
      Zded<   	 	 	 	 	 d&dd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d'dZd(dZed)d       Zej                   d*d       Zd+dZ	 	 d,dZd-dZed.d       Ze	 	 	 	 	 	 d/d       Zed0d       Zed1d       Zed2d       Zed3d       Zd4dZ	 	 	 	 d5dZd6dZed7d        Zd8d!Zd"d#e jB                  f	 	 	 	 	 	 	 d9d$Z"	 d:	 	 	 d;d%Z#y)<	KeyPointsu#  
    The `sv.KeyPoints` class in the Supervision library standardizes results from
    various keypoint detection and pose estimation models into a consistent format. This
    class simplifies data manipulation and filtering, providing a uniform API for
    integration with Supervision [keypoints annotators](/latest/keypoint/annotators).

    === "RF-DETR"

        [RF-DETR](https://github.com/roboflow/rf-detr) keypoint models return
        `sv.KeyPoints` directly from `model.predict()` — no additional
        conversion is needed.

        ```python
        import cv2
        import supervision as sv
        from rfdetr import RFDETRKeypointPreview

        image = cv2.imread("<SOURCE_IMAGE_PATH>")
        model = RFDETRKeypointPreview()

        key_points = model.predict(image)
        ```

    === "Ultralytics"

        Use [`sv.KeyPoints.from_ultralytics`](/latest/keypoint/core/#supervision.key_points.core.KeyPoints.from_ultralytics)
        method, which accepts [YOLOv8-pose](https://docs.ultralytics.com/models/yolov8/), [YOLO11-pose](https://docs.ultralytics.com/models/yolo11/)
        [pose](https://docs.ultralytics.com/tasks/pose/) result.

        ```python
        import cv2
        import supervision as sv
        from ultralytics import YOLO

        image = cv2.imread("<SOURCE_IMAGE_PATH>")
        model = YOLO('yolo11s-pose.pt')

        result = model(image)[0]
        key_points = sv.KeyPoints.from_ultralytics(result)
        ```

    === "Inference"

        Use [`sv.KeyPoints.from_inference`](/latest/keypoint/core/#supervision.key_points.core.KeyPoints.from_inference)
        method, which accepts [Inference](https://inference.roboflow.com/) pose result.

        ```python
        import cv2
        import supervision as sv
        from inference import get_model

        image = cv2.imread("<SOURCE_IMAGE_PATH>")
        model = get_model(model_id="<POSE_MODEL_ID>", api_key="<ROBOFLOW_API_KEY>")

        result = model.infer(image)[0]
        key_points = sv.KeyPoints.from_inference(result)
        ```

    === "MediaPipe"

        Use [`sv.KeyPoints.from_mediapipe`](/latest/keypoint/core/#supervision.key_points.core.KeyPoints.from_mediapipe)
        method, which accepts [MediaPipe](https://github.com/google-ai-edge/mediapipe)
        pose result.


        ```python
        import cv2
        import mediapipe as mp
        import supervision as sv

        image = cv2.imread("<SOURCE_IMAGE_PATH>")
        image_height, image_width, _ = image.shape
        mediapipe_image = mp.Image(
            image_format=mp.ImageFormat.SRGB,
            data=cv2.cvtColor(image, cv2.COLOR_BGR2RGB))

        options = mp.tasks.vision.PoseLandmarkerOptions(
            base_options=mp.tasks.BaseOptions(
                model_asset_path="pose_landmarker_heavy.task"
            ),
            running_mode=mp.tasks.vision.RunningMode.IMAGE,
            num_poses=2)

        PoseLandmarker = mp.tasks.vision.PoseLandmarker
        with PoseLandmarker.create_from_options(options) as landmarker:
            pose_landmarker_result = landmarker.detect(mediapipe_image)

        key_points = sv.KeyPoints.from_mediapipe(
            pose_landmarker_result, (image_width, image_height))
        ```

    === "Transformers"

        Use [`sv.KeyPoints.from_transformers`](/latest/keypoint/core/#supervision.key_points.core.KeyPoints.from_transformers)
        method, which accepts [ViTPose](https://huggingface.co/docs/transformers/en/model_doc/vitpose) result.

        ```python
        from PIL import Image
        import requests
        import supervision as sv
        import torch
        from transformers import (
            AutoProcessor,
            RTDetrForObjectDetection,
            VitPoseForPoseEstimation,
        )

        device = "cuda" if torch.cuda.is_available() else "cpu"
        image = Image.open("<SOURCE_IMAGE_PATH>")

        DETECTION_MODEL_ID = "PekingU/rtdetr_r50vd_coco_o365"

        detection_processor = AutoProcessor.from_pretrained(DETECTION_MODEL_ID, use_fast=True)
        detection_model = RTDetrForObjectDetection.from_pretrained(DETECTION_MODEL_ID, device_map=DEVICE)

        inputs = detection_processor(images=frame, return_tensors="pt").to(DEVICE)

        with torch.no_grad():
            outputs = detection_model(**inputs)

        target_size = torch.tensor([(frame.height, frame.width)])
        results = detection_processor.post_process_object_detection(
            outputs, target_sizes=target_size, threshold=0.3)

        detections = sv.Detections.from_transformers(results[0])
        boxes = sv.xyxy_to_xywh(detections[detections.class_id == 0].xyxy)

        POSE_ESTIMATION_MODEL_ID = "usyd-community/vitpose-base-simple"

        pose_estimation_processor = AutoProcessor.from_pretrained(POSE_ESTIMATION_MODEL_ID)
        pose_estimation_model = VitPoseForPoseEstimation.from_pretrained(
            POSE_ESTIMATION_MODEL_ID, device_map=DEVICE)

        inputs = pose_estimation_processor(frame, boxes=[boxes], return_tensors="pt").to(DEVICE)

        with torch.no_grad():
            outputs = pose_estimation_model(**inputs)

        results = pose_estimation_processor.post_process_pose_estimation(outputs, boxes=[boxes])
        key_point = sv.KeyPoints.from_transformers(results[0])
        ```

    Attributes:
        xy: An array of shape `(n, m, 2)` containing
            `n` detected objects, each composed of `m` equally-sized
            sets of key points, where each point is `[x, y]`.
        class_id: An array of shape
            `(n,)` containing the class ids of the detected objects.
        keypoint_confidence: An array of shape
            `(n, m)` containing the confidence scores of each keypoint.
        detection_confidence: An array of shape
            `(n,)` containing the detection-level confidence scores.
        visible: An optional boolean array of shape
            `(n, m)` indicating which keypoints are visible. When ``None``,
            all keypoints are treated as visible. Set this to filter anchors
            without removing data: ``key_points.visible = key_points.keypoint_confidence > 0.3``.
        data: A dictionary containing additional
            data where each key is a string representing the data type, and the value
            is either a NumPy array or a list of corresponding data of length `n`
            (one entry per detected object).
    npt.NDArray[np.float32]xyNnpt.NDArray[np.int_] | Noneclass_idnpt.NDArray[np.float32] | Nonekeypoint_confidencedetection_confidencenpt.NDArray[np.bool_] | Nonevisible)default_factoryz.dict[str, npt.NDArray[np.generic] | list[Any]]data)
confidencec                   ||t        d      t        d       |}|| _        || _        || _        || _        || _        ||ni | _        | j                          y)a  Initialize KeyPoints.

        Args:
            xy: Array of shape `(n, m, 2)` with keypoint coordinates.
            class_id: Array of shape `(n,)` with class IDs. Defaults to None.
            keypoint_confidence: Array of shape `(n, m)` with per-keypoint
                confidence scores. Defaults to None.
            detection_confidence: Array of shape `(n,)` with detection-level
                confidence scores. Defaults to None.
            visible: Boolean array of shape `(n, m)` indicating visible
                keypoints. Defaults to None.
            data: Dictionary of additional per-detection data arrays.
                Defaults to an empty dict.
            confidence: Deprecated since `0.29.0`, removed in `0.32.0`.
                Use ``keypoint_confidence`` instead. Raises ``ValueError``
                if passed together with ``keypoint_confidence``.

        Raises:
            ValueError: If both ``confidence`` and ``keypoint_confidence``
                are provided.
        Nuw   Cannot pass both 'confidence' and 'keypoint_confidence'. 'confidence' is deprecated — use 'keypoint_confidence' only.z'confidence' parameter in `KeyPoints()` is deprecated since `0.29.0` and will be removed in `0.32.0`. Use 'keypoint_confidence' instead.)	
ValueErrorr   r9   r;   r=   r>   r@   rB   __post_init__)selfr9   r;   r=   r>   r@   rB   rC   s           r   __init__zKeyPoints.__init__   sz    @ !". U  1
 #- #6 $8! ,D"	r   c                    t        | j                  | j                  | j                  | j                  | j
                  | j                         y )N)r9   r;   rC   r>   r@   rB   )r   r9   r;   r=   r>   r@   rB   rG   s    r   rF   zKeyPoints.__post_init__*  s8    "ww]]//!%!:!:LL	
r   c                0    t        d       | j                  S )z=Deprecated since 0.29.0. Use ``keypoint_confidence`` instead.}'KeyPoints.confidence' is deprecated since 0.29.0 and will be removed in 0.32.0. Use 'KeyPoints.keypoint_confidence' instead.r   r=   rJ   s    r   rC   zKeyPoints.confidence4  s      	N	
 '''r   c                (    t        d       || _        y )NrL   rM   )rG   values     r   rC   zKeyPoints.confidence=  s    N	
 $) r   c                ,    t        | j                        S )a  
        Returns the number of objects in the `sv.KeyPoints` object.

        Returns:
            The number of objects.

        Example:
            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> xy = np.array([[[10, 20], [30, 40]]], dtype=np.float32)
            >>> key_points = sv.KeyPoints(xy=xy)
            >>> len(key_points)
            1

            ```
        )lenr9   rJ   s    r   __len__zKeyPoints.__len__E  s    $ 477|r   c              #    K   t        t        | j                              D ]a  }| j                  |   | j                  | j                  |   nd| j                  | j                  |   ndt        | j                  |      f c yw)z
        Iterates over the Keypoint object and yield a tuple of
        `(xy, keypoint_confidence, class_id, data)` for each object detection.
        N)rangerQ   r9   r=   r;   r   rB   )rG   r3   s     r   __iter__zKeyPoints.__iter__Y  s}      s477|$ 	A
++7 ((+$(MM$=a 4dii+ 	s   BBc                   t        |t              st        S t        t	        j
                  | j                  |j                        t        | j                  |j                        t        | j                  |j                        t        | j                  |j                        t        | j                  |j                        t        | j                  |j                        g      S r   )r    r7   NotImplementedr2   r   r   r9   r   r;   r=   r>   r@   r   rB   )rG   others     r   __eq__zKeyPoints.__eq__q  s    %+!!tww1%dmmU^^D%,,e.G.G &--u/I/I &dllEMMBdii4
 	
r   c                ,   t        |t              rt        d      t        |d      r|j	                  dd      }nt        |d      r|j                         }|j                  d      s| j                         S g }g }g }g }|d   D ]  }g }g }|d   D ]/  }	|j                  |	d   |	d	   g       |j                  |	d
          1 |j                  |       |j                  |       |j                  |d          |j                  |d           t        t        j                  |      i}
 | t        j                  |t        j                        t        j                  |t        j                        t        j                  |t              |
      S )a  
        Create a `sv.KeyPoints` object from the [Roboflow](https://roboflow.com/)
        API inference result or the [Inference](https://inference.roboflow.com/)
        package results.

        Args:
            inference_result: The result from the
                Roboflow API or Inference package containing predictions with keypoints.

        Returns:
            A `sv.KeyPoints` object containing the keypoint coordinates, class IDs,
                and class names, and confidences of each keypoint.

        Examples:
            ```python
            import cv2
            import supervision as sv
            from inference import get_model

            image = cv2.imread("<SOURCE_IMAGE_PATH>")
            model = get_model(model_id="<POSE_MODEL_ID>", api_key="<ROBOFLOW_API_KEY>")

            result = model.infer(image)[0]
            key_points = sv.KeyPoints.from_inference(result)
            ```

            ```python
            import cv2
            import supervision as sv
            from inference_sdk import InferenceHTTPClient

            image = cv2.imread("<SOURCE_IMAGE_PATH>")
            client = InferenceHTTPClient(
                api_url="https://detect.roboflow.com",
                api_key="<ROBOFLOW_API_KEY>"
            )

            result = client.infer(image, model_id="<POSE_MODEL_ID>")
            key_points = sv.KeyPoints.from_inference(result)
            ```
        z}from_inference() operates on a single result at a time.You can retrieve it like so:  inference_result = model.infer(image)[0]dictT)exclude_noneby_aliasjsonpredictions	keypointsr$   yrC   r;   classr,   r9   r=   r;   rB   )r    r1   rE   hasattrr[   r^   getemptyappendr   r   r*   float32r'   )clsinference_resultr9   rC   r;   class_names
predictionprediction_xyprediction_confidencekeypointrB   s              r   from_inferencezKeyPoints.from_inference  s   V &-Y 
 #V,/44$QU4V%v./446##M299;
*=9 
	4JM$&!&{3 E$$hsmXc]%CD%,,Xl-CDE IIm$34OOJz23z'23
	4 "288K#8@
 xx"**- "2:: FXXhc2	
 	
r   c                ~   t        |d      r[|j                  }t        |j                  t              s|j                  g }n}|j                  j                  D cg c]  }| c}g}nWt        |d      r|j
                  }n>t        |d      r2|j                  g }n#|j                  D cg c]  }|j                   }}t              dk(  r| j                         S g }g }|D ]  }g }	g }
|D ]R  }|j                  |d   z  |j                  |d   z  g}|	j                  |       |
j                  |j                         T |j                  |	       |j                  |
         | t        j                  |t        j                        t        j                  |t        j                              S c c}w c c}w )a  
        Creates a `sv.KeyPoints` instance from a
        [MediaPipe](https://github.com/google-ai-edge/mediapipe)
        pose landmark detection inference result.

        Args:
            mediapipe_results: The output results from Mediapipe. It supports pose
                and face landmarks from `PoseLandmarker`, `FaceLandmarker` and the
                legacy ones from `Pose` and `FaceMesh`.
            resolution_wh: A tuple of the form `(width, height)` representing the
                resolution of the frame.

        Returns:
            A `sv.KeyPoints` object containing the keypoint coordinates and
                confidences of each keypoint.

        !!! tip
            Before you start, download model bundles from the
            [MediaPipe website](https://ai.google.dev/edge/mediapipe/solutions/vision/pose_landmarker/index#models).

        Examples:
            ```python
            import cv2
            import mediapipe as mp
            import supervision as sv

            image = cv2.imread("<SOURCE_IMAGE_PATH>")
            image_height, image_width, _ = image.shape
            mediapipe_image = mp.Image(
                image_format=mp.ImageFormat.SRGB,
                data=cv2.cvtColor(image, cv2.COLOR_BGR2RGB))

            options = mp.tasks.vision.PoseLandmarkerOptions(
                base_options=mp.tasks.BaseOptions(
                    model_asset_path="pose_landmarker_heavy.task"
                ),
                running_mode=mp.tasks.vision.RunningMode.IMAGE,
                num_poses=2)

            PoseLandmarker = mp.tasks.vision.PoseLandmarker
            with PoseLandmarker.create_from_options(options) as landmarker:
                pose_landmarker_result = landmarker.detect(mediapipe_image)

            key_points = sv.KeyPoints.from_mediapipe(
                pose_landmarker_result, (image_width, image_height))
            ```

            ```python
            import cv2
            import mediapipe as mp
            import supervision as sv

            image = cv2.imread("<SOURCE_IMAGE_PATH>")
            image_height, image_width, _ = image.shape
            mediapipe_image = mp.Image(
                image_format=mp.ImageFormat.SRGB,
                data=cv2.cvtColor(image, cv2.COLOR_BGR2RGB))

            options = mp.tasks.vision.FaceLandmarkerOptions(
                base_options=mp.tasks.BaseOptions(
                    model_asset_path="face_landmarker.task"
                ),
                output_face_blendshapes=True,
                output_facial_transformation_matrixes=True,
                num_faces=2)

            FaceLandmarker = mp.tasks.vision.FaceLandmarker
            with FaceLandmarker.create_from_options(options) as landmarker:
                face_landmarker_result = landmarker.detect(mediapipe_image)

            key_points = sv.KeyPoints.from_mediapipe(
                face_landmarker_result, (image_width, image_height))
            ```

        pose_landmarksface_landmarksmulti_face_landmarksr   r   rc   )r9   r=   )re   rs   r    r1   landmarkrt   ru   rQ   rg   r$   ra   rh   
visibilityr   r*   ri   )rj   mediapipe_resultsresolution_whresultsrv   face_landmarkr9   rC   posern   ro   keypoint_xys               r   from_mediapipezKeyPoints.from_mediapipe  s   ^ $&67'66G/>>E$33; G
 ->,L,L,U,U ( %G &(89'66G&(>? 55= *;)O)O% "** 
 w<199;
 	5DM$&!  BJJq!11JJq!11 $$[1%,,X-@-@AB IIm$34	5 xx"**- "2:: F
 	
Gs   	F5*F:c                T   |j                   j                  j                         dk(  r| j                         S |j                   j                  j	                         j                         }|j                  j                  j	                         j                         j                  t              }t        j                  |D cg c]  }|j                  |    c}      }|j                   j                  j	                         j                         }t        |i} | ||||      S c c}w )a  
        Creates a `sv.KeyPoints` instance from a
        [YOLOv8](https://github.com/ultralytics/ultralytics) pose inference result.

        Args:
            ultralytics_results: The output Results instance from YOLOv8.

        Returns:
            A `sv.KeyPoints` object containing the keypoint coordinates, class IDs,
                and class names, and confidences of each keypoint.

        Examples:
            ```python
            import cv2
            import supervision as sv
            from ultralytics import YOLO

            image = cv2.imread("<SOURCE_IMAGE_PATH>")
            model = YOLO('yolov8s-pose.pt')

            result = model(image)[0]
            key_points = sv.KeyPoints.from_ultralytics(result)
            ```
        r   )r9   r;   r=   rB   )r`   r9   numelrg   cpunumpyboxesrj   astyper'   r   r*   namesconfr   )rj   ultralytics_resultsr9   r;   r3   rl   rC   rB   s           r   from_ultralyticszKeyPoints.from_ultralyticsU  s    4 ((++113q899; **--11399;&,,00446<<>EEcJhhhO 3 9 9! <OP(2277;;=CCE
!;@
 b8RVWW  Ps   D%c                   t        |j                  j                        dk(  r| j                         S |j                  j                  ddddddf   }|j                  j                  dddddf   }t	        |j                  d      r|j                  j
                  }nd}i }|>|j                  2g }|D ]"  }|j                  |   }|j                  |       $ ||t        <    | ||||      S )a  
        Create a `sv.KeyPoints` instance from a [YOLO-NAS](https://github.com/Deci-AI/super-gradients/blob/master/YOLONAS-POSE.md)
        pose inference results.

        Args:
            yolo_nas_results: The output object from YOLO NAS.

        Returns:
            A `sv.KeyPoints` object containing the keypoint coordinates, class IDs,
                and class names, and confidences of each keypoint.

        Examples:
            ```python
            import cv2
            import torch
            import supervision as sv
            import super_gradients

            image = cv2.imread("<SOURCE_IMAGE_PATH>")

            device = "cuda" if torch.cuda.is_available() else "cpu"
            model = super_gradients.training.models.get(
                "yolo_nas_pose_s", pretrained_weights="coco_pose").to(device)

            results = model.predict(image, conf=0.1)
            key_points = sv.KeyPoints.from_yolo_nas(results)
            ```
        r   N   labelsrd   )	rQ   rm   posesrg   re   r   rl   rh   r   )	rj   yolo_nas_resultsr9   rC   r;   rB   rl   c_idnames	            r   from_yolo_naszKeyPoints.from_yolo_nas|  s    < **001Q699;((..q!RaRx8%0066q!Qw?
 #..9'2299HH?A$4$@$@$LK  )'33D9""4() +6D&' *	
 	
r   c                .   t        |d   d      r|d   j                  j                         j                         j                  dk(  r| j                         S  | |d   j                  j                         j                         ddddddf   |d   j                  j                         j                         dddddf   |d   j                  j                         j                         j                  t                    S | j                         S )a  
        Create a `sv.KeyPoints` object from the
        [Detectron2](https://github.com/facebookresearch/detectron2) inference result.

        Args:
            detectron2_results: The output of a
                Detectron2 model containing instances with prediction data.

        Returns:
            A `sv.KeyPoints` object containing the keypoint coordinates, class IDs,
                and class names, and confidences of each keypoint.

        Examples:
            ```python
            import cv2
            import supervision as sv
            from detectron2.engine import DefaultPredictor
            from detectron2.config import get_cfg


            image = cv2.imread("<SOURCE_IMAGE_PATH>")
            cfg = get_cfg()
            cfg.merge_from_file("<CONFIG_PATH>")
            cfg.MODEL.WEIGHTS = "<WEIGHTS_PATH>"
            predictor = DefaultPredictor(cfg)

            result = predictor(image)
            keypoints = sv.KeyPoints.from_detectron2(result)
            ```
        	instancespred_keypointsr   Nr   r9   r=   r;   )	re   r   r   r   sizerg   pred_classesr   r'   )rj   detectron2_resultss     r   from_detectron2zKeyPoints.from_detectron2  s    B %k24DE!+.==AACIIKPPTUUyy{"%k2Arr# %7{$CAq%" ,K8cce  99;r   c           	        d|d   v r5|d   d   j                         j                         j                  dk(  r| j                         S |D cg c]D  }|d   j                         j                         |d   j                         j                         fF }}t	        | \  }} | t        j                  |      j                  t
        j                        t        j                  |      j                  t
        j                        t        j                  t        |            j                  t                    S | j                         S c c}w )ap	  
        Create a `sv.KeyPoints` object from the
        [Transformers](https://github.com/huggingface/transformers) inference result.

        Args:
            transformers_results: The output of a
                Transformers model containing instances with prediction data.

        Returns:
            A `sv.KeyPoints` object containing the keypoint coordinates, class IDs,
                and class names, and confidences of each keypoint.

        Examples:
            ```python
            from PIL import Image
            import requests
            import supervision as sv
            import torch
            from transformers import (
                AutoProcessor,
                RTDetrForObjectDetection,
                VitPoseForPoseEstimation,
            )

            device = "cuda" if torch.cuda.is_available() else "cpu"
            image = Image.open("<SOURCE_IMAGE_PATH>")

            DETECTION_MODEL_ID = "PekingU/rtdetr_r50vd_coco_o365"

            detection_processor = AutoProcessor.from_pretrained(DETECTION_MODEL_ID, use_fast=True)
            detection_model = RTDetrForObjectDetection.from_pretrained(DETECTION_MODEL_ID, device_map=device)

            inputs = detection_processor(images=frame, return_tensors="pt").to(device)

            with torch.no_grad():
                outputs = detection_model(**inputs)

            target_size = torch.tensor([(frame.height, frame.width)])
            results = detection_processor.post_process_object_detection(
                outputs, target_sizes=target_size, threshold=0.3)

            detections = sv.Detections.from_transformers(results[0])
            boxes = sv.xyxy_to_xywh(detections[detections.class_id == 0].xyxy)

            POSE_ESTIMATION_MODEL_ID = "usyd-community/vitpose-base-simple"

            pose_estimation_processor = AutoProcessor.from_pretrained(POSE_ESTIMATION_MODEL_ID)
            pose_estimation_model = VitPoseForPoseEstimation.from_pretrained(
                POSE_ESTIMATION_MODEL_ID, device_map=device)

            inputs = pose_estimation_processor(frame, boxes=[boxes], return_tensors="pt").to(device)

            with torch.no_grad():
                outputs = pose_estimation_model(**inputs)

            results = pose_estimation_processor.post_process_pose_estimation(outputs, boxes=[boxes])
            key_point = sv.KeyPoints.from_transformers(results[0])
            ```

        r`   r   scoresr   )r   r   r   rg   zipr   stackr   ri   arangerQ   r'   )rj   transformers_resultsresultresult_datar9   r   s         r   from_transformerszKeyPoints.from_transformers  s    ~ .q11#A&{3779??AFF!Kyy{" 3
  ;'++-3358$((*002K  k*JB88B<&&rzz2$&HHV$4$;$;BJJ$G3r7+2237  99;!s   A	Ec                   t        | j                        }|j                  d   |k7  rt        d|j                  d    d| d      |j                  d   | j                  j                  d   k7  r6t        d|j                  d    d| j                  j                  d    d      t	        j
                  |d      }|dkD  r7t	        j                  ||d   k(        st        d	|j                                |dkD  rt        |d         nd}t	        j                  ||| j                  j                  d
   f| j                  j                        }d}| j                  Vt        t        j                  t        j                     t	        j                  ||f| j                  j                              }d}| j                   t	        j                  ||ft"              }t%        |      D ]t  }t	        j&                  ||         }	| j                  ||	f   ||<   | | j                  | j                  ||	f   ||<   |T| j                   a| j                   ||	f   ||<   v d}
| j(                  | j(                  j+                         }
d}| j,                  | j,                  j+                         }t/        | j0                  t3        d            }t5        |||
|||      S )u  Filter keypoints using a 2D boolean mask of shape `(n, m)`.

        This method selects the **same set of keypoints from every object**, so
        every row of `mask` must contain the same number of `True` values.  The
        result is a new `KeyPoints` whose keypoint count is that uniform `k`.

        This is suitable for use cases such as *"keep only the left-side joints for
        all persons"* — where the selected joint indices are identical across objects.

        It is **not** suitable for per-object confidence filtering
        (`kp[kp.confidence > 0.5]`) when the threshold yields a different number of
        passing keypoints per object, because NumPy cannot represent a ragged
        `(n, ?, 2)` array.  For that pattern either process objects individually or
        zero out low-confidence entries in-place via `kp.confidence`.

        For the single-object case (`n == 1`) any boolean mask always satisfies the
        uniform-count requirement, so `kp[kp.confidence > 0.5]` works as expected.

        Args:
            mask: A boolean array of shape `(n, m)` where `n` is the number of
                objects and `m` is the number of keypoints per object.  Every row
                must select the same number of keypoints so that the result can be
                stored in a uniform `(n, k, ...)` array.

        Returns:
            A new `KeyPoints` instance containing only the keypoints selected by
            the mask for each object.

        Raises:
            ValueError: If `mask.shape[0]` does not match the number of objects, if
                `mask.shape[1]` does not match the number of keypoints, or if
                different rows of the mask select different numbers of `True` values.
        r   z2D boolean mask row count z does not match object count .r   z2D boolean mask column count z does not match keypoint count axiszCannot filter keypoints with a 2D boolean mask where rows have different numbers of True values. All objects must select the same number of keypoints. Got counts per object: r   rc   Nr9   r=   r>   r@   r;   rB   )rQ   r9   shaperE   r   sumr2   tolistr'   zerosr,   r=   r
   nptNDArrayri   r@   r!   rT   r-   r>   copyr;   r   rB   slicer7   )rG   maskncountskxy_selectedkeypoint_confidence_selectedvisible_selectedrowrow_indicesdetection_confidence_selectedclass_id_selecteddata_selecteds                r   _get_by_2d_bool_maskzKeyPoints._get_by_2d_bool_mask>  s   D L::a=A,TZZ]O <  !s!%  ::a=DGGMM!,,/

1 ?""&''--"2!316  1%q5&) 34* +1--/):<   !eCq	Nhh1dggmmA&67tww}}MGK$##/+/BJJ'!Qt'?'?'E'EF,( :><<#!xxAd;8 	GC..c3K#wwsK'78K,8,,8484L4L$5,S1  +0H(,S+5E(F %	G )-%$$0,0,E,E,J,J,L) ==$ $ 2 2 4%diit= <!>$&
 	
r   c                	   t        |t              r| j                  j                  |      S t        |t        j
                        r\|j                  dk(  rM|j                  t        k(  r:| j                  t        t        j                  t        j                     |            S t        |t              s|t        d      f}|\  }}t        |t               r|g}t        |t"              r't%        d |D              rt	        j&                  |      }t        |t"              r't%        d |D              rt	        j&                  |      }t        |t        j
                        r(|j                  t        k(  rt	        j(                  |      }t        |t        j
                        r(|j                  t        k(  rt	        j(                  |      }|}t        |t"        t        j
                  f      rt        |t"        t        j
                  f      rt	        j*                  |      sjt	        j*                  |      sUt	        j,                  t        t.        |      t        t.        |            \  }}t        t.        |      }t        t.        |      }t1        |      }| j2                  ||f   }d}	| j4                  | j4                  ||f   }	d}
| j6                  | j6                  |   }
d}| j8                  | j8                  ||f   }| j:                  | j:                  |   nd}t=        | j                  t        t.        |            }|j                  dk(  r>|j?                  ddd      }|	|	j?                  dd      }	|B|j?                  dd      }n.|j                  dk(  rt	        j*                  |d         s/t        |d   t        j
                        rV|d   j                  dk(  rD|t        j@                  df   }|	|	t        j@                  df   }	||t        j@                  df   }nt	        j*                  |d         s/t        |d   t        j
                        r^|d   j                  dk(  rL|ddt        j@                  ddf   }|	|	ddt        j@                  f   }	||ddt        j@                  f   }tC        ||	|
|||      S )	a	  
        Get a subset of the KeyPoints object or access an item from its data field.

        Supports detection-level (skeleton) filtering, keypoint-level (anchor)
        filtering, combined tuple indexing, and data field access by string key.

        Args:
            index: The index, indices, or key to access a subset of the KeyPoints
                or an item from the data.

        Returns:
            A subset of the KeyPoints object or an item from the data field.

        Examples:
            ```python
            import supervision as sv

            key_points = sv.KeyPoints(...)

            # detection-level filtering (returns KeyPoints)
            high_conf = key_points[key_points.detection_confidence > 0.5]
            class_0 = key_points[key_points.class_id == 0]

            # keypoint-level filtering (returns KeyPoints)
            visible = key_points[key_points.keypoint_confidence > 0.3]

            # indexing
            first = key_points[0]
            first_two = key_points[0:2]
            subset = key_points[[0, 2]]

            # anchor selection (uniform across all skeletons)
            nose_and_eyes = key_points[:, [0, 1, 2]]

            # data field access
            class_names = key_points['class_name']
            ```
        r   Nc              3  <   K   | ]  }t        |t                y wr   r   r"   s     r   r%   z(KeyPoints.__getitem__.<locals>.<genexpr>       &Fqz!T':&Fr&   c              3  <   K   | ]  }t        |t                y wr   r   r"   s     r   r%   z(KeyPoints.__getitem__.<locals>.<genexpr>  r   r&   r   r   .r   )"r    strrB   rf   r   r+   r/   r,   r!   r   r
   r   r   bool_tupler   r'   r1   r2   r*   r-   isscalarix_r   r4   r9   r=   r>   r@   r;   r   r0   newaxisr7   )rG   indexr3   jraw_ii_ixj_ixrow_ir   r   r   r   r   r   s                 r   __getitem__zKeyPoints.__getitem__  s   T eS!99==''eRZZ(UZZ1_PTAT,,T#++bhh2G-OPP%'E$K(E1aAa3&FA&F#FAa3&FA&F#FAa$Dq!Aa$Dq!A q4,-1tRZZ01KKNKKNS!d3l;JD$S$AS$A$U+ggadm'+$##/+/+C+CAqD+I((,%$$0,0,E,Ee,L)<<##||AqD148MM4MDMM%0SW%diic51ABq %--aA6K+7/K/S/Sq0,  +#3#;#;Aq#A "{{58$58RZZ0U1X]]a5G)"**c/:/;3O

C40 $/'7

C'H$U1X&58RZZ0U1X]]a5G)!RZZ*:;/;3O2::40 $/'72::'F$ <!>$&
 	
r   c                    t        |t        j                  t        f      st	        d      t        |t              rt        j
                  |      }|| j                  |<   y)a  
        Set a value in the data dictionary of the `sv.KeyPoints` object.

        Args:
            key: The key in the data dictionary to set.
            value: The value to set for the key.

        Examples:
            ```python
            import cv2
            import supervision as sv
            from ultralytics import YOLO

            image = cv2.imread("<SOURCE_IMAGE_PATH>")
            model = YOLO('yolov8s.pt')

            result = model(image)[0]
            key_points = sv.KeyPoints.from_ultralytics(result)

            key_points['class_name'] = [
                 model.model.names[class_id]
                 for class_id
                 in key_points.class_id
             ]
            ```
        z$Value must be a np.ndarray or a listN)r    r   r+   r1   	TypeErrorr*   rB   )rG   keyrO   s      r   __setitem__zKeyPoints.__setitem__&  sG    6 %"**d!34BCCeT"HHUOE		#r   c                Z     | t        j                  dt         j                              S )aF  
        Create an empty KeyPoints object with no key points.

        Returns:
            An empty `sv.KeyPoints` object.

        Examples:
            ```pycon
            >>> import supervision as sv
            >>> key_points = sv.KeyPoints.empty()
            >>> len(key_points)
            0

            ```
        )r   r   r   rc   )r9   )r   rg   ri   )rj   s    r   rg   zKeyPoints.emptyI  s    " bhhy

;<<r   c                V    t         j                         }| j                  |_        | |k(  S )ai  
        Returns `True` if the `KeyPoints` object is considered empty.

        Returns:
            `True` if the object is empty, `False` otherwise.

        Example:
            ```pycon
            >>> import supervision as sv
            >>> key_points = sv.KeyPoints.empty()
            >>> key_points.is_empty()
            True

            ```
        )r7   rg   rB   )rG   empty_key_pointss     r   is_emptyzKeyPoints.is_empty\  s*      %??, $		'''r   g      ?Fc                   t        |       dk(  r| S | j                  t        d      |s| j                  t        d      | j                  }t        j                  |dk(  d       }| j                  || j                  z  }t        j                  t        j                  ||d   t
        j                        d      }t        j                  t        j                  ||d   t
        j                        d      }t        j                  t        j                  ||d   t
        j                         d      }t        j                  t        j                  ||d   t
        j                         d      }	t        j                  ||||	gd      j                  t
        j                        }
|r2t        j                  |
| j                  j!                  dd      g      }nwt#        t$        j&                  t
        j(                     | j                        }t        j                  |
| j                  j!                  dd      |j!                  dd      g      }t+        |||	      }t#        t,        | |         S )
a  
        Performs non-max suppression on the keypoint detections. Bounding boxes
        are derived from valid keypoints of each skeleton, and standard box NMS
        is applied. A keypoint is considered valid when its coordinates are not
        all-zero and its `visible` flag is `True` (if `visible` is set).

        Args:
            threshold: The intersection-over-union threshold to use for
                non-maximum suppression. Must be in [0, 1]. Defaults to 0.5.
            class_agnostic: Whether to perform class-agnostic non-maximum
                suppression. If True, the class_id of each detection will be
                ignored. Defaults to False.
            overlap_metric: Metric used to compute the degree of overlap
                between pairs of bounding boxes. Defaults to
                `OverlapMetric.IOU`.

        Returns:
            A new `sv.KeyPoints` object after non-maximum suppression.

        Raises:
            ValueError: If `detection_confidence` is None.
            ValueError: If `class_agnostic` is False and `class_id`
                is None.

        Examples:
            ```python
            import cv2
            import supervision as sv
            from rfdetr import RFDETRKeypointPreview

            image = cv2.imread("<SOURCE_IMAGE_PATH>")
            model = RFDETRKeypointPreview()

            key_points = model.predict(image)
            key_points = key_points.with_nms(threshold=0.5)
            ```
        r   zDKeyPoints detection_confidence must be given for NMS to be executed.zKeyPoints class_id must be given for NMS to be executed. If you intended to perform class agnostic NMS set class_agnostic=True.r   ).r   r   ).r   )r_   iou_thresholdoverlap_metric)rQ   r>   rE   r;   r9   r   r2   r@   minwhereinfmaxr   r   ri   hstackr0   r
   r   r   int_r   r7   )rG   	thresholdclass_agnosticr   r9   validx_miny_minx_maxy_maxxyxyr_   r;   keeps                 r   with_nmszKeyPoints.with_nmsp  s   V t9>K$$,V  $--"7'  WWab))<<#DLL(Erxxr&z266:Crxxr&z266:Crxxr&zBFF7;!Drxxr&zBFF7;!Dxxue41=DDRZZP))T4+D+D+L+LRQR+S$TUKCKK0$--@H))--55b!<$$R+K '##)
 ItDz**r   c                `   | j                         rt        j                         S | j                  }|r:t	        j
                  t        |      t        j                        }|dd|ddf   }t	        j                  |dk(  d       }|j                  d      }|dddddf   |dddddf   }}t	        j                  ||t        j                        j                  d      }t	        j                  ||t        j                        j                  d      }	t	        j                  ||t        j                         j                  d      }
t	        j                  ||t        j                         j                  d      }t	        j                  ||	|
|fd      j                  t        j                         }d|| <   | j"                  *| j"                  j                  t        j                         }nU| j$                  G| j$                  }|r	|ddf   }|j'                  d      j                  t        j                         }nd}t        ||      }| j(                  |_        | j*                  |_        t-        t        |t-        t.        |j0                        dkD           }|S )	a;  
        Convert a KeyPoints object to a Detections object. This
        approximates the bounding box of the detected object by
        taking the bounding box that fits all key points.

        Args:
            selected_keypoint_indices: The
                indices of the key points to include in the bounding box
                calculation. This helps focus on a subset of key points,
                e.g. when some are occluded. Captures all key points by
                default. An empty sequence (`[]`) is treated the same as
                `None` and selects all key points.

        Returns:
            detections: The converted detections object.

        Examples:
            ```pycon
            >>> import numpy as np
            >>> import supervision as sv
            >>> key_points = sv.KeyPoints(
            ...     xy=np.array([[[10, 20], [30, 40]]], dtype=np.float32)
            ... )
            >>> detections = key_points.as_detections()
            >>> detections.xyxy
            array([[10., 20., 30., 40.]], dtype=float32)

            ```
        rc   Nr   r   r   r   g        )r   rC   )r   r   rg   r9   r   asarrayr1   intpr2   anyr   r   r   r   r   r   ri   r>   r=   meanr;   rB   r
   r   area)rG   selected_keypoint_indicesr9   indicesr   	has_validr$   ra   r   r   r   r   r   rC   r=   
detectionss                   r   as_detectionszKeyPoints.as_detections  s"   @ ==?##%%WW$jj&?!@PGAwM"B aa((II1I%	!Q'{Bq!QwK1266*..A.6266*..A.6BFF7+//Q/7BFF7+//Q/7xxue41=DDRZZPiZ$$02299"**EJ%%1"&":":(&9!W*&E#,11q19@@LJJTjA
"mm
))
*jc:??1Ka1O&PQ
r   )NNNNN)r9   r8   r;   r:   r=   r<   r>   r<   r@   r?   rB   z5dict[str, npt.NDArray[np.generic] | list[Any]] | NonerC   r<   returnNone)r   r   )r   r<   )rO   r<   r   r   )r   r'   )r   zIterator[tuple[npt.NDArray[np.float32], npt.NDArray[np.float32] | None, npt.NDArray[np.int_] | None, dict[str, npt.NDArray[np.generic] | list[Any]]]])rX   objectr   r!   )rk   r   r   r7   )rx   r   ry   ztuple[int, int]r   r7   )r   r   r   r7   )r   r   r   r7   )r   r   r   r7   )r   r   r   r7   )r   znpt.NDArray[np.bool_]r   r7   )r   zIndex1D | Index2D | strr   z6KeyPoints | npt.NDArray[np.generic] | list[Any] | None)r   r   rO   z#npt.NDArray[np.generic] | list[Any]r   r   )r   r7   )r   r!   )r   floatr   r!   r   r   r   r7   r   )r   zIterable[int] | Noner   r   )$__name__
__module____qualname____doc____annotations__r;   r=   r>   r@   r   r[   rB   rH   rF   propertyrC   setterrR   rU   rY   classmethodrq   r~   r   r   r   r   r   r   r   rg   r   r   IOUr   r    r   r   r7   r7   J   sP   `D 	 ,0H)0:>7>;?8?,0G)0;@QU;VD
8V
 15>B?C04FJ3 6:3#3 .3 <	3
 =3 .3 D3 33 
3j
 ( ( ) )(
0
$ Q
 Q
f {
 #{
4C{
	{
 {
z $X $XL 7
 7
r 0 0d R Rh]
~G
&G
 
@G
R!F = =$(, $(5(9(9	V+V+ V+ &	V+
 
V+r AEF)=F	Fr   r7   )r   npt.NDArray[np.generic] | Noner   r  r   r!   )r3   _RowIndexInputr   r)   )3
__future__r   loggingcollections.abcr   r   dataclassesr   r   typingr   r	   r
   r   r   numpy.typingr   supervision.configr   supervision.detection.corer   $supervision.detection.utils.internalr   r   'supervision.detection.utils.iou_and_nmsr   r   supervision.utils.internalr   supervision.validatorsr   	getLoggerr   loggerr'   r   r1   r!   r   r   r   Index1Dr   Index2Dr(   genericr  r)   r   r4   r7   r  r   r   <module>r     sJ   "  . ( # #   4 1 M 7 =			8	$
	IJKKKK  
!JJsOKK

I		 CKK

3T#YEF )))*) 
). C C Cr   