kinemotion 0.14.4__tar.gz → 0.15.0__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.14.4 → kinemotion-0.15.0}/CHANGELOG.md +13 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/CLAUDE.md +1 -1
- {kinemotion-0.14.4 → kinemotion-0.15.0}/PKG-INFO +3 -3
- {kinemotion-0.14.4 → kinemotion-0.15.0}/README.md +2 -2
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/api/dropjump.md +1 -1
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/api/overview.md +2 -2
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/index.md +1 -1
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/reference/parameters.md +4 -4
- {kinemotion-0.14.4 → kinemotion-0.15.0}/examples/bulk/README.md +35 -35
- {kinemotion-0.14.4 → kinemotion-0.15.0}/examples/bulk/bulk_processing.py +31 -23
- {kinemotion-0.14.4 → kinemotion-0.15.0}/examples/bulk/simple_example.py +14 -9
- {kinemotion-0.14.4 → kinemotion-0.15.0}/pyproject.toml +1 -1
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/__init__.py +8 -8
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/api.py +27 -27
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/test_api.py +38 -38
- {kinemotion-0.14.4 → kinemotion-0.15.0}/uv.lock +1 -1
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.dockerignore +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.github/pull_request_template.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.github/workflows/docs.yml +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.github/workflows/release.yml +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.gitignore +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.pre-commit-config.yaml +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.readthedocs.yml +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/.tool-versions +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/CODE_OF_CONDUCT.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/CONTRIBUTING.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/Dockerfile +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/GEMINI.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/LICENSE +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/SECURITY.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/README.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/api/cmj.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/api/core.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/development/errors-findings.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/development/validation-plan.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/guides/bulk-processing.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/guides/camera-setup.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/guides/cmj-guide.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/reference/pose-systems.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/research/sports-biomechanics-pose-estimation.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/technical/framerate.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/technical/imu-metadata.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/technical/real-time-analysis.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/technical/triple-extension.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/docs/translations/es/camera-setup.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/examples/programmatic_usage.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/mkdocs.yml +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/requirements-docs.txt +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/samples/cmjs/README.md +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/cli.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/cmj/__init__.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/cmj/analysis.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/cmj/cli.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/cmj/debug_overlay.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/cmj/joint_angles.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/cmj/kinematics.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/core/__init__.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/core/auto_tuning.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/core/cli_utils.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/core/debug_overlay_utils.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/core/filtering.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/core/pose.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/core/smoothing.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/core/video_io.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/dropjump/__init__.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/dropjump/analysis.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/dropjump/cli.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/dropjump/debug_overlay.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/dropjump/kinematics.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/src/kinemotion/py.typed +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/__init__.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/test_adaptive_threshold.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/test_aspect_ratio.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/test_cmj_analysis.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/test_cmj_kinematics.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/test_com_estimation.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/test_contact_detection.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/test_filtering.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/test_kinematics.py +0 -0
- {kinemotion-0.14.4 → kinemotion-0.15.0}/tests/test_polyorder.py +0 -0
|
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
<!-- version list -->
|
|
9
9
|
|
|
10
|
+
## v0.15.0 (2025-11-06)
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- Standardize drop jump API naming for consistency with CMJ
|
|
15
|
+
([`fcd92d0`](https://github.com/feniix/kinemotion/commit/fcd92d0802408d02dcb83a97816b491f92c36f28))
|
|
16
|
+
|
|
17
|
+
### Breaking Changes
|
|
18
|
+
|
|
19
|
+
- Users must update imports and function calls from process_video to process_dropjump_video,
|
|
20
|
+
VideoConfig to DropJumpVideoConfig, and process_videos_bulk to process_dropjump_videos_bulk.
|
|
21
|
+
|
|
22
|
+
|
|
10
23
|
## v0.14.4 (2025-11-06)
|
|
11
24
|
|
|
12
25
|
### Bug Fixes
|
|
@@ -192,7 +192,7 @@ kinemotion cmj-analyze videos/*.mp4 --batch --workers 4
|
|
|
192
192
|
|
|
193
193
|
```python
|
|
194
194
|
# Drop jump
|
|
195
|
-
from kinemotion import
|
|
195
|
+
from kinemotion import process_dropjump_video
|
|
196
196
|
metrics = process_video("video.mp4", drop_height=0.40)
|
|
197
197
|
|
|
198
198
|
# CMJ
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kinemotion
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.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
|
|
@@ -191,7 +191,7 @@ Use kinemotion as a library for automated pipelines and custom analysis.
|
|
|
191
191
|
### Drop Jump API
|
|
192
192
|
|
|
193
193
|
```python
|
|
194
|
-
from kinemotion import
|
|
194
|
+
from kinemotion import process_dropjump_video
|
|
195
195
|
|
|
196
196
|
# Process a single video
|
|
197
197
|
metrics = process_video(
|
|
@@ -211,7 +211,7 @@ print(f"Flight time: {metrics.flight_time * 1000:.1f} ms")
|
|
|
211
211
|
|
|
212
212
|
```python
|
|
213
213
|
# Drop jump bulk processing
|
|
214
|
-
from kinemotion import
|
|
214
|
+
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk
|
|
215
215
|
|
|
216
216
|
configs = [
|
|
217
217
|
VideoConfig("video1.mp4", drop_height=0.40),
|
|
@@ -162,7 +162,7 @@ Use kinemotion as a library for automated pipelines and custom analysis.
|
|
|
162
162
|
### Drop Jump API
|
|
163
163
|
|
|
164
164
|
```python
|
|
165
|
-
from kinemotion import
|
|
165
|
+
from kinemotion import process_dropjump_video
|
|
166
166
|
|
|
167
167
|
# Process a single video
|
|
168
168
|
metrics = process_video(
|
|
@@ -182,7 +182,7 @@ print(f"Flight time: {metrics.flight_time * 1000:.1f} ms")
|
|
|
182
182
|
|
|
183
183
|
```python
|
|
184
184
|
# Drop jump bulk processing
|
|
185
|
-
from kinemotion import
|
|
185
|
+
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk
|
|
186
186
|
|
|
187
187
|
configs = [
|
|
188
188
|
VideoConfig("video1.mp4", drop_height=0.40),
|
|
@@ -31,7 +31,7 @@ See [CMJ API](cmj.md) for detailed documentation.
|
|
|
31
31
|
## Basic Usage
|
|
32
32
|
|
|
33
33
|
```python
|
|
34
|
-
from kinemotion import
|
|
34
|
+
from kinemotion import process_dropjump_video, process_cmj_video
|
|
35
35
|
|
|
36
36
|
# Drop jump analysis
|
|
37
37
|
drop_metrics = process_video("dropjump.mp4", drop_height=0.40)
|
|
@@ -43,7 +43,7 @@ cmj_metrics = process_cmj_video("cmj.mp4")
|
|
|
43
43
|
## Batch Processing
|
|
44
44
|
|
|
45
45
|
```python
|
|
46
|
-
from kinemotion import
|
|
46
|
+
from kinemotion import process_dropjump_videos_bulk, process_cmj_videos_bulk
|
|
47
47
|
|
|
48
48
|
# Batch drop jump analysis
|
|
49
49
|
results = process_videos_bulk(
|
|
@@ -24,7 +24,7 @@ kinemotion dropjump-analyze video.mp4 --drop-height 0.40
|
|
|
24
24
|
Or via Python API:
|
|
25
25
|
|
|
26
26
|
```python
|
|
27
|
-
from kinemotion import
|
|
27
|
+
from kinemotion import process_dropjump_video
|
|
28
28
|
|
|
29
29
|
metrics = process_video("video.mp4", drop_height=0.40)
|
|
30
30
|
print(f"Ground contact time: {metrics.ground_contact_time:.3f}s")
|
|
@@ -76,14 +76,14 @@ kinemotion dropjump-analyze videos/*.mp4 --batch --drop-height 0.40 \
|
|
|
76
76
|
For more control, use the Python API:
|
|
77
77
|
|
|
78
78
|
```python
|
|
79
|
-
from kinemotion import
|
|
79
|
+
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk
|
|
80
80
|
|
|
81
81
|
configs = [
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
DropJumpVideoConfig("video1.mp4", drop_height=0.40, quality="fast"),
|
|
83
|
+
DropJumpVideoConfig("video2.mp4", drop_height=0.30, quality="accurate"), # Different settings per video
|
|
84
84
|
]
|
|
85
85
|
|
|
86
|
-
results =
|
|
86
|
+
results = process_dropjump_videos_bulk(configs, max_workers=4)
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
See `examples/bulk/README.md` for complete API documentation.
|
|
@@ -16,10 +16,10 @@ Kinemotion can be used as a library in your Python code, not just as a CLI tool.
|
|
|
16
16
|
### Single Video Processing
|
|
17
17
|
|
|
18
18
|
```python
|
|
19
|
-
from kinemotion import
|
|
19
|
+
from kinemotion import process_dropjump_video
|
|
20
20
|
|
|
21
21
|
# Process a single video
|
|
22
|
-
metrics =
|
|
22
|
+
metrics = process_dropjump_video(
|
|
23
23
|
video_path="athlete_jump.mp4",
|
|
24
24
|
drop_height=0.40, # 40cm drop box (REQUIRED)
|
|
25
25
|
verbose=True
|
|
@@ -33,17 +33,17 @@ print(f"Flight time: {metrics.flight_time_ms:.1f} ms")
|
|
|
33
33
|
### Bulk Video Processing
|
|
34
34
|
|
|
35
35
|
```python
|
|
36
|
-
from kinemotion import
|
|
36
|
+
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk
|
|
37
37
|
|
|
38
38
|
# Configure multiple videos
|
|
39
39
|
configs = [
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
DropJumpVideoConfig("video1.mp4", drop_height=0.40),
|
|
41
|
+
DropJumpVideoConfig("video2.mp4", drop_height=0.30),
|
|
42
|
+
DropJumpVideoConfig("video3.mp4", drop_height=0.50),
|
|
43
43
|
]
|
|
44
44
|
|
|
45
45
|
# Process in parallel with 4 workers
|
|
46
|
-
results =
|
|
46
|
+
results = process_dropjump_videos_bulk(configs, max_workers=4)
|
|
47
47
|
|
|
48
48
|
# Check results
|
|
49
49
|
for result in results:
|
|
@@ -113,7 +113,7 @@ Process a single drop jump video.
|
|
|
113
113
|
- `FileNotFoundError`: Video file not found
|
|
114
114
|
- `ValueError`: Invalid parameters or video cannot be processed
|
|
115
115
|
|
|
116
|
-
#### `
|
|
116
|
+
#### `process_dropjump_videos_bulk()`
|
|
117
117
|
|
|
118
118
|
Process multiple videos in parallel.
|
|
119
119
|
|
|
@@ -134,7 +134,7 @@ Process multiple videos in parallel.
|
|
|
134
134
|
Configuration for a single video.
|
|
135
135
|
|
|
136
136
|
```python
|
|
137
|
-
|
|
137
|
+
DropJumpVideoConfig(
|
|
138
138
|
video_path="video.mp4",
|
|
139
139
|
drop_height=0.40,
|
|
140
140
|
quality="balanced",
|
|
@@ -177,7 +177,7 @@ Analysis results for a drop jump.
|
|
|
177
177
|
|
|
178
178
|
```python
|
|
179
179
|
from pathlib import Path
|
|
180
|
-
from kinemotion import
|
|
180
|
+
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk
|
|
181
181
|
|
|
182
182
|
# Find all MP4 files
|
|
183
183
|
video_dir = Path("athlete_videos")
|
|
@@ -185,7 +185,7 @@ video_files = list(video_dir.glob("*.mp4"))
|
|
|
185
185
|
|
|
186
186
|
# Create configs with consistent settings
|
|
187
187
|
configs = [
|
|
188
|
-
|
|
188
|
+
DropJumpVideoConfig(
|
|
189
189
|
video_path=str(video_file),
|
|
190
190
|
drop_height=0.40,
|
|
191
191
|
quality="balanced",
|
|
@@ -199,7 +199,7 @@ def show_progress(result):
|
|
|
199
199
|
status = "✓" if result.success else "✗"
|
|
200
200
|
print(f"{status} {result.video_path}")
|
|
201
201
|
|
|
202
|
-
results =
|
|
202
|
+
results = process_dropjump_videos_bulk(
|
|
203
203
|
configs,
|
|
204
204
|
max_workers=4,
|
|
205
205
|
progress_callback=show_progress
|
|
@@ -215,11 +215,11 @@ print(f"\nAverage jump height: {avg_jump:.3f} m")
|
|
|
215
215
|
|
|
216
216
|
```python
|
|
217
217
|
import csv
|
|
218
|
-
from kinemotion import
|
|
218
|
+
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk
|
|
219
219
|
|
|
220
220
|
# Process videos
|
|
221
221
|
configs = [...] # Your video configs
|
|
222
|
-
results =
|
|
222
|
+
results = process_dropjump_videos_bulk(configs, max_workers=4)
|
|
223
223
|
|
|
224
224
|
# Export successful results
|
|
225
225
|
with open("results.csv", "w", newline="") as f:
|
|
@@ -244,29 +244,29 @@ with open("results.csv", "w", newline="") as f:
|
|
|
244
244
|
### 3. Different Quality Settings
|
|
245
245
|
|
|
246
246
|
```python
|
|
247
|
-
from kinemotion import
|
|
247
|
+
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk
|
|
248
248
|
|
|
249
249
|
configs = [
|
|
250
250
|
# Fast: Quick screening
|
|
251
|
-
|
|
251
|
+
DropJumpVideoConfig("video1.mp4", drop_height=0.40, quality="fast"),
|
|
252
252
|
|
|
253
253
|
# Balanced: Default, good accuracy/speed
|
|
254
|
-
|
|
254
|
+
DropJumpVideoConfig("video2.mp4", drop_height=0.40, quality="balanced"),
|
|
255
255
|
|
|
256
256
|
# Accurate: Research-grade, slower
|
|
257
|
-
|
|
257
|
+
DropJumpVideoConfig("video3.mp4", drop_height=0.40, quality="accurate"),
|
|
258
258
|
]
|
|
259
259
|
|
|
260
|
-
results =
|
|
260
|
+
results = process_dropjump_videos_bulk(configs, max_workers=3)
|
|
261
261
|
```
|
|
262
262
|
|
|
263
263
|
### 4. Custom Parameters for Challenging Videos
|
|
264
264
|
|
|
265
265
|
```python
|
|
266
|
-
from kinemotion import
|
|
266
|
+
from kinemotion import process_dropjump_video
|
|
267
267
|
|
|
268
268
|
# Low quality video - more aggressive smoothing
|
|
269
|
-
metrics =
|
|
269
|
+
metrics = process_dropjump_video(
|
|
270
270
|
video_path="low_quality.mp4",
|
|
271
271
|
drop_height=0.40,
|
|
272
272
|
smoothing_window=7, # More smoothing
|
|
@@ -275,7 +275,7 @@ metrics = process_video(
|
|
|
275
275
|
)
|
|
276
276
|
|
|
277
277
|
# High speed video - let auto-tuning handle FPS
|
|
278
|
-
metrics =
|
|
278
|
+
metrics = process_dropjump_video(
|
|
279
279
|
video_path="high_speed_120fps.mp4",
|
|
280
280
|
drop_height=0.40,
|
|
281
281
|
quality="accurate" # Auto-adjusts for 120fps
|
|
@@ -285,11 +285,11 @@ metrics = process_video(
|
|
|
285
285
|
### 5. Generate Debug Videos
|
|
286
286
|
|
|
287
287
|
```python
|
|
288
|
-
from kinemotion import
|
|
288
|
+
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk
|
|
289
289
|
|
|
290
290
|
# Process and save debug videos for review
|
|
291
291
|
configs = [
|
|
292
|
-
|
|
292
|
+
DropJumpVideoConfig(
|
|
293
293
|
video_path="athlete1_trial1.mp4",
|
|
294
294
|
drop_height=0.40,
|
|
295
295
|
output_video="debug/athlete1_trial1_debug.mp4",
|
|
@@ -298,7 +298,7 @@ configs = [
|
|
|
298
298
|
# ... more videos
|
|
299
299
|
]
|
|
300
300
|
|
|
301
|
-
results =
|
|
301
|
+
results = process_dropjump_videos_bulk(configs, max_workers=2)
|
|
302
302
|
```
|
|
303
303
|
|
|
304
304
|
## Performance Tips
|
|
@@ -326,14 +326,14 @@ Debug videos are slow to generate. Skip them for large batches:
|
|
|
326
326
|
|
|
327
327
|
```python
|
|
328
328
|
# Don't set output_video parameter
|
|
329
|
-
|
|
329
|
+
DropJumpVideoConfig("video.mp4", drop_height=0.40) # No debug video
|
|
330
330
|
```
|
|
331
331
|
|
|
332
332
|
### 4. Process Videos Sequentially for Single Machine
|
|
333
333
|
|
|
334
334
|
```python
|
|
335
335
|
# Use max_workers=1 if you have limited memory
|
|
336
|
-
results =
|
|
336
|
+
results = process_dropjump_videos_bulk(configs, max_workers=1)
|
|
337
337
|
```
|
|
338
338
|
|
|
339
339
|
## Error Handling
|
|
@@ -341,7 +341,7 @@ results = process_videos_bulk(configs, max_workers=1)
|
|
|
341
341
|
All errors are isolated per video - one failure doesn't crash the batch:
|
|
342
342
|
|
|
343
343
|
```python
|
|
344
|
-
results =
|
|
344
|
+
results = process_dropjump_videos_bulk(configs, max_workers=4)
|
|
345
345
|
|
|
346
346
|
for result in results:
|
|
347
347
|
if result.success:
|
|
@@ -362,19 +362,19 @@ for result in results:
|
|
|
362
362
|
|
|
363
363
|
```python
|
|
364
364
|
import pandas as pd
|
|
365
|
-
from kinemotion import
|
|
365
|
+
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk
|
|
366
366
|
|
|
367
367
|
# Read video list from CSV
|
|
368
368
|
df = pd.read_csv("videos.csv") # Columns: path, drop_height
|
|
369
369
|
|
|
370
370
|
# Create configs
|
|
371
371
|
configs = [
|
|
372
|
-
|
|
372
|
+
DropJumpVideoConfig(row.path, row.drop_height)
|
|
373
373
|
for _, row in df.iterrows()
|
|
374
374
|
]
|
|
375
375
|
|
|
376
376
|
# Process
|
|
377
|
-
results =
|
|
377
|
+
results = process_dropjump_videos_bulk(configs, max_workers=4)
|
|
378
378
|
|
|
379
379
|
# Create results DataFrame
|
|
380
380
|
results_data = []
|
|
@@ -396,7 +396,7 @@ results_df.to_csv("analysis_results.csv", index=False)
|
|
|
396
396
|
|
|
397
397
|
```python
|
|
398
398
|
import click
|
|
399
|
-
from kinemotion import
|
|
399
|
+
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk
|
|
400
400
|
|
|
401
401
|
@click.command()
|
|
402
402
|
@click.argument("video_dir", type=click.Path(exists=True))
|
|
@@ -408,13 +408,13 @@ def analyze_directory(video_dir, drop_height, workers):
|
|
|
408
408
|
|
|
409
409
|
videos = list(Path(video_dir).glob("*.mp4"))
|
|
410
410
|
configs = [
|
|
411
|
-
|
|
411
|
+
DropJumpVideoConfig(str(v), drop_height=drop_height)
|
|
412
412
|
for v in videos
|
|
413
413
|
]
|
|
414
414
|
|
|
415
415
|
click.echo(f"Processing {len(videos)} videos with {workers} workers...")
|
|
416
416
|
|
|
417
|
-
results =
|
|
417
|
+
results = process_dropjump_videos_bulk(configs, max_workers=workers)
|
|
418
418
|
|
|
419
419
|
successful = [r for r in results if r.success]
|
|
420
420
|
click.echo(f"Success: {len(successful)}/{len(results)}")
|
|
@@ -439,7 +439,7 @@ uv sync
|
|
|
439
439
|
Reduce `max_workers` or process videos sequentially:
|
|
440
440
|
|
|
441
441
|
```python
|
|
442
|
-
results =
|
|
442
|
+
results = process_dropjump_videos_bulk(configs, max_workers=1)
|
|
443
443
|
```
|
|
444
444
|
|
|
445
445
|
### Video Processing Failures
|
|
@@ -8,7 +8,11 @@ using the kinemotion API for high-throughput analysis.
|
|
|
8
8
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
|
|
11
|
-
from kinemotion.api import
|
|
11
|
+
from kinemotion.api import (
|
|
12
|
+
DropJumpVideoConfig,
|
|
13
|
+
DropJumpVideoResult,
|
|
14
|
+
process_dropjump_videos_bulk,
|
|
15
|
+
)
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
def example_simple_bulk() -> None:
|
|
@@ -18,13 +22,13 @@ def example_simple_bulk() -> None:
|
|
|
18
22
|
print("=" * 80)
|
|
19
23
|
|
|
20
24
|
video_configs = [
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
DropJumpVideoConfig(video_path="video1.mp4"),
|
|
26
|
+
DropJumpVideoConfig(video_path="video2.mp4"),
|
|
27
|
+
DropJumpVideoConfig(video_path="video3.mp4"),
|
|
24
28
|
]
|
|
25
29
|
|
|
26
30
|
# Process videos with 4 parallel workers
|
|
27
|
-
results =
|
|
31
|
+
results = process_dropjump_videos_bulk(video_configs, max_workers=4)
|
|
28
32
|
|
|
29
33
|
# Print results
|
|
30
34
|
for result in results:
|
|
@@ -39,19 +43,19 @@ def example_advanced_configuration() -> None:
|
|
|
39
43
|
|
|
40
44
|
advanced_configs = [
|
|
41
45
|
# Fast analysis for quick screening
|
|
42
|
-
|
|
46
|
+
DropJumpVideoConfig(
|
|
43
47
|
video_path="athlete1_trial1.mp4",
|
|
44
48
|
quality="fast",
|
|
45
49
|
json_output="results/athlete1_trial1.json",
|
|
46
50
|
),
|
|
47
51
|
# Balanced analysis (default)
|
|
48
|
-
|
|
52
|
+
DropJumpVideoConfig(
|
|
49
53
|
video_path="athlete1_trial2.mp4",
|
|
50
54
|
quality="balanced",
|
|
51
55
|
json_output="results/athlete1_trial2.json",
|
|
52
56
|
),
|
|
53
57
|
# Research-grade accurate analysis with debug video
|
|
54
|
-
|
|
58
|
+
DropJumpVideoConfig(
|
|
55
59
|
video_path="athlete1_trial3.mp4",
|
|
56
60
|
quality="accurate",
|
|
57
61
|
output_video="debug/athlete1_trial3_debug.mp4",
|
|
@@ -64,23 +68,25 @@ def example_advanced_configuration() -> None:
|
|
|
64
68
|
Path("debug").mkdir(exist_ok=True)
|
|
65
69
|
|
|
66
70
|
# Progress callback to show completion
|
|
67
|
-
def on_progress(result:
|
|
71
|
+
def on_progress(result: DropJumpVideoResult) -> None:
|
|
68
72
|
status = "✓" if result.success else "✗"
|
|
69
73
|
print(
|
|
70
74
|
f"{status} Completed: {result.video_path} ({result.processing_time:.2f}s)"
|
|
71
75
|
)
|
|
72
76
|
|
|
73
|
-
|
|
77
|
+
process_dropjump_videos_bulk(
|
|
78
|
+
advanced_configs, max_workers=2, progress_callback=on_progress
|
|
79
|
+
)
|
|
74
80
|
|
|
75
81
|
|
|
76
|
-
def example_process_directory() -> list[
|
|
82
|
+
def example_process_directory() -> list[DropJumpVideoResult]:
|
|
77
83
|
"""Example 3: Process entire directory with consistent settings."""
|
|
78
84
|
print("\n" + "=" * 80)
|
|
79
85
|
print("EXAMPLE 3: Process Directory")
|
|
80
86
|
print("=" * 80)
|
|
81
87
|
|
|
82
88
|
# Progress callback to show completion
|
|
83
|
-
def on_progress(result:
|
|
89
|
+
def on_progress(result: DropJumpVideoResult) -> None:
|
|
84
90
|
status = "✓" if result.success else "✗"
|
|
85
91
|
print(
|
|
86
92
|
f"{status} Completed: {result.video_path} ({result.processing_time:.2f}s)"
|
|
@@ -96,7 +102,7 @@ def example_process_directory() -> list[VideoResult]:
|
|
|
96
102
|
|
|
97
103
|
# Create configs with same drop height for all
|
|
98
104
|
dir_configs = [
|
|
99
|
-
|
|
105
|
+
DropJumpVideoConfig(
|
|
100
106
|
video_path=str(video_file),
|
|
101
107
|
quality="balanced",
|
|
102
108
|
json_output=f"results/{video_file.stem}.json",
|
|
@@ -106,7 +112,7 @@ def example_process_directory() -> list[VideoResult]:
|
|
|
106
112
|
|
|
107
113
|
print(f"Found {len(video_files)} videos to process")
|
|
108
114
|
|
|
109
|
-
results =
|
|
115
|
+
results = process_dropjump_videos_bulk(
|
|
110
116
|
dir_configs, max_workers=4, progress_callback=on_progress
|
|
111
117
|
)
|
|
112
118
|
|
|
@@ -114,7 +120,7 @@ def example_process_directory() -> list[VideoResult]:
|
|
|
114
120
|
return results
|
|
115
121
|
|
|
116
122
|
|
|
117
|
-
def example_export_csv(results: list[
|
|
123
|
+
def example_export_csv(results: list[DropJumpVideoResult]) -> None:
|
|
118
124
|
"""Example 4: Export results to CSV."""
|
|
119
125
|
print("\n" + "=" * 80)
|
|
120
126
|
print("EXAMPLE 4: Export to CSV")
|
|
@@ -181,14 +187,14 @@ def example_custom_parameters() -> None:
|
|
|
181
187
|
|
|
182
188
|
custom_configs = [
|
|
183
189
|
# Low quality video - use more aggressive smoothing
|
|
184
|
-
|
|
190
|
+
DropJumpVideoConfig(
|
|
185
191
|
video_path="low_quality.mp4",
|
|
186
192
|
smoothing_window=7, # More smoothing
|
|
187
193
|
velocity_threshold=0.025, # Higher threshold
|
|
188
194
|
quality="accurate",
|
|
189
195
|
),
|
|
190
196
|
# High speed video - adjust for higher framerate
|
|
191
|
-
|
|
197
|
+
DropJumpVideoConfig(
|
|
192
198
|
video_path="high_speed_120fps.mp4",
|
|
193
199
|
quality="accurate",
|
|
194
200
|
# Auto-tuning will handle FPS adjustments
|
|
@@ -196,17 +202,19 @@ def example_custom_parameters() -> None:
|
|
|
196
202
|
]
|
|
197
203
|
|
|
198
204
|
# Progress callback to show completion
|
|
199
|
-
def on_progress(result:
|
|
205
|
+
def on_progress(result: DropJumpVideoResult) -> None:
|
|
200
206
|
status = "✓" if result.success else "✗"
|
|
201
207
|
print(
|
|
202
208
|
f"{status} Completed: {result.video_path} ({result.processing_time:.2f}s)"
|
|
203
209
|
)
|
|
204
210
|
|
|
205
211
|
# Process with custom settings
|
|
206
|
-
|
|
212
|
+
process_dropjump_videos_bulk(
|
|
213
|
+
custom_configs, max_workers=2, progress_callback=on_progress
|
|
214
|
+
)
|
|
207
215
|
|
|
208
216
|
|
|
209
|
-
def print_result(result:
|
|
217
|
+
def print_result(result: DropJumpVideoResult) -> None:
|
|
210
218
|
"""Print a single video processing result."""
|
|
211
219
|
if result.success:
|
|
212
220
|
assert result.metrics is not None
|
|
@@ -224,7 +232,7 @@ def print_result(result: VideoResult) -> None:
|
|
|
224
232
|
print(f" Error: {result.error}")
|
|
225
233
|
|
|
226
234
|
|
|
227
|
-
def print_summary(results: list[
|
|
235
|
+
def print_summary(results: list[DropJumpVideoResult]) -> None:
|
|
228
236
|
"""Print summary statistics for a batch of results."""
|
|
229
237
|
successful = [r for r in results if r.success]
|
|
230
238
|
failed = [r for r in results if not r.success]
|
|
@@ -274,7 +282,7 @@ def main() -> None:
|
|
|
274
282
|
|
|
275
283
|
def example_single_video() -> None:
|
|
276
284
|
"""Example: Process a single video programmatically."""
|
|
277
|
-
from kinemotion.api import
|
|
285
|
+
from kinemotion.api import process_dropjump_video
|
|
278
286
|
|
|
279
287
|
print("\n" + "=" * 80)
|
|
280
288
|
print("SINGLE VIDEO PROCESSING")
|
|
@@ -282,7 +290,7 @@ def example_single_video() -> None:
|
|
|
282
290
|
|
|
283
291
|
try:
|
|
284
292
|
# Process single video with verbose output
|
|
285
|
-
metrics =
|
|
293
|
+
metrics = process_dropjump_video(
|
|
286
294
|
video_path="sample.mp4",
|
|
287
295
|
quality="balanced",
|
|
288
296
|
output_video="sample_debug.mp4",
|
|
@@ -5,7 +5,12 @@ Simple example: Process a single video or multiple videos using kinemotion.
|
|
|
5
5
|
This demonstrates the most straightforward way to use kinemotion as a library.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from kinemotion.api import
|
|
8
|
+
from kinemotion.api import (
|
|
9
|
+
DropJumpVideoConfig,
|
|
10
|
+
DropJumpVideoResult,
|
|
11
|
+
process_dropjump_video,
|
|
12
|
+
process_dropjump_videos_bulk,
|
|
13
|
+
)
|
|
9
14
|
|
|
10
15
|
|
|
11
16
|
def process_single_video_example() -> None:
|
|
@@ -13,7 +18,7 @@ def process_single_video_example() -> None:
|
|
|
13
18
|
print("Processing single video...")
|
|
14
19
|
|
|
15
20
|
# Process with just the video path
|
|
16
|
-
metrics =
|
|
21
|
+
metrics = process_dropjump_video(
|
|
17
22
|
video_path="my_video.mp4",
|
|
18
23
|
verbose=True,
|
|
19
24
|
)
|
|
@@ -35,21 +40,21 @@ def process_multiple_videos_example() -> None:
|
|
|
35
40
|
|
|
36
41
|
# Configure videos to process
|
|
37
42
|
configs = [
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
DropJumpVideoConfig("athlete1_jump1.mp4"),
|
|
44
|
+
DropJumpVideoConfig("athlete1_jump2.mp4"),
|
|
45
|
+
DropJumpVideoConfig("athlete1_jump3.mp4"),
|
|
46
|
+
DropJumpVideoConfig("athlete2_jump1.mp4", quality="accurate"),
|
|
42
47
|
]
|
|
43
48
|
|
|
44
49
|
# Process all videos using 4 parallel workers
|
|
45
50
|
# Progress callback shows completion status
|
|
46
|
-
def show_progress(result:
|
|
51
|
+
def show_progress(result: DropJumpVideoResult) -> None:
|
|
47
52
|
if result.success:
|
|
48
53
|
print(f"✓ {result.video_path} - {result.processing_time:.1f}s")
|
|
49
54
|
else:
|
|
50
55
|
print(f"✗ {result.video_path} - ERROR: {result.error}")
|
|
51
56
|
|
|
52
|
-
results =
|
|
57
|
+
results = process_dropjump_videos_bulk(
|
|
53
58
|
configs, max_workers=4, progress_callback=show_progress
|
|
54
59
|
)
|
|
55
60
|
|
|
@@ -71,7 +76,7 @@ def process_with_outputs_example() -> None:
|
|
|
71
76
|
"""Process video and save debug video + JSON results."""
|
|
72
77
|
print("\nProcessing with output files...")
|
|
73
78
|
|
|
74
|
-
metrics =
|
|
79
|
+
metrics = process_dropjump_video(
|
|
75
80
|
video_path="my_video.mp4",
|
|
76
81
|
output_video="debug_output.mp4", # Save annotated video
|
|
77
82
|
json_output="results.json", # Save metrics as JSON
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
from .api import (
|
|
4
4
|
CMJVideoConfig,
|
|
5
5
|
CMJVideoResult,
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
DropJumpVideoConfig,
|
|
7
|
+
DropJumpVideoResult,
|
|
8
8
|
process_cmj_video,
|
|
9
9
|
process_cmj_videos_bulk,
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
process_dropjump_video,
|
|
11
|
+
process_dropjump_videos_bulk,
|
|
12
12
|
)
|
|
13
13
|
from .cmj.kinematics import CMJMetrics
|
|
14
14
|
from .dropjump.kinematics import DropJumpMetrics
|
|
@@ -17,10 +17,10 @@ __version__ = "0.1.0"
|
|
|
17
17
|
|
|
18
18
|
__all__ = [
|
|
19
19
|
# Drop jump API
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
20
|
+
"process_dropjump_video",
|
|
21
|
+
"process_dropjump_videos_bulk",
|
|
22
|
+
"DropJumpVideoConfig",
|
|
23
|
+
"DropJumpVideoResult",
|
|
24
24
|
"DropJumpMetrics",
|
|
25
25
|
# CMJ API
|
|
26
26
|
"process_cmj_video",
|