kinemotion 0.11.3__py3-none-any.whl → 0.11.5__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/api.py CHANGED
@@ -620,7 +620,6 @@ class CMJVideoConfig:
620
620
  json_output: str | None = None
621
621
  smoothing_window: int | None = None
622
622
  velocity_threshold: float | None = None
623
- countermovement_threshold: float | None = None
624
623
  min_contact_frames: int | None = None
625
624
  visibility_threshold: float | None = None
626
625
  detection_confidence: float | None = None
@@ -927,7 +926,6 @@ def _process_cmj_video_wrapper(config: CMJVideoConfig) -> CMJVideoResult:
927
926
  json_output=config.json_output,
928
927
  smoothing_window=config.smoothing_window,
929
928
  velocity_threshold=config.velocity_threshold,
930
- countermovement_threshold=config.countermovement_threshold,
931
929
  min_contact_frames=config.min_contact_frames,
932
930
  visibility_threshold=config.visibility_threshold,
933
931
  detection_confidence=config.detection_confidence,
kinemotion/cmj/cli.py CHANGED
@@ -10,16 +10,15 @@ from typing import Any
10
10
  import click
11
11
  import numpy as np
12
12
 
13
- from ..core.auto_tuning import (
14
- AnalysisParameters as AutoTunedParams,
15
- )
16
13
  from ..core.auto_tuning import (
17
14
  QualityPreset,
18
15
  analyze_video_sample,
19
16
  auto_tune_parameters,
20
17
  )
21
18
  from ..core.cli_utils import (
19
+ apply_expert_param_overrides,
22
20
  determine_initial_confidence,
21
+ print_auto_tuned_params,
23
22
  smooth_landmark_sequence,
24
23
  track_all_frames,
25
24
  )
