Source code for pose.keypoints

"""Keypoint skeleton definitions for COCO (human) and common animal models."""

from __future__ import annotations

from dataclasses import dataclass, field

# ── COCO 17-keypoint skeleton (YOLOv8-pose default) ──────────────────────────
COCO_KEYPOINTS: list[str] = [
    "nose",
    "left_eye",
    "right_eye",
    "left_ear",
    "right_ear",
    "left_shoulder",
    "right_shoulder",
    "left_elbow",
    "right_elbow",
    "left_wrist",
    "right_wrist",
    "left_hip",
    "right_hip",
    "left_knee",
    "right_knee",
    "left_ankle",
    "right_ankle",
]

# Skeleton edges as (kp_index_a, kp_index_b) pairs for drawing limbs
COCO_SKELETON: list[tuple[int, int]] = [
    (0, 1),
    (0, 2),
    (1, 3),
    (2, 4),  # face
    (5, 6),  # shoulders
    (5, 7),
    (7, 9),
    (6, 8),
    (8, 10),  # arms
    (5, 11),
    (6, 12),
    (11, 12),  # torso
    (11, 13),
    (13, 15),
    (12, 14),
    (14, 16),  # legs
]

COCO_COLORS: list[tuple[int, int, int]] = [
    (255, 0, 85),
    (255, 0, 0),
    (255, 85, 0),
    (255, 170, 0),
    (255, 255, 0),
    (170, 255, 0),
    (85, 255, 0),
    (0, 255, 0),
    (0, 255, 85),
    (0, 255, 170),
    (0, 255, 255),
    (0, 170, 255),
    (0, 85, 255),
    (0, 0, 255),
    (85, 0, 255),
    (170, 0, 255),
    (255, 0, 170),
]

# ── DeepLabCut-style mouse skeleton (example — replace with your DLC project) ─
MOUSE_KEYPOINTS: list[str] = [
    "snout",
    "left_ear",
    "right_ear",
    "neck",
    "left_forepaw",
    "right_forepaw",
    "mid_back",
    "left_hindpaw",
    "right_hindpaw",
    "tail_base",
    "tail_mid",
    "tail_tip",
]

MOUSE_SKELETON: list[tuple[int, int]] = [
    (0, 1),
    (0, 2),
    (0, 3),  # head
    (3, 4),
    (3, 5),  # forepaws
    (3, 6),
    (6, 7),
    (6, 8),  # mid-body + hindpaws
    (6, 9),
    (9, 10),
    (10, 11),  # tail
]


[docs] @dataclass class PoseResult: """Normalised output from any pose estimator backend. Attributes ---------- frame_index : int Caller-supplied frame index this result was computed from. timestamp_ns : int Caller-supplied timestamp (ns) this result was computed from. camera_index : int Caller-supplied camera index this result was computed from. subjects : list of SubjectPose One entry per detected subject in this frame. backend : str, default "unknown" Identifies which estimator/model produced this result (e.g. ``"yolov8-pose/yolov8n-pose.pt"``). inference_ms : float, default 0.0 Wall-clock inference time for this frame, in milliseconds. """ frame_index: int timestamp_ns: int camera_index: int subjects: list[SubjectPose] = field(default_factory=list) backend: str = "unknown" inference_ms: float = 0.0
[docs] @dataclass class SubjectPose: """Keypoints for a single detected subject. Attributes ---------- subject_id : int Tracking ID, or ``-1`` if no cross-frame tracking is performed. confidence : float Overall detection confidence, in ``[0, 1]``. keypoints : list of tuple of float ``(x_px, y_px)`` per keypoint, in the backend's own keypoint order (e.g. :data:`COCO_KEYPOINTS`). visibilities : list of float Per-keypoint confidence, in ``[0, 1]``, parallel to ``keypoints``. bbox_xyxy : tuple of float, default (0, 0, 0, 0) Subject's detection bounding box, ``(x1, y1, x2, y2)`` pixels. """ subject_id: int # tracking ID (-1 if no tracking) confidence: float # overall detection confidence 0-1 keypoints: list[tuple[float, float]] # (x_px, y_px) per keypoint visibilities: list[float] # 0-1 confidence per keypoint bbox_xyxy: tuple[float, float, float, float] = (0, 0, 0, 0)