OTVision 0.6.8__tar.gz → 0.6.10__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.
Files changed (345) hide show
  1. {otvision-0.6.8 → otvision-0.6.10}/.github/workflows/release-pypi.yml +5 -6
  2. {otvision-0.6.8 → otvision-0.6.10}/.github/workflows/release-testpypi.yml +6 -6
  3. otvision-0.6.10/.github/workflows/test.yml +30 -0
  4. {otvision-0.6.8 → otvision-0.6.10}/OTVision/abstraction/pipes_and_filter.py +4 -4
  5. otvision-0.6.10/OTVision/application/buffer.py +28 -0
  6. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/config_parser.py +51 -2
  7. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/detect/current_object_detector.py +2 -4
  8. otvision-0.6.10/OTVision/application/event/new_otvision_config.py +6 -0
  9. otvision-0.6.8/OTVision/application/detect/detection_file_save_path_provider.py → otvision-0.6.10/OTVision/application/otvision_save_path_provider.py +8 -7
  10. otvision-0.6.10/OTVision/application/track/ottrk.py +203 -0
  11. otvision-0.6.10/OTVision/application/track/tracking_run_id.py +35 -0
  12. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/builder.py +8 -14
  13. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/detected_frame_buffer.py +13 -1
  14. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/detected_frame_producer.py +2 -2
  15. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/detected_frame_producer_factory.py +4 -8
  16. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/otdet.py +109 -41
  17. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/otdet_file_writer.py +52 -29
  18. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/rtsp_input_source.py +15 -3
  19. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/video_input_source.py +8 -8
  20. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/yolo.py +3 -7
  21. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/detect_producer_consumer.py +3 -3
  22. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/frame.py +12 -0
  23. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/input_source_detect.py +3 -3
  24. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/object_detection.py +4 -6
  25. {otvision-0.6.8 → otvision-0.6.10}/OTVision/helpers/date.py +16 -0
  26. {otvision-0.6.8 → otvision-0.6.10}/OTVision/plugin/ffmpeg_video_writer.py +2 -4
  27. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/builder.py +2 -5
  28. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/id_generator.py +1 -3
  29. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/parser/chunk_parser_plugins.py +1 -19
  30. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/parser/frame_group_parser_plugins.py +19 -74
  31. otvision-0.6.10/OTVision/track/stream_ottrk_file_writer.py +116 -0
  32. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/track.py +2 -1
  33. {otvision-0.6.8 → otvision-0.6.10}/OTVision/version.py +1 -1
  34. {otvision-0.6.8 → otvision-0.6.10}/PKG-INFO +9 -2
  35. {otvision-0.6.8 → otvision-0.6.10}/config.yml +8 -14
  36. otvision-0.6.10/install.cmd +19 -0
  37. {otvision-0.6.8 → otvision-0.6.10}/install.sh +8 -7
  38. otvision-0.6.10/install_cuda.cmd +19 -0
  39. otvision-0.6.10/install_cuda.sh +27 -0
  40. {otvision-0.6.8 → otvision-0.6.10}/install_dev.cmd +2 -3
  41. {otvision-0.6.8 → otvision-0.6.10}/install_dev.sh +1 -2
  42. otvision-0.6.10/pyproject.toml +157 -0
  43. {otvision-0.6.8 → otvision-0.6.10}/tests/application/test_buffer.py +6 -34
  44. otvision-0.6.10/tests/application/test_config_parser.py +136 -0
  45. otvision-0.6.8/tests/application/detect/test_detection_file_save_path_provider.py → otvision-0.6.10/tests/application/test_otvision_save_path_provider.py +11 -11
  46. otvision-0.6.10/tests/application/track/test_ottrk.py +449 -0
  47. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/test_otdet.py +2 -1
  48. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/test_otdet_file_writer.py +11 -6
  49. {otvision-0.6.8 → otvision-0.6.10}/tests/track/test_frame_group_parser_plugins.py +3 -3
  50. otvision-0.6.10/tests/track/test_stream_ottrk_file_writer.py +413 -0
  51. {otvision-0.6.8 → otvision-0.6.10}/tests/track/test_track.py +1 -1
  52. {otvision-0.6.8 → otvision-0.6.10}/update_precommit.py +10 -0
  53. otvision-0.6.10/uv.lock +1951 -0
  54. otvision-0.6.8/.github/workflows/test.yml +0 -25
  55. otvision-0.6.8/OTVision/application/buffer.py +0 -35
  56. otvision-0.6.8/install.cmd +0 -16
  57. otvision-0.6.8/pyproject.toml +0 -62
  58. otvision-0.6.8/requirements-dev.txt +0 -15
  59. otvision-0.6.8/requirements.txt +0 -18
  60. {otvision-0.6.8 → otvision-0.6.10}/.editorconfig +0 -0
  61. {otvision-0.6.8 → otvision-0.6.10}/.flake8 +0 -0
  62. {otvision-0.6.8 → otvision-0.6.10}/.github/dependabot.yml +0 -0
  63. {otvision-0.6.8 → otvision-0.6.10}/.github/workflows/build-nightly.yml +0 -0
  64. {otvision-0.6.8 → otvision-0.6.10}/.github/workflows/build-release.yml +0 -0
  65. {otvision-0.6.8 → otvision-0.6.10}/.github/workflows/linter.yml +0 -0
  66. {otvision-0.6.8 → otvision-0.6.10}/.gitignore +0 -0
  67. {otvision-0.6.8 → otvision-0.6.10}/.pre-commit-config.yaml +0 -0
  68. {otvision-0.6.8 → otvision-0.6.10}/.vscode/launch.json +0 -0
  69. {otvision-0.6.8 → otvision-0.6.10}/.vscode/scripts/build_debug_env.cmd +0 -0
  70. {otvision-0.6.8 → otvision-0.6.10}/.vscode/scripts/build_debug_env.sh +0 -0
  71. {otvision-0.6.8 → otvision-0.6.10}/.vscode/scripts/teardown_debug_env.cmd +0 -0
  72. {otvision-0.6.8 → otvision-0.6.10}/.vscode/scripts/teardown_debug_env.sh +0 -0
  73. {otvision-0.6.8 → otvision-0.6.10}/.vscode/settings.json +0 -0
  74. {otvision-0.6.8 → otvision-0.6.10}/.vscode/tasks.json +0 -0
  75. {otvision-0.6.8 → otvision-0.6.10}/.yamllint.yaml +0 -0
  76. {otvision-0.6.8 → otvision-0.6.10}/LICENSE +0 -0
  77. {otvision-0.6.8 → otvision-0.6.10}/OTVision/__init__.py +0 -0
  78. {otvision-0.6.8 → otvision-0.6.10}/OTVision/abstraction/__init__.py +0 -0
  79. {otvision-0.6.8 → otvision-0.6.10}/OTVision/abstraction/defaults.py +0 -0
  80. {otvision-0.6.8 → otvision-0.6.10}/OTVision/abstraction/observer.py +0 -0
  81. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/__init__.py +0 -0
  82. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/config.py +0 -0
  83. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/configure_logger.py +0 -0
  84. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/detect/__init__.py +0 -0
  85. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/detect/current_object_detector_metadata.py +0 -0
  86. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/detect/detected_frame_factory.py +0 -0
  87. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/detect/factory.py +0 -0
  88. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/detect/get_detect_cli_args.py +0 -0
  89. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/detect/timestamper.py +0 -0
  90. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/detect/update_detect_config_with_cli_args.py +0 -0
  91. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/event/__init__.py +0 -0
  92. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/event/new_video_start.py +0 -0
  93. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/frame_count_provider.py +0 -0
  94. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/get_config.py +0 -0
  95. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/get_current_config.py +0 -0
  96. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/track/__init__.py +0 -0
  97. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/track/get_track_cli_args.py +0 -0
  98. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/track/update_current_track_config.py +0 -0
  99. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/track/update_track_config_with_cli_args.py +0 -0
  100. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/update_current_config.py +0 -0
  101. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/video/__init__.py +0 -0
  102. {otvision-0.6.8 → otvision-0.6.10}/OTVision/application/video/generate_video.py +0 -0
  103. {otvision-0.6.8 → otvision-0.6.10}/OTVision/config.py +0 -0
  104. {otvision-0.6.8 → otvision-0.6.10}/OTVision/convert/__init__.py +0 -0
  105. {otvision-0.6.8 → otvision-0.6.10}/OTVision/convert/convert.py +0 -0
  106. {otvision-0.6.8 → otvision-0.6.10}/OTVision/dataformat.py +0 -0
  107. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/__init__.py +0 -0
  108. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/cli.py +0 -0
  109. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/detect.py +0 -0
  110. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/file_based_detect_builder.py +0 -0
  111. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/plugin_av/__init__.py +0 -0
  112. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/plugin_av/rotate_frame.py +0 -0
  113. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/pyav_frame_count_provider.py +0 -0
  114. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/rtsp_based_detect_builder.py +0 -0
  115. {otvision-0.6.8 → otvision-0.6.10}/OTVision/detect/timestamper.py +0 -0
  116. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/__init__.py +0 -0
  117. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/cli.py +0 -0
  118. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/current_config.py +0 -0
  119. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/detection.py +0 -0
  120. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/serialization.py +0 -0
  121. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/time.py +0 -0
  122. {otvision-0.6.8 → otvision-0.6.10}/OTVision/domain/video_writer.py +0 -0
  123. {otvision-0.6.8 → otvision-0.6.10}/OTVision/helpers/__init__.py +0 -0
  124. {otvision-0.6.8 → otvision-0.6.10}/OTVision/helpers/files.py +0 -0
  125. {otvision-0.6.8 → otvision-0.6.10}/OTVision/helpers/formats.py +0 -0
  126. {otvision-0.6.8 → otvision-0.6.10}/OTVision/helpers/input_types.py +0 -0
  127. {otvision-0.6.8 → otvision-0.6.10}/OTVision/helpers/log.py +0 -0
  128. {otvision-0.6.8 → otvision-0.6.10}/OTVision/helpers/machine.py +0 -0
  129. {otvision-0.6.8 → otvision-0.6.10}/OTVision/helpers/video.py +0 -0
  130. {otvision-0.6.8 → otvision-0.6.10}/OTVision/plugin/__init__.py +0 -0
  131. {otvision-0.6.8 → otvision-0.6.10}/OTVision/plugin/generate_video.py +0 -0
  132. {otvision-0.6.8 → otvision-0.6.10}/OTVision/plugin/yaml_serialization.py +0 -0
  133. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/__init__.py +0 -0
  134. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/cli.py +0 -0
  135. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/exporter/__init__.py +0 -0
  136. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/exporter/filebased_exporter.py +0 -0
  137. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/model/__init__.py +0 -0
  138. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/model/filebased/__init__.py +0 -0
  139. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/model/filebased/frame_chunk.py +0 -0
  140. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/model/filebased/frame_group.py +0 -0
  141. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/model/track_exporter.py +0 -0
  142. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/model/tracking_interfaces.py +0 -0
  143. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/parser/__init__.py +0 -0
  144. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/tracker/__init__.py +0 -0
  145. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/tracker/filebased_tracking.py +0 -0
  146. {otvision-0.6.8 → otvision-0.6.10}/OTVision/track/tracker/tracker_plugin_iou.py +0 -0
  147. {otvision-0.6.8 → otvision-0.6.10}/OTVision/transform/__init__.py +0 -0
  148. {otvision-0.6.8 → otvision-0.6.10}/OTVision/transform/get_homography.py +0 -0
  149. {otvision-0.6.8 → otvision-0.6.10}/OTVision/transform/reference_points_picker.py +0 -0
  150. {otvision-0.6.8 → otvision-0.6.10}/OTVision/transform/transform.py +0 -0
  151. {otvision-0.6.8 → otvision-0.6.10}/OTVision/view/__init__.py +0 -0
  152. {otvision-0.6.8 → otvision-0.6.10}/OTVision/view/helpers/OTC.ico +0 -0
  153. {otvision-0.6.8 → otvision-0.6.10}/OTVision/view/view.py +0 -0
  154. {otvision-0.6.8 → otvision-0.6.10}/OTVision/view/view_convert.py +0 -0
  155. {otvision-0.6.8 → otvision-0.6.10}/OTVision/view/view_detect.py +0 -0
  156. {otvision-0.6.8 → otvision-0.6.10}/OTVision/view/view_helpers.py +0 -0
  157. {otvision-0.6.8 → otvision-0.6.10}/OTVision/view/view_track.py +0 -0
  158. {otvision-0.6.8 → otvision-0.6.10}/OTVision/view/view_transform.py +0 -0
  159. {otvision-0.6.8 → otvision-0.6.10}/OTVision.bat +0 -0
  160. {otvision-0.6.8 → otvision-0.6.10}/README.md +0 -0
  161. {otvision-0.6.8 → otvision-0.6.10}/clean-up-repository.sh +0 -0
  162. {otvision-0.6.8 → otvision-0.6.10}/convert.py +0 -0
  163. {otvision-0.6.8 → otvision-0.6.10}/detect.py +0 -0
  164. {otvision-0.6.8 → otvision-0.6.10}/export_models.py +0 -0
  165. {otvision-0.6.8 → otvision-0.6.10}/generate_video.py +0 -0
  166. {otvision-0.6.8 → otvision-0.6.10}/reference_points_picker.py +0 -0
  167. {otvision-0.6.8 → otvision-0.6.10}/tests/__init__.py +0 -0
  168. {otvision-0.6.8 → otvision-0.6.10}/tests/abstraction/__init__.py +0 -0
  169. {otvision-0.6.8 → otvision-0.6.10}/tests/abstraction/test_defaults.py +0 -0
  170. {otvision-0.6.8 → otvision-0.6.10}/tests/abstraction/test_observer.py +0 -0
  171. {otvision-0.6.8 → otvision-0.6.10}/tests/application/__init__.py +0 -0
  172. {otvision-0.6.8 → otvision-0.6.10}/tests/application/detect/__init__.py +0 -0
  173. {otvision-0.6.8 → otvision-0.6.10}/tests/application/detect/test_current_object_detector.py +0 -0
  174. {otvision-0.6.8 → otvision-0.6.10}/tests/application/detect/test_detected_frame_factory.py +0 -0
  175. {otvision-0.6.8 → otvision-0.6.10}/tests/application/detect/test_get_detect_cli_args.py +0 -0
  176. {otvision-0.6.8 → otvision-0.6.10}/tests/application/detect/test_timestamper.py +0 -0
  177. {otvision-0.6.8 → otvision-0.6.10}/tests/application/detect/test_update_detect_config_with_cli_args.py +0 -0
  178. {otvision-0.6.8 → otvision-0.6.10}/tests/application/test_get_config.py +0 -0
  179. {otvision-0.6.8 → otvision-0.6.10}/tests/application/track/__init__.py +0 -0
  180. {otvision-0.6.8 → otvision-0.6.10}/tests/application/track/test_get_track_cli_args.py +0 -0
  181. {otvision-0.6.8 → otvision-0.6.10}/tests/application/track/test_update_current_track_config.py +0 -0
  182. {otvision-0.6.8 → otvision-0.6.10}/tests/application/track/test_update_track_config_with_cli_args.py +0 -0
  183. {otvision-0.6.8 → otvision-0.6.10}/tests/cli/custom_cli_test_config.yaml +0 -0
  184. {otvision-0.6.8 → otvision-0.6.10}/tests/cli/test_convert_cli.py +0 -0
  185. {otvision-0.6.8 → otvision-0.6.10}/tests/cli/test_detect_cli.py +0 -0
  186. {otvision-0.6.8 → otvision-0.6.10}/tests/cli/test_track_cli.py +0 -0
  187. {otvision-0.6.8 → otvision-0.6.10}/tests/conftest.py +0 -0
  188. {otvision-0.6.8 → otvision-0.6.10}/tests/convert/__init__.py +0 -0
  189. {otvision-0.6.8 → otvision-0.6.10}/tests/convert/test_convert.py +0 -0
  190. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_CamView.png +0 -0
  191. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_CamView_Cars-Cyclist.png +0 -0
  192. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_CamView_Cars-Truck.png +0 -0
  193. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_CamView_refpts.png +0 -0
  194. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.gpkg +0 -0
  195. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  196. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  197. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  198. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otrfpts +0 -0
  199. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  200. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.gpkg +0 -0
  201. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  202. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  203. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  204. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otrfpts +0 -0
  205. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  206. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_FR20.otrfpts +0 -0
  207. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Satellite.jpg +0 -0
  208. {otvision-0.6.8 → otvision-0.6.10}/tests/data/Testvideo_Satellite_far.jpg +0 -0
  209. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  210. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  211. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  212. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  213. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/fail_fps_from_filename/Testvideo_Cars-Cyclist_F20_2020-01-01_00-00-00.h264 +0 -0
  214. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/fail_fps_from_filename/Testvideo_Cars-Truck_2020-01-01_00-00-00.h264 +0 -0
  215. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/fps_from_filename/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  216. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/fps_from_filename/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  217. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/fps_from_filename/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  218. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/fps_from_filename/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  219. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/input_fps_20/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  220. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/input_fps_20/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  221. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/input_fps_20/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  222. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/input_fps_20/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  223. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/input_fps_40/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  224. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/input_fps_40/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  225. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/input_fps_40/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  226. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/input_fps_40/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  227. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.avi +0 -0
  228. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  229. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.avi +0 -0
  230. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  231. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  232. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mkv +0 -0
  233. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  234. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mkv +0 -0
  235. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  236. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mov +0 -0
  237. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  238. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mov +0 -0
  239. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  240. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  241. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  242. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  243. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/rotation/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00_rotate.h264 +0 -0
  244. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/rotation/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00_rotate.mov +0 -0
  245. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/rotation/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00_rotate.mp4 +0 -0
  246. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/rotation/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00_rotate.h264 +0 -0
  247. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/rotation/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00_rotate.mov +0 -0
  248. {otvision-0.6.8 → otvision-0.6.10}/tests/data/convert/rotation/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00_rotate.mp4 +0 -0
  249. {otvision-0.6.8 → otvision-0.6.10}/tests/data/detect/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  250. {otvision-0.6.8 → otvision-0.6.10}/tests/data/detect/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  251. {otvision-0.6.8 → otvision-0.6.10}/tests/data/detect/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  252. {otvision-0.6.8 → otvision-0.6.10}/tests/data/detect/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  253. {otvision-0.6.8 → otvision-0.6.10}/tests/data/detect/rotated-Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  254. {otvision-0.6.8 → otvision-0.6.10}/tests/data/log/_otvision_logs/test.log +0 -0
  255. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  256. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  257. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  258. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  259. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  260. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  261. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  262. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  263. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  264. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  265. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  266. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  267. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  268. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  269. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  270. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  271. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  272. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  273. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  274. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  275. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  276. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  277. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  278. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  279. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  280. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  281. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  282. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  283. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_min_10/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  284. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_min_10/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  285. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_min_10/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  286. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_min_10/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  287. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_min_3/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  288. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_min_3/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  289. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_min_3/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  290. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_min_3/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  291. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_miss_max_25/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  292. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_miss_max_25/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  293. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_miss_max_25/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  294. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_miss_max_25/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  295. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_miss_max_75/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  296. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_miss_max_75/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  297. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_miss_max_75/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  298. {otvision-0.6.8 → otvision-0.6.10}/tests/data/track/t_miss_max_75/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  299. {otvision-0.6.8 → otvision-0.6.10}/tests/data/transform/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.gpkg +0 -0
  300. {otvision-0.6.8 → otvision-0.6.10}/tests/data/transform/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otrfpts +0 -0
  301. {otvision-0.6.8 → otvision-0.6.10}/tests/data/transform/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  302. {otvision-0.6.8 → otvision-0.6.10}/tests/data/transform/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.gpkg +0 -0
  303. {otvision-0.6.8 → otvision-0.6.10}/tests/data/transform/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otrfpts +0 -0
  304. {otvision-0.6.8 → otvision-0.6.10}/tests/data/transform/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  305. {otvision-0.6.8 → otvision-0.6.10}/tests/data/transform/Testvideo_FR20.otrfpts +0 -0
  306. {otvision-0.6.8 → otvision-0.6.10}/tests/data/yolov8m.mlpackage/Data/com.apple.CoreML/model.mlmodel +0 -0
  307. {otvision-0.6.8 → otvision-0.6.10}/tests/data/yolov8m.mlpackage/Data/com.apple.CoreML/weights/weight.bin +0 -0
  308. {otvision-0.6.8 → otvision-0.6.10}/tests/data/yolov8m.mlpackage/Manifest.json +0 -0
  309. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/__init__.py +0 -0
  310. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/detect_test.py +0 -0
  311. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/plugin_av/__init__.py +0 -0
  312. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/plugin_av/test_rotate_frame.py +0 -0
  313. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/test_detected_frame_buffer.py +0 -0
  314. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/test_detected_frame_producer.py +0 -0
  315. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/test_detected_frame_producer_factory.py +0 -0
  316. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/test_pyav_frame_count_provider.py +0 -0
  317. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/test_rtsp_input_source.py +0 -0
  318. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/test_video_input_source.py +0 -0
  319. {otvision-0.6.8 → otvision-0.6.10}/tests/detect/yolo_test.py +0 -0
  320. {otvision-0.6.8 → otvision-0.6.10}/tests/helpers/__init__.py +0 -0
  321. {otvision-0.6.8 → otvision-0.6.10}/tests/helpers/files_test.py +0 -0
  322. {otvision-0.6.8 → otvision-0.6.10}/tests/helpers/formats_test.py +0 -0
  323. {otvision-0.6.8 → otvision-0.6.10}/tests/helpers/test_log.py +0 -0
  324. {otvision-0.6.8 → otvision-0.6.10}/tests/log/__init__.py +0 -0
  325. {otvision-0.6.8 → otvision-0.6.10}/tests/log/log_maker.py +0 -0
  326. {otvision-0.6.8 → otvision-0.6.10}/tests/log/test_log.py +0 -0
  327. {otvision-0.6.8 → otvision-0.6.10}/tests/plugin/__init__.py +0 -0
  328. {otvision-0.6.8 → otvision-0.6.10}/tests/plugin/test_ffmpeg_video_file_writer.py +0 -0
  329. {otvision-0.6.8 → otvision-0.6.10}/tests/test_config.py +0 -0
  330. {otvision-0.6.8 → otvision-0.6.10}/tests/track/__init__.py +0 -0
  331. {otvision-0.6.8 → otvision-0.6.10}/tests/track/helper/__init__.py +0 -0
  332. {otvision-0.6.8 → otvision-0.6.10}/tests/track/helper/data_builder.py +0 -0
  333. {otvision-0.6.8 → otvision-0.6.10}/tests/track/parser/__init__.py +0 -0
  334. {otvision-0.6.8 → otvision-0.6.10}/tests/track/parser/test_chunk_parser_plugins.py +0 -0
  335. {otvision-0.6.8 → otvision-0.6.10}/tests/track/test_frame_chunk.py +0 -0
  336. {otvision-0.6.8 → otvision-0.6.10}/tests/track/test_frame_group.py +0 -0
  337. {otvision-0.6.8 → otvision-0.6.10}/tests/track/test_tracking_data_structures.py +0 -0
  338. {otvision-0.6.8 → otvision-0.6.10}/tests/transform/__init__.py +0 -0
  339. {otvision-0.6.8 → otvision-0.6.10}/tests/transform/test_transform.py +0 -0
  340. {otvision-0.6.8 → otvision-0.6.10}/tests/utils/__init__.py +0 -0
  341. {otvision-0.6.8 → otvision-0.6.10}/tests/utils/generator.py +0 -0
  342. {otvision-0.6.8 → otvision-0.6.10}/tests/utils/mocking.py +0 -0
  343. {otvision-0.6.8 → otvision-0.6.10}/track.py +0 -0
  344. {otvision-0.6.8 → otvision-0.6.10}/transform.py +0 -0
  345. {otvision-0.6.8 → otvision-0.6.10}/view.py +0 -0
