kinemotion 0.27.0__py3-none-any.whl → 0.29.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/__init__.py +1 -1
- kinemotion/cmj/analysis.py +43 -10
- kinemotion/cmj/joint_angles.py +23 -6
- kinemotion/cmj/kinematics.py +33 -23
- kinemotion/core/cmj_metrics_validator.py +717 -0
- kinemotion/core/cmj_validation_bounds.py +380 -0
- kinemotion/core/formatting.py +75 -0
- kinemotion/dropjump/kinematics.py +15 -46
- {kinemotion-0.27.0.dist-info → kinemotion-0.29.0.dist-info}/METADATA +111 -49
- {kinemotion-0.27.0.dist-info → kinemotion-0.29.0.dist-info}/RECORD +13 -10
- {kinemotion-0.27.0.dist-info → kinemotion-0.29.0.dist-info}/WHEEL +0 -0
- {kinemotion-0.27.0.dist-info → kinemotion-0.29.0.dist-info}/entry_points.txt +0 -0
- {kinemotion-0.27.0.dist-info → kinemotion-0.29.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kinemotion
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.29.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
|
|
@@ -67,7 +67,7 @@ Description-Content-Type: text/markdown
|
|
|
67
67
|
|
|
68
68
|
- **Ground contact detection** based on foot velocity and position
|
|
69
69
|
- **Automatic drop jump detection** - identifies box → drop → landing → jump phases
|
|
70
|
-
- **Metrics**: Ground contact time, flight time, jump height (
|
|
70
|
+
- **Metrics**: Ground contact time, flight time, jump height (calculated from flight time)
|
|
71
71
|
- **Reactive strength index** calculations
|
|
72
72
|
|
|
73
73
|
### Counter Movement Jump (CMJ) Analysis
|
|
@@ -267,27 +267,33 @@ kinemotion cmj-analyze videos/*.mp4 --batch --workers 4 \
|
|
|
267
267
|
--csv-summary summary.csv
|
|
268
268
|
```
|
|
269
269
|
|
|
270
|
-
### Quality
|
|
270
|
+
### Quality Assessment
|
|
271
271
|
|
|
272
|
-
All analysis outputs include automatic quality assessment to help you know when to trust results:
|
|
272
|
+
All analysis outputs include automatic quality assessment in the metadata section to help you know when to trust results:
|
|
273
273
|
|
|
274
274
|
```json
|
|
275
275
|
{
|
|
276
|
-
"
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
"quality_score": 87.3,
|
|
280
|
-
"quality_indicators": {
|
|
281
|
-
"avg_visibility": 0.89,
|
|
282
|
-
"min_visibility": 0.82,
|
|
283
|
-
"tracking_stable": true,
|
|
284
|
-
"phase_detection_clear": true,
|
|
285
|
-
"outliers_detected": 2,
|
|
286
|
-
"outlier_percentage": 1.5,
|
|
287
|
-
"position_variance": 0.0008,
|
|
288
|
-
"fps": 60.0
|
|
276
|
+
"data": {
|
|
277
|
+
"jump_height_m": 0.352,
|
|
278
|
+
"flight_time_ms": 534.2
|
|
289
279
|
},
|
|
290
|
-
"
|
|
280
|
+
"metadata": {
|
|
281
|
+
"quality": {
|
|
282
|
+
"confidence": "high",
|
|
283
|
+
"quality_score": 87.3,
|
|
284
|
+
"quality_indicators": {
|
|
285
|
+
"avg_visibility": 0.89,
|
|
286
|
+
"min_visibility": 0.82,
|
|
287
|
+
"tracking_stable": true,
|
|
288
|
+
"phase_detection_clear": true,
|
|
289
|
+
"outliers_detected": 2,
|
|
290
|
+
"outlier_percentage": 1.5,
|
|
291
|
+
"position_variance": 0.0008,
|
|
292
|
+
"fps": 60.0
|
|
293
|
+
},
|
|
294
|
+
"warnings": []
|
|
295
|
+
}
|
|
296
|
+
}
|
|
291
297
|
}
|
|
292
298
|
```
|
|
293
299
|
|
|
@@ -310,9 +316,9 @@ All analysis outputs include automatic quality assessment to help you know when
|
|
|
310
316
|
```python
|
|
311
317
|
# Only use high-confidence results
|
|
312
318
|
metrics = process_cmj_video("video.mp4")
|
|
313
|
-
if metrics.quality_assessment.confidence == "high":
|
|
319
|
+
if metrics.quality_assessment is not None and metrics.quality_assessment.confidence == "high":
|
|
314
320
|
print(f"Reliable jump height: {metrics.jump_height:.3f}m")
|
|
315
|
-
|
|
321
|
+
elif metrics.quality_assessment is not None:
|
|
316
322
|
print(f"Low quality - warnings: {metrics.quality_assessment.warnings}")
|
|
317
323
|
```
|
|
318
324
|
|
|
@@ -414,14 +420,9 @@ Kinemotion automatically optimizes parameters based on your video:
|
|
|
414
420
|
- **Quality-based adjustments**: Adapts smoothing based on MediaPipe tracking confidence
|
|
415
421
|
- **Always enabled**: Outlier rejection, curvature analysis, drop start detection
|
|
416
422
|
|
|
417
|
-
###
|
|
423
|
+
### Parameters
|
|
418
424
|
|
|
419
|
-
|
|
420
|
-
- Height of drop box/platform in meters (e.g., 0.40 for 40cm)
|
|
421
|
-
- Used for accurate calibration of jump height measurements
|
|
422
|
-
- Measure your box height accurately for best results
|
|
423
|
-
|
|
424
|
-
### Optional Parameters
|
|
425
|
+
All parameters are optional. Kinemotion uses intelligent auto-tuning to select optimal settings based on video characteristics.
|
|
425
426
|
|
|
426
427
|
- `--quality [fast|balanced|accurate]` (default: balanced)
|
|
427
428
|
|
|
@@ -460,32 +461,95 @@ For advanced users who need manual control:
|
|
|
460
461
|
|
|
461
462
|
## Output Format
|
|
462
463
|
|
|
463
|
-
### JSON
|
|
464
|
+
### Drop Jump JSON Output
|
|
464
465
|
|
|
465
466
|
```json
|
|
466
467
|
{
|
|
467
|
-
"
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
468
|
+
"data": {
|
|
469
|
+
"ground_contact_time_ms": 245.67,
|
|
470
|
+
"flight_time_ms": 456.78,
|
|
471
|
+
"jump_height_m": 0.339,
|
|
472
|
+
"jump_height_kinematic_m": 0.339,
|
|
473
|
+
"jump_height_trajectory_normalized": 0.0845,
|
|
474
|
+
"contact_start_frame": 45,
|
|
475
|
+
"contact_end_frame": 67,
|
|
476
|
+
"flight_start_frame": 68,
|
|
477
|
+
"flight_end_frame": 95,
|
|
478
|
+
"peak_height_frame": 82,
|
|
479
|
+
"contact_start_frame_precise": 45.234,
|
|
480
|
+
"contact_end_frame_precise": 67.891,
|
|
481
|
+
"flight_start_frame_precise": 68.123,
|
|
482
|
+
"flight_end_frame_precise": 94.567
|
|
483
|
+
},
|
|
484
|
+
"metadata": {
|
|
485
|
+
"quality": { },
|
|
486
|
+
"processing_info": { }
|
|
487
|
+
}
|
|
477
488
|
}
|
|
478
489
|
```
|
|
479
490
|
|
|
480
|
-
**Fields**:
|
|
491
|
+
**Data Fields**:
|
|
481
492
|
|
|
482
|
-
- `
|
|
483
|
-
- `
|
|
493
|
+
- `ground_contact_time_ms`: Duration of ground contact phase in milliseconds
|
|
494
|
+
- `flight_time_ms`: Duration of flight phase in milliseconds
|
|
495
|
+
- `jump_height_m`: Jump height calculated from flight time: h = g × t² / 8
|
|
496
|
+
- `jump_height_kinematic_m`: Kinematic estimate (same as `jump_height_m`)
|
|
484
497
|
- `jump_height_trajectory_normalized`: Position-based measurement in normalized coordinates (0-1 range)
|
|
485
|
-
- `
|
|
486
|
-
- `
|
|
498
|
+
- `contact_start_frame`: Frame index where contact begins (integer, for visualization)
|
|
499
|
+
- `contact_end_frame`: Frame index where contact ends (integer, for visualization)
|
|
500
|
+
- `flight_start_frame`: Frame index where flight begins (integer, for visualization)
|
|
501
|
+
- `flight_end_frame`: Frame index where flight ends (integer, for visualization)
|
|
502
|
+
- `peak_height_frame`: Frame index at maximum jump height (integer, for visualization)
|
|
503
|
+
- `contact_start_frame_precise`: Sub-frame precise timing for contact start (fractional, for calculations)
|
|
504
|
+
- `contact_end_frame_precise`: Sub-frame precise timing for contact end (fractional, for calculations)
|
|
505
|
+
- `flight_start_frame_precise`: Sub-frame precise timing for flight start (fractional, for calculations)
|
|
506
|
+
- `flight_end_frame_precise`: Sub-frame precise timing for flight end (fractional, for calculations)
|
|
507
|
+
|
|
508
|
+
**Note**: Integer frame indices are provided for visualization in debug videos. Precise fractional frames are used for all timing calculations and provide sub-frame accuracy (±10ms at 30fps).
|
|
509
|
+
|
|
510
|
+
### CMJ JSON Output
|
|
511
|
+
|
|
512
|
+
```json
|
|
513
|
+
{
|
|
514
|
+
"data": {
|
|
515
|
+
"jump_height_m": 0.352,
|
|
516
|
+
"flight_time_ms": 534.2,
|
|
517
|
+
"countermovement_depth_m": 0.285,
|
|
518
|
+
"eccentric_duration_ms": 612.5,
|
|
519
|
+
"concentric_duration_ms": 321.8,
|
|
520
|
+
"total_movement_time_ms": 934.3,
|
|
521
|
+
"peak_eccentric_velocity_m_s": -2.145,
|
|
522
|
+
"peak_concentric_velocity_m_s": 3.789,
|
|
523
|
+
"transition_time_ms": 125.4,
|
|
524
|
+
"standing_start_frame": 12.5,
|
|
525
|
+
"lowest_point_frame": 45.2,
|
|
526
|
+
"takeoff_frame": 67.8,
|
|
527
|
+
"landing_frame": 102.3,
|
|
528
|
+
"tracking_method": "foot"
|
|
529
|
+
},
|
|
530
|
+
"metadata": {
|
|
531
|
+
"quality": { },
|
|
532
|
+
"processing_info": { }
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
```
|
|
487
536
|
|
|
488
|
-
**
|
|
537
|
+
**Data Fields**:
|
|
538
|
+
|
|
539
|
+
- `jump_height_m`: Jump height calculated from flight time: h = g × t² / 8
|
|
540
|
+
- `flight_time_ms`: Duration of flight phase in milliseconds
|
|
541
|
+
- `countermovement_depth_m`: Maximum downward displacement during eccentric (descent) phase
|
|
542
|
+
- `eccentric_duration_ms`: Time from start of countermovement to lowest point
|
|
543
|
+
- `concentric_duration_ms`: Time from lowest point to takeoff
|
|
544
|
+
- `total_movement_time_ms`: Total time from countermovement start to takeoff
|
|
545
|
+
- `peak_eccentric_velocity_m_s`: Maximum downward velocity during descent (negative value)
|
|
546
|
+
- `peak_concentric_velocity_m_s`: Maximum upward velocity during propulsion (positive value)
|
|
547
|
+
- `transition_time_ms`: Duration at lowest point (amortization phase between descent and propulsion)
|
|
548
|
+
- `standing_start_frame`: Frame where standing phase ends and countermovement begins
|
|
549
|
+
- `lowest_point_frame`: Frame at the lowest point of the countermovement
|
|
550
|
+
- `takeoff_frame`: Frame where athlete leaves ground
|
|
551
|
+
- `landing_frame`: Frame where athlete lands after jump
|
|
552
|
+
- `tracking_method`: Tracking method used - "foot" (foot landmarks) or "com" (center of mass estimation)
|
|
489
553
|
|
|
490
554
|
### Debug Video
|
|
491
555
|
|
|
@@ -542,8 +606,7 @@ The debug video includes:
|
|
|
542
606
|
|
|
543
607
|
**Solutions**:
|
|
544
608
|
|
|
545
|
-
1. **
|
|
546
|
-
- Theoretically improves accuracy (⚠️ unvalidated)
|
|
609
|
+
1. **Check video quality**: Ensure video frame rate is adequate (30fps or higher recommended)
|
|
547
610
|
1. **Verify flight time detection**: Check `flight_start_frame` and `flight_end_frame` in JSON
|
|
548
611
|
1. **Compare measurements**: JSON output includes both `jump_height_m` (primary) and `jump_height_kinematic_m` (kinematic-only)
|
|
549
612
|
1. **Check for drop jump detection**: If doing a drop jump, ensure first phase is elevated enough (>5% of frame height)
|
|
@@ -581,8 +644,7 @@ The debug video includes:
|
|
|
581
644
|
1. **Metric Calculation**:
|
|
582
645
|
- Ground contact time = contact phase duration (using fractional frames)
|
|
583
646
|
- Flight time = flight phase duration (using fractional frames)
|
|
584
|
-
- Jump height =
|
|
585
|
-
- Fallback: kinematic estimate (g × t²) / 8 with optional empirical correction factor (⚠️ unvalidated)
|
|
647
|
+
- Jump height = kinematic estimate from flight time: (g × t²) / 8
|
|
586
648
|
|
|
587
649
|
## Development
|
|
588
650
|
|
|
@@ -593,7 +655,7 @@ This project enforces strict code quality standards:
|
|
|
593
655
|
- **Type safety**: Full pyright strict mode compliance with complete type annotations
|
|
594
656
|
- **Linting**: Comprehensive ruff checks (pycodestyle, pyflakes, isort, pep8-naming, etc.)
|
|
595
657
|
- **Formatting**: Black code style
|
|
596
|
-
- **Testing**: pytest with
|
|
658
|
+
- **Testing**: pytest with 261 comprehensive tests (74.27% coverage)
|
|
597
659
|
- **PEP 561 compliant**: Includes py.typed marker for type checking support
|
|
598
660
|
|
|
599
661
|
### Development Commands
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
kinemotion/__init__.py,sha256=
|
|
1
|
+
kinemotion/__init__.py,sha256=sxdDOekOrIgjxm842gy-6zfq7OWmGl9ShJtXCm4JI7c,723
|
|
2
2
|
kinemotion/api.py,sha256=tbkjXsfe0N0Bmik6XRIOYM7Nom4QqeQJSpDx7IoiuSA,38177
|
|
3
3
|
kinemotion/cli.py,sha256=cqYV_7URH0JUDy1VQ_EDLv63FmNO4Ns20m6s1XAjiP4,464
|
|
4
4
|
kinemotion/cmj/__init__.py,sha256=Ynv0-Oco4I3Y1Ubj25m3h9h2XFqeNwpAewXmAYOmwfU,127
|
|
5
|
-
kinemotion/cmj/analysis.py,sha256=
|
|
5
|
+
kinemotion/cmj/analysis.py,sha256=il7-sfM89ZetxLhmw9boViaP4E8Y3mlS_XI-B5txmMs,19795
|
|
6
6
|
kinemotion/cmj/cli.py,sha256=12FEfWrseG4kCUbgHHdBPkWp6zzVQ0VAzfgNJotArmM,10792
|
|
7
7
|
kinemotion/cmj/debug_overlay.py,sha256=D-y2FQKI01KY0WXFKTKg6p9Qj3AkXCE7xjau3Ais080,15886
|
|
8
|
-
kinemotion/cmj/joint_angles.py,sha256=
|
|
9
|
-
kinemotion/cmj/kinematics.py,sha256
|
|
8
|
+
kinemotion/cmj/joint_angles.py,sha256=HmheIEiKcQz39cRezk4h-htorOhGNPsqKIR9RsAEKts,9960
|
|
9
|
+
kinemotion/cmj/kinematics.py,sha256=-iBFg2AkQR4LaThCQzO09fx6qJed27ZfMDQJgE7Si4k,9772
|
|
10
10
|
kinemotion/core/__init__.py,sha256=HsqolRa60cW3vrG8F9Lvr9WvWcs5hCmsTzSgo7imi-4,1278
|
|
11
11
|
kinemotion/core/auto_tuning.py,sha256=j6cul_qC6k0XyryCG93C1AWH2MKPj3UBMzuX02xaqfI,11235
|
|
12
12
|
kinemotion/core/cli_utils.py,sha256=Pq1JF7yvK1YbH0tOUWKjplthCbWsJQt4Lv7esPYH4FM,7254
|
|
13
|
+
kinemotion/core/cmj_metrics_validator.py,sha256=Jfh8oxhxz5BCBIPdeMRHa60tZsliDkN10RiLQYkmck4,27262
|
|
14
|
+
kinemotion/core/cmj_validation_bounds.py,sha256=WBMuJx6ewb-rYan3xmQu32m7bs9h8J5isa4LduZuZkI,13507
|
|
13
15
|
kinemotion/core/debug_overlay_utils.py,sha256=TyUb5okv5qw8oeaX3jsUO_kpwf1NnaHEAOTm-8LwTno,4587
|
|
14
16
|
kinemotion/core/filtering.py,sha256=f-m-aA59e4WqE6u-9MA51wssu7rI-Y_7n1cG8IWdeRQ,11241
|
|
17
|
+
kinemotion/core/formatting.py,sha256=G_3eqgOtym9RFOZVEwCxye4A2cyrmgvtQ214vIshowU,2480
|
|
15
18
|
kinemotion/core/metadata.py,sha256=PyGHL6sx7Hj21lyorg2VsWP9BGTj_y_-wWU6eKCEfJo,6817
|
|
16
19
|
kinemotion/core/pose.py,sha256=ztemdZ_ysVVK3gbXabm8qS_dr1VfJX9KZjmcO-Z-iNE,8532
|
|
17
20
|
kinemotion/core/quality.py,sha256=OC9nuf5IrQ9xURf3eA50VoNWOqkGwbjJpS90q2FDQzA,13082
|
|
@@ -21,10 +24,10 @@ kinemotion/dropjump/__init__.py,sha256=yc1XiZ9vfo5h_n7PKVSiX2TTgaIfGL7Y7SkQtiDZj
|
|
|
21
24
|
kinemotion/dropjump/analysis.py,sha256=BQ5NqSPNJjFQOb-W4bXSLvjCgWd-nvqx5NElyeqZJC4,29067
|
|
22
25
|
kinemotion/dropjump/cli.py,sha256=ZyroaYPwz8TgfL39Wcaj6m68Awl6lYXC75ttaflU-c0,16236
|
|
23
26
|
kinemotion/dropjump/debug_overlay.py,sha256=LkPw6ucb7beoYWS4L-Lvjs1KLCm5wAWDAfiznUeV2IQ,5668
|
|
24
|
-
kinemotion/dropjump/kinematics.py,sha256=
|
|
27
|
+
kinemotion/dropjump/kinematics.py,sha256=Yr3G7AQwtYy1dxyeOAYfqqgd4pzoZwWQAhZzxI5RbnE,16658
|
|
25
28
|
kinemotion/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
kinemotion-0.
|
|
27
|
-
kinemotion-0.
|
|
28
|
-
kinemotion-0.
|
|
29
|
-
kinemotion-0.
|
|
30
|
-
kinemotion-0.
|
|
29
|
+
kinemotion-0.29.0.dist-info/METADATA,sha256=ZAHFxbzTJXP_okBnSjd8zqqlZrKmTr89pny0ktv2H-0,25810
|
|
30
|
+
kinemotion-0.29.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
31
|
+
kinemotion-0.29.0.dist-info/entry_points.txt,sha256=zaqnAnjLvcdrk1Qvj5nvXZCZ2gp0prS7it1zTJygcIY,50
|
|
32
|
+
kinemotion-0.29.0.dist-info/licenses/LICENSE,sha256=KZajvqsHw0NoOHOi2q0FZ4NBe9HdV6oey-IPYAtHXfg,1088
|
|
33
|
+
kinemotion-0.29.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|