kinemotion 0.73.0__py3-none-any.whl → 0.74.0__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.
Potentially problematic release.
This version of kinemotion might be problematic. Click here for more details.
- kinemotion/core/__init__.py +11 -0
- kinemotion/core/auto_tuning.py +74 -27
- kinemotion/core/cli_utils.py +74 -0
- kinemotion/core/quality.py +4 -6
- kinemotion/core/validation.py +70 -0
- kinemotion/core/video_analysis_base.py +132 -0
- kinemotion/core/video_io.py +27 -18
- kinemotion/countermovement_jump/analysis.py +0 -97
- kinemotion/countermovement_jump/api.py +37 -11
- kinemotion/countermovement_jump/cli.py +6 -46
- kinemotion/countermovement_jump/metrics_validator.py +143 -229
- kinemotion/drop_jump/analysis.py +54 -29
- kinemotion/drop_jump/api.py +46 -16
- kinemotion/drop_jump/cli.py +8 -58
- kinemotion/drop_jump/kinematics.py +98 -50
- kinemotion/drop_jump/metrics_validator.py +24 -50
- {kinemotion-0.73.0.dist-info → kinemotion-0.74.0.dist-info}/METADATA +1 -1
- {kinemotion-0.73.0.dist-info → kinemotion-0.74.0.dist-info}/RECORD +21 -20
- {kinemotion-0.73.0.dist-info → kinemotion-0.74.0.dist-info}/WHEEL +0 -0
- {kinemotion-0.73.0.dist-info → kinemotion-0.74.0.dist-info}/entry_points.txt +0 -0
- {kinemotion-0.73.0.dist-info → kinemotion-0.74.0.dist-info}/licenses/LICENSE +0 -0
kinemotion/drop_jump/api.py
CHANGED
|
@@ -8,8 +8,11 @@ from pathlib import Path
|
|
|
8
8
|
from typing import TYPE_CHECKING
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
+
import numpy as np
|
|
11
12
|
from numpy.typing import NDArray
|
|
12
13
|
|
|
14
|
+
from .analysis import ContactState
|
|
15
|
+
|
|
13
16
|
from ..core.auto_tuning import (
|
|
14
17
|
AnalysisParameters,
|
|
15
18
|
QualityPreset,
|
|
@@ -57,6 +60,7 @@ __all__ = [
|
|
|
57
60
|
"DropJumpVideoConfig",
|
|
58
61
|
"DropJumpVideoResult",
|
|
59
62
|
"process_dropjump_video",
|
|
63
|
+
"process_dropjump_video_from_config",
|
|
60
64
|
"process_dropjump_videos_bulk",
|
|
61
65
|
]
|
|
62
66
|
|
|
@@ -98,14 +102,33 @@ class DropJumpVideoConfig:
|
|
|
98
102
|
overrides: AnalysisOverrides | None = None
|
|
99
103
|
detection_confidence: float | None = None
|
|
100
104
|
tracking_confidence: float | None = None
|
|
105
|
+
verbose: bool = False
|
|
106
|
+
timer: Timer | None = None
|
|
107
|
+
pose_tracker: "MediaPipePoseTracker | None" = None
|
|
108
|
+
|
|
109
|
+
def to_kwargs(self) -> dict:
|
|
110
|
+
"""Convert config to kwargs dict for process_dropjump_video."""
|
|
111
|
+
return {
|
|
112
|
+
"video_path": self.video_path,
|
|
113
|
+
"quality": self.quality,
|
|
114
|
+
"output_video": self.output_video,
|
|
115
|
+
"json_output": self.json_output,
|
|
116
|
+
"drop_start_frame": self.drop_start_frame,
|
|
117
|
+
"overrides": self.overrides,
|
|
118
|
+
"detection_confidence": self.detection_confidence,
|
|
119
|
+
"tracking_confidence": self.tracking_confidence,
|
|
120
|
+
"verbose": self.verbose,
|
|
121
|
+
"timer": self.timer,
|
|
122
|
+
"pose_tracker": self.pose_tracker,
|
|
123
|
+
}
|
|
101
124
|
|
|
102
125
|
|
|
103
126
|
def _assess_dropjump_quality(
|
|
104
|
-
vertical_positions: "NDArray",
|
|
105
|
-
visibilities: "NDArray",
|
|
106
|
-
contact_states: list,
|
|
127
|
+
vertical_positions: "NDArray[np.float64]",
|
|
128
|
+
visibilities: "NDArray[np.float64]",
|
|
129
|
+
contact_states: list["ContactState"],
|
|
107
130
|
fps: float,
|
|
108
|
-
) -> tuple:
|
|
131
|
+
) -> tuple[QualityAssessment, "NDArray[np.bool_]", bool, int]:
|
|
109
132
|
"""Assess tracking quality and detect phases.
|
|
110
133
|
|
|
111
134
|
Returns:
|
|
@@ -607,6 +630,23 @@ def process_dropjump_video(
|
|
|
607
630
|
return metrics
|
|
608
631
|
|
|
609
632
|
|
|
633
|
+
def process_dropjump_video_from_config(
|
|
634
|
+
config: DropJumpVideoConfig,
|
|
635
|
+
) -> DropJumpMetrics:
|
|
636
|
+
"""Process a drop jump video using a configuration object.
|
|
637
|
+
|
|
638
|
+
This is a convenience wrapper around process_dropjump_video that
|
|
639
|
+
accepts a DropJumpVideoConfig instead of individual parameters.
|
|
640
|
+
|
|
641
|
+
Args:
|
|
642
|
+
config: Configuration object containing all analysis parameters
|
|
643
|
+
|
|
644
|
+
Returns:
|
|
645
|
+
DropJumpMetrics object containing analysis results
|
|
646
|
+
"""
|
|
647
|
+
return process_dropjump_video(**config.to_kwargs())
|
|
648
|
+
|
|
649
|
+
|
|
610
650
|
def process_dropjump_videos_bulk(
|
|
611
651
|
configs: list[DropJumpVideoConfig],
|
|
612
652
|
max_workers: int = 4,
|
|
@@ -633,18 +673,8 @@ def _process_dropjump_video_wrapper(config: DropJumpVideoConfig) -> DropJumpVide
|
|
|
633
673
|
start_time = time.perf_counter()
|
|
634
674
|
|
|
635
675
|
try:
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
quality=config.quality,
|
|
639
|
-
output_video=config.output_video,
|
|
640
|
-
json_output=config.json_output,
|
|
641
|
-
drop_start_frame=config.drop_start_frame,
|
|
642
|
-
overrides=config.overrides,
|
|
643
|
-
detection_confidence=config.detection_confidence,
|
|
644
|
-
tracking_confidence=config.tracking_confidence,
|
|
645
|
-
verbose=False,
|
|
646
|
-
)
|
|
647
|
-
|
|
676
|
+
# Use convenience wrapper to avoid parameter unpacking
|
|
677
|
+
metrics = process_dropjump_video_from_config(config)
|
|
648
678
|
processing_time = time.perf_counter() - start_time
|
|
649
679
|
|
|
650
680
|
return DropJumpVideoResult(
|
kinemotion/drop_jump/cli.py
CHANGED
|
@@ -10,8 +10,12 @@ from typing import TYPE_CHECKING
|
|
|
10
10
|
import click
|
|
11
11
|
|
|
12
12
|
from ..core.cli_utils import (
|
|
13
|
+
batch_processing_options,
|
|
13
14
|
collect_video_files,
|
|
15
|
+
common_output_options,
|
|
14
16
|
generate_batch_output_paths,
|
|
17
|
+
quality_option,
|
|
18
|
+
verbose_option,
|
|
15
19
|
)
|
|
16
20
|
from .api import (
|
|
17
21
|
DropJumpVideoConfig,
|
|
@@ -39,64 +43,10 @@ class AnalysisParameters:
|
|
|
39
43
|
|
|
40
44
|
@click.command(name="dropjump-analyze")
|
|
41
45
|
@click.argument("video_path", nargs=-1, type=click.Path(exists=False), required=True)
|
|
42
|
-
@
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
help="Path for debug video output (optional)",
|
|
47
|
-
)
|
|
48
|
-
@click.option(
|
|
49
|
-
"--json-output",
|
|
50
|
-
"-j",
|
|
51
|
-
type=click.Path(),
|
|
52
|
-
help="Path for JSON metrics output (default: stdout)",
|
|
53
|
-
)
|
|
54
|
-
@click.option(
|
|
55
|
-
"--quality",
|
|
56
|
-
type=click.Choice(["fast", "balanced", "accurate"], case_sensitive=False),
|
|
57
|
-
default="balanced",
|
|
58
|
-
help=(
|
|
59
|
-
"Analysis quality preset: "
|
|
60
|
-
"fast (quick, less precise), "
|
|
61
|
-
"balanced (default, good for most cases), "
|
|
62
|
-
"accurate (research-grade, slower)"
|
|
63
|
-
),
|
|
64
|
-
show_default=True,
|
|
65
|
-
)
|
|
66
|
-
@click.option(
|
|
67
|
-
"--verbose",
|
|
68
|
-
"-v",
|
|
69
|
-
is_flag=True,
|
|
70
|
-
help="Show auto-selected parameters and analysis details",
|
|
71
|
-
)
|
|
72
|
-
# Batch processing options
|
|
73
|
-
@click.option(
|
|
74
|
-
"--batch",
|
|
75
|
-
is_flag=True,
|
|
76
|
-
help="Enable batch processing mode for multiple videos",
|
|
77
|
-
)
|
|
78
|
-
@click.option(
|
|
79
|
-
"--workers",
|
|
80
|
-
type=int,
|
|
81
|
-
default=4,
|
|
82
|
-
help="Number of parallel workers for batch processing (default: 4)",
|
|
83
|
-
show_default=True,
|
|
84
|
-
)
|
|
85
|
-
@click.option(
|
|
86
|
-
"--output-dir",
|
|
87
|
-
type=click.Path(),
|
|
88
|
-
help="Directory for debug video outputs (batch mode only)",
|
|
89
|
-
)
|
|
90
|
-
@click.option(
|
|
91
|
-
"--json-output-dir",
|
|
92
|
-
type=click.Path(),
|
|
93
|
-
help="Directory for JSON metrics outputs (batch mode only)",
|
|
94
|
-
)
|
|
95
|
-
@click.option(
|
|
96
|
-
"--csv-summary",
|
|
97
|
-
type=click.Path(),
|
|
98
|
-
help="Path for CSV summary export (batch mode only)",
|
|
99
|
-
)
|
|
46
|
+
@common_output_options
|
|
47
|
+
@quality_option
|
|
48
|
+
@verbose_option
|
|
49
|
+
@batch_processing_options
|
|
100
50
|
# Expert parameters (hidden in help, but always available for advanced users)
|
|
101
51
|
@click.option(
|
|
102
52
|
"--drop-start-frame",
|
|
@@ -226,8 +226,90 @@ def _compute_robust_phase_position(
|
|
|
226
226
|
return float(np.median(window_positions))
|
|
227
227
|
|
|
228
228
|
|
|
229
|
+
def _detect_drop_jump_air_first_pattern(
|
|
230
|
+
air_phases_indexed: list[tuple[int, int, int]],
|
|
231
|
+
ground_phases: list[tuple[int, int, int]],
|
|
232
|
+
) -> tuple[int, int] | None:
|
|
233
|
+
"""Detect drop jump using air-first pattern (box + drop classified as IN_AIR).
|
|
234
|
+
|
|
235
|
+
Pattern: IN_AIR(box+drop) → ON_GROUND(contact) → IN_AIR(flight) → ON_GROUND(land)
|
|
236
|
+
|
|
237
|
+
Args:
|
|
238
|
+
air_phases_indexed: Air phases with indices
|
|
239
|
+
ground_phases: Ground phases with indices
|
|
240
|
+
|
|
241
|
+
Returns:
|
|
242
|
+
(contact_start, contact_end) if drop jump detected, None otherwise
|
|
243
|
+
"""
|
|
244
|
+
if not air_phases_indexed or len(ground_phases) < 2:
|
|
245
|
+
return None
|
|
246
|
+
|
|
247
|
+
_, _, first_air_idx = air_phases_indexed[0]
|
|
248
|
+
first_ground_start, first_ground_end, first_ground_idx = ground_phases[0]
|
|
249
|
+
|
|
250
|
+
# Drop jump: first phase is IN_AIR (index 0), second phase is ground (index 1)
|
|
251
|
+
if first_air_idx != 0 or first_ground_idx != 1:
|
|
252
|
+
return None
|
|
253
|
+
|
|
254
|
+
# Check for flight phase after contact
|
|
255
|
+
air_after_contact = [i for _, _, i in air_phases_indexed if i > first_ground_idx]
|
|
256
|
+
if not air_after_contact:
|
|
257
|
+
return None
|
|
258
|
+
|
|
259
|
+
return first_ground_start, first_ground_end
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
def _detect_drop_jump_height_pattern(
|
|
263
|
+
air_phases_indexed: list[tuple[int, int, int]],
|
|
264
|
+
ground_phases: list[tuple[int, int, int]],
|
|
265
|
+
foot_y_positions: NDArray[np.float64],
|
|
266
|
+
) -> tuple[int, int] | None:
|
|
267
|
+
"""Detect drop jump using height comparison (box detected as ground).
|
|
268
|
+
|
|
269
|
+
Legacy detection: first ground is on elevated box (lower y value).
|
|
270
|
+
|
|
271
|
+
Args:
|
|
272
|
+
air_phases_indexed: Air phases with indices
|
|
273
|
+
ground_phases: Ground phases with indices
|
|
274
|
+
foot_y_positions: Vertical position array
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
(contact_start, contact_end) if drop jump detected, None otherwise
|
|
278
|
+
"""
|
|
279
|
+
if not air_phases_indexed or len(ground_phases) < 2:
|
|
280
|
+
return None
|
|
281
|
+
|
|
282
|
+
_, _, first_air_idx = air_phases_indexed[0]
|
|
283
|
+
first_ground_start, first_ground_end, first_ground_idx = ground_phases[0]
|
|
284
|
+
|
|
285
|
+
# This pattern: first ground is before first air (athlete on box)
|
|
286
|
+
if first_ground_idx >= first_air_idx:
|
|
287
|
+
return None
|
|
288
|
+
|
|
289
|
+
ground_after_air = [
|
|
290
|
+
(start, end, idx) for start, end, idx in ground_phases if idx > first_air_idx
|
|
291
|
+
]
|
|
292
|
+
if not ground_after_air:
|
|
293
|
+
return None
|
|
294
|
+
|
|
295
|
+
first_ground_y = _compute_robust_phase_position(
|
|
296
|
+
foot_y_positions, first_ground_start, first_ground_end
|
|
297
|
+
)
|
|
298
|
+
second_ground_start, second_ground_end, _ = ground_after_air[0]
|
|
299
|
+
second_ground_y = _compute_robust_phase_position(
|
|
300
|
+
foot_y_positions, second_ground_start, second_ground_end
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
# If second ground is significantly lower (>7% of frame), it's a drop jump
|
|
304
|
+
height_diff = second_ground_y - first_ground_y
|
|
305
|
+
if height_diff <= 0.07:
|
|
306
|
+
return None
|
|
307
|
+
|
|
308
|
+
return second_ground_start, second_ground_end
|
|
309
|
+
|
|
310
|
+
|
|
229
311
|
def _identify_main_contact_phase(
|
|
230
|
-
phases: list[tuple[int, int, ContactState]],
|
|
312
|
+
phases: list[tuple[int, int, ContactState]], # noqa: ARG001 # Used in caller for context
|
|
231
313
|
ground_phases: list[tuple[int, int, int]],
|
|
232
314
|
air_phases_indexed: list[tuple[int, int, int]],
|
|
233
315
|
foot_y_positions: NDArray[np.float64],
|
|
@@ -253,55 +335,21 @@ def _identify_main_contact_phase(
|
|
|
253
335
|
Returns:
|
|
254
336
|
Tuple of (contact_start, contact_end, is_drop_jump)
|
|
255
337
|
"""
|
|
256
|
-
#
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
#
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
air_after_contact = [
|
|
272
|
-
(s, e, i) for s, e, i in air_phases_indexed if i > first_ground_idx
|
|
273
|
-
]
|
|
274
|
-
if air_after_contact:
|
|
275
|
-
# This is a drop jump: first ground = contact, last ground = landing
|
|
276
|
-
is_drop_jump = True
|
|
277
|
-
contact_start, contact_end = first_ground_start, first_ground_end
|
|
278
|
-
|
|
279
|
-
# Legacy detection: first ground is on elevated box (lower y)
|
|
280
|
-
# This handles cases where box level IS detected as ground
|
|
281
|
-
if not is_drop_jump and first_ground_idx < first_air_idx:
|
|
282
|
-
ground_after_air = [
|
|
283
|
-
(start, end, idx) for start, end, idx in ground_phases if idx > first_air_idx
|
|
284
|
-
]
|
|
285
|
-
if ground_after_air:
|
|
286
|
-
first_ground_y = _compute_robust_phase_position(
|
|
287
|
-
foot_y_positions, first_ground_start, first_ground_end
|
|
288
|
-
)
|
|
289
|
-
second_ground_start, second_ground_end, _ = ground_after_air[0]
|
|
290
|
-
second_ground_y = _compute_robust_phase_position(
|
|
291
|
-
foot_y_positions, second_ground_start, second_ground_end
|
|
292
|
-
)
|
|
293
|
-
# If first ground is significantly higher (>7% of frame), it's a drop jump
|
|
294
|
-
if second_ground_y - first_ground_y > 0.07:
|
|
295
|
-
is_drop_jump = True
|
|
296
|
-
contact_start, contact_end = second_ground_start, second_ground_end
|
|
297
|
-
|
|
298
|
-
if not is_drop_jump:
|
|
299
|
-
# Regular jump: use longest ground contact phase
|
|
300
|
-
contact_start, contact_end = max(
|
|
301
|
-
[(s, e) for s, e, _ in ground_phases], key=lambda p: p[1] - p[0]
|
|
302
|
-
)
|
|
303
|
-
|
|
304
|
-
return contact_start, contact_end, is_drop_jump
|
|
338
|
+
# Try air-first detection pattern (most common for clean videos)
|
|
339
|
+
result = _detect_drop_jump_air_first_pattern(air_phases_indexed, ground_phases)
|
|
340
|
+
if result is not None:
|
|
341
|
+
return result[0], result[1], True
|
|
342
|
+
|
|
343
|
+
# Try height-based detection (fallback for box-as-ground videos)
|
|
344
|
+
result = _detect_drop_jump_height_pattern(air_phases_indexed, ground_phases, foot_y_positions)
|
|
345
|
+
if result is not None:
|
|
346
|
+
return result[0], result[1], True
|
|
347
|
+
|
|
348
|
+
# Regular jump: use longest ground contact phase
|
|
349
|
+
contact_start, contact_end = max(
|
|
350
|
+
[(s, e) for s, e, _ in ground_phases], key=lambda p: p[1] - p[0]
|
|
351
|
+
)
|
|
352
|
+
return contact_start, contact_end, False
|
|
305
353
|
|
|
306
354
|
|
|
307
355
|
def _find_precise_phase_timing(
|
|
@@ -114,63 +114,37 @@ class DropJumpMetricsValidator(MetricsValidator):
|
|
|
114
114
|
) -> None:
|
|
115
115
|
"""Validate contact time."""
|
|
116
116
|
contact_time_s = contact_time_ms / 1000.0
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
)
|
|
126
|
-
elif result.athlete_profile and not bounds.contains(
|
|
127
|
-
contact_time_s, result.athlete_profile
|
|
128
|
-
):
|
|
129
|
-
profile_name = result.athlete_profile.value
|
|
130
|
-
result.add_warning(
|
|
131
|
-
"contact_time",
|
|
132
|
-
f"Contact time {contact_time_s:.3f}s unusual for {profile_name} athlete",
|
|
133
|
-
value=contact_time_s,
|
|
134
|
-
)
|
|
117
|
+
self._validate_metric_with_bounds(
|
|
118
|
+
name="contact_time",
|
|
119
|
+
value=contact_time_s,
|
|
120
|
+
bounds=DropJumpBounds.CONTACT_TIME,
|
|
121
|
+
profile=result.athlete_profile,
|
|
122
|
+
result=result,
|
|
123
|
+
format_str="{value:.3f}s",
|
|
124
|
+
)
|
|
135
125
|
|
|
136
126
|
def _check_flight_time(self, flight_time_ms: float, result: DropJumpValidationResult) -> None:
|
|
137
127
|
"""Validate flight time."""
|
|
138
128
|
flight_time_s = flight_time_ms / 1000.0
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
)
|
|
148
|
-
elif result.athlete_profile and not bounds.contains(flight_time_s, result.athlete_profile):
|
|
149
|
-
profile_name = result.athlete_profile.value
|
|
150
|
-
result.add_warning(
|
|
151
|
-
"flight_time",
|
|
152
|
-
f"Flight time {flight_time_s:.3f}s unusual for {profile_name} athlete",
|
|
153
|
-
value=flight_time_s,
|
|
154
|
-
)
|
|
129
|
+
self._validate_metric_with_bounds(
|
|
130
|
+
name="flight_time",
|
|
131
|
+
value=flight_time_s,
|
|
132
|
+
bounds=DropJumpBounds.FLIGHT_TIME,
|
|
133
|
+
profile=result.athlete_profile,
|
|
134
|
+
result=result,
|
|
135
|
+
format_str="{value:.3f}s",
|
|
136
|
+
)
|
|
155
137
|
|
|
156
138
|
def _check_jump_height(self, jump_height_m: float, result: DropJumpValidationResult) -> None:
|
|
157
139
|
"""Validate jump height."""
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
)
|
|
167
|
-
elif result.athlete_profile and not bounds.contains(jump_height_m, result.athlete_profile):
|
|
168
|
-
profile_name = result.athlete_profile.value
|
|
169
|
-
result.add_warning(
|
|
170
|
-
"jump_height",
|
|
171
|
-
f"Jump height {jump_height_m:.3f}m unusual for {profile_name} athlete",
|
|
172
|
-
value=jump_height_m,
|
|
173
|
-
)
|
|
140
|
+
self._validate_metric_with_bounds(
|
|
141
|
+
name="jump_height",
|
|
142
|
+
value=jump_height_m,
|
|
143
|
+
bounds=DropJumpBounds.JUMP_HEIGHT,
|
|
144
|
+
profile=result.athlete_profile,
|
|
145
|
+
result=result,
|
|
146
|
+
format_str="{value:.3f}m",
|
|
147
|
+
)
|
|
174
148
|
|
|
175
149
|
def _check_rsi(
|
|
176
150
|
self,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kinemotion
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.74.0
|
|
4
4
|
Summary: Video-based kinematic analysis for athletic performance
|
|
5
5
|
Project-URL: Homepage, https://github.com/feniix/kinemotion
|
|
6
6
|
Project-URL: Repository, https://github.com/feniix/kinemotion
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
kinemotion/__init__.py,sha256=GovgX2mxUmfTH2HsMqlOCfU28niiTdu0c7iTIACcly4,1079
|
|
2
2
|
kinemotion/api.py,sha256=x7rHYgh-bpc6a1kMp9fnnFkU7y96qYelDbzcqN3oUKY,1110
|
|
3
3
|
kinemotion/cli.py,sha256=H3--5whfauDuOyW31lrK1MF-2U-61V11ft5RIndZuUU,644
|
|
4
|
-
kinemotion/core/__init__.py,sha256=
|
|
5
|
-
kinemotion/core/auto_tuning.py,sha256=
|
|
6
|
-
kinemotion/core/cli_utils.py,sha256=
|
|
4
|
+
kinemotion/core/__init__.py,sha256=E7HDsetuKTJ7EBb8ftNifJoKS8uhS4snRO7HgISyBoM,2035
|
|
5
|
+
kinemotion/core/auto_tuning.py,sha256=ZDmHJJw69wzlRkEJ8OtLPE6KV5wLHcMha1RePVRICkI,11836
|
|
6
|
+
kinemotion/core/cli_utils.py,sha256=6VA8HSnVvKaWMm7d9ahrqwFPXuRPp53s0dib1yCE7yQ,4179
|
|
7
7
|
kinemotion/core/debug_overlay_utils.py,sha256=QaVkHuFZpXUrdiMlm8ylQn6baJOj8jcZeiV4kDqODt0,17441
|
|
8
8
|
kinemotion/core/determinism.py,sha256=Frw-KAOvAxTL_XtxoWpXCjMbQPUKEAusK6JctlkeuRo,2509
|
|
9
9
|
kinemotion/core/experimental.py,sha256=G1EpkmWQ8d-rPaN1n0P7mF6XUzrbW0Br3nVkIzJ1D9M,3694
|
|
@@ -15,36 +15,37 @@ kinemotion/core/overlay_constants.py,sha256=zZreHHWe00p2XuCJsbRFqN6g-AAUAnx53LwK
|
|
|
15
15
|
kinemotion/core/pipeline_utils.py,sha256=i0x9HM2wzQDvvD9Y54VPIU20Nu-k-IYy6AY9fHPAetY,15179
|
|
16
16
|
kinemotion/core/pose.py,sha256=Z795p0EnaTUeWHO8FuApFcMGTLwZ47JOjs5f5TzRvdk,14224
|
|
17
17
|
kinemotion/core/pose_landmarks.py,sha256=LcEbL5K5xKia6dCzWf6Ft18UIE1CLMMqCZ3KUjwUDzM,1558
|
|
18
|
-
kinemotion/core/quality.py,sha256=
|
|
18
|
+
kinemotion/core/quality.py,sha256=JxuM6jwO9i07S6Don3Fki9eFDyITQ6OYJr8YhPSTL7s,13010
|
|
19
19
|
kinemotion/core/smoothing.py,sha256=F1DCsnvPBi62XJLygOJ5MkNlRa7BCLg_E9ORtCWcoKk,16562
|
|
20
20
|
kinemotion/core/timing.py,sha256=ITX77q4hbtajRuWfgwYhws8nCvOeKFlEdKjCu8lD9_w,7938
|
|
21
21
|
kinemotion/core/types.py,sha256=m141buSkEsqflt5VFaTHtRq_IcimjI3_T_EfaNpIVxY,1652
|
|
22
|
-
kinemotion/core/validation.py,sha256
|
|
23
|
-
kinemotion/core/
|
|
22
|
+
kinemotion/core/validation.py,sha256=-8Wwe56PO37F0OAEMpWr1AB_7QmFtDY5bVmux3oiLYM,9585
|
|
23
|
+
kinemotion/core/video_analysis_base.py,sha256=U8j-6-dv6uiGUiIHl53AIVFUiVHotgTmMNvCArSXx0E,4045
|
|
24
|
+
kinemotion/core/video_io.py,sha256=tLAHm63_sap-CXQpLzmgUXpWZ5_TtBI9LHP8Tk2L-z4,9355
|
|
24
25
|
kinemotion/countermovement_jump/__init__.py,sha256=SkAw9ka8Yd1Qfv9hcvk22m3EfucROzYrSNGNF5kDzho,113
|
|
25
|
-
kinemotion/countermovement_jump/analysis.py,sha256=
|
|
26
|
-
kinemotion/countermovement_jump/api.py,sha256=
|
|
27
|
-
kinemotion/countermovement_jump/cli.py,sha256=
|
|
26
|
+
kinemotion/countermovement_jump/analysis.py,sha256=0ocj1ZbaV4rPeor-y6jvDIKsGalZoozwo7kxwFhQQ1w,20637
|
|
27
|
+
kinemotion/countermovement_jump/api.py,sha256=uNo2JLuFDeBdpi3Y2qf-DyG-1KIRwmSF7HjXMu9Cwj0,19320
|
|
28
|
+
kinemotion/countermovement_jump/cli.py,sha256=m727IOg5BuixgNraCXc2sjW5jGrxrg7RKvFS4qyrBK8,8902
|
|
28
29
|
kinemotion/countermovement_jump/debug_overlay.py,sha256=vF5Apiz8zDRpgrVzf52manLW99m1kHQAPSdUkar5rPs,11474
|
|
29
30
|
kinemotion/countermovement_jump/joint_angles.py,sha256=by5M4LDtUfd2_Z9DmcgUl0nsvarsBYjgsE8KWWYcn08,11255
|
|
30
31
|
kinemotion/countermovement_jump/kinematics.py,sha256=KwA8uSj3g1SeNf0NXMSHsp3gIw6Gfa-6QWIwdYdRXYw,13362
|
|
31
|
-
kinemotion/countermovement_jump/metrics_validator.py,sha256=
|
|
32
|
+
kinemotion/countermovement_jump/metrics_validator.py,sha256=Gozn88jBpe77GhLIMYZfcAlfAmu4_k9R73bCfcwUsTI,24691
|
|
32
33
|
kinemotion/countermovement_jump/validation_bounds.py,sha256=-0iXDhH-RntiGZi_Co22V6qtA5D-hLzkrPkVcfoNd2U,11343
|
|
33
34
|
kinemotion/drop_jump/__init__.py,sha256=yBbEbPdY6sqozWtTvfbvuUZnrVWSSjBp61xK34M29F4,878
|
|
34
|
-
kinemotion/drop_jump/analysis.py,sha256=
|
|
35
|
-
kinemotion/drop_jump/api.py,sha256=
|
|
36
|
-
kinemotion/drop_jump/cli.py,sha256=
|
|
35
|
+
kinemotion/drop_jump/analysis.py,sha256=ppbhB6Z9GTPzFlIOXso7tq0ldCpf1EZbYk2v31ClLV8,33998
|
|
36
|
+
kinemotion/drop_jump/api.py,sha256=xcA7CkBjLQZhIs6UHr2mo5jT1p-D6e3cgRAFLSwZCmE,21927
|
|
37
|
+
kinemotion/drop_jump/cli.py,sha256=WTUJWCjBl9SgR3Z-2cml1EQhVF8HaXIXQ27fS4tnR7U,14693
|
|
37
38
|
kinemotion/drop_jump/debug_overlay.py,sha256=X4mvCi5Qi1gnvSZZAsUs-0ZRUx9mVBbEUznOFO21HO8,8470
|
|
38
|
-
kinemotion/drop_jump/kinematics.py,sha256=
|
|
39
|
-
kinemotion/drop_jump/metrics_validator.py,sha256=
|
|
39
|
+
kinemotion/drop_jump/kinematics.py,sha256=59Q035bXAGGEAdrfLA2mALkWfJUifs35Tvk89xfU8pc,23657
|
|
40
|
+
kinemotion/drop_jump/metrics_validator.py,sha256=yY0wzFzUUDLn6pZcOnwErMlIt_aTWq-RyAkqIemBG5M,7885
|
|
40
41
|
kinemotion/drop_jump/validation_bounds.py,sha256=k31qy-kCXTiCTx0RPo2t8yZ-faLxqGO-AeF05QfBFb0,5125
|
|
41
42
|
kinemotion/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
43
|
kinemotion/models/pose_landmarker_lite.task,sha256=WZKeHR7pUodzXd2DOxnPSsRtKbx6_du_Z1PEWWkNV0o,5777746
|
|
43
44
|
kinemotion/models/rtmpose-s_simcc-body7_pt-body7-halpe26_700e-256x192-7f134165_20230605.onnx,sha256=dfZTq8kbhv8RxWiXS0HUIJNCUpxYTBN45dFIorPflEs,133
|
|
44
45
|
kinemotion/models/yolox_tiny_8xb8-300e_humanart-6f3252f9.onnx,sha256=UsutHVQ6GP3X5pCcp52EN8q7o2J3d-TnxZqlF48kY6I,133
|
|
45
46
|
kinemotion/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
-
kinemotion-0.
|
|
47
|
-
kinemotion-0.
|
|
48
|
-
kinemotion-0.
|
|
49
|
-
kinemotion-0.
|
|
50
|
-
kinemotion-0.
|
|
47
|
+
kinemotion-0.74.0.dist-info/METADATA,sha256=lg3dJnKHLKkm-_hs373v_JfjXrJniQp5ngwe9jKMVaU,26125
|
|
48
|
+
kinemotion-0.74.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
49
|
+
kinemotion-0.74.0.dist-info/entry_points.txt,sha256=zaqnAnjLvcdrk1Qvj5nvXZCZ2gp0prS7it1zTJygcIY,50
|
|
50
|
+
kinemotion-0.74.0.dist-info/licenses/LICENSE,sha256=KZajvqsHw0NoOHOi2q0FZ4NBe9HdV6oey-IPYAtHXfg,1088
|
|
51
|
+
kinemotion-0.74.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|