kinemotion 0.70.1__py3-none-any.whl → 0.71.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. kinemotion/__init__.py +4 -1
  2. kinemotion/cmj/analysis.py +79 -30
  3. kinemotion/cmj/api.py +16 -39
  4. kinemotion/cmj/cli.py +0 -21
  5. kinemotion/cmj/debug_overlay.py +154 -286
  6. kinemotion/cmj/joint_angles.py +96 -31
  7. kinemotion/cmj/metrics_validator.py +30 -51
  8. kinemotion/cmj/validation_bounds.py +1 -18
  9. kinemotion/core/__init__.py +0 -2
  10. kinemotion/core/auto_tuning.py +91 -99
  11. kinemotion/core/debug_overlay_utils.py +142 -15
  12. kinemotion/core/experimental.py +55 -51
  13. kinemotion/core/filtering.py +15 -11
  14. kinemotion/core/overlay_constants.py +61 -0
  15. kinemotion/core/pose.py +67 -499
  16. kinemotion/core/smoothing.py +65 -51
  17. kinemotion/core/types.py +15 -0
  18. kinemotion/core/validation.py +6 -7
  19. kinemotion/core/video_io.py +14 -9
  20. kinemotion/dropjump/__init__.py +2 -2
  21. kinemotion/dropjump/analysis.py +67 -44
  22. kinemotion/dropjump/api.py +12 -44
  23. kinemotion/dropjump/cli.py +63 -105
  24. kinemotion/dropjump/debug_overlay.py +124 -65
  25. kinemotion/dropjump/validation_bounds.py +1 -1
  26. kinemotion/models/rtmpose-s_simcc-body7_pt-body7-halpe26_700e-256x192-7f134165_20230605.onnx +0 -0
  27. kinemotion/models/yolox_tiny_8xb8-300e_humanart-6f3252f9.onnx +0 -0
  28. {kinemotion-0.70.1.dist-info → kinemotion-0.71.1.dist-info}/METADATA +1 -5
  29. kinemotion-0.71.1.dist-info/RECORD +50 -0
  30. kinemotion/core/rtmpose_cpu.py +0 -626
  31. kinemotion/core/rtmpose_wrapper.py +0 -190
  32. kinemotion-0.70.1.dist-info/RECORD +0 -51
  33. {kinemotion-0.70.1.dist-info → kinemotion-0.71.1.dist-info}/WHEEL +0 -0
  34. {kinemotion-0.70.1.dist-info → kinemotion-0.71.1.dist-info}/entry_points.txt +0 -0
  35. {kinemotion-0.70.1.dist-info → kinemotion-0.71.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,190 +0,0 @@
1
- """RTMPose wrapper for CUDA and CoreML acceleration.
2
-
3
- This adapter wraps RTMLib's BodyWithFeet for CUDA (NVIDIA GPU) and CoreML (Apple Silicon)
4
- acceleration, matching kinemotion's PoseTracker API.
5
-
6
- Performance:
7
- - CUDA (RTX 4070 Ti Super): 133 FPS (271% of MediaPipe)
8
- - CoreML (M1 Pro): 42 FPS (94% of MediaPipe)
9
- - Accuracy: 9-12px mean difference from MediaPipe
10
- """
11
-
12
- from __future__ import annotations
13
-
14
- import numpy as np
15
- from rtmlib import BodyWithFeet
16
-
17
- from kinemotion.core.timing import NULL_TIMER, Timer
18
-
19
- # Halpe-26 to kinemotion landmark mapping
20
- HALPE_TO_KINEMOTION = {
21
- 0: "nose",
22
- 5: "left_shoulder",
23
- 6: "right_shoulder",
24
- 11: "left_hip",
25
- 12: "right_hip",
26
- 13: "left_knee",
27
- 14: "right_knee",
28
- 15: "left_ankle",
29
- 16: "right_ankle",
30
- 20: "left_foot_index",
31
- 21: "right_foot_index",
32
- 24: "left_heel",
33
- 25: "right_heel",
34
- }
35
-
36
-
37
- class RTMPoseWrapper:
38
- """RTMPose wrapper for CUDA/CoreML acceleration.
39
-
40
- Uses RTMLib's BodyWithFeet (Halpe-26 format) which provides all 13
41
- kinemotion landmarks including feet.
42
-
43
- Supports:
44
- - device='cuda': NVIDIA GPU acceleration (fastest)
45
- - device='mps': Apple Silicon CoreML acceleration
46
- - device='cpu': Fallback (unoptimized, use rtmpose_cpu.py instead)
47
-
48
- Attributes:
49
- timer: Optional Timer for measuring operations
50
- estimator: RTMLib BodyWithFeet estimator instance
51
- mode: RTMLib mode ('lightweight', 'balanced', 'performance')
52
- device: Target device ('cuda', 'mps', 'cpu')
53
- """
54
-
55
- def __init__(
56
- self,
57
- min_detection_confidence: float = 0.5,
58
- min_tracking_confidence: float = 0.5,
59
- timer: Timer | None = None,
60
- mode: str = "lightweight",
61
- backend: str = "onnxruntime",
62
- device: str = "cpu",
63
- pose_input_size: tuple[int, int] | None = None,
64
- ) -> None:
65
- """Initialize the RTMPose wrapper.
66
-
67
- Args:
68
- min_detection_confidence: Minimum confidence for pose detection
69
- min_tracking_confidence: Minimum confidence for pose tracking
70
- timer: Optional Timer for measuring operations
71
- mode: RTMLib performance mode:
72
- - 'lightweight': Fastest, RTMPose-s
73
- - 'balanced': Default mode
74
- - 'performance': Best accuracy, RTMPose-m
75
- backend: RTMLib backend ('onnxruntime', 'opencv')
76
- device: RTMLib device ('cpu', 'cuda', 'mps')
77
- pose_input_size: Custom input size as (height, width) tuple
78
- """
79
- self.timer = timer or NULL_TIMER
80
- self.mode = mode
81
- self.backend = backend
82
- self.device = device
83
-
84
- with self.timer.measure("rtmpose_wrapper_initialization"):
85
- kwargs = {
86
- "mode": mode,
87
- "backend": backend,
88
- "device": device,
89
- }
90
- if pose_input_size is not None:
91
- kwargs["pose_input_size"] = pose_input_size # type: ignore[assignment]
92
- self.estimator = BodyWithFeet(**kwargs) # type: ignore[arg-type]
93
-
94
- def process_frame(
95
- self, frame: np.ndarray, timestamp_ms: int = 0
96
- ) -> dict[str, tuple[float, float, float]] | None:
97
- """Process a single frame and extract pose landmarks.
98
-
99
- Args:
100
- frame: BGR image frame (OpenCV format)
101
- timestamp_ms: Frame timestamp in milliseconds (unused, for API compatibility)
102
-
103
- Returns:
104
- Dictionary mapping landmark names to (x, y, visibility) tuples,
105
- or None if no pose detected. Coordinates are normalized (0-1).
106
- """
107
- if frame.size == 0:
108
- return None
109
-
110
- height, width = frame.shape[:2]
111
-
112
- # RTMLib expects RGB, but BodyWithFeet handles conversion internally
113
- with self.timer.measure("rtmpose_inference"):
114
- keypoints, scores = self.estimator(frame)
115
-
116
- if keypoints.shape[0] == 0:
117
- return None
118
-
119
- # Extract first person's keypoints
120
- with self.timer.measure("landmark_extraction"):
121
- landmarks = self._extract_landmarks(keypoints[0], scores[0], width, height)
122
-
123
- return landmarks
124
-
125
- def _extract_landmarks(
126
- self,
127
- keypoints: np.ndarray,
128
- scores: np.ndarray,
129
- img_width: int,
130
- img_height: int,
131
- ) -> dict[str, tuple[float, float, float]]:
132
- """Extract and convert RTMLib landmarks to MediaPipe format.
133
-
134
- Args:
135
- keypoints: (26, 2) array of pixel coordinates
136
- scores: (26,) array of confidence scores
137
- img_width: Image width for normalization
138
- img_height: Image height for normalization
139
-
140
- Returns:
141
- Dictionary mapping kinemotion landmark names to normalized
142
- (x, y, visibility) tuples.
143
- """
144
- landmarks = {}
145
-
146
- for halpe_idx, name in HALPE_TO_KINEMOTION.items():
147
- x_pixel, y_pixel = keypoints[halpe_idx]
148
- confidence = float(scores[halpe_idx])
149
-
150
- # Normalize to [0, 1] like MediaPipe
151
- x_norm = float(x_pixel / img_width)
152
- y_norm = float(y_pixel / img_height)
153
-
154
- # Clamp to valid range
155
- x_norm = max(0.0, min(1.0, x_norm))
156
- y_norm = max(0.0, min(1.0, y_norm))
157
-
158
- # Use confidence as visibility (MediaPipe compatibility)
159
- landmarks[name] = (x_norm, y_norm, confidence)
160
-
161
- return landmarks
162
-
163
- def close(self) -> None:
164
- """Release resources (no-op for RTMLib)."""
165
- pass
166
-
167
-
168
- def create_rtmpose_wrapper(
169
- device: str = "cpu",
170
- mode: str = "lightweight",
171
- timer: Timer | None = None,
172
- ) -> RTMPoseWrapper:
173
- """Factory function to create an RTMPose wrapper.
174
-
175
- Args:
176
- device: Target device ('cuda', 'mps', 'cpu')
177
- mode: Performance mode ('lightweight', 'balanced', 'performance')
178
- timer: Optional Timer for measuring operations
179
-
180
- Returns:
181
- Configured RTMPoseWrapper instance
182
-
183
- Example:
184
- # CUDA (NVIDIA GPU)
185
- tracker = create_rtmpose_wrapper(device='cuda')
186
-
187
- # CoreML (Apple Silicon)
188
- tracker = create_rtmpose_wrapper(device='mps')
189
- """
190
- return RTMPoseWrapper(device=device, mode=mode, timer=timer)
@@ -1,51 +0,0 @@
1
- kinemotion/__init__.py,sha256=Ho_BUtsM0PBxBW1ye9RlUg0ZqBlgGudRI9bZTF7QKUI,966
2
- kinemotion/api.py,sha256=uG1e4bTnj2c-6cbZJEZ_LjMwFdaG32ba2KcK_XjE_NI,1040
3
- kinemotion/cli.py,sha256=_Us9krSce4GUKtlLIPrFUhKmPWURzeJ1-ydR_YU2VGw,626
4
- kinemotion/cmj/__init__.py,sha256=SkAw9ka8Yd1Qfv9hcvk22m3EfucROzYrSNGNF5kDzho,113
5
- kinemotion/cmj/analysis.py,sha256=jM9ZX44h1__Cg2iIhAYRoo_5fPwIOeV5Q2FZ22rMvKY,22202
6
- kinemotion/cmj/api.py,sha256=Pyc0IoFyvBWcLnWq3lV9pn2ZcdFEU8ki_GX1DfXARSU,19417
7
- kinemotion/cmj/cli.py,sha256=-hNNN7rshrICJ7bG0EfSdEDOPNcGX_CtOZfgrZfatQg,10522
8
- kinemotion/cmj/debug_overlay.py,sha256=bX9aPLhXiLCCMZW9v8Y4OiOAaZO0i-UGr-Pl8HCsmbI,15810
9
- kinemotion/cmj/joint_angles.py,sha256=HmheIEiKcQz39cRezk4h-htorOhGNPsqKIR9RsAEKts,9960
10
- kinemotion/cmj/kinematics.py,sha256=KwA8uSj3g1SeNf0NXMSHsp3gIw6Gfa-6QWIwdYdRXYw,13362
11
- kinemotion/cmj/metrics_validator.py,sha256=3oFB331Xch2sRMTvqALiwOvsWkCUhrLQ7ZCZ4QhI2lA,30986
12
- kinemotion/cmj/validation_bounds.py,sha256=Ry915JdInPXbqjaVGNY_urnDO1PAkCSJqHwNKRq-VkU,12048
13
- kinemotion/core/__init__.py,sha256=8WB7tAJPKOxgNzbhIEOnGnkRr0CcdNeTnz91Jsiyafo,1812
14
- kinemotion/core/auto_tuning.py,sha256=lhAqPc-eLjMYx9BCvKdECE7TD2Dweb9KcifV6JHaXOE,11278
15
- kinemotion/core/cli_utils.py,sha256=sQPbT6XWWau-sm9yuN5c3eS5xNzoQGGXwSz6hQXtRvM,1859
16
- kinemotion/core/debug_overlay_utils.py,sha256=D4aT8xstThPcV2i5D4KJZJEttW6E_4GE5QiERqe1MwI,13049
17
- kinemotion/core/determinism.py,sha256=Frw-KAOvAxTL_XtxoWpXCjMbQPUKEAusK6JctlkeuRo,2509
18
- kinemotion/core/experimental.py,sha256=IK05AF4aZS15ke85hF3TWCqRIXU1AlD_XKzFz735Ua8,3640
19
- kinemotion/core/filtering.py,sha256=Oc__pV6iHEGyyovbqa5SUi-6v8QyvaRVwA0LRayM884,11355
20
- kinemotion/core/formatting.py,sha256=G_3eqgOtym9RFOZVEwCxye4A2cyrmgvtQ214vIshowU,2480
21
- kinemotion/core/metadata.py,sha256=bJAVa4nym__zx1hNowSZduMGKBSGOPxTbBQkjm6N0D0,7207
22
- kinemotion/core/model_downloader.py,sha256=mqhJBHGaNe0aN9qbcBqvcTk9FDd7xaHqEcwD-fyP89c,5205
23
- kinemotion/core/pipeline_utils.py,sha256=B5jMXoiLaTh02uGA2MIe1uZLVSRGZ5nxbARuvdrjDrQ,15161
24
- kinemotion/core/pose.py,sha256=d5hCWiKifuB80shOC68uuRIYoXVBOQOtU54RjgNaTqc,28637
25
- kinemotion/core/pose_landmarks.py,sha256=LcEbL5K5xKia6dCzWf6Ft18UIE1CLMMqCZ3KUjwUDzM,1558
26
- kinemotion/core/quality.py,sha256=VUkRL2N6B7lfIZ2pE9han_U68JwarmZz1U0ygHkgkhE,13022
27
- kinemotion/core/rtmpose_cpu.py,sha256=Mox8Hon3hulyA6uHKUIe2hCR4xinDZfotOOIVncXi2M,22356
28
- kinemotion/core/rtmpose_wrapper.py,sha256=R5QlZIHJczM1AxvVqF256DcD_LvGvHyjrFnxCsWc7do,6202
29
- kinemotion/core/smoothing.py,sha256=ELMHL7pzSqYffjnLDBUMBJIgt1AwOssDInE8IiXBbig,15942
30
- kinemotion/core/timing.py,sha256=ITX77q4hbtajRuWfgwYhws8nCvOeKFlEdKjCu8lD9_w,7938
31
- kinemotion/core/types.py,sha256=A_HclzKpf3By5DiJ0wY9B-dQJrIVAAhUfGab7qTSIL8,1279
32
- kinemotion/core/validation.py,sha256=0xVv-ftWveV60fJ97kmZMuy2Qqqb5aZLR50dDIrjnhg,6773
33
- kinemotion/core/video_io.py,sha256=TxdLUEpekGytesL3X3k78WWgZTOd5fuge30hU4Uy48Y,9198
34
- kinemotion/dropjump/__init__.py,sha256=tC3H3BrCg8Oj-db-Vrtx4PH_llR1Ppkd5jwaOjhQcLg,862
35
- kinemotion/dropjump/analysis.py,sha256=YomuoJF_peyrBSpeT89Q5_sBgY0kEDyq7TFrtEnRLjs,28049
36
- kinemotion/dropjump/api.py,sha256=0AGA896H97x9GZoO8kX75iBCNCHEEm1lH99yoqJceW8,21522
37
- kinemotion/dropjump/cli.py,sha256=sJccY6HrRqj6DKERtsUgy__Wmp-pdm5c765EN3ydiec,17562
38
- kinemotion/dropjump/debug_overlay.py,sha256=9RQYXPRf0q2wdy6y2Ak2R4tpRceDwC8aJrXZzkmh3Wo,5942
39
- kinemotion/dropjump/kinematics.py,sha256=dx4PuXKfKMKcsc_HX6sXj8rHXf9ksiZIOAIkJ4vBlY4,19637
40
- kinemotion/dropjump/metrics_validator.py,sha256=lSfo4Lm5FHccl8ijUP6SA-kcSh50LS9hF8UIyWxcnW8,9243
41
- kinemotion/dropjump/validation_bounds.py,sha256=x4yjcFxyvdMp5e7MkcoUosGLeGsxBh1Lft6h__AQ2G8,5124
42
- kinemotion/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
- kinemotion/models/pose_landmarker_lite.task,sha256=WZKeHR7pUodzXd2DOxnPSsRtKbx6_du_Z1PEWWkNV0o,5777746
44
- kinemotion/models/rtmpose-s_simcc-body7_pt-body7-halpe26_700e-256x192-7f134165_20230605.onnx,sha256=hcXWaaoLDHlpeZ6p4GINO4wdPCtoeCQ-mKHvg1FFeYY,22793379
45
- kinemotion/models/yolox_tiny_8xb8-300e_humanart-6f3252f9.onnx,sha256=zrEcBymPlcUNfFq-uQbQM0DIXyOqeePmaWbn-2wwclA,20283006
46
- kinemotion/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
- kinemotion-0.70.1.dist-info/METADATA,sha256=nQ1AOdsgyVvO96oAwTXuAJ7Gbi29FYbg2mv6UCsF7h0,26372
48
- kinemotion-0.70.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
49
- kinemotion-0.70.1.dist-info/entry_points.txt,sha256=zaqnAnjLvcdrk1Qvj5nvXZCZ2gp0prS7it1zTJygcIY,50
50
- kinemotion-0.70.1.dist-info/licenses/LICENSE,sha256=KZajvqsHw0NoOHOi2q0FZ4NBe9HdV6oey-IPYAtHXfg,1088
51
- kinemotion-0.70.1.dist-info/RECORD,,