kinemotion 0.10.2__tar.gz → 0.10.3__tar.gz
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-0.10.2 → kinemotion-0.10.3}/CHANGELOG.md +8 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/PKG-INFO +1 -1
- {kinemotion-0.10.2 → kinemotion-0.10.3}/pyproject.toml +1 -1
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/dropjump/cli.py +49 -48
- {kinemotion-0.10.2 → kinemotion-0.10.3}/uv.lock +1 -1
- {kinemotion-0.10.2 → kinemotion-0.10.3}/.dockerignore +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/.github/pull_request_template.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/.github/workflows/release.yml +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/.gitignore +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/.pre-commit-config.yaml +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/.tool-versions +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/CLAUDE.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/CODE_OF_CONDUCT.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/CONTRIBUTING.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/Dockerfile +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/GEMINI.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/LICENSE +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/README.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/SECURITY.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/docs/BULK_PROCESSING.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/docs/ERRORS_FINDINGS.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/docs/FRAMERATE.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/docs/IMU_METADATA_PRESERVATION.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/docs/PARAMETERS.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/docs/VALIDATION_PLAN.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/examples/bulk/README.md +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/examples/bulk/bulk_processing.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/examples/bulk/simple_example.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/examples/programmatic_usage.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/__init__.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/api.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/cli.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/core/__init__.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/core/auto_tuning.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/core/filtering.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/core/pose.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/core/smoothing.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/core/video_io.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/dropjump/__init__.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/dropjump/analysis.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/dropjump/debug_overlay.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/dropjump/kinematics.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/src/kinemotion/py.typed +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/tests/__init__.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/tests/test_adaptive_threshold.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/tests/test_api.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/tests/test_aspect_ratio.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/tests/test_com_estimation.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/tests/test_contact_detection.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/tests/test_filtering.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/tests/test_kinematics.py +0 -0
- {kinemotion-0.10.2 → kinemotion-0.10.3}/tests/test_polyorder.py +0 -0
|
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
<!-- version list -->
|
|
9
9
|
|
|
10
|
+
## v0.10.3 (2025-11-03)
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- Reduce function parameter count using dataclass
|
|
15
|
+
([`0b8abfd`](https://github.com/feniix/kinemotion/commit/0b8abfd6ee53835ba3d787924747ab5e46066395))
|
|
16
|
+
|
|
17
|
+
|
|
10
18
|
## v0.10.2 (2025-11-03)
|
|
11
19
|
|
|
12
20
|
### Bug Fixes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kinemotion
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.3
|
|
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
|
|
@@ -4,6 +4,7 @@ import csv
|
|
|
4
4
|
import glob
|
|
5
5
|
import json
|
|
6
6
|
import sys
|
|
7
|
+
from dataclasses import dataclass
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from typing import Any
|
|
9
10
|
|
|
@@ -27,6 +28,19 @@ from .debug_overlay import DebugOverlayRenderer
|
|
|
27
28
|
from .kinematics import calculate_drop_jump_metrics
|
|
28
29
|
|
|
29
30
|
|
|
31
|
+
@dataclass
|
|
32
|
+
class AnalysisParameters:
|
|
33
|
+
"""Expert parameters for analysis customization."""
|
|
34
|
+
|
|
35
|
+
drop_start_frame: int | None = None
|
|
36
|
+
smoothing_window: int | None = None
|
|
37
|
+
velocity_threshold: float | None = None
|
|
38
|
+
min_contact_frames: int | None = None
|
|
39
|
+
visibility_threshold: float | None = None
|
|
40
|
+
detection_confidence: float | None = None
|
|
41
|
+
tracking_confidence: float | None = None
|
|
42
|
+
|
|
43
|
+
|
|
30
44
|
@click.command(name="dropjump-analyze")
|
|
31
45
|
@click.argument("video_path", nargs=-1, type=click.Path(exists=False), required=True)
|
|
32
46
|
@click.option(
|
|
@@ -202,6 +216,17 @@ def dropjump_analyze(
|
|
|
202
216
|
# Determine if batch mode should be used
|
|
203
217
|
use_batch = batch or len(video_files) > 1
|
|
204
218
|
|
|
219
|
+
# Group expert parameters
|
|
220
|
+
params = AnalysisParameters(
|
|
221
|
+
drop_start_frame=drop_start_frame,
|
|
222
|
+
smoothing_window=smoothing_window,
|
|
223
|
+
velocity_threshold=velocity_threshold,
|
|
224
|
+
min_contact_frames=min_contact_frames,
|
|
225
|
+
visibility_threshold=visibility_threshold,
|
|
226
|
+
detection_confidence=detection_confidence,
|
|
227
|
+
tracking_confidence=tracking_confidence,
|
|
228
|
+
)
|
|
229
|
+
|
|
205
230
|
if use_batch:
|
|
206
231
|
_process_batch(
|
|
207
232
|
video_files,
|
|
@@ -211,13 +236,7 @@ def dropjump_analyze(
|
|
|
211
236
|
output_dir,
|
|
212
237
|
json_output_dir,
|
|
213
238
|
csv_summary,
|
|
214
|
-
|
|
215
|
-
smoothing_window,
|
|
216
|
-
velocity_threshold,
|
|
217
|
-
min_contact_frames,
|
|
218
|
-
visibility_threshold,
|
|
219
|
-
detection_confidence,
|
|
220
|
-
tracking_confidence,
|
|
239
|
+
params,
|
|
221
240
|
)
|
|
222
241
|
else:
|
|
223
242
|
# Single video mode (original behavior)
|
|
@@ -228,13 +247,7 @@ def dropjump_analyze(
|
|
|
228
247
|
drop_height,
|
|
229
248
|
quality,
|
|
230
249
|
verbose,
|
|
231
|
-
|
|
232
|
-
smoothing_window,
|
|
233
|
-
velocity_threshold,
|
|
234
|
-
min_contact_frames,
|
|
235
|
-
visibility_threshold,
|
|
236
|
-
detection_confidence,
|
|
237
|
-
tracking_confidence,
|
|
250
|
+
params,
|
|
238
251
|
)
|
|
239
252
|
|
|
240
253
|
|
|
@@ -245,13 +258,7 @@ def _process_single(
|
|
|
245
258
|
drop_height: float,
|
|
246
259
|
quality: str,
|
|
247
260
|
verbose: bool,
|
|
248
|
-
|
|
249
|
-
smoothing_window: int | None,
|
|
250
|
-
velocity_threshold: float | None,
|
|
251
|
-
min_contact_frames: int | None,
|
|
252
|
-
visibility_threshold: float | None,
|
|
253
|
-
detection_confidence: float | None,
|
|
254
|
-
tracking_confidence: float | None,
|
|
261
|
+
expert_params: AnalysisParameters,
|
|
255
262
|
) -> None:
|
|
256
263
|
"""Process a single video (original CLI behavior)."""
|
|
257
264
|
click.echo(f"Analyzing video: {video_path}", err=True)
|
|
@@ -285,10 +292,10 @@ def _process_single(
|
|
|
285
292
|
initial_tracking_conf = 0.6
|
|
286
293
|
|
|
287
294
|
# Override with expert values if provided
|
|
288
|
-
if detection_confidence is not None:
|
|
289
|
-
initial_detection_conf = detection_confidence
|
|
290
|
-
if tracking_confidence is not None:
|
|
291
|
-
initial_tracking_conf = tracking_confidence
|
|
295
|
+
if expert_params.detection_confidence is not None:
|
|
296
|
+
initial_detection_conf = expert_params.detection_confidence
|
|
297
|
+
if expert_params.tracking_confidence is not None:
|
|
298
|
+
initial_tracking_conf = expert_params.tracking_confidence
|
|
292
299
|
|
|
293
300
|
# Initialize pose tracker
|
|
294
301
|
tracker = PoseTracker(
|
|
@@ -334,14 +341,14 @@ def _process_single(
|
|
|
334
341
|
params = auto_tune_parameters(characteristics, quality_preset)
|
|
335
342
|
|
|
336
343
|
# Apply expert overrides if provided
|
|
337
|
-
if smoothing_window is not None:
|
|
338
|
-
params.smoothing_window = smoothing_window
|
|
339
|
-
if velocity_threshold is not None:
|
|
340
|
-
params.velocity_threshold = velocity_threshold
|
|
341
|
-
if min_contact_frames is not None:
|
|
342
|
-
params.min_contact_frames = min_contact_frames
|
|
343
|
-
if visibility_threshold is not None:
|
|
344
|
-
params.visibility_threshold = visibility_threshold
|
|
344
|
+
if expert_params.smoothing_window is not None:
|
|
345
|
+
params.smoothing_window = expert_params.smoothing_window
|
|
346
|
+
if expert_params.velocity_threshold is not None:
|
|
347
|
+
params.velocity_threshold = expert_params.velocity_threshold
|
|
348
|
+
if expert_params.min_contact_frames is not None:
|
|
349
|
+
params.min_contact_frames = expert_params.min_contact_frames
|
|
350
|
+
if expert_params.visibility_threshold is not None:
|
|
351
|
+
params.visibility_threshold = expert_params.visibility_threshold
|
|
345
352
|
|
|
346
353
|
# Show selected parameters if verbose
|
|
347
354
|
if verbose:
|
|
@@ -463,7 +470,7 @@ def _process_single(
|
|
|
463
470
|
vertical_positions,
|
|
464
471
|
video.fps,
|
|
465
472
|
drop_height_m=drop_height,
|
|
466
|
-
drop_start_frame=drop_start_frame,
|
|
473
|
+
drop_start_frame=expert_params.drop_start_frame,
|
|
467
474
|
velocity_threshold=params.velocity_threshold,
|
|
468
475
|
smoothing_window=params.smoothing_window,
|
|
469
476
|
polyorder=params.polyorder,
|
|
@@ -545,13 +552,7 @@ def _process_batch(
|
|
|
545
552
|
output_dir: str | None,
|
|
546
553
|
json_output_dir: str | None,
|
|
547
554
|
csv_summary: str | None,
|
|
548
|
-
|
|
549
|
-
smoothing_window: int | None,
|
|
550
|
-
velocity_threshold: float | None,
|
|
551
|
-
min_contact_frames: int | None,
|
|
552
|
-
visibility_threshold: float | None,
|
|
553
|
-
detection_confidence: float | None,
|
|
554
|
-
tracking_confidence: float | None,
|
|
555
|
+
expert_params: AnalysisParameters,
|
|
555
556
|
) -> None:
|
|
556
557
|
"""Process multiple videos in batch mode using parallel processing."""
|
|
557
558
|
click.echo(
|
|
@@ -588,13 +589,13 @@ def _process_batch(
|
|
|
588
589
|
quality=quality,
|
|
589
590
|
output_video=debug_video,
|
|
590
591
|
json_output=json_file,
|
|
591
|
-
drop_start_frame=drop_start_frame,
|
|
592
|
-
smoothing_window=smoothing_window,
|
|
593
|
-
velocity_threshold=velocity_threshold,
|
|
594
|
-
min_contact_frames=min_contact_frames,
|
|
595
|
-
visibility_threshold=visibility_threshold,
|
|
596
|
-
detection_confidence=detection_confidence,
|
|
597
|
-
tracking_confidence=tracking_confidence,
|
|
592
|
+
drop_start_frame=expert_params.drop_start_frame,
|
|
593
|
+
smoothing_window=expert_params.smoothing_window,
|
|
594
|
+
velocity_threshold=expert_params.velocity_threshold,
|
|
595
|
+
min_contact_frames=expert_params.min_contact_frames,
|
|
596
|
+
visibility_threshold=expert_params.visibility_threshold,
|
|
597
|
+
detection_confidence=expert_params.detection_confidence,
|
|
598
|
+
tracking_confidence=expert_params.tracking_confidence,
|
|
598
599
|
)
|
|
599
600
|
configs.append(config)
|
|
600
601
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|