@@ -31,19 +31,18 @@ jobs:
31
31
  uses: actions/setup-python@v5
32
32
  with:
33
33
  python-version: "3.12"
34
+ - name: Install uv
35
+ uses: astral-sh/setup-uv@v6
36
+ with:
37
+ enable-cache: true
34
38
  - name: Update Python Package Version
35
39
  uses: platomo/update-version-py-action@v1.0.1
36
40
  with:
37
41
  version: ${{ github.ref_name }}
38
42
  file-path: "OTVision"
39
- - name: Install pypa/build
40
- shell: bash
41
- run: |
42
- python3 -m pip install build --user
43
-
44
43
  - name: Build a binary wheel and a source tarball
45
44
  shell: bash
46
- run: python -m build --outdir ${{ env.out_dir }}
45
+ run: uv build --out-dir ${{ env.out_dir }}
47
46
 
48
47
  - name: Store the distribution packages
49
48
  uses: actions/upload-artifact@v4
@@ -35,6 +35,11 @@ jobs:
35
35
  with:
36
36
  python-version: "3.12"
37
37
 
38
+ - name: Install uv
39
+ uses: astral-sh/setup-uv@v6
40
+ with:
41
+ enable-cache: true
42
+
38
43
  - name: Get latest tag and create new version
39
44
  id: get_version
