opensportslib 0.3.0.dev2__tar.gz → 0.3.0.dev4__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.
- {opensportslib-0.3.0.dev2/opensportslib.egg-info → opensportslib-0.3.0.dev4}/PKG-INFO +1 -1
- opensportslib-0.3.0.dev4/opensportslib/configs/localization/h5_header_skeleton.yaml +65 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/loader.py +42 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/data.py +67 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/load_annotations.py +119 -2
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/datasets/localization_dataset.py +412 -2
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/datasets/utils/tracking.py +172 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/metrics/localization_metric.py +4 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/backbones/builder.py +44 -1
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/e2e.py +36 -13
- opensportslib-0.3.0.dev4/opensportslib/models/base/rule_based.py +1144 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4/opensportslib.egg-info}/PKG-INFO +1 -1
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib.egg-info/SOURCES.txt +3 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/pyproject.toml +1 -1
- opensportslib-0.3.0.dev4/scripts/run_header_spotting_eval.py +495 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_config_architecture.py +15 -1
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_config_split_override_sync.py +8 -0
- opensportslib-0.3.0.dev4/tests/test_h5_header_skeleton_spotter.py +305 -0
- opensportslib-0.3.0.dev2/opensportslib/models/base/rule_based.py +0 -579
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/LICENSE +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/LICENSE-COMMERCIAL +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/MANIFEST.in +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/README.md +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/examples/quickstart/basic_classification.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/examples/quickstart/basic_localization.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/examples/quickstart/basic_vqa.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/apis/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/apis/base_task_model.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/apis/classification.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/apis/localization.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/apis/vqa.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/cli.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/classification/default.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/classification/sngar_frames.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/classification/sngar_tracking.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/classification/video.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/default.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/localization/calf_resnetpca512.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/localization/default.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/localization/h5_header_distance.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/localization/h5_header_distance_angle.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/localization/h5_header_distance_speed.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/localization/h5_header_distance_speed_angle.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/localization/h5_header_rule.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/localization/netvladpp_resnetpca512.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/localization/video_dali.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/localization/video_ocv.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/vqa/default.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/vqa/qwen.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/vqa/qwen3_vl_native.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/vqa/qwen_lora.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/vqa/qwen_sngar_frames.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/configs/vqa/xvars.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/accessors.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/conflicts.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/migrate.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/migrations/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/migrations/legacy_to_canonical.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/runtime_adapter.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/schema.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/schemas/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/schemas/schema_canonical.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/schemas/schema_legacy.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/config/validate.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/loss/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/loss/builder.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/loss/calf.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/loss/ce.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/loss/combine.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/loss/nll.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/optimizer/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/optimizer/builder.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/sampler/weighted_sampler.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/scheduler/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/scheduler/builder.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/trainer/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/trainer/classification_trainer.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/trainer/localization_trainer.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/trainer/vqa_trainer.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/checkpoint.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/config.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/config_normalize.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/ddp.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/default_args.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/hf_runtime.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/lightning.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/seed.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/video_processing.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/wandb.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/datasets/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/datasets/builder.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/datasets/classification_dataset.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/datasets/utils/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/datasets/utils/h5_tracking.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/datasets/vqa_dataset.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/legacy_config/classification.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/legacy_config/localization-e2e-ocv.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/legacy_config/localization-json_calf_resnetpca512.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/legacy_config/localization-json_netvlad++_resnetpca512.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/legacy_config/localization.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/legacy_config/sngar-frames.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/legacy_config/sngar-tracking.yaml +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/metrics/classification_metric.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/metrics/vqa_metric.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/contextaware.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/learnablepooling.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/qwen_vl_native.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/qwen_xvars.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/tracking.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/vars.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/video.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/video_chatgpt_compat.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/video_mae.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/base/xvars_videochatgpt.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/builder.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/heads/builder.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/neck/builder.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/common.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/impl/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/impl/asformer.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/impl/calf.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/impl/gsm.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/impl/gtad.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/impl/tsm.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/litebase.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/modules.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/shift.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/utils.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/vqa_prediction_priors.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/vqa_prompting.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/models/utils/xvars_clip_index.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/setup/setup.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/tools/__init__.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/tools/_common.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/tools/hf_transfer.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/tools/osl_json_to_parquet.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/tools/parquet_to_osl_json.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib.egg-info/dependency_links.txt +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib.egg-info/entry_points.txt +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib.egg-info/requires.txt +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib.egg-info/top_level.txt +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/scripts/run_h5_header_rule_inference.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/setup.cfg +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/conftest.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_classification_dataset_paths.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_classification_trainer_dataloader.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_config_utils_smoke.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_conversion_tools.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_extract_xvars_features.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_h5_header_rule_spotter.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_h5_tracking_dataset.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_hf_transfer_tools.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_localization_dali_filenames.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_package_smoke.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_pretrained_config_merge_policy.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_public_apis_smoke.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_setup_cli.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_subset_train_infer_integration.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_task_model_api_contract.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_vqa_api.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_vqa_metrics_semantic.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_vqa_qwen_xvars.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_vqa_training_lora.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tests/test_vqa_xvars_videochatgpt.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/convert/build_sn_vqa_2026_vqa.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/convert/build_soccernet_gar.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/convert/build_soccernet_gar_action_spotting.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/convert/build_soccernet_gar_vqa.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/convert/build_xvars_indexes.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/convert/extract_xvars_clip_features.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/convert/osl_json_to_parquet_webdataset.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/convert/parquet_webdataset_to_osl_json.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/download/download_hf_repo.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/download/download_osl_hf.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/download/upload_osl_hf.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/training/classification.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/training/localization.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/training/vqa.py +0 -0
- {opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/tools/upload/upload_model_hf.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensportslib
|
|
3
|
-
Version: 0.3.0.
|
|
3
|
+
Version: 0.3.0.dev4
|
|
4
4
|
Summary: OpenSportsLib is the professional library, designed for advanced video understanding in sports. It provides state-of-the-art tools for action recognition, spotting, retrieval, and captioning, making it ideal for researchers, analysts, and developers working with sports video data.
|
|
5
5
|
Author: Jeet Vora
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
TASK: localization
|
|
2
|
+
VERSION: 2
|
|
3
|
+
|
|
4
|
+
SYSTEM:
|
|
5
|
+
paths:
|
|
6
|
+
work_dir: ./outputs/header_spotting_skeleton
|
|
7
|
+
device: cpu
|
|
8
|
+
gpu:
|
|
9
|
+
count: 0
|
|
10
|
+
|
|
11
|
+
DATA:
|
|
12
|
+
common:
|
|
13
|
+
dataset_name: h5_headers
|
|
14
|
+
data_root: /home/giancos/FIFA_data/128083
|
|
15
|
+
classes:
|
|
16
|
+
- header
|
|
17
|
+
splits:
|
|
18
|
+
test:
|
|
19
|
+
type: H5OSLJsonSpotting
|
|
20
|
+
# Manifest listing the joints/ball h5 pair and the scan window; the
|
|
21
|
+
# eval scripts generate one per run under their own work dir.
|
|
22
|
+
annotation_path: ./outputs/header_wc22/manifest.json
|
|
23
|
+
source_path: /home/giancos/FIFA_data/128083
|
|
24
|
+
dataloader:
|
|
25
|
+
batch_size: 1
|
|
26
|
+
shuffle: false
|
|
27
|
+
num_workers: 0
|
|
28
|
+
pin_memory: false
|
|
29
|
+
inputs:
|
|
30
|
+
tracking:
|
|
31
|
+
modality: player_joints_h5
|
|
32
|
+
representation: raw
|
|
33
|
+
source:
|
|
34
|
+
format: h5
|
|
35
|
+
sampling: {}
|
|
36
|
+
transform: {}
|
|
37
|
+
augmentations: {}
|
|
38
|
+
params: {}
|
|
39
|
+
|
|
40
|
+
MODEL:
|
|
41
|
+
metadata:
|
|
42
|
+
family: RuleBased
|
|
43
|
+
runner:
|
|
44
|
+
type: runner_h5_header_rule
|
|
45
|
+
components:
|
|
46
|
+
rule:
|
|
47
|
+
kind: algorithm
|
|
48
|
+
source:
|
|
49
|
+
provider: opensportslib
|
|
50
|
+
registry: rule_based
|
|
51
|
+
name: h5_header_skeleton
|
|
52
|
+
# Thresholds default to DEFAULT_SKELETON_RULE_PARAMS in
|
|
53
|
+
# opensportslib/models/base/rule_based.py. Override here only what this
|
|
54
|
+
# run needs to differ — restating a default pins it, so later tuning of
|
|
55
|
+
# the defaults would silently not reach this config.
|
|
56
|
+
params:
|
|
57
|
+
label: header
|
|
58
|
+
head_name: action
|
|
59
|
+
topology: []
|
|
60
|
+
|
|
61
|
+
TRAIN:
|
|
62
|
+
trainer:
|
|
63
|
+
type: trainer_rule_based
|
|
64
|
+
execution:
|
|
65
|
+
enabled: false
|
|
@@ -20,6 +20,10 @@ from .runtime_adapter import maybe_namespace, namespace_to_plain_dict
|
|
|
20
20
|
_YAML_SUFFIXES = {".yaml", ".yml"}
|
|
21
21
|
_TASK_DIRS = {"classification", "localization", "vqa"}
|
|
22
22
|
_INTERPOLATION_RE = re.compile(r"\$\{([^}]+)\}")
|
|
23
|
+
_CPU_OPENCV_SPLIT_TYPES = {
|
|
24
|
+
"VideoGameWithDali": "VideoGameWithOpencv",
|
|
25
|
+
"VideoGameWithDaliVideo": "VideoGameWithOpencvVideo",
|
|
26
|
+
}
|
|
23
27
|
|
|
24
28
|
|
|
25
29
|
def _load_single_yaml(path: str | Path) -> Any:
|
|
@@ -131,6 +135,42 @@ def load_raw_config(path: str | Path) -> dict[str, Any]:
|
|
|
131
135
|
raise ValueError("Unsupported config format. Use YAML or JSON.")
|
|
132
136
|
|
|
133
137
|
|
|
138
|
+
def _normalize_cpu_loader_backend(payload: dict[str, Any]) -> dict[str, Any]:
|
|
139
|
+
system = payload.get("SYSTEM", {})
|
|
140
|
+
if not isinstance(system, dict):
|
|
141
|
+
return payload
|
|
142
|
+
|
|
143
|
+
if str(system.get("device", "auto")).lower() != "cpu":
|
|
144
|
+
return payload
|
|
145
|
+
|
|
146
|
+
data = payload.get("DATA", {})
|
|
147
|
+
if not isinstance(data, dict):
|
|
148
|
+
return payload
|
|
149
|
+
|
|
150
|
+
common = data.get("common", {})
|
|
151
|
+
if not isinstance(common, dict):
|
|
152
|
+
return payload
|
|
153
|
+
|
|
154
|
+
runtime = common.get("runtime", {})
|
|
155
|
+
if not isinstance(runtime, dict):
|
|
156
|
+
runtime = {}
|
|
157
|
+
common["runtime"] = runtime
|
|
158
|
+
runtime["loader_backend"] = "opencv"
|
|
159
|
+
|
|
160
|
+
splits = common.get("splits", {})
|
|
161
|
+
if not isinstance(splits, dict):
|
|
162
|
+
return payload
|
|
163
|
+
|
|
164
|
+
for split_cfg in splits.values():
|
|
165
|
+
if not isinstance(split_cfg, dict):
|
|
166
|
+
continue
|
|
167
|
+
split_type = split_cfg.get("type")
|
|
168
|
+
if split_type in _CPU_OPENCV_SPLIT_TYPES:
|
|
169
|
+
split_cfg["type"] = _CPU_OPENCV_SPLIT_TYPES[split_type]
|
|
170
|
+
|
|
171
|
+
return payload
|
|
172
|
+
|
|
173
|
+
|
|
134
174
|
def load_config(
|
|
135
175
|
config_path: str | Path,
|
|
136
176
|
*,
|
|
@@ -139,6 +179,7 @@ def load_config(
|
|
|
139
179
|
) -> Any:
|
|
140
180
|
raw = load_raw_config(config_path)
|
|
141
181
|
canonical = migrate_config(raw, as_namespace=False)
|
|
182
|
+
canonical = _normalize_cpu_loader_backend(canonical)
|
|
142
183
|
assert_no_legacy_aliases(canonical)
|
|
143
184
|
|
|
144
185
|
if validate:
|
|
@@ -168,6 +209,7 @@ def resolve_config(
|
|
|
168
209
|
) -> Any:
|
|
169
210
|
payload = namespace_to_plain_dict(config)
|
|
170
211
|
canonical = migrate_config(payload, as_namespace=False)
|
|
212
|
+
canonical = _normalize_cpu_loader_backend(canonical)
|
|
171
213
|
assert_no_legacy_aliases(canonical)
|
|
172
214
|
return maybe_namespace(canonical, as_namespace=as_namespace)
|
|
173
215
|
|
|
@@ -83,6 +83,73 @@ def tracking_collate_fn(batch):
|
|
|
83
83
|
'id': [item['id'] for item in batch],
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
|
|
87
|
+
def _flatten_graphs_to_batch(list_of_graph_lists):
|
|
88
|
+
"""Flatten a batch of per-sample per-frame graph lists into one PyG Batch.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
list_of_graph_lists: list of length B, each a list of T
|
|
92
|
+
torch_geometric.data.Data objects (one per frame in the clip).
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
A torch_geometric.data.Batch of all B*T graphs, with a plain int
|
|
96
|
+
`.seq_len` attribute (T) attached so a graph_conv_seq backbone can
|
|
97
|
+
reshape the pooled per-frame embeddings back to (B, T, H). Plain
|
|
98
|
+
int attributes survive Batch.to(device).
|
|
99
|
+
"""
|
|
100
|
+
try:
|
|
101
|
+
from torch_geometric.data import Batch
|
|
102
|
+
except ImportError as exc:
|
|
103
|
+
raise ImportError(
|
|
104
|
+
"torch-geometric is required for tracking spotting collate functions. "
|
|
105
|
+
"Run: `opensportslib setup --pyg` to install the correct version "
|
|
106
|
+
"based on your system (PyTorch & CUDA compatible)."
|
|
107
|
+
) from exc
|
|
108
|
+
|
|
109
|
+
seq_len = len(list_of_graph_lists[0])
|
|
110
|
+
all_graphs = [g for graphs in list_of_graph_lists for g in graphs]
|
|
111
|
+
batched = Batch.from_data_list(all_graphs)
|
|
112
|
+
batched.seq_len = seq_len
|
|
113
|
+
return batched
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def tracking_spotting_collate_fn(batch):
|
|
117
|
+
"""
|
|
118
|
+
Collate function for tracking-based action-spotting training clips.
|
|
119
|
+
Flattens the B*T per-frame graphs of a batch into one PyG Batch (see
|
|
120
|
+
_flatten_graphs_to_batch) and stacks the dense per-frame labels into
|
|
121
|
+
(B, T).
|
|
122
|
+
"""
|
|
123
|
+
frame = _flatten_graphs_to_batch([item["graphs"] for item in batch])
|
|
124
|
+
labels = torch.as_tensor(
|
|
125
|
+
np.stack([item["label"] for item in batch]), dtype=torch.long
|
|
126
|
+
)
|
|
127
|
+
return {
|
|
128
|
+
"frame": frame,
|
|
129
|
+
"label": labels,
|
|
130
|
+
"contains_event": torch.tensor(
|
|
131
|
+
[item["contains_event"] for item in batch], dtype=torch.long
|
|
132
|
+
),
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def tracking_spotting_eval_collate_fn(batch):
|
|
137
|
+
"""
|
|
138
|
+
Collate function for tracking-based action-spotting sliding-window eval
|
|
139
|
+
clips. Requires dataloader batch_size=1 (mirrors how the E2E inferer
|
|
140
|
+
reads clip["frame"][0] for RGB datasets): wraps the single clip's
|
|
141
|
+
flattened PyG Batch in a 1-element list under "frame" so that indexing
|
|
142
|
+
keeps working unmodified.
|
|
143
|
+
"""
|
|
144
|
+
assert len(batch) == 1, "tracking spotting eval requires dataloader batch_size=1"
|
|
145
|
+
item = batch[0]
|
|
146
|
+
frame = _flatten_graphs_to_batch([item["graphs"]])
|
|
147
|
+
return {
|
|
148
|
+
"video": [item["video"]],
|
|
149
|
+
"start": torch.tensor([item["start"]]),
|
|
150
|
+
"frame": [frame],
|
|
151
|
+
}
|
|
152
|
+
|
|
86
153
|
def mixup_data(x, y, alpha=0.2):
|
|
87
154
|
"""blend pairs of samples and their labels for mixup augmentation."""
|
|
88
155
|
lam = np.random.beta(alpha, alpha) if alpha > 0 else 1.0
|
{opensportslib-0.3.0.dev2 → opensportslib-0.3.0.dev4}/opensportslib/core/utils/load_annotations.py
RENAMED
|
@@ -4,6 +4,7 @@ import tqdm
|
|
|
4
4
|
import logging
|
|
5
5
|
import cv2
|
|
6
6
|
import math
|
|
7
|
+
import numpy as np
|
|
7
8
|
import torch
|
|
8
9
|
from opensportslib.core.utils.video_processing import get_stride, read_fps, get_num_frames
|
|
9
10
|
from opensportslib.core.utils.config import load_json
|
|
@@ -302,6 +303,116 @@ def annotationstoe2eformat(
|
|
|
302
303
|
|
|
303
304
|
return labels_e2e, task_name_list[0]
|
|
304
305
|
|
|
306
|
+
|
|
307
|
+
def annotationstoe2eformat_tracking(label_files, video_dirs, extract_fps):
|
|
308
|
+
"""
|
|
309
|
+
Adapt tracking-parquet action-spotting annotations to E2E format.
|
|
310
|
+
|
|
311
|
+
Mirrors annotationstoe2eformat's output schema, but reads a whole-match
|
|
312
|
+
tracking parquet (via the per-game cache built by
|
|
313
|
+
opensportslib.datasets.utils.tracking.load_or_build_game_cache) instead
|
|
314
|
+
of a video file. Each event's position_ms is mapped to a native frame
|
|
315
|
+
index via a searchsorted lookup on the cached videoTimeMs column (the
|
|
316
|
+
absolute match clock, which lines up directly with position_ms) rather
|
|
317
|
+
than the from-scratch fps computation the video path uses, then
|
|
318
|
+
converted to a decimated (extract_fps) frame index the same way
|
|
319
|
+
FrameReader converts native video frames.
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
label_files (str | list[str]): Annotation JSON files.
|
|
323
|
+
video_dirs (str | list[str]): Root directories containing the
|
|
324
|
+
tracking parquets referenced by each annotation file.
|
|
325
|
+
extract_fps (float): Target fps to decimate the native tracking
|
|
326
|
+
stream to. A non-positive value keeps every native frame.
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
(labels_e2e, task_name): labels_e2e is a list of dicts with the
|
|
330
|
+
same keys as annotationstoe2eformat's output (events/fps/
|
|
331
|
+
num_frames/num_frames_base/video/path/num_events), plus a
|
|
332
|
+
"stride" field (native rows per decimated frame) that dataset
|
|
333
|
+
classes use to slice windows out of the cached native features.
|
|
334
|
+
"""
|
|
335
|
+
from opensportslib.datasets.utils.tracking import load_or_build_game_cache
|
|
336
|
+
|
|
337
|
+
if not isinstance(label_files, list):
|
|
338
|
+
label_files = [label_files]
|
|
339
|
+
if not isinstance(video_dirs, list):
|
|
340
|
+
video_dirs = [video_dirs]
|
|
341
|
+
assert len(label_files) == len(video_dirs)
|
|
342
|
+
|
|
343
|
+
labels_e2e = []
|
|
344
|
+
classes_by_label_dir = []
|
|
345
|
+
task_name_list = []
|
|
346
|
+
|
|
347
|
+
for label_path, video_dir in zip(label_files, video_dirs):
|
|
348
|
+
logging.info(f"Processing {label_path} to e2e format (tracking)")
|
|
349
|
+
|
|
350
|
+
annotations = load_json(label_path)
|
|
351
|
+
|
|
352
|
+
for task_name, task_data in annotations["labels"].items():
|
|
353
|
+
labels = task_data.get("labels", {})
|
|
354
|
+
task_name_list.append(task_name)
|
|
355
|
+
classes_by_label_dir.append(labels)
|
|
356
|
+
|
|
357
|
+
videos = annotations["data"]
|
|
358
|
+
|
|
359
|
+
for video in tqdm.tqdm(videos):
|
|
360
|
+
video_input = video["inputs"][0]
|
|
361
|
+
video_path = video_input["path"]
|
|
362
|
+
full_video_path = os.path.join(video_dir, video_path)
|
|
363
|
+
assert os.path.isfile(full_video_path), full_video_path
|
|
364
|
+
|
|
365
|
+
_, times, _ = load_or_build_game_cache(full_video_path)
|
|
366
|
+
num_frames = len(times)
|
|
367
|
+
|
|
368
|
+
native_fps = video_input.get("fps")
|
|
369
|
+
if not native_fps:
|
|
370
|
+
native_fps = 1000.0 / float(np.median(np.diff(times)))
|
|
371
|
+
|
|
372
|
+
target_fps = (
|
|
373
|
+
extract_fps if (extract_fps and extract_fps < native_fps) else native_fps
|
|
374
|
+
)
|
|
375
|
+
sample_fps = read_fps(native_fps, target_fps)
|
|
376
|
+
stride = get_stride(native_fps, target_fps)
|
|
377
|
+
num_frames_after = get_num_frames(num_frames, native_fps, target_fps)
|
|
378
|
+
|
|
379
|
+
events = []
|
|
380
|
+
for ann in video.get("events", []):
|
|
381
|
+
position_ms = float(ann["position_ms"])
|
|
382
|
+
native_idx = int(np.searchsorted(times, position_ms))
|
|
383
|
+
native_idx = min(max(native_idx, 0), num_frames - 1)
|
|
384
|
+
adj_frame = native_idx // stride
|
|
385
|
+
|
|
386
|
+
if adj_frame == 0:
|
|
387
|
+
adj_frame = 1
|
|
388
|
+
|
|
389
|
+
events.append({
|
|
390
|
+
"frame": int(adj_frame),
|
|
391
|
+
"label": ann["label"],
|
|
392
|
+
})
|
|
393
|
+
|
|
394
|
+
events.sort(key=lambda x: x["frame"])
|
|
395
|
+
|
|
396
|
+
labels_e2e.append({
|
|
397
|
+
"events": events,
|
|
398
|
+
"fps": sample_fps,
|
|
399
|
+
"num_frames": num_frames_after,
|
|
400
|
+
"num_frames_base": num_frames,
|
|
401
|
+
"num_events": len(events),
|
|
402
|
+
"video": full_video_path,
|
|
403
|
+
"path": video_path,
|
|
404
|
+
"stride": stride,
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
base_classes = classes_by_label_dir[0]
|
|
408
|
+
for c in classes_by_label_dir:
|
|
409
|
+
assert c == base_classes
|
|
410
|
+
|
|
411
|
+
labels_e2e.sort(key=lambda x: x["video"])
|
|
412
|
+
|
|
413
|
+
return labels_e2e, task_name_list[0]
|
|
414
|
+
|
|
415
|
+
|
|
305
416
|
# def annotationstoe2eformat(label_files, video_dirs, input_fps, extract_fps, dali):
|
|
306
417
|
# """Adapt annotations jsons to e2e format.
|
|
307
418
|
|
|
@@ -496,7 +607,7 @@ def check_config(cfg, split="train"):
|
|
|
496
607
|
if get_loader_backend(cfg) == "dali":
|
|
497
608
|
cfg.TRAIN.execution.repartitions = get_repartition_gpu(cfg.SYSTEM.gpu.count)
|
|
498
609
|
primary_modality = get_data_modality(cfg)
|
|
499
|
-
assert primary_modality in ["rgb", "video"]
|
|
610
|
+
assert primary_modality in ["rgb", "video", "tracking_parquet"]
|
|
500
611
|
backbone_type = get_component_name_by_kind(cfg, "encoder")
|
|
501
612
|
assert backbone_type in [
|
|
502
613
|
# From torchvision
|
|
@@ -513,6 +624,8 @@ def check_config(cfg, split="train"):
|
|
|
513
624
|
"rny008",
|
|
514
625
|
"rny008_tsm",
|
|
515
626
|
"rny008_gsm",
|
|
627
|
+
# tracking graph encoder, sequence output (see models/backbones/builder.py)
|
|
628
|
+
"graph_conv_seq",
|
|
516
629
|
# From timm
|
|
517
630
|
"convnextt",
|
|
518
631
|
"convnextt_tsm",
|
|
@@ -588,7 +701,11 @@ def whether_infer_split(cfg):
|
|
|
588
701
|
return True
|
|
589
702
|
else:
|
|
590
703
|
return False
|
|
591
|
-
elif split_type
|
|
704
|
+
elif split_type in (
|
|
705
|
+
"VideoGameWithOpencvVideo",
|
|
706
|
+
"VideoGameWithDaliVideo",
|
|
707
|
+
"TrackingActionSpotVideo",
|
|
708
|
+
):
|
|
592
709
|
if annotation_path and annotation_path.endswith(".json"):
|
|
593
710
|
return True
|
|
594
711
|
else:
|