OTVision 0.6.8__tar.gz → 0.6.9__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.
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/abstraction/pipes_and_filter.py +4 -4
- otvision-0.6.9/OTVision/application/buffer.py +28 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/config_parser.py +51 -2
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/detect/current_object_detector.py +2 -4
- otvision-0.6.9/OTVision/application/event/new_otvision_config.py +6 -0
- otvision-0.6.8/OTVision/application/detect/detection_file_save_path_provider.py → otvision-0.6.9/OTVision/application/otvision_save_path_provider.py +8 -7
- otvision-0.6.9/OTVision/application/track/ottrk.py +203 -0
- otvision-0.6.9/OTVision/application/track/tracking_run_id.py +35 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/builder.py +8 -14
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/detected_frame_buffer.py +13 -1
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/detected_frame_producer.py +2 -2
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/detected_frame_producer_factory.py +4 -8
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/otdet.py +109 -41
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/otdet_file_writer.py +52 -29
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/rtsp_input_source.py +15 -3
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/video_input_source.py +8 -8
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/yolo.py +3 -7
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/detect_producer_consumer.py +3 -3
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/frame.py +12 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/input_source_detect.py +3 -3
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/object_detection.py +4 -6
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/helpers/date.py +16 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/plugin/ffmpeg_video_writer.py +2 -4
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/builder.py +2 -5
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/id_generator.py +1 -3
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/parser/chunk_parser_plugins.py +1 -19
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/parser/frame_group_parser_plugins.py +19 -74
- otvision-0.6.9/OTVision/track/stream_ottrk_file_writer.py +116 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/track.py +2 -1
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/version.py +1 -1
- {otvision-0.6.8 → otvision-0.6.9}/PKG-INFO +1 -1
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/test_buffer.py +6 -34
- otvision-0.6.9/tests/application/test_config_parser.py +136 -0
- otvision-0.6.8/tests/application/detect/test_detection_file_save_path_provider.py → otvision-0.6.9/tests/application/test_otvision_save_path_provider.py +11 -11
- otvision-0.6.9/tests/application/track/test_ottrk.py +449 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/test_otdet.py +2 -1
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/test_otdet_file_writer.py +11 -6
- {otvision-0.6.8 → otvision-0.6.9}/tests/track/test_frame_group_parser_plugins.py +3 -3
- otvision-0.6.9/tests/track/test_stream_ottrk_file_writer.py +413 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/track/test_track.py +1 -1
- otvision-0.6.8/OTVision/application/buffer.py +0 -35
- {otvision-0.6.8 → otvision-0.6.9}/.editorconfig +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.flake8 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.github/dependabot.yml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.github/workflows/build-nightly.yml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.github/workflows/build-release.yml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.github/workflows/linter.yml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.github/workflows/release-pypi.yml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.github/workflows/release-testpypi.yml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.github/workflows/test.yml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.gitignore +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.pre-commit-config.yaml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.vscode/launch.json +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.vscode/scripts/build_debug_env.cmd +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.vscode/scripts/build_debug_env.sh +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.vscode/scripts/teardown_debug_env.cmd +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.vscode/scripts/teardown_debug_env.sh +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.vscode/settings.json +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.vscode/tasks.json +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/.yamllint.yaml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/LICENSE +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/abstraction/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/abstraction/defaults.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/abstraction/observer.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/config.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/configure_logger.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/detect/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/detect/current_object_detector_metadata.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/detect/detected_frame_factory.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/detect/factory.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/detect/get_detect_cli_args.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/detect/timestamper.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/detect/update_detect_config_with_cli_args.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/event/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/event/new_video_start.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/frame_count_provider.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/get_config.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/get_current_config.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/track/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/track/get_track_cli_args.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/track/update_current_track_config.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/track/update_track_config_with_cli_args.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/update_current_config.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/video/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/application/video/generate_video.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/config.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/convert/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/convert/convert.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/dataformat.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/cli.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/detect.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/file_based_detect_builder.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/plugin_av/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/plugin_av/rotate_frame.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/pyav_frame_count_provider.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/rtsp_based_detect_builder.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/detect/timestamper.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/cli.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/current_config.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/detection.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/serialization.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/time.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/domain/video_writer.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/helpers/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/helpers/files.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/helpers/formats.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/helpers/input_types.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/helpers/log.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/helpers/machine.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/helpers/video.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/plugin/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/plugin/generate_video.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/plugin/yaml_serialization.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/cli.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/exporter/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/exporter/filebased_exporter.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/model/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/model/filebased/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/model/filebased/frame_chunk.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/model/filebased/frame_group.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/model/track_exporter.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/model/tracking_interfaces.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/parser/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/tracker/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/tracker/filebased_tracking.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/track/tracker/tracker_plugin_iou.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/transform/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/transform/get_homography.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/transform/reference_points_picker.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/transform/transform.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/view/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/view/helpers/OTC.ico +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/view/view.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/view/view_convert.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/view/view_detect.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/view/view_helpers.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/view/view_track.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision/view/view_transform.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/OTVision.bat +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/README.md +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/clean-up-repository.sh +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/config.yml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/convert.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/detect.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/export_models.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/generate_video.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/install.cmd +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/install.sh +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/install_dev.cmd +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/install_dev.sh +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/pyproject.toml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/reference_points_picker.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/requirements-dev.txt +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/requirements.txt +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/abstraction/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/abstraction/test_defaults.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/abstraction/test_observer.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/detect/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/detect/test_current_object_detector.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/detect/test_detected_frame_factory.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/detect/test_get_detect_cli_args.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/detect/test_timestamper.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/detect/test_update_detect_config_with_cli_args.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/test_get_config.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/track/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/track/test_get_track_cli_args.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/track/test_update_current_track_config.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/application/track/test_update_track_config_with_cli_args.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/cli/custom_cli_test_config.yaml +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/cli/test_convert_cli.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/cli/test_detect_cli.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/cli/test_track_cli.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/conftest.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/convert/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/convert/test_convert.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_CamView.png +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_CamView_Cars-Cyclist.png +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_CamView_Cars-Truck.png +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_CamView_refpts.png +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.gpkg +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otrfpts +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.gpkg +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otrfpts +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_FR20.otrfpts +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Satellite.jpg +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/Testvideo_Satellite_far.jpg +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/fail_fps_from_filename/Testvideo_Cars-Cyclist_F20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/fail_fps_from_filename/Testvideo_Cars-Truck_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/fps_from_filename/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/fps_from_filename/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/fps_from_filename/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/fps_from_filename/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/input_fps_20/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/input_fps_20/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/input_fps_20/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/input_fps_20/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/input_fps_40/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/input_fps_40/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/input_fps_40/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/input_fps_40/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.avi +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.avi +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mkv +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mkv +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mov +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mov +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/rotation/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00_rotate.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/rotation/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00_rotate.mov +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/rotation/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00_rotate.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/rotation/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00_rotate.h264 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/rotation/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00_rotate.mov +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/convert/rotation/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00_rotate.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/detect/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/detect/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/detect/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/detect/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/detect/rotated-Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/log/_otvision_logs/test.log +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_min_10/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_min_10/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_min_10/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_min_10/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_min_3/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_min_3/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_min_3/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_min_3/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_miss_max_25/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_miss_max_25/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_miss_max_25/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_miss_max_25/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_miss_max_75/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_miss_max_75/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_miss_max_75/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/track/t_miss_max_75/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/transform/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.gpkg +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/transform/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otrfpts +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/transform/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/transform/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.gpkg +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/transform/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otrfpts +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/transform/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/transform/Testvideo_FR20.otrfpts +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/yolov8m.mlpackage/Data/com.apple.CoreML/model.mlmodel +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/yolov8m.mlpackage/Data/com.apple.CoreML/weights/weight.bin +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/data/yolov8m.mlpackage/Manifest.json +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/detect_test.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/plugin_av/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/plugin_av/test_rotate_frame.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/test_detected_frame_buffer.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/test_detected_frame_producer.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/test_detected_frame_producer_factory.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/test_pyav_frame_count_provider.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/test_rtsp_input_source.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/test_video_input_source.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/detect/yolo_test.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/helpers/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/helpers/files_test.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/helpers/formats_test.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/helpers/test_log.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/log/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/log/log_maker.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/log/test_log.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/plugin/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/plugin/test_ffmpeg_video_file_writer.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/test_config.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/track/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/track/helper/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/track/helper/data_builder.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/track/parser/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/track/parser/test_chunk_parser_plugins.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/track/test_frame_chunk.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/track/test_frame_group.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/track/test_tracking_data_structures.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/transform/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/transform/test_transform.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/utils/__init__.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/utils/generator.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/tests/utils/mocking.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/track.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/transform.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/update_precommit.py +0 -0
- {otvision-0.6.8 → otvision-0.6.9}/view.py +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
-
from typing import
|
|
2
|
+
from typing import Iterator
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class Filter[IN, OUT](ABC):
|
|
@@ -14,14 +14,14 @@ class Filter[IN, OUT](ABC):
|
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
16
|
@abstractmethod
|
|
17
|
-
def filter(self, pipe:
|
|
17
|
+
def filter(self, pipe: Iterator[IN]) -> Iterator[OUT]:
|
|
18
18
|
"""Process elements from the input pipe and produce output elements.
|
|
19
19
|
|
|
20
20
|
Args:
|
|
21
|
-
pipe (
|
|
21
|
+
pipe (Iterator[IN]): Input stream of elements to be processed.
|
|
22
22
|
|
|
23
23
|
Returns:
|
|
24
|
-
|
|
24
|
+
Iterator[OUT]: Output stream of processed elements.
|
|
25
25
|
|
|
26
26
|
"""
|
|
27
27
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from abc import abstractmethod
|
|
2
|
+
from typing import Iterator
|
|
3
|
+
|
|
4
|
+
from OTVision.abstraction.pipes_and_filter import Filter
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Buffer[T, OBSERVING_TYPE](Filter[T, T]):
|
|
8
|
+
def __init__(self) -> None:
|
|
9
|
+
self._buffer: list[T] = []
|
|
10
|
+
|
|
11
|
+
def filter(self, pipe: Iterator[T]) -> Iterator[T]:
|
|
12
|
+
for element in pipe:
|
|
13
|
+
self.buffer(element)
|
|
14
|
+
yield element
|
|
15
|
+
|
|
16
|
+
def buffer(self, to_buffer: T) -> None:
|
|
17
|
+
self._buffer.append(to_buffer)
|
|
18
|
+
|
|
19
|
+
def _get_buffered_elements(self) -> list[T]:
|
|
20
|
+
return self._buffer
|
|
21
|
+
|
|
22
|
+
def _reset_buffer(self) -> None:
|
|
23
|
+
del self._buffer
|
|
24
|
+
self._buffer = list()
|
|
25
|
+
|
|
26
|
+
@abstractmethod
|
|
27
|
+
def on_flush(self, event: OBSERVING_TYPE) -> None:
|
|
28
|
+
raise NotImplementedError
|
|
@@ -75,14 +75,21 @@ from OTVision.application.config import (
|
|
|
75
75
|
from OTVision.domain.serialization import Deserializer
|
|
76
76
|
|
|
77
77
|
|
|
78
|
+
class InvalidOtvisionConfigError(Exception):
|
|
79
|
+
pass
|
|
80
|
+
|
|
81
|
+
|
|
78
82
|
class ConfigParser:
|
|
79
83
|
|
|
80
84
|
def __init__(self, deserializer: Deserializer) -> None:
|
|
81
85
|
self._deserialize = deserializer
|
|
82
86
|
|
|
83
87
|
def parse(self, file: Path) -> Config:
|
|
84
|
-
|
|
85
|
-
|
|
88
|
+
raw_data = self._deserialize.deserialize(file)
|
|
89
|
+
config = self.parse_from_dict(raw_data)
|
|
90
|
+
|
|
91
|
+
self.validate_config(config)
|
|
92
|
+
return config
|
|
86
93
|
|
|
87
94
|
def parse_from_dict(self, d: dict) -> Config:
|
|
88
95
|
log_dict = d.get(LOG)
|
|
@@ -286,3 +293,45 @@ class ConfigParser:
|
|
|
286
293
|
save_dir=save_dir,
|
|
287
294
|
flush_buffer_size=flush_buffer_size,
|
|
288
295
|
)
|
|
296
|
+
|
|
297
|
+
def validate_config(self, config: Config) -> None:
|
|
298
|
+
self.validate_flush_buffer_support_track_lifecycle(config)
|
|
299
|
+
|
|
300
|
+
def validate_flush_buffer_support_track_lifecycle(self, config: Config) -> None:
|
|
301
|
+
"""Validate that the flush buffer size supports complete track lifecycle.
|
|
302
|
+
|
|
303
|
+
In streaming mode, the flush buffer size must be larger than the tracking
|
|
304
|
+
parameters t_min and t_miss_max to ensure tracks can complete their full
|
|
305
|
+
lifecycle before being flushed. This prevents premature flushing of
|
|
306
|
+
unfinished tracks.
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
config (Config): The configuration to validate
|
|
310
|
+
|
|
311
|
+
Raises:
|
|
312
|
+
InvalidOtvisionConfigError: If the flush buffer size is not greater
|
|
313
|
+
than both t_min and t_miss_max values
|
|
314
|
+
|
|
315
|
+
Note:
|
|
316
|
+
This validation only applies when stream configuration is present.
|
|
317
|
+
The constraint ensures that:
|
|
318
|
+
- Tracks have enough frames to reach minimum track length (t_min)
|
|
319
|
+
- Tracks can handle maximum missing frames (t_miss_max) before completion
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
if config.stream is None:
|
|
323
|
+
return
|
|
324
|
+
|
|
325
|
+
flush_buffer_size = config.stream.flush_buffer_size
|
|
326
|
+
if (
|
|
327
|
+
config.track.t_min < flush_buffer_size
|
|
328
|
+
and config.track.t_miss_max < flush_buffer_size
|
|
329
|
+
):
|
|
330
|
+
return
|
|
331
|
+
|
|
332
|
+
raise InvalidOtvisionConfigError(
|
|
333
|
+
f"The flush buffer size ({flush_buffer_size}) must be greater than the "
|
|
334
|
+
f"t_min ({config.track.t_min}) and t_miss_max "
|
|
335
|
+
f"({config.track.t_miss_max}) values to allow tracks to complete "
|
|
336
|
+
"before flushing."
|
|
337
|
+
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Iterator
|
|
2
2
|
|
|
3
3
|
from OTVision.abstraction.pipes_and_filter import Filter
|
|
4
4
|
from OTVision.application.get_current_config import GetCurrentConfig
|
|
@@ -33,7 +33,5 @@ class CurrentObjectDetector(Filter[Frame, DetectedFrame]):
|
|
|
33
33
|
detect_config = self._get_current_config.get().detect
|
|
34
34
|
return self._factory.create(detect_config)
|
|
35
35
|
|
|
36
|
-
def filter(
|
|
37
|
-
self, pipe: Generator[Frame, None, None]
|
|
38
|
-
) -> Generator[DetectedFrame, None, None]:
|
|
36
|
+
def filter(self, pipe: Iterator[Frame]) -> Iterator[DetectedFrame]:
|
|
39
37
|
return self.get().detect(pipe)
|
|
@@ -3,8 +3,9 @@ from pathlib import Path
|
|
|
3
3
|
from OTVision.application.get_current_config import GetCurrentConfig
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class
|
|
7
|
-
"""Provides a mechanism to generate file save paths for
|
|
6
|
+
class OtvisionSavePathProvider:
|
|
7
|
+
"""Provides a mechanism to generate file save paths for OTVision tasks such as
|
|
8
|
+
detect and track.
|
|
8
9
|
|
|
9
10
|
This class is responsible for deriving the appropriate filenames for
|
|
10
11
|
detection files based on the source and current configuration
|
|
@@ -19,11 +20,11 @@ class DetectionFileSavePathProvider:
|
|
|
19
20
|
def __init__(self, get_current_config: GetCurrentConfig) -> None:
|
|
20
21
|
self._get_current_config = get_current_config
|
|
21
22
|
|
|
22
|
-
def provide(self, source: str) -> Path:
|
|
23
|
+
def provide(self, source: str, file_type: str) -> Path:
|
|
23
24
|
config = self._get_current_config.get()
|
|
24
25
|
return derive_filename(
|
|
25
26
|
video_file=Path(source),
|
|
26
|
-
|
|
27
|
+
file_type=file_type,
|
|
27
28
|
detect_start=config.detect.detect_start,
|
|
28
29
|
detect_end=config.detect.detect_end,
|
|
29
30
|
)
|
|
@@ -31,7 +32,7 @@ class DetectionFileSavePathProvider:
|
|
|
31
32
|
|
|
32
33
|
def derive_filename(
|
|
33
34
|
video_file: Path,
|
|
34
|
-
|
|
35
|
+
file_type: str,
|
|
35
36
|
detect_start: int | None = None,
|
|
36
37
|
detect_end: int | None = None,
|
|
37
38
|
) -> Path:
|
|
@@ -45,7 +46,7 @@ def derive_filename(
|
|
|
45
46
|
If None, no starting marker will be appended.
|
|
46
47
|
detect_end (int | None): The ending marker to append to the filename. If None,
|
|
47
48
|
no ending marker will be appended.
|
|
48
|
-
|
|
49
|
+
file_type (str): The file suffix to apply to the derived filename.
|
|
49
50
|
|
|
50
51
|
Returns:
|
|
51
52
|
Path: The modified video file path with the updated stem and suffix applied.
|
|
@@ -56,4 +57,4 @@ def derive_filename(
|
|
|
56
57
|
if detect_end is not None:
|
|
57
58
|
cutout += f"_end_{detect_end}"
|
|
58
59
|
new_stem = f"{video_file.stem}{cutout}"
|
|
59
|
-
return video_file.with_stem(new_stem).with_suffix(
|
|
60
|
+
return video_file.with_stem(new_stem).with_suffix(file_type)
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
from collections import defaultdict
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import Self
|
|
5
|
+
|
|
6
|
+
from OTVision import dataformat, version
|
|
7
|
+
from OTVision.detect.otdet import (
|
|
8
|
+
OtdetBuilderConfig,
|
|
9
|
+
OtdetMetadataBuilder,
|
|
10
|
+
extract_expected_duration_from_otdet,
|
|
11
|
+
extract_start_date_from_otdet,
|
|
12
|
+
)
|
|
13
|
+
from OTVision.domain.detection import TrackedDetection, TrackId
|
|
14
|
+
from OTVision.domain.frame import FrameNo, TrackedFrame
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class OttrkBuilderConfig:
|
|
19
|
+
otdet_builder_config: OtdetBuilderConfig
|
|
20
|
+
number_of_frames: int
|
|
21
|
+
sigma_l: float
|
|
22
|
+
sigma_h: float
|
|
23
|
+
sigma_iou: float
|
|
24
|
+
t_min: int
|
|
25
|
+
t_miss_max: int
|
|
26
|
+
tracking_run_id: str
|
|
27
|
+
frame_group: int
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class OttrkBuilderError(Exception):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class OttrkBuilder:
|
|
35
|
+
@property
|
|
36
|
+
def config(self) -> OttrkBuilderConfig:
|
|
37
|
+
if self._config is None:
|
|
38
|
+
raise OttrkBuilderError("Ottrk builder config is not set")
|
|
39
|
+
return self._config
|
|
40
|
+
|
|
41
|
+
def __init__(self, otdet_metadata_builder: OtdetMetadataBuilder) -> None:
|
|
42
|
+
self._config: OttrkBuilderConfig | None = None
|
|
43
|
+
self._otdet_metadata_builder = otdet_metadata_builder
|
|
44
|
+
self._tracked_detections: dict[TrackId, list[dict]] = defaultdict(list)
|
|
45
|
+
|
|
46
|
+
def build(self) -> dict:
|
|
47
|
+
result = {
|
|
48
|
+
dataformat.METADATA: self.build_metadata(),
|
|
49
|
+
dataformat.DATA: {
|
|
50
|
+
dataformat.DETECTIONS: self._build_data(),
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
self.reset()
|
|
54
|
+
return result
|
|
55
|
+
|
|
56
|
+
def build_metadata(self) -> dict:
|
|
57
|
+
otdet_metadata = self._otdet_metadata_builder.build(
|
|
58
|
+
self.config.number_of_frames
|
|
59
|
+
)
|
|
60
|
+
start_date = extract_start_date_from_otdet(otdet_metadata)
|
|
61
|
+
duration = extract_expected_duration_from_otdet(otdet_metadata)
|
|
62
|
+
end_date = start_date + duration
|
|
63
|
+
ottrk_metadata = self._build_track_metadata(start_date, end_date)
|
|
64
|
+
return {
|
|
65
|
+
**otdet_metadata,
|
|
66
|
+
**ottrk_metadata,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
def _build_track_metadata(self, start_date: datetime, end_date: datetime) -> dict:
|
|
70
|
+
result = create_ottrk_metadata_entry(
|
|
71
|
+
start_date=start_date,
|
|
72
|
+
end_date=end_date,
|
|
73
|
+
sigma_l=self.config.sigma_l,
|
|
74
|
+
sigma_h=self.config.sigma_h,
|
|
75
|
+
sigma_iou=self.config.sigma_iou,
|
|
76
|
+
t_min=self.config.t_min,
|
|
77
|
+
t_miss_max=self.config.t_miss_max,
|
|
78
|
+
)
|
|
79
|
+
result[dataformat.TRACKING_RUN_ID] = self.config.tracking_run_id
|
|
80
|
+
result[dataformat.FRAME_GROUP] = self.config.frame_group
|
|
81
|
+
return result
|
|
82
|
+
|
|
83
|
+
def _build_data(self) -> list[dict]:
|
|
84
|
+
return sorted(
|
|
85
|
+
(
|
|
86
|
+
detection
|
|
87
|
+
for detections in self._tracked_detections.values()
|
|
88
|
+
for detection in detections
|
|
89
|
+
),
|
|
90
|
+
key=lambda detection: (
|
|
91
|
+
detection[dataformat.FRAME],
|
|
92
|
+
detection[dataformat.OCCURRENCE],
|
|
93
|
+
),
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
def set_config(self, config: OttrkBuilderConfig) -> Self:
|
|
97
|
+
self._config = config
|
|
98
|
+
self._otdet_metadata_builder.add_config(config.otdet_builder_config)
|
|
99
|
+
return self
|
|
100
|
+
|
|
101
|
+
def add_tracked_frames(self, tracked_frames: list[TrackedFrame]) -> Self:
|
|
102
|
+
finished_tracks = set()
|
|
103
|
+
discarded_tracks = set()
|
|
104
|
+
|
|
105
|
+
for tracked_frame in tracked_frames:
|
|
106
|
+
finished_tracks.update(tracked_frame.finished_tracks)
|
|
107
|
+
discarded_tracks.update(tracked_frame.discarded_tracks)
|
|
108
|
+
|
|
109
|
+
for detection in tracked_frame.detections:
|
|
110
|
+
self._tracked_detections[detection.track_id].append(
|
|
111
|
+
self._serialize_tracked_detection(
|
|
112
|
+
frame_no=tracked_frame.no,
|
|
113
|
+
detection=detection,
|
|
114
|
+
occurrence=tracked_frame.occurrence,
|
|
115
|
+
)
|
|
116
|
+
)
|
|
117
|
+
self.__sort_detections()
|
|
118
|
+
self.discard_tracks(discarded_tracks)
|
|
119
|
+
self.finish_tracks(finished_tracks)
|
|
120
|
+
return self
|
|
121
|
+
|
|
122
|
+
def _serialize_tracked_detection(
|
|
123
|
+
self,
|
|
124
|
+
frame_no: FrameNo,
|
|
125
|
+
detection: TrackedDetection,
|
|
126
|
+
occurrence: datetime,
|
|
127
|
+
) -> dict:
|
|
128
|
+
result = detection.to_otdet()
|
|
129
|
+
result[dataformat.INTERPOLATED_DETECTION] = False
|
|
130
|
+
result[dataformat.FIRST] = detection.is_first
|
|
131
|
+
result[dataformat.FINISHED] = False
|
|
132
|
+
result[dataformat.TRACK_ID] = detection.track_id
|
|
133
|
+
result[dataformat.FRAME] = frame_no
|
|
134
|
+
result[dataformat.OCCURRENCE] = occurrence.timestamp()
|
|
135
|
+
result[dataformat.INPUT_FILE_PATH] = self.config.otdet_builder_config.source
|
|
136
|
+
return result
|
|
137
|
+
|
|
138
|
+
def __sort_detections(self) -> None:
|
|
139
|
+
for detections in self._tracked_detections.values():
|
|
140
|
+
detections.sort(key=lambda detection: (detection[dataformat.OCCURRENCE]))
|
|
141
|
+
|
|
142
|
+
def reset(self) -> Self:
|
|
143
|
+
self._config = None
|
|
144
|
+
self._otdet_metadata_builder.reset()
|
|
145
|
+
self._tracked_detections = defaultdict(list)
|
|
146
|
+
return self
|
|
147
|
+
|
|
148
|
+
def discard_tracks(self, tracks: set[TrackId]) -> Self:
|
|
149
|
+
for track_id in tracks:
|
|
150
|
+
self.discard_track(track_id)
|
|
151
|
+
return self
|
|
152
|
+
|
|
153
|
+
def discard_track(self, track_id: TrackId) -> Self:
|
|
154
|
+
try:
|
|
155
|
+
del self._tracked_detections[track_id]
|
|
156
|
+
except KeyError:
|
|
157
|
+
pass
|
|
158
|
+
return self
|
|
159
|
+
|
|
160
|
+
def finish_tracks(self, tracks: set[TrackId]) -> Self:
|
|
161
|
+
for track_id in tracks:
|
|
162
|
+
self.finish_track(track_id)
|
|
163
|
+
return self
|
|
164
|
+
|
|
165
|
+
def finish_track(self, track_id: TrackId) -> Self:
|
|
166
|
+
if track_id in self._tracked_detections:
|
|
167
|
+
self._tracked_detections[track_id][-1][dataformat.FINISHED] = True
|
|
168
|
+
return self
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def create_ottrk_metadata_entry(
|
|
172
|
+
start_date: datetime,
|
|
173
|
+
end_date: datetime,
|
|
174
|
+
sigma_l: float,
|
|
175
|
+
sigma_h: float,
|
|
176
|
+
sigma_iou: float,
|
|
177
|
+
t_min: int,
|
|
178
|
+
t_miss_max: int,
|
|
179
|
+
) -> dict:
|
|
180
|
+
return {
|
|
181
|
+
dataformat.OTTRACK_VERSION: version.ottrack_version(),
|
|
182
|
+
dataformat.TRACKING: {
|
|
183
|
+
dataformat.OTVISION_VERSION: version.otvision_version(),
|
|
184
|
+
dataformat.FIRST_TRACKED_VIDEO_START: start_date.timestamp(),
|
|
185
|
+
dataformat.LAST_TRACKED_VIDEO_END: end_date.timestamp(),
|
|
186
|
+
dataformat.TRACKER: create_tracker_metadata(
|
|
187
|
+
sigma_l, sigma_h, sigma_iou, t_min, t_miss_max
|
|
188
|
+
),
|
|
189
|
+
},
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def create_tracker_metadata(
|
|
194
|
+
sigma_l: float, sigma_h: float, sigma_iou: float, t_min: int, t_miss_max: int
|
|
195
|
+
) -> dict:
|
|
196
|
+
return {
|
|
197
|
+
dataformat.NAME: "IOU",
|
|
198
|
+
dataformat.SIGMA_L: sigma_l,
|
|
199
|
+
dataformat.SIGMA_H: sigma_h,
|
|
200
|
+
dataformat.SIGMA_IOU: sigma_iou,
|
|
201
|
+
dataformat.T_MIN: t_min,
|
|
202
|
+
dataformat.T_MISS_MAX: t_miss_max,
|
|
203
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
|
|
3
|
+
StrIdGenerator = Callable[[], str]
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CurrentTrackingRunId:
|
|
7
|
+
def __init__(self) -> None:
|
|
8
|
+
self._current_tracking_run_id: str | None = None
|
|
9
|
+
|
|
10
|
+
def update(self, tracking_run_id: str) -> None:
|
|
11
|
+
self._current_tracking_run_id = tracking_run_id
|
|
12
|
+
|
|
13
|
+
def get(self) -> str:
|
|
14
|
+
if self._current_tracking_run_id is None:
|
|
15
|
+
raise ValueError("Tracking run id is not set!")
|
|
16
|
+
return self._current_tracking_run_id
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class GenerateNewTrackingRunId:
|
|
20
|
+
def __init__(
|
|
21
|
+
self, id_generator: StrIdGenerator, current: CurrentTrackingRunId
|
|
22
|
+
) -> None:
|
|
23
|
+
self._generate_id = id_generator
|
|
24
|
+
self._current = current
|
|
25
|
+
|
|
26
|
+
def generate(self) -> None:
|
|
27
|
+
self._current.update(self._generate_id())
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class GetCurrentTrackingRunId:
|
|
31
|
+
def __init__(self, current: CurrentTrackingRunId) -> None:
|
|
32
|
+
self._current = current
|
|
33
|
+
|
|
34
|
+
def get(self) -> str:
|
|
35
|
+
return self._current.get()
|
|
@@ -3,7 +3,6 @@ from argparse import ArgumentParser
|
|
|
3
3
|
from functools import cached_property
|
|
4
4
|
|
|
5
5
|
from OTVision.abstraction.observer import Subject
|
|
6
|
-
from OTVision.application.buffer import Buffer
|
|
7
6
|
from OTVision.application.config import Config, DetectConfig
|
|
8
7
|
from OTVision.application.config_parser import ConfigParser
|
|
9
8
|
from OTVision.application.configure_logger import ConfigureLogger
|
|
@@ -12,9 +11,6 @@ from OTVision.application.detect.current_object_detector_metadata import (
|
|
|
12
11
|
CurrentObjectDetectorMetadata,
|
|
13
12
|
)
|
|
14
13
|
from OTVision.application.detect.detected_frame_factory import DetectedFrameFactory
|
|
15
|
-
from OTVision.application.detect.detection_file_save_path_provider import (
|
|
16
|
-
DetectionFileSavePathProvider,
|
|
17
|
-
)
|
|
18
14
|
from OTVision.application.detect.factory import ObjectDetectorCachedFactory
|
|
19
15
|
from OTVision.application.detect.get_detect_cli_args import GetDetectCliArgs
|
|
20
16
|
from OTVision.application.detect.update_detect_config_with_cli_args import (
|
|
@@ -23,20 +19,20 @@ from OTVision.application.detect.update_detect_config_with_cli_args import (
|
|
|
23
19
|
from OTVision.application.frame_count_provider import FrameCountProvider
|
|
24
20
|
from OTVision.application.get_config import GetConfig
|
|
25
21
|
from OTVision.application.get_current_config import GetCurrentConfig
|
|
22
|
+
from OTVision.application.otvision_save_path_provider import OtvisionSavePathProvider
|
|
26
23
|
from OTVision.application.update_current_config import UpdateCurrentConfig
|
|
27
24
|
from OTVision.detect.cli import ArgparseDetectCliParser
|
|
28
25
|
from OTVision.detect.detect import OTVisionVideoDetect
|
|
29
26
|
from OTVision.detect.detected_frame_buffer import (
|
|
30
27
|
DetectedFrameBuffer,
|
|
31
28
|
DetectedFrameBufferEvent,
|
|
32
|
-
FlushEvent,
|
|
33
29
|
)
|
|
34
30
|
from OTVision.detect.detected_frame_producer import (
|
|
35
31
|
DetectedFrameProducerFactory,
|
|
36
32
|
SimpleDetectedFrameProducer,
|
|
37
33
|
)
|
|
38
|
-
from OTVision.detect.otdet import OtdetBuilder
|
|
39
|
-
from OTVision.detect.otdet_file_writer import OtdetFileWriter
|
|
34
|
+
from OTVision.detect.otdet import OtdetBuilder, OtdetMetadataBuilder
|
|
35
|
+
from OTVision.detect.otdet_file_writer import OtdetFileWriter, OtdetFileWrittenEvent
|
|
40
36
|
from OTVision.detect.plugin_av.rotate_frame import AvVideoFrameRotator
|
|
41
37
|
from OTVision.detect.pyav_frame_count_provider import PyAVFrameCountProvider
|
|
42
38
|
from OTVision.detect.timestamper import TimestamperFactory
|
|
@@ -44,7 +40,6 @@ from OTVision.detect.yolo import YoloDetectionConverter, YoloFactory
|
|
|
44
40
|
from OTVision.domain.cli import DetectCliParser
|
|
45
41
|
from OTVision.domain.current_config import CurrentConfig
|
|
46
42
|
from OTVision.domain.detect_producer_consumer import DetectedFrameProducer
|
|
47
|
-
from OTVision.domain.frame import DetectedFrame
|
|
48
43
|
from OTVision.domain.input_source_detect import InputSourceDetect
|
|
49
44
|
from OTVision.domain.object_detection import ObjectDetectorFactory
|
|
50
45
|
from OTVision.domain.serialization import Deserializer
|
|
@@ -77,7 +72,7 @@ class DetectBuilder(ABC):
|
|
|
77
72
|
|
|
78
73
|
@cached_property
|
|
79
74
|
def otdet_builder(self) -> OtdetBuilder:
|
|
80
|
-
return OtdetBuilder()
|
|
75
|
+
return OtdetBuilder(OtdetMetadataBuilder())
|
|
81
76
|
|
|
82
77
|
@cached_property
|
|
83
78
|
def object_detector_factory(self) -> ObjectDetectorFactory:
|
|
@@ -118,8 +113,8 @@ class DetectBuilder(ABC):
|
|
|
118
113
|
return TimestamperFactory(self.frame_count_provider, self.get_current_config)
|
|
119
114
|
|
|
120
115
|
@cached_property
|
|
121
|
-
def detection_file_save_path_provider(self) ->
|
|
122
|
-
return
|
|
116
|
+
def detection_file_save_path_provider(self) -> OtvisionSavePathProvider:
|
|
117
|
+
return OtvisionSavePathProvider(self.get_current_config)
|
|
123
118
|
|
|
124
119
|
@cached_property
|
|
125
120
|
def frame_count_provider(self) -> FrameCountProvider:
|
|
@@ -128,6 +123,7 @@ class DetectBuilder(ABC):
|
|
|
128
123
|
@cached_property
|
|
129
124
|
def otdet_file_writer(self) -> OtdetFileWriter:
|
|
130
125
|
return OtdetFileWriter(
|
|
126
|
+
subject=Subject[OtdetFileWrittenEvent](),
|
|
131
127
|
builder=self.otdet_builder,
|
|
132
128
|
get_current_config=self.get_current_config,
|
|
133
129
|
current_object_detector_metadata=self.current_object_detector_metadata,
|
|
@@ -146,9 +142,7 @@ class DetectBuilder(ABC):
|
|
|
146
142
|
)
|
|
147
143
|
|
|
148
144
|
@cached_property
|
|
149
|
-
def detected_frame_buffer(
|
|
150
|
-
self,
|
|
151
|
-
) -> Buffer[DetectedFrame, DetectedFrameBufferEvent, FlushEvent]:
|
|
145
|
+
def detected_frame_buffer(self) -> DetectedFrameBuffer:
|
|
152
146
|
return DetectedFrameBuffer(subject=Subject[DetectedFrameBufferEvent]())
|
|
153
147
|
|
|
154
148
|
@cached_property
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
2
|
from datetime import datetime, timedelta
|
|
3
3
|
|
|
4
|
+
from OTVision.abstraction.observer import Observable, Subject
|
|
4
5
|
from OTVision.application.buffer import Buffer
|
|
5
6
|
from OTVision.domain.frame import DetectedFrame
|
|
6
7
|
|
|
@@ -49,7 +50,18 @@ class DetectedFrameBufferEvent:
|
|
|
49
50
|
frames: list[DetectedFrame]
|
|
50
51
|
|
|
51
52
|
|
|
52
|
-
class DetectedFrameBuffer(
|
|
53
|
+
class DetectedFrameBuffer(
|
|
54
|
+
Buffer[DetectedFrame, FlushEvent], Observable[DetectedFrameBufferEvent]
|
|
55
|
+
):
|
|
56
|
+
def __init__(self, subject: Subject[DetectedFrameBufferEvent]) -> None:
|
|
57
|
+
Buffer.__init__(self)
|
|
58
|
+
Observable.__init__(self, subject)
|
|
59
|
+
|
|
60
|
+
def on_flush(self, event: FlushEvent) -> None:
|
|
61
|
+
buffered_elements = self._get_buffered_elements()
|
|
62
|
+
self._notify_observers(buffered_elements, event)
|
|
63
|
+
self._reset_buffer()
|
|
64
|
+
|
|
53
65
|
def _notify_observers(
|
|
54
66
|
self, elements: list[DetectedFrame], event: FlushEvent
|
|
55
67
|
) -> None:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Iterator
|
|
2
2
|
|
|
3
3
|
from OTVision.detect.detected_frame_producer_factory import DetectedFrameProducerFactory
|
|
4
4
|
from OTVision.domain.detect_producer_consumer import DetectedFrameProducer
|
|
@@ -10,5 +10,5 @@ class SimpleDetectedFrameProducer(DetectedFrameProducer):
|
|
|
10
10
|
def __init__(self, producer_factory: DetectedFrameProducerFactory) -> None:
|
|
11
11
|
self._producer_factory = producer_factory
|
|
12
12
|
|
|
13
|
-
def produce(self) ->
|
|
13
|
+
def produce(self) -> Iterator[DetectedFrame]:
|
|
14
14
|
return self._producer_factory.create()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Iterator
|
|
2
2
|
|
|
3
3
|
from OTVision.abstraction.pipes_and_filter import Filter
|
|
4
4
|
from OTVision.application.get_current_config import GetCurrentConfig
|
|
@@ -21,21 +21,17 @@ class DetectedFrameProducerFactory:
|
|
|
21
21
|
self._detected_frame_buffer = detected_frame_buffer
|
|
22
22
|
self._get_current_config = get_current_config
|
|
23
23
|
|
|
24
|
-
def create(self) ->
|
|
24
|
+
def create(self) -> Iterator[DetectedFrame]:
|
|
25
25
|
if self._get_current_config.get().detect.write_video:
|
|
26
26
|
return self.__create_with_video_writer()
|
|
27
27
|
return self.__create_without_video_writer()
|
|
28
28
|
|
|
29
|
-
def __create_without_video_writer(
|
|
30
|
-
self,
|
|
31
|
-
) -> Generator[DetectedFrame, None, None]:
|
|
29
|
+
def __create_without_video_writer(self) -> Iterator[DetectedFrame]:
|
|
32
30
|
return self._detected_frame_buffer.filter(
|
|
33
31
|
self._detection_filter.filter(self._input_source.produce())
|
|
34
32
|
)
|
|
35
33
|
|
|
36
|
-
def __create_with_video_writer(
|
|
37
|
-
self,
|
|
38
|
-
) -> Generator[DetectedFrame, None, None]:
|
|
34
|
+
def __create_with_video_writer(self) -> Iterator[DetectedFrame]:
|
|
39
35
|
return self._detected_frame_buffer.filter(
|
|
40
36
|
self._detection_filter.filter(
|
|
41
37
|
self._video_writer_filter.filter(self._input_source.produce())
|