@@ -299,50 +298,6 @@ def cmj_analyze( # NOSONAR(S107) - Click CLI requires individual parameters for
299
298
  sys.exit(1)
300
299
 
301
300
 
302
- def _apply_expert_param_overrides(
303
- params: AutoTunedParams, expert_params: AnalysisParameters
304
- ) -> AutoTunedParams:
305
- """Apply expert parameter overrides to auto-tuned parameters."""
306
- if expert_params.smoothing_window is not None:
307
- params.smoothing_window = expert_params.smoothing_window
308
- if expert_params.velocity_threshold is not None:
309
- params.velocity_threshold = expert_params.velocity_threshold
310
- if expert_params.min_contact_frames is not None:
311
- params.min_contact_frames = expert_params.min_contact_frames
312
- if expert_params.visibility_threshold is not None:
313
- params.visibility_threshold = expert_params.visibility_threshold
314
- return params
315
-
316
-
317
- def _print_auto_tuned_params(
318
- video: VideoProcessor,
319
- quality_preset: QualityPreset,
320
- params: AutoTunedParams,
321
- countermovement_threshold: float,
322
- ) -> None:
323
- """Print auto-tuned parameters in verbose mode."""
324
- click.echo("\n" + "=" * 60, err=True)
325
- click.echo("AUTO-TUNED PARAMETERS", err=True)
326
- click.echo("=" * 60, err=True)
327
- click.echo(f"Video FPS: {video.fps:.2f}", err=True)
328
- click.echo(f"Quality preset: {quality_preset.value}", err=True)
329
- click.echo("\nSelected parameters:", err=True)
330
- click.echo(f" smoothing_window: {params.smoothing_window}", err=True)
331
- click.echo(f" polyorder: {params.polyorder}", err=True)
332
- click.echo(f" velocity_threshold: {params.velocity_threshold:.4f}", err=True)
333
- click.echo(
334
- f" countermovement_threshold: {countermovement_threshold:.4f}", err=True
335
- )
336
- click.echo(f" min_contact_frames: {params.min_contact_frames}", err=True)
337
- click.echo(f" visibility_threshold: {params.visibility_threshold}", err=True)
338
- click.echo(f" detection_confidence: {params.detection_confidence}", err=True)
339
- click.echo(f" tracking_confidence: {params.tracking_confidence}", err=True)
340
- click.echo(f" outlier_rejection: {params.outlier_rejection}", err=True)
341
- click.echo(f" bilateral_filter: {params.bilateral_filter}", err=True)
342
- click.echo(f" use_curvature: {params.use_curvature}", err=True)
343
- click.echo("=" * 60 + "\n", err=True)
344
-
345
-
346
301
  def _get_foot_position(frame_landmarks: dict | None, last_position: float) -> float:
347
302
  """Extract average foot position from frame landmarks."""
348
303
  if not frame_landmarks:
@@ -419,7 +374,7 @@ def _process_single(
419
374
  landmarks_sequence, video.fps, video.frame_count
420
375
  )
421
376
  params = auto_tune_parameters(characteristics, quality_preset)
422
- params = _apply_expert_param_overrides(params, expert_params)
377
+ params = apply_expert_param_overrides(params, expert_params)
423
378
 
424
379
  # Calculate countermovement threshold (FPS-adjusted)
425
380
  # Base: +0.015 at 30fps (POSITIVE for downward motion in normalized coords)
@@ -429,8 +384,13 @@ def _process_single(
429
384
 
430
385
  # Show parameters if verbose
431
386
  if verbose:
432
- _print_auto_tuned_params(
433
- video, quality_preset, params, countermovement_threshold
387
+ print_auto_tuned_params(
388
+ video,
389
+ quality_preset,
390
+ params,
391
+ extra_params={
392
+ "countermovement_threshold": countermovement_threshold
393
+ },
434
394
  )
435
395
 
436
396
  # Apply smoothing
@@ -4,7 +4,7 @@ from typing import Any, Protocol
4
4
 
5
5
  import click
6
6
 
7
- from .auto_tuning import AutoTunedParams, QualityPreset
7
+ from .auto_tuning import AutoTunedParams, QualityPreset, VideoCharacteristics
8
8
  from .pose import PoseTracker
9
9
  from .smoothing import smooth_landmarks, smooth_landmarks_advanced
10
10
  from .video_io import VideoProcessor
@@ -15,6 +15,10 @@ class ExpertParameters(Protocol):
15
15
 
16
16
  detection_confidence: float | None
17
17
  tracking_confidence: float | None
18
+ smoothing_window: int | None
19
+ velocity_threshold: float | None
20
+ min_contact_frames: int | None
21
+ visibility_threshold: float | None
18
22
 
19
23
 
20
24
  def determine_initial_confidence(
@@ -79,6 +83,81 @@ def track_all_frames(video: VideoProcessor, tracker: PoseTracker) -> tuple[list,
79
83
  return frames, landmarks_sequence
80
84
 
81
85
 
86
+ def apply_expert_param_overrides(
87
+ params: AutoTunedParams, expert_params: ExpertParameters
88
+ ) -> AutoTunedParams:
89
+ """Apply expert parameter overrides to auto-tuned parameters.
90
+
91
+ Args:
92
+ params: Auto-tuned parameters
93
+ expert_params: Expert overrides
94
+
95
+ Returns:
96
+ Modified params object (mutated in place)
97
+ """
98
+ if expert_params.smoothing_window is not None:
99
+ params.smoothing_window = expert_params.smoothing_window
100
+ if expert_params.velocity_threshold is not None:
101
+ params.velocity_threshold = expert_params.velocity_threshold
102
+ if expert_params.min_contact_frames is not None:
103
+ params.min_contact_frames = expert_params.min_contact_frames
104
+ if expert_params.visibility_threshold is not None:
105
+ params.visibility_threshold = expert_params.visibility_threshold
106
+ return params
107
+
108
+
109
+ def print_auto_tuned_params(
110
+ video: VideoProcessor,
111
+ quality_preset: QualityPreset,
112
+ params: AutoTunedParams,
113
+ characteristics: VideoCharacteristics | None = None,
114
+ extra_params: dict[str, Any] | None = None,
115
+ ) -> None:
116
+ """Print auto-tuned parameters in verbose mode.
117
+
118
+ Args:
119
+ video: Video processor
120
+ quality_preset: Quality preset
121
+ params: Auto-tuned parameters
122
+ characteristics: Optional video characteristics (for tracking quality display)
123
+ extra_params: Optional extra parameters to display (e.g., countermovement_threshold)
124
+ """
125
+ click.echo("\n" + "=" * 60, err=True)
126
+ click.echo("AUTO-TUNED PARAMETERS", err=True)
127
+ click.echo("=" * 60, err=True)
128
+ click.echo(f"Video FPS: {video.fps:.2f}", err=True)
129
+
130
+ if characteristics:
131
+ click.echo(
132
+ f"Tracking quality: {characteristics.tracking_quality} "
133
+ f"(avg visibility: {characteristics.avg_visibility:.2f})",
134
+ err=True,
135
+ )
136
+
137
+ click.echo(f"Quality preset: {quality_preset.value}", err=True)
138
+ click.echo("\nSelected parameters:", err=True)
139
+ click.echo(f" smoothing_window: {params.smoothing_window}", err=True)
140
+ click.echo(f" polyorder: {params.polyorder}", err=True)
141
+ click.echo(f" velocity_threshold: {params.velocity_threshold:.4f}", err=True)
142
+
143
+ # Print extra parameters if provided
144
+ if extra_params:
145
+ for key, value in extra_params.items():
146
+ if isinstance(value, float):
147
+ click.echo(f" {key}: {value:.4f}", err=True)
148
+ else:
149
+ click.echo(f" {key}: {value}", err=True)
150
+
151
+ click.echo(f" min_contact_frames: {params.min_contact_frames}", err=True)
152
+ click.echo(f" visibility_threshold: {params.visibility_threshold}", err=True)
153
+ click.echo(f" detection_confidence: {params.detection_confidence}", err=True)
154
+ click.echo(f" tracking_confidence: {params.tracking_confidence}", err=True)
155
+ click.echo(f" outlier_rejection: {params.outlier_rejection}", err=True)
156
+ click.echo(f" bilateral_filter: {params.bilateral_filter}", err=True)
157
+ click.echo(f" use_curvature: {params.use_curvature}", err=True)
158
+ click.echo("=" * 60 + "\n", err=True)
159
+
160
+
82
161
  def smooth_landmark_sequence(landmarks_sequence: list, params: AutoTunedParams) -> list:
83
162
  """Apply smoothing to landmark sequence.
84
163
 
@@ -12,17 +12,15 @@ import click
12
12
  import numpy as np
13
13
 
14
14
  from ..api import VideoConfig, VideoResult, process_videos_bulk
15
- from ..core.auto_tuning import (
16
- AnalysisParameters as AutoTunedParams,
17
- )
18
15
  from ..core.auto_tuning import (
19
16
  QualityPreset,
20
- VideoCharacteristics,
21
17
  analyze_video_sample,
22
18
  auto_tune_parameters,
23
19
  )
24
20
  from ..core.cli_utils import (
21
+ apply_expert_param_overrides,
25
22
  determine_initial_confidence,
23
+ print_auto_tuned_params,
26
24
  smooth_landmark_sequence,
27
25
  track_all_frames,
28
26
  )
@@ -260,67 +258,6 @@ def dropjump_analyze( # NOSONAR(S107) - Click CLI requires individual parameter
260
258
  )
261
259
 
262
260
 
263
- def _apply_expert_param_overrides(
264
- params: AutoTunedParams, expert_params: AnalysisParameters
265
- ) -> AutoTunedParams:
266
- """Apply expert parameter overrides to auto-tuned parameters.
267
-
268
- Args:
269
- params: Auto-tuned parameters
270
- expert_params: Expert overrides
271
-
272
- Returns:
273
- Modified params object (mutated in place)
274
- """
275
- if expert_params.smoothing_window is not None:
276
- params.smoothing_window = expert_params.smoothing_window
277
- if expert_params.velocity_threshold is not None:
278
- params.velocity_threshold = expert_params.velocity_threshold
279
- if expert_params.min_contact_frames is not None:
280
- params.min_contact_frames = expert_params.min_contact_frames
281
- if expert_params.visibility_threshold is not None:
282
- params.visibility_threshold = expert_params.visibility_threshold
283
- return params
284
-
285
-
286
- def _print_auto_tuned_params(
287
- video: VideoProcessor,
288
- characteristics: VideoCharacteristics,
289
- quality_preset: QualityPreset,
290
- params: AutoTunedParams,
291
- ) -> None:
292
- """Print auto-tuned parameters in verbose mode.
293
-
294
- Args:
295
- video: Video processor
296
- characteristics: Video characteristics
297
- quality_preset: Quality preset
298
- params: Auto-tuned parameters
299
- """
300
- click.echo("\n" + "=" * 60, err=True)
301
- click.echo("AUTO-TUNED PARAMETERS", err=True)
302
- click.echo("=" * 60, err=True)
303
- click.echo(f"Video FPS: {video.fps:.2f}", err=True)
304
- click.echo(
305
- f"Tracking quality: {characteristics.tracking_quality} "
306
- f"(avg visibility: {characteristics.avg_visibility:.2f})",
307
- err=True,
308
- )
309
- click.echo(f"Quality preset: {quality_preset.value}", err=True)
310
- click.echo("\nSelected parameters:", err=True)
311
- click.echo(f" smoothing_window: {params.smoothing_window}", err=True)
312
- click.echo(f" polyorder: {params.polyorder}", err=True)
313
- click.echo(f" velocity_threshold: {params.velocity_threshold:.4f}", err=True)
314
- click.echo(f" min_contact_frames: {params.min_contact_frames}", err=True)
315
- click.echo(f" visibility_threshold: {params.visibility_threshold}", err=True)
316
- click.echo(f" detection_confidence: {params.detection_confidence}", err=True)
317
- click.echo(f" tracking_confidence: {params.tracking_confidence}", err=True)
318
- click.echo(f" outlier_rejection: {params.outlier_rejection}", err=True)
319
- click.echo(f" bilateral_filter: {params.bilateral_filter}", err=True)
320
- click.echo(f" use_curvature: {params.use_curvature}", err=True)
321
- click.echo("=" * 60 + "\n", err=True)
322
-
323
-
324
261
  def _extract_positions_and_visibilities(
325
262
  smoothed_landmarks: list,
326
263
  ) -> tuple[np.ndarray, np.ndarray]:
@@ -458,11 +395,11 @@ def _process_single(
458
395
  landmarks_sequence, video.fps, video.frame_count
459
396
  )
460
397
  params = auto_tune_parameters(characteristics, quality_preset)
461
- params = _apply_expert_param_overrides(params, expert_params)
398
+ params = apply_expert_param_overrides(params, expert_params)
462
399
 
463
400
  # Show parameters if verbose
464
401
  if verbose:
465
- _print_auto_tuned_params(video, characteristics, quality_preset, params)
402
+ print_auto_tuned_params(video, quality_preset, params, characteristics)
466
403
 
467
404
  # Apply smoothing
468
405
  smoothed_landmarks = smooth_landmark_sequence(landmarks_sequence, params)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kinemotion
3
- Version: 0.11.3
3
+ Version: 0.11.5
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,27 +1,27 @@
1
1
  kinemotion/__init__.py,sha256=REBC9wrwYC_grvCS00qEOyign65Zc1sc-5buLpyqQxA,654
2
- kinemotion/api.py,sha256=10Rj_dqAa6KCcmCjlGEtQFZLoNyqeMzFLo7vGZcttWY,31586
2
+ kinemotion/api.py,sha256=M6KqzdspOvtJ9Wl555HGe3ITzvRFhPK4xeqcX7IA98s,31463
3
3
  kinemotion/cli.py,sha256=cqYV_7URH0JUDy1VQ_EDLv63FmNO4Ns20m6s1XAjiP4,464
4
4
  kinemotion/cmj/__init__.py,sha256=Ynv0-Oco4I3Y1Ubj25m3h9h2XFqeNwpAewXmAYOmwfU,127
5
5
  kinemotion/cmj/analysis.py,sha256=4HYGn4VDIB6oExAees-VcPfpNgWOltpgwjyNTU7YAb4,18263
6
- kinemotion/cmj/cli.py,sha256=lVVlh8teFHXbDzaFdDfq3xSwRf4kVwyYyd6FU8ta_Ec,19044
6
+ kinemotion/cmj/cli.py,sha256=3CQPJOC3N00dFz_mrEgSHq9pIA-RyOynZoNUIk8RzD0,17040
7
7
  kinemotion/cmj/debug_overlay.py,sha256=ELrSYQ9LmLV81bJS5w9i2c4VwRS0EYAUnMehMHU7VGc,18724
8
8
  kinemotion/cmj/joint_angles.py,sha256=8ucpDGPvbt4iX3tx9eVxJEUv0laTm2Y58_--VzJCogE,9113
9
9
  kinemotion/cmj/kinematics.py,sha256=Xl_PlC2OqMoA-zOc3SRB_GqI0AgLlJol5FTPe5J_qLc,7573
10
10
  kinemotion/core/__init__.py,sha256=3yzDhb5PekDNjydqrs8aWGneUGJBt-lB0SoB_Y2FXqU,1010
11
11
  kinemotion/core/auto_tuning.py,sha256=cvmxUI-CbahpOJQtR2r5jOx4Q6yKPe3DO1o15hOQIdw,10508
12
- kinemotion/core/cli_utils.py,sha256=hNf2-_LIbi-ntXAkovjqcuWifYLazikqJBzeTN9YmZc,3492
12
+ kinemotion/core/cli_utils.py,sha256=iI1bHZxgbzxW5-2X3tTHEy2mqR49o3oIlwFptZ6gCco,6726
13
13
  kinemotion/core/filtering.py,sha256=f-m-aA59e4WqE6u-9MA51wssu7rI-Y_7n1cG8IWdeRQ,11241
14
14
  kinemotion/core/pose.py,sha256=Wfd1RR-2ZznYpWeQUbySwcV3mvReqn8n3XO6S7pGq4M,8390
15
15
  kinemotion/core/smoothing.py,sha256=FON4qKtsSp1-03GnJrDkEUAePaACn4QPMJF0eTIYqR0,12925
16
16
  kinemotion/core/video_io.py,sha256=z8Z0qbNaKbcdB40KnbNOBMzab3BbgnhBxp-mUBYeXgM,6577
17
17
  kinemotion/dropjump/__init__.py,sha256=yc1XiZ9vfo5h_n7PKVSiX2TTgaIfGL7Y7SkQtiDZj_E,838
18
18
  kinemotion/dropjump/analysis.py,sha256=HfJt2t9IsMBiBUz7apIzdxbRH9QqzlFnDVVWcKhU3ow,23291
19
- kinemotion/dropjump/cli.py,sha256=eXO-9H9z0g-EJUD1uIT37KIMgfyje4fPAO2FgZiEZzk,24985
19
+ kinemotion/dropjump/cli.py,sha256=-iBgHNwW_dijHe6_JIEGSBUzvFb6tZV0aopbPd-9jC8,22402
20
20
  kinemotion/dropjump/debug_overlay.py,sha256=GMo-jCl5OPIv82uPxDbBVI7CsAMwATTvxZMeWfs8k8M,8701
21
21
  kinemotion/dropjump/kinematics.py,sha256=RM_O8Kdc6aEiPIu_99N4cu-4EhYSQxtBGASJF_dmQaU,19081
22
22
  kinemotion/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
- kinemotion-0.11.3.dist-info/METADATA,sha256=Yu4EP1FzusXr0Y0KRNIfywzuw0nNYeACUojxFhzrDuE,18990
24
- kinemotion-0.11.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
25
- kinemotion-0.11.3.dist-info/entry_points.txt,sha256=zaqnAnjLvcdrk1Qvj5nvXZCZ2gp0prS7it1zTJygcIY,50
26
- kinemotion-0.11.3.dist-info/licenses/LICENSE,sha256=KZajvqsHw0NoOHOi2q0FZ4NBe9HdV6oey-IPYAtHXfg,1088
27
- kinemotion-0.11.3.dist-info/RECORD,,
23
+ kinemotion-0.11.5.dist-info/METADATA,sha256=gsLG_2Z3qbeG2UpWqp7mfyqWDXj2SpwrsXG5cgh8oEo,18990
24
+ kinemotion-0.11.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
25
+ kinemotion-0.11.5.dist-info/entry_points.txt,sha256=zaqnAnjLvcdrk1Qvj5nvXZCZ2gp0prS7it1zTJygcIY,50
26
+ kinemotion-0.11.5.dist-info/licenses/LICENSE,sha256=KZajvqsHw0NoOHOi2q0FZ4NBe9HdV6oey-IPYAtHXfg,1088
27
+ kinemotion-0.11.5.dist-info/RECORD,,