40
45
  run: |
@@ -58,14 +63,9 @@ jobs:
58
63
  with:
59
64
  version: ${{ steps.get_version.outputs.new_version }}
60
65
  file-path: "OTVision"
61
- - name: Install pypa/build
62
- shell: bash
63
- run: |
64
- python3 -m pip install build --user
65
-
66
66
  - name: Build a binary wheel and a source tarball
67
67
  shell: bash
68
- run: python -m build --outdir ${{ env.out_dir }}
68
+ run: uv build --out-dir ${{ env.out_dir }}
69
69
 
70
70
  - name: Store the distribution packages
71
71
  uses: actions/upload-artifact@v4
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: Test
3
+
4
+ on:
5
+ # Run tests each time a PR is opened or changed.
6
+ # Allow other Workflows (e.g., build workflows) to call this workflow.
7
+ pull_request:
8
+ workflow_call:
9
+
10
+ permissions: read-all
11
+
12
+ jobs:
13
+ test:
14
+ name: Run Python tests on multiple OS and Python versions
15
+ strategy:
16
+ fail-fast: True
17
+ matrix:
18
+ os: [ubuntu-latest, windows-latest]
19
+ py: ["3.12"]
20
+ runs-on: ${{ matrix.os }}
21
+ steps:
22
+ - name: Checkout repository
23
+ uses: actions/checkout@v4
24
+ - name: Run Python Tests
25
+ uses: platomo/test-python-app-action@v2
26
+ timeout-minutes: 60
27
+ with:
28
+ py-version: ${{ matrix.py }}
29
+ package-path: OTVision
30
+ ffmpeg-required: True
@@ -1,5 +1,5 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Generator
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: Generator[IN, None, None]) -> Generator[OUT, None, None]:
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 (Generator[IN, None, None]): Input stream of elements to be processed.
21
+ pipe (Iterator[IN]): Input stream of elements to be processed.
22
22
 
23
23
  Returns:
24
- Generator[OUT, None, None]: Output stream of processed elements.
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
- data = self._deserialize.deserialize(file)
85
- return self.parse_from_dict(data)
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 Generator
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)
@@ -0,0 +1,6 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass(slots=True)
5
+ class NewOtvisionConfigEvent:
6
+ pass
@@ -3,8 +3,9 @@ from pathlib import Path
3
3
  from OTVision.application.get_current_config import GetCurrentConfig
4
4
 
5
5
 
6
- class DetectionFileSavePathProvider:
7
- """Provides a mechanism to generate file save paths for detections.
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
- detect_suffix=config.filetypes.detect,
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
- detect_suffix: str,
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
- detect_suffix (str): The file suffix to apply to the derived filename.
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(detect_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) -> DetectionFileSavePathProvider:
122
- return DetectionFileSavePathProvider(self.get_current_config)
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(Buffer[DetectedFrame, DetectedFrameBufferEvent, FlushEvent]):
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 Generator
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) -> Generator[DetectedFrame, None, None]:
13
+ def produce(self) -> Iterator[DetectedFrame]:
14
14
  return self._producer_factory.create()
@@ -1,4 +1,4 @@
1
- from typing import Generator
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) -> Generator[DetectedFrame, None, None]:
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())