OTVision 0.6.6__tar.gz → 0.6.8__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 (335) hide show
  1. {otvision-0.6.6 → otvision-0.6.8}/.github/workflows/release-testpypi.yml +24 -1
  2. {otvision-0.6.6 → otvision-0.6.8}/.pre-commit-config.yaml +6 -6
  3. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/config.py +18 -0
  4. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/config_parser.py +17 -9
  5. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/detect/update_detect_config_with_cli_args.py +16 -0
  6. otvision-0.6.8/OTVision/application/event/new_video_start.py +9 -0
  7. otvision-0.6.8/OTVision/application/video/generate_video.py +15 -0
  8. {otvision-0.6.6 → otvision-0.6.8}/OTVision/config.py +2 -0
  9. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/builder.py +27 -8
  10. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/cli.py +44 -1
  11. otvision-0.6.8/OTVision/detect/detected_frame_producer.py +14 -0
  12. otvision-0.6.8/OTVision/detect/detected_frame_producer_factory.py +43 -0
  13. otvision-0.6.8/OTVision/detect/file_based_detect_builder.py +55 -0
  14. otvision-0.6.8/OTVision/detect/rtsp_based_detect_builder.py +69 -0
  15. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/rtsp_input_source.py +135 -34
  16. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/video_input_source.py +38 -6
  17. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/yolo.py +9 -1
  18. {otvision-0.6.6 → otvision-0.6.8}/OTVision/domain/cli.py +10 -0
  19. {otvision-0.6.6 → otvision-0.6.8}/OTVision/domain/input_source_detect.py +1 -3
  20. {otvision-0.6.6 → otvision-0.6.8}/OTVision/domain/time.py +2 -2
  21. otvision-0.6.8/OTVision/domain/video_writer.py +30 -0
  22. otvision-0.6.8/OTVision/plugin/ffmpeg_video_writer.py +300 -0
  23. otvision-0.6.8/OTVision/plugin/generate_video.py +24 -0
  24. {otvision-0.6.6 → otvision-0.6.8}/OTVision/version.py +1 -1
  25. {otvision-0.6.6 → otvision-0.6.8}/PKG-INFO +6 -6
  26. {otvision-0.6.6 → otvision-0.6.8}/config.yml +8 -8
  27. {otvision-0.6.6 → otvision-0.6.8}/export_models.py +50 -3
  28. otvision-0.6.8/generate_video.py +55 -0
  29. {otvision-0.6.6 → otvision-0.6.8}/requirements-dev.txt +1 -1
  30. {otvision-0.6.6 → otvision-0.6.8}/requirements.txt +5 -5
  31. {otvision-0.6.6 → otvision-0.6.8}/tests/application/detect/test_update_detect_config_with_cli_args.py +3 -0
  32. {otvision-0.6.6 → otvision-0.6.8}/tests/cli/test_detect_cli.py +9 -4
  33. otvision-0.6.8/tests/detect/test_detected_frame_producer.py +22 -0
  34. otvision-0.6.8/tests/detect/test_detected_frame_producer_factory.py +85 -0
  35. {otvision-0.6.6 → otvision-0.6.8}/tests/detect/test_rtsp_input_source.py +105 -25
  36. {otvision-0.6.6 → otvision-0.6.8}/tests/detect/test_video_input_source.py +102 -33
  37. otvision-0.6.8/tests/plugin/test_ffmpeg_video_file_writer.py +264 -0
  38. otvision-0.6.8/tests/track/parser/__init__.py +0 -0
  39. otvision-0.6.8/tests/transform/__init__.py +0 -0
  40. otvision-0.6.8/tests/utils/__init__.py +0 -0
  41. otvision-0.6.6/OTVision/application/detect/detected_frame_producer.py +0 -24
  42. otvision-0.6.6/OTVision/detect/file_based_detect_builder.py +0 -19
  43. otvision-0.6.6/OTVision/detect/rtsp_based_detect_builder.py +0 -37
  44. otvision-0.6.6/tests/application/detect/test_detected_frame_producer.py +0 -49
  45. {otvision-0.6.6 → otvision-0.6.8}/.editorconfig +0 -0
  46. {otvision-0.6.6 → otvision-0.6.8}/.flake8 +0 -0
  47. {otvision-0.6.6 → otvision-0.6.8}/.github/dependabot.yml +0 -0
  48. {otvision-0.6.6 → otvision-0.6.8}/.github/workflows/build-nightly.yml +0 -0
  49. {otvision-0.6.6 → otvision-0.6.8}/.github/workflows/build-release.yml +0 -0
  50. {otvision-0.6.6 → otvision-0.6.8}/.github/workflows/linter.yml +0 -0
  51. {otvision-0.6.6 → otvision-0.6.8}/.github/workflows/release-pypi.yml +0 -0
  52. {otvision-0.6.6 → otvision-0.6.8}/.github/workflows/test.yml +0 -0
  53. {otvision-0.6.6 → otvision-0.6.8}/.gitignore +0 -0
  54. {otvision-0.6.6 → otvision-0.6.8}/.vscode/launch.json +0 -0
  55. {otvision-0.6.6 → otvision-0.6.8}/.vscode/scripts/build_debug_env.cmd +0 -0
  56. {otvision-0.6.6 → otvision-0.6.8}/.vscode/scripts/build_debug_env.sh +0 -0
  57. {otvision-0.6.6 → otvision-0.6.8}/.vscode/scripts/teardown_debug_env.cmd +0 -0
  58. {otvision-0.6.6 → otvision-0.6.8}/.vscode/scripts/teardown_debug_env.sh +0 -0
  59. {otvision-0.6.6 → otvision-0.6.8}/.vscode/settings.json +0 -0
  60. {otvision-0.6.6 → otvision-0.6.8}/.vscode/tasks.json +0 -0
  61. {otvision-0.6.6 → otvision-0.6.8}/.yamllint.yaml +0 -0
  62. {otvision-0.6.6 → otvision-0.6.8}/LICENSE +0 -0
  63. {otvision-0.6.6 → otvision-0.6.8}/OTVision/__init__.py +0 -0
  64. {otvision-0.6.6 → otvision-0.6.8}/OTVision/abstraction/__init__.py +0 -0
  65. {otvision-0.6.6 → otvision-0.6.8}/OTVision/abstraction/defaults.py +0 -0
  66. {otvision-0.6.6 → otvision-0.6.8}/OTVision/abstraction/observer.py +0 -0
  67. {otvision-0.6.6 → otvision-0.6.8}/OTVision/abstraction/pipes_and_filter.py +0 -0
  68. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/__init__.py +0 -0
  69. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/buffer.py +0 -0
  70. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/configure_logger.py +0 -0
  71. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/detect/__init__.py +0 -0
  72. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/detect/current_object_detector.py +0 -0
  73. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/detect/current_object_detector_metadata.py +0 -0
  74. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/detect/detected_frame_factory.py +0 -0
  75. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/detect/detection_file_save_path_provider.py +0 -0
  76. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/detect/factory.py +0 -0
  77. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/detect/get_detect_cli_args.py +0 -0
  78. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/detect/timestamper.py +0 -0
  79. {otvision-0.6.6/OTVision/application/track → otvision-0.6.8/OTVision/application/event}/__init__.py +0 -0
  80. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/frame_count_provider.py +0 -0
  81. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/get_config.py +0 -0
  82. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/get_current_config.py +0 -0
  83. {otvision-0.6.6/OTVision/convert → otvision-0.6.8/OTVision/application/track}/__init__.py +0 -0
  84. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/track/get_track_cli_args.py +0 -0
  85. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/track/update_current_track_config.py +0 -0
  86. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/track/update_track_config_with_cli_args.py +0 -0
  87. {otvision-0.6.6 → otvision-0.6.8}/OTVision/application/update_current_config.py +0 -0
  88. {otvision-0.6.6/OTVision/detect → otvision-0.6.8/OTVision/application/video}/__init__.py +0 -0
  89. {otvision-0.6.6/OTVision/detect/plugin_av → otvision-0.6.8/OTVision/convert}/__init__.py +0 -0
  90. {otvision-0.6.6 → otvision-0.6.8}/OTVision/convert/convert.py +0 -0
  91. {otvision-0.6.6 → otvision-0.6.8}/OTVision/dataformat.py +0 -0
  92. {otvision-0.6.6/OTVision/domain → otvision-0.6.8/OTVision/detect}/__init__.py +0 -0
  93. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/detect.py +0 -0
  94. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/detected_frame_buffer.py +0 -0
  95. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/otdet.py +0 -0
  96. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/otdet_file_writer.py +0 -0
  97. {otvision-0.6.6/OTVision/helpers → otvision-0.6.8/OTVision/detect/plugin_av}/__init__.py +0 -0
  98. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/plugin_av/rotate_frame.py +0 -0
  99. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/pyav_frame_count_provider.py +0 -0
  100. {otvision-0.6.6 → otvision-0.6.8}/OTVision/detect/timestamper.py +0 -0
  101. {otvision-0.6.6/OTVision/plugin → otvision-0.6.8/OTVision/domain}/__init__.py +0 -0
  102. {otvision-0.6.6 → otvision-0.6.8}/OTVision/domain/current_config.py +0 -0
  103. {otvision-0.6.6 → otvision-0.6.8}/OTVision/domain/detect_producer_consumer.py +0 -0
  104. {otvision-0.6.6 → otvision-0.6.8}/OTVision/domain/detection.py +0 -0
  105. {otvision-0.6.6 → otvision-0.6.8}/OTVision/domain/frame.py +0 -0
  106. {otvision-0.6.6 → otvision-0.6.8}/OTVision/domain/object_detection.py +0 -0
  107. {otvision-0.6.6 → otvision-0.6.8}/OTVision/domain/serialization.py +0 -0
  108. {otvision-0.6.6/OTVision/track → otvision-0.6.8/OTVision/helpers}/__init__.py +0 -0
  109. {otvision-0.6.6 → otvision-0.6.8}/OTVision/helpers/date.py +0 -0
  110. {otvision-0.6.6 → otvision-0.6.8}/OTVision/helpers/files.py +0 -0
  111. {otvision-0.6.6 → otvision-0.6.8}/OTVision/helpers/formats.py +0 -0
  112. {otvision-0.6.6 → otvision-0.6.8}/OTVision/helpers/input_types.py +0 -0
  113. {otvision-0.6.6 → otvision-0.6.8}/OTVision/helpers/log.py +0 -0
  114. {otvision-0.6.6 → otvision-0.6.8}/OTVision/helpers/machine.py +0 -0
  115. {otvision-0.6.6 → otvision-0.6.8}/OTVision/helpers/video.py +0 -0
  116. {otvision-0.6.6/OTVision/track/exporter → otvision-0.6.8/OTVision/plugin}/__init__.py +0 -0
  117. {otvision-0.6.6 → otvision-0.6.8}/OTVision/plugin/yaml_serialization.py +0 -0
  118. {otvision-0.6.6/OTVision/track/model → otvision-0.6.8/OTVision/track}/__init__.py +0 -0
  119. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/builder.py +0 -0
  120. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/cli.py +0 -0
  121. {otvision-0.6.6/OTVision/track/model/filebased → otvision-0.6.8/OTVision/track/exporter}/__init__.py +0 -0
  122. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/exporter/filebased_exporter.py +0 -0
  123. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/id_generator.py +0 -0
  124. {otvision-0.6.6/OTVision/track/parser → otvision-0.6.8/OTVision/track/model}/__init__.py +0 -0
  125. {otvision-0.6.6/OTVision/track/tracker → otvision-0.6.8/OTVision/track/model/filebased}/__init__.py +0 -0
  126. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/model/filebased/frame_chunk.py +0 -0
  127. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/model/filebased/frame_group.py +0 -0
  128. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/model/track_exporter.py +0 -0
  129. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/model/tracking_interfaces.py +0 -0
  130. {otvision-0.6.6/OTVision/transform → otvision-0.6.8/OTVision/track/parser}/__init__.py +0 -0
  131. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/parser/chunk_parser_plugins.py +0 -0
  132. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/parser/frame_group_parser_plugins.py +0 -0
  133. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/track.py +0 -0
  134. {otvision-0.6.6/OTVision/view → otvision-0.6.8/OTVision/track/tracker}/__init__.py +0 -0
  135. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/tracker/filebased_tracking.py +0 -0
  136. {otvision-0.6.6 → otvision-0.6.8}/OTVision/track/tracker/tracker_plugin_iou.py +0 -0
  137. {otvision-0.6.6/tests → otvision-0.6.8/OTVision/transform}/__init__.py +0 -0
  138. {otvision-0.6.6 → otvision-0.6.8}/OTVision/transform/get_homography.py +0 -0
  139. {otvision-0.6.6 → otvision-0.6.8}/OTVision/transform/reference_points_picker.py +0 -0
  140. {otvision-0.6.6 → otvision-0.6.8}/OTVision/transform/transform.py +0 -0
  141. {otvision-0.6.6/tests/abstraction → otvision-0.6.8/OTVision/view}/__init__.py +0 -0
  142. {otvision-0.6.6 → otvision-0.6.8}/OTVision/view/helpers/OTC.ico +0 -0
  143. {otvision-0.6.6 → otvision-0.6.8}/OTVision/view/view.py +0 -0
  144. {otvision-0.6.6 → otvision-0.6.8}/OTVision/view/view_convert.py +0 -0
  145. {otvision-0.6.6 → otvision-0.6.8}/OTVision/view/view_detect.py +0 -0
  146. {otvision-0.6.6 → otvision-0.6.8}/OTVision/view/view_helpers.py +0 -0
  147. {otvision-0.6.6 → otvision-0.6.8}/OTVision/view/view_track.py +0 -0
  148. {otvision-0.6.6 → otvision-0.6.8}/OTVision/view/view_transform.py +0 -0
  149. {otvision-0.6.6 → otvision-0.6.8}/OTVision.bat +0 -0
  150. {otvision-0.6.6 → otvision-0.6.8}/README.md +0 -0
  151. {otvision-0.6.6 → otvision-0.6.8}/clean-up-repository.sh +0 -0
  152. {otvision-0.6.6 → otvision-0.6.8}/convert.py +0 -0
  153. {otvision-0.6.6 → otvision-0.6.8}/detect.py +0 -0
  154. {otvision-0.6.6 → otvision-0.6.8}/install.cmd +0 -0
  155. {otvision-0.6.6 → otvision-0.6.8}/install.sh +0 -0
  156. {otvision-0.6.6 → otvision-0.6.8}/install_dev.cmd +0 -0
  157. {otvision-0.6.6 → otvision-0.6.8}/install_dev.sh +0 -0
  158. {otvision-0.6.6 → otvision-0.6.8}/pyproject.toml +0 -0
  159. {otvision-0.6.6 → otvision-0.6.8}/reference_points_picker.py +0 -0
  160. {otvision-0.6.6/tests/application → otvision-0.6.8/tests}/__init__.py +0 -0
  161. {otvision-0.6.6/tests/application/detect → otvision-0.6.8/tests/abstraction}/__init__.py +0 -0
  162. {otvision-0.6.6 → otvision-0.6.8}/tests/abstraction/test_defaults.py +0 -0
  163. {otvision-0.6.6 → otvision-0.6.8}/tests/abstraction/test_observer.py +0 -0
  164. {otvision-0.6.6/tests/application/track → otvision-0.6.8/tests/application}/__init__.py +0 -0
  165. {otvision-0.6.6/tests/convert → otvision-0.6.8/tests/application/detect}/__init__.py +0 -0
  166. {otvision-0.6.6 → otvision-0.6.8}/tests/application/detect/test_current_object_detector.py +0 -0
  167. {otvision-0.6.6 → otvision-0.6.8}/tests/application/detect/test_detected_frame_factory.py +0 -0
  168. {otvision-0.6.6 → otvision-0.6.8}/tests/application/detect/test_detection_file_save_path_provider.py +0 -0
  169. {otvision-0.6.6 → otvision-0.6.8}/tests/application/detect/test_get_detect_cli_args.py +0 -0
  170. {otvision-0.6.6 → otvision-0.6.8}/tests/application/detect/test_timestamper.py +0 -0
  171. {otvision-0.6.6 → otvision-0.6.8}/tests/application/test_buffer.py +0 -0
  172. {otvision-0.6.6 → otvision-0.6.8}/tests/application/test_get_config.py +0 -0
  173. {otvision-0.6.6/tests/detect → otvision-0.6.8/tests/application/track}/__init__.py +0 -0
  174. {otvision-0.6.6 → otvision-0.6.8}/tests/application/track/test_get_track_cli_args.py +0 -0
  175. {otvision-0.6.6 → otvision-0.6.8}/tests/application/track/test_update_current_track_config.py +0 -0
  176. {otvision-0.6.6 → otvision-0.6.8}/tests/application/track/test_update_track_config_with_cli_args.py +0 -0
  177. {otvision-0.6.6 → otvision-0.6.8}/tests/cli/custom_cli_test_config.yaml +0 -0
  178. {otvision-0.6.6 → otvision-0.6.8}/tests/cli/test_convert_cli.py +0 -0
  179. {otvision-0.6.6 → otvision-0.6.8}/tests/cli/test_track_cli.py +0 -0
  180. {otvision-0.6.6 → otvision-0.6.8}/tests/conftest.py +0 -0
  181. {otvision-0.6.6/tests/detect/plugin_av → otvision-0.6.8/tests/convert}/__init__.py +0 -0
  182. {otvision-0.6.6 → otvision-0.6.8}/tests/convert/test_convert.py +0 -0
  183. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_CamView.png +0 -0
  184. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_CamView_Cars-Cyclist.png +0 -0
  185. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_CamView_Cars-Truck.png +0 -0
  186. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_CamView_refpts.png +0 -0
  187. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.gpkg +0 -0
  188. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  189. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  190. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  191. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otrfpts +0 -0
  192. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  193. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.gpkg +0 -0
  194. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  195. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  196. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  197. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otrfpts +0 -0
  198. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  199. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_FR20.otrfpts +0 -0
  200. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Satellite.jpg +0 -0
  201. {otvision-0.6.6 → otvision-0.6.8}/tests/data/Testvideo_Satellite_far.jpg +0 -0
  202. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  203. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  204. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  205. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  206. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/fail_fps_from_filename/Testvideo_Cars-Cyclist_F20_2020-01-01_00-00-00.h264 +0 -0
  207. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/fail_fps_from_filename/Testvideo_Cars-Truck_2020-01-01_00-00-00.h264 +0 -0
  208. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/fps_from_filename/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  209. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/fps_from_filename/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  210. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/fps_from_filename/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  211. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/fps_from_filename/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  212. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/input_fps_20/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  213. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/input_fps_20/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  214. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/input_fps_20/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  215. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/input_fps_20/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  216. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/input_fps_40/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  217. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/input_fps_40/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  218. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/input_fps_40/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  219. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/input_fps_40/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  220. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.avi +0 -0
  221. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  222. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.avi +0 -0
  223. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_avi/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  224. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  225. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mkv +0 -0
  226. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  227. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mkv/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mkv +0 -0
  228. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  229. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mov +0 -0
  230. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  231. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mov/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mov +0 -0
  232. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.h264 +0 -0
  233. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  234. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.h264 +0 -0
  235. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/output_filetype_mp4/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  236. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/rotation/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00_rotate.h264 +0 -0
  237. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/rotation/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00_rotate.mov +0 -0
  238. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/rotation/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00_rotate.mp4 +0 -0
  239. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/rotation/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00_rotate.h264 +0 -0
  240. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/rotation/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00_rotate.mov +0 -0
  241. {otvision-0.6.6 → otvision-0.6.8}/tests/data/convert/rotation/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00_rotate.mp4 +0 -0
  242. {otvision-0.6.6 → otvision-0.6.8}/tests/data/detect/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  243. {otvision-0.6.6 → otvision-0.6.8}/tests/data/detect/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.mp4 +0 -0
  244. {otvision-0.6.6 → otvision-0.6.8}/tests/data/detect/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  245. {otvision-0.6.6 → otvision-0.6.8}/tests/data/detect/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  246. {otvision-0.6.6 → otvision-0.6.8}/tests/data/detect/rotated-Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.mp4 +0 -0
  247. {otvision-0.6.6 → otvision-0.6.8}/tests/data/log/_otvision_logs/test.log +0 -0
  248. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  249. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/default/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  250. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  251. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/default/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  252. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  253. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  254. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  255. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_h_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  256. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  257. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  258. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  259. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_h_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  260. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  261. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  262. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  263. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_iou_0_2/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  264. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  265. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  266. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  267. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_iou_0_6/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  268. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  269. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  270. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  271. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_l_0_1/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  272. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  273. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  274. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  275. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/sigma_l_0_5/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  276. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_min_10/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  277. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_min_10/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  278. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_min_10/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  279. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_min_10/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  280. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_min_3/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  281. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_min_3/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  282. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_min_3/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  283. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_min_3/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  284. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_miss_max_25/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  285. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_miss_max_25/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  286. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_miss_max_25/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  287. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_miss_max_25/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  288. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_miss_max_75/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otdet +0 -0
  289. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_miss_max_75/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  290. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_miss_max_75/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otdet +0 -0
  291. {otvision-0.6.6 → otvision-0.6.8}/tests/data/track/t_miss_max_75/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  292. {otvision-0.6.6 → otvision-0.6.8}/tests/data/transform/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.gpkg +0 -0
  293. {otvision-0.6.6 → otvision-0.6.8}/tests/data/transform/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.otrfpts +0 -0
  294. {otvision-0.6.6 → otvision-0.6.8}/tests/data/transform/Testvideo_Cars-Cyclist_FR20_2020-01-01_00-00-00.ottrk +0 -0
  295. {otvision-0.6.6 → otvision-0.6.8}/tests/data/transform/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.gpkg +0 -0
  296. {otvision-0.6.6 → otvision-0.6.8}/tests/data/transform/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.otrfpts +0 -0
  297. {otvision-0.6.6 → otvision-0.6.8}/tests/data/transform/Testvideo_Cars-Truck_FR20_2020-01-01_00-00-00.ottrk +0 -0
  298. {otvision-0.6.6 → otvision-0.6.8}/tests/data/transform/Testvideo_FR20.otrfpts +0 -0
  299. {otvision-0.6.6 → otvision-0.6.8}/tests/data/yolov8m.mlpackage/Data/com.apple.CoreML/model.mlmodel +0 -0
  300. {otvision-0.6.6 → otvision-0.6.8}/tests/data/yolov8m.mlpackage/Data/com.apple.CoreML/weights/weight.bin +0 -0
  301. {otvision-0.6.6 → otvision-0.6.8}/tests/data/yolov8m.mlpackage/Manifest.json +0 -0
  302. {otvision-0.6.6/tests/helpers → otvision-0.6.8/tests/detect}/__init__.py +0 -0
  303. {otvision-0.6.6 → otvision-0.6.8}/tests/detect/detect_test.py +0 -0
  304. {otvision-0.6.6/tests/log → otvision-0.6.8/tests/detect/plugin_av}/__init__.py +0 -0
  305. {otvision-0.6.6 → otvision-0.6.8}/tests/detect/plugin_av/test_rotate_frame.py +0 -0
  306. {otvision-0.6.6 → otvision-0.6.8}/tests/detect/test_detected_frame_buffer.py +0 -0
  307. {otvision-0.6.6 → otvision-0.6.8}/tests/detect/test_otdet.py +0 -0
  308. {otvision-0.6.6 → otvision-0.6.8}/tests/detect/test_otdet_file_writer.py +0 -0
  309. {otvision-0.6.6 → otvision-0.6.8}/tests/detect/test_pyav_frame_count_provider.py +0 -0
  310. {otvision-0.6.6 → otvision-0.6.8}/tests/detect/yolo_test.py +0 -0
  311. {otvision-0.6.6/tests/track → otvision-0.6.8/tests/helpers}/__init__.py +0 -0
  312. {otvision-0.6.6 → otvision-0.6.8}/tests/helpers/files_test.py +0 -0
  313. {otvision-0.6.6 → otvision-0.6.8}/tests/helpers/formats_test.py +0 -0
  314. {otvision-0.6.6 → otvision-0.6.8}/tests/helpers/test_log.py +0 -0
  315. {otvision-0.6.6/tests/track/helper → otvision-0.6.8/tests/log}/__init__.py +0 -0
  316. {otvision-0.6.6 → otvision-0.6.8}/tests/log/log_maker.py +0 -0
  317. {otvision-0.6.6 → otvision-0.6.8}/tests/log/test_log.py +0 -0
  318. {otvision-0.6.6/tests/track/parser → otvision-0.6.8/tests/plugin}/__init__.py +0 -0
  319. {otvision-0.6.6 → otvision-0.6.8}/tests/test_config.py +0 -0
  320. {otvision-0.6.6/tests/transform → otvision-0.6.8/tests/track}/__init__.py +0 -0
  321. {otvision-0.6.6/tests/utils → otvision-0.6.8/tests/track/helper}/__init__.py +0 -0
  322. {otvision-0.6.6 → otvision-0.6.8}/tests/track/helper/data_builder.py +0 -0
  323. {otvision-0.6.6 → otvision-0.6.8}/tests/track/parser/test_chunk_parser_plugins.py +0 -0
  324. {otvision-0.6.6 → otvision-0.6.8}/tests/track/test_frame_chunk.py +0 -0
  325. {otvision-0.6.6 → otvision-0.6.8}/tests/track/test_frame_group.py +0 -0
  326. {otvision-0.6.6 → otvision-0.6.8}/tests/track/test_frame_group_parser_plugins.py +0 -0
  327. {otvision-0.6.6 → otvision-0.6.8}/tests/track/test_track.py +0 -0
  328. {otvision-0.6.6 → otvision-0.6.8}/tests/track/test_tracking_data_structures.py +0 -0
  329. {otvision-0.6.6 → otvision-0.6.8}/tests/transform/test_transform.py +0 -0
  330. {otvision-0.6.6 → otvision-0.6.8}/tests/utils/generator.py +0 -0
  331. {otvision-0.6.6 → otvision-0.6.8}/tests/utils/mocking.py +0 -0
  332. {otvision-0.6.6 → otvision-0.6.8}/track.py +0 -0
  333. {otvision-0.6.6 → otvision-0.6.8}/transform.py +0 -0
  334. {otvision-0.6.6 → otvision-0.6.8}/update_precommit.py +0 -0
  335. {otvision-0.6.6 → otvision-0.6.8}/view.py +0 -0
@@ -26,14 +26,37 @@ jobs:
26
26
  steps:
27
27
  - name: Checkout code
28
28
  uses: actions/checkout@v4
29
+
30
+ - name: Fetch all tags
31
+ run: git fetch --tags --unshallow
32
+
29
33
  - name: Set up Python
30
34
  uses: actions/setup-python@v5
31
35
  with:
32
36
  python-version: "3.12"
37
+
38
+ - name: Get latest tag and create new version
39
+ id: get_version
40
+ run: |
41
+ # Get the latest tag in format v*.*.* (ignoring tags like "nightly")
42
+ LATEST_TAG="$(git tag -l "v*.*.*" | sort -V | tail -n 1 || echo 'v0.0.0')"
43
+ # Extract version without 'v' prefix
44
+ VERSION="${LATEST_TAG#v}"
45
+ # Split version into parts
46
+ IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"
47
+ # Increment patch version
48
+ PATCH="$((PATCH + 1))"
49
+ # Create new version with incremented patch
50
+ INCREMENTED_VERSION="$MAJOR.$MINOR.$PATCH"
51
+ DATE_TIME="$(date +'%Y%m%d%H%M%S')"
52
+ NEW_VERSION="${INCREMENTED_VERSION}a${DATE_TIME}"
53
+ echo "Final version: $NEW_VERSION"
54
+ echo "new_version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
55
+
33
56
  - name: Update Python Package Version
34
57
  uses: platomo/update-version-py-action@v1.0.1
35
58
  with:
36
- version: nightly
59
+ version: ${{ steps.get_version.outputs.new_version }}
37
60
  file-path: "OTVision"
38
61
  - name: Install pypa/build
39
62
  shell: bash
@@ -45,14 +45,15 @@ repos:
45
45
  entry: mypy .
46
46
  additional_dependencies:
47
47
  - av==13.0.0
48
- - black==24.8.0
48
+ - black==25.1.0
49
49
  - coremltools==8.2; sys_platform == 'darwin'
50
+ - ffmpeg-python==0.2.0
50
51
  - fire==0.7.0
51
52
  - hatch-requirements-txt==0.4.1
52
53
  - ijson==3.3.0
53
54
  - interrogate==1.5.0
54
55
  - isort==5.13.2
55
- - more-itertools==10.5.0
56
+ - more-itertools==10.7.0
56
57
  - moviepy==1.0.3
57
58
  - mypy==1.15.0
58
59
  - numpy==1.26.4; sys_platform == 'win32'
@@ -63,17 +64,16 @@ repos:
63
64
  - pre-commit==3.8.0
64
65
  - pytest-cov==5.0.0
65
66
  - pytest==8.3.3
66
- - torch==2.3.1
67
- - torchvision==0.18.1
67
+ - torchvision==0.22.1
68
68
  - twine==6.1.0
69
69
  - types-PyYAML
70
70
  - types-flake8
71
71
  - types-geopandas
72
72
  - types-jsonschema
73
- - types-setuptools
73
+ - types-torch
74
74
  - types-tqdm
75
75
  - types-ujson
76
- - ultralytics==8.3.94
76
+ - ultralytics==8.3.159
77
77
  - yamllint==1.35.1
78
78
  always_run: true
79
79
  pass_filenames: false
@@ -2,6 +2,12 @@ from dataclasses import dataclass, field
2
2
  from datetime import datetime, timedelta
3
3
  from pathlib import Path
4
4
 
5
+ from OTVision.plugin.ffmpeg_video_writer import (
6
+ ConstantRateFactor,
7
+ EncodingSpeed,
8
+ VideoCodec,
9
+ )
10
+
5
11
  AVAILABLE_WEIGHTS = "AVAILABLEWEIGHTS"
6
12
  CALIBRATIONS = "CALIBRATIONS"
7
13
  COL_WIDTH = "COLWIDTH"
@@ -58,6 +64,10 @@ LOG_DIR = "LOG_DIR"
58
64
  START_TIME = "START_TIME"
59
65
  DETECT_END = "DETECT_END"
60
66
  DETECT_START = "DETECT_START"
67
+ WRITE_VIDEO = "WRITE_VIDEO"
68
+ VIDEO_CODEC = "VIDEO_CODEC"
69
+ ENCODING_SPEED = "ENCODING_SPEED"
70
+ CRF = "CRF"
61
71
  DATETIME_FORMAT = "%Y-%m-%d_%H-%M-%S"
62
72
  DEFAULT_EXPECTED_DURATION: timedelta = timedelta(minutes=15)
63
73
  """Default length of a video is 15 minutes."""
@@ -289,6 +299,10 @@ class DetectConfig:
289
299
  start_time: datetime | None = None
290
300
  detect_start: int | None = None
291
301
  detect_end: int | None = None
302
+ write_video: bool = False
303
+ video_codec: VideoCodec = VideoCodec.H264_SOFTWARE
304
+ encoding_speed: EncodingSpeed = EncodingSpeed.FAST
305
+ crf: ConstantRateFactor = ConstantRateFactor.DEFAULT
292
306
 
293
307
  def to_dict(self) -> dict:
294
308
  expected_duration = (
@@ -306,6 +320,10 @@ class DetectConfig:
306
320
  START_TIME: self.start_time,
307
321
  DETECT_START: self.detect_start,
308
322
  DETECT_END: self.detect_end,
323
+ WRITE_VIDEO: self.write_video,
324
+ VIDEO_CODEC: self.video_codec.value,
325
+ ENCODING_SPEED: self.encoding_speed.value,
326
+ CRF: self.crf.name,
309
327
  }
310
328
 
311
329
 
@@ -5,12 +5,14 @@ from OTVision.application.config import (
5
5
  COL_WIDTH,
6
6
  CONF,
7
7
  CONVERT,
8
+ CRF,
8
9
  DATETIME_FORMAT,
9
10
  DEFAULT_FILETYPE,
10
11
  DELETE_INPUT,
11
12
  DETECT,
12
13
  DETECT_END,
13
14
  DETECT_START,
15
+ ENCODING_SPEED,
14
16
  EXPECTED_DURATION,
15
17
  FLUSH_BUFFER_SIZE,
16
18
  FONT,
@@ -51,8 +53,10 @@ from OTVision.application.config import (
51
53
  TRANSFORM,
52
54
  UNDISTORT,
53
55
  VID,
56
+ VIDEO_CODEC,
54
57
  WEIGHTS,
55
58
  WINDOW,
59
+ WRITE_VIDEO,
56
60
  YOLO,
57
61
  Config,
58
62
  ConvertConfig,
@@ -181,15 +185,19 @@ class ConfigParser:
181
185
 
182
186
  start_time = self._parse_start_time(data)
183
187
  return DetectConfig(
184
- sources,
185
- data.get(RUN_CHAINED, DetectConfig.run_chained),
186
- yolo_config,
187
- expected_duration,
188
- data.get(OVERWRITE, DetectConfig.overwrite),
189
- data.get(HALF_PRECISION, DetectConfig.half_precision),
190
- start_time,
191
- data.get(DETECT_START, DetectConfig.detect_start),
192
- data.get(DETECT_END, DetectConfig.detect_end),
188
+ paths=sources,
189
+ run_chained=data.get(RUN_CHAINED, DetectConfig.run_chained),
190
+ yolo_config=yolo_config,
191
+ expected_duration=expected_duration,
192
+ overwrite=data.get(OVERWRITE, DetectConfig.overwrite),
193
+ half_precision=data.get(HALF_PRECISION, DetectConfig.half_precision),
194
+ start_time=start_time,
195
+ detect_start=data.get(DETECT_START, DetectConfig.detect_start),
196
+ detect_end=data.get(DETECT_END, DetectConfig.detect_end),
197
+ write_video=data.get(WRITE_VIDEO, DetectConfig.write_video),
198
+ video_codec=data.get(VIDEO_CODEC, DetectConfig.video_codec),
199
+ encoding_speed=data.get(ENCODING_SPEED, DetectConfig.encoding_speed),
200
+ crf=data.get(CRF, DetectConfig.crf),
193
201
  )
194
202
 
195
203
  def parse_yolo_config(self, data: dict) -> YoloConfig:
@@ -84,6 +84,22 @@ class UpdateDetectConfigWithCliArgs:
84
84
  if cli_args.detect_end is not None
85
85
  else detect_config.detect_end
86
86
  ),
87
+ write_video=(
88
+ cli_args.write_video
89
+ if cli_args.write_video is not None
90
+ else detect_config.write_video
91
+ ),
92
+ video_codec=(
93
+ cli_args.video_codec
94
+ if cli_args.video_codec is not None
95
+ else detect_config.video_codec
96
+ ),
97
+ encoding_speed=(
98
+ cli_args.encoding_speed
99
+ if cli_args.encoding_speed is not None
100
+ else detect_config.encoding_speed
101
+ ),
102
+ crf=cli_args.crf if cli_args.crf is not None else detect_config.crf,
87
103
  )
88
104
 
89
105
  def _update_log_config(self, config: Config, cli_args: DetectCliArgs) -> _LogConfig:
@@ -0,0 +1,9 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass(frozen=True)
5
+ class NewVideoStartEvent:
6
+ output: str
7
+ width: int
8
+ height: int
9
+ fps: float
@@ -0,0 +1,15 @@
1
+ from OTVision.abstraction.pipes_and_filter import Filter
2
+ from OTVision.domain.frame import Frame
3
+ from OTVision.domain.input_source_detect import InputSourceDetect
4
+
5
+
6
+ class GenerateVideo:
7
+ def __init__(
8
+ self, input_source: InputSourceDetect, video_writer: Filter[Frame, Frame]
9
+ ) -> None:
10
+ self._input_source = input_source
11
+ self._video_writer = video_writer
12
+
13
+ def generate(self) -> None:
14
+ for frame in self._video_writer.filter(self._input_source.produce()):
15
+ pass
@@ -77,6 +77,7 @@ from OTVision.application.config import (
77
77
  VIDEOS,
78
78
  WEIGHTS,
79
79
  WINDOW,
80
+ WRITE_VIDEO,
80
81
  YOLO,
81
82
  Config,
82
83
  )
@@ -176,6 +177,7 @@ CONFIG[DETECT][OVERWRITE] = True
176
177
  CONFIG[DETECT][HALF_PRECISION] = False
177
178
  CONFIG[DETECT][DETECT_START] = None
178
179
  CONFIG[DETECT][DETECT_END] = None
180
+ CONFIG[DETECT][WRITE_VIDEO] = False
179
181
 
180
182
  # TRACK
181
183
  CONFIG[TRACK] = {}
@@ -4,7 +4,7 @@ from functools import cached_property
4
4
 
5
5
  from OTVision.abstraction.observer import Subject
6
6
  from OTVision.application.buffer import Buffer
7
- from OTVision.application.config import Config
7
+ from OTVision.application.config import Config, DetectConfig
8
8
  from OTVision.application.config_parser import ConfigParser
9
9
  from OTVision.application.configure_logger import ConfigureLogger
10
10
  from OTVision.application.detect.current_object_detector import CurrentObjectDetector
@@ -12,9 +12,6 @@ from OTVision.application.detect.current_object_detector_metadata import (
12
12
  CurrentObjectDetectorMetadata,
13
13
  )
14
14
  from OTVision.application.detect.detected_frame_factory import DetectedFrameFactory
15
- from OTVision.application.detect.detected_frame_producer import (
16
- SimpleDetectedFrameProducer,
17
- )
18
15
  from OTVision.application.detect.detection_file_save_path_provider import (
19
16
  DetectionFileSavePathProvider,
20
17
  )
@@ -34,6 +31,10 @@ from OTVision.detect.detected_frame_buffer import (
34
31
  DetectedFrameBufferEvent,
35
32
  FlushEvent,
36
33
  )
34
+ from OTVision.detect.detected_frame_producer import (
35
+ DetectedFrameProducerFactory,
36
+ SimpleDetectedFrameProducer,
37
+ )
37
38
  from OTVision.detect.otdet import OtdetBuilder
38
39
  from OTVision.detect.otdet_file_writer import OtdetFileWriter
39
40
  from OTVision.detect.plugin_av.rotate_frame import AvVideoFrameRotator
@@ -47,6 +48,7 @@ from OTVision.domain.frame import DetectedFrame
47
48
  from OTVision.domain.input_source_detect import InputSourceDetect
48
49
  from OTVision.domain.object_detection import ObjectDetectorFactory
49
50
  from OTVision.domain.serialization import Deserializer
51
+ from OTVision.domain.video_writer import VideoWriter
50
52
  from OTVision.plugin.yaml_serialization import YamlDeserializer
51
53
 
52
54
 
@@ -152,9 +154,17 @@ class DetectBuilder(ABC):
152
154
  @cached_property
153
155
  def detected_frame_producer(self) -> DetectedFrameProducer:
154
156
  return SimpleDetectedFrameProducer(
157
+ producer_factory=self.detected_frame_producer_factory,
158
+ )
159
+
160
+ @cached_property
161
+ def detected_frame_producer_factory(self) -> DetectedFrameProducerFactory:
162
+ return DetectedFrameProducerFactory(
155
163
  input_source=self.input_source,
164
+ video_writer_filter=self.video_file_writer,
156
165
  detection_filter=self.current_object_detector,
157
166
  detected_frame_buffer=self.detected_frame_buffer,
167
+ get_current_config=self.get_current_config,
158
168
  )
159
169
 
160
170
  @cached_property
@@ -165,6 +175,10 @@ class DetectBuilder(ABC):
165
175
  def yaml_deserializer(self) -> Deserializer:
166
176
  return YamlDeserializer()
167
177
 
178
+ @property
179
+ def detect_config(self) -> DetectConfig:
180
+ return self.current_config.get().detect
181
+
168
182
  def __init__(self, argv: list[str] | None = None) -> None:
169
183
  self.argv = argv
170
184
 
@@ -173,6 +187,15 @@ class DetectBuilder(ABC):
173
187
  def input_source(self) -> InputSourceDetect:
174
188
  raise NotImplementedError
175
189
 
190
+ @property
191
+ @abstractmethod
192
+ def video_file_writer(self) -> VideoWriter:
193
+ raise NotImplementedError
194
+
195
+ @abstractmethod
196
+ def register_observers(self) -> None:
197
+ raise NotImplementedError
198
+
176
199
  def build(self) -> OTVisionVideoDetect:
177
200
  self.register_observers()
178
201
  self._preload_object_detection_model()
@@ -181,7 +204,3 @@ class DetectBuilder(ABC):
181
204
  def _preload_object_detection_model(self) -> None:
182
205
  model = self.current_object_detector.get()
183
206
  model.preload()
184
-
185
- def register_observers(self) -> None:
186
- self.input_source.register(self.detected_frame_buffer.on_flush)
187
- self.detected_frame_buffer.register(self.otdet_file_writer.write)
@@ -6,6 +6,11 @@ from OTVision.application.config import DATETIME_FORMAT
6
6
  from OTVision.domain.cli import CliParseError, DetectCliArgs, DetectCliParser
7
7
  from OTVision.helpers.files import check_if_all_paths_exist
8
8
  from OTVision.helpers.log import DEFAULT_LOG_FILE, VALID_LOG_LEVELS
9
+ from OTVision.plugin.ffmpeg_video_writer import (
10
+ ConstantRateFactor,
11
+ EncodingSpeed,
12
+ VideoCodec,
13
+ )
9
14
 
10
15
 
11
16
  class ArgparseDetectCliParser(DetectCliParser):
@@ -128,6 +133,34 @@ class ArgparseDetectCliParser(DetectCliParser):
128
133
  help="Specify end of detection in seconds.",
129
134
  required=False,
130
135
  )
136
+ self._parser.add_argument(
137
+ "--write-video",
138
+ default=None,
139
+ action="store_true",
140
+ help="Write video to output folder. Not supported on Windows.",
141
+ required=False,
142
+ )
143
+ self._parser.add_argument(
144
+ "--video-codec",
145
+ default=None,
146
+ choices=VideoCodec.as_list(),
147
+ help="Video codec for video writer. Default is 'libx264'",
148
+ required=False,
149
+ )
150
+ self._parser.add_argument(
151
+ "--encoding-speed",
152
+ default=None,
153
+ choices=EncodingSpeed.as_list(),
154
+ help="Encoding speed for video writer. Default is 'fast'",
155
+ required=False,
156
+ )
157
+ self._parser.add_argument(
158
+ "--crf",
159
+ default=None,
160
+ choices=ConstantRateFactor.as_list(),
161
+ help="Constant rate factor for video writer. Default is 'DEFAULT'",
162
+ required=False,
163
+ )
131
164
 
132
165
  def parse(self) -> DetectCliArgs:
133
166
  args = self._parser.parse_args(self._argv)
@@ -151,11 +184,21 @@ class ArgparseDetectCliParser(DetectCliParser):
151
184
  detect_start=(
152
185
  int(args.detect_start) if args.detect_start is not None else None
153
186
  ),
154
- detect_end=int(args.detect_end) if args.detect_end is not None else None,
187
+ detect_end=(int(args.detect_end) if args.detect_end is not None else None),
155
188
  logfile=Path(args.logfile),
156
189
  log_level_console=args.log_level_console,
157
190
  log_level_file=args.log_level_file,
158
191
  logfile_overwrite=args.logfile_overwrite,
192
+ write_video=args.write_video,
193
+ video_codec=(
194
+ VideoCodec(args.video_codec) if args.video_codec is not None else None
195
+ ),
196
+ encoding_speed=(
197
+ EncodingSpeed(args.encoding_speed)
198
+ if args.encoding_speed is not None
199
+ else None
200
+ ),
201
+ crf=ConstantRateFactor[args.crf] if args.crf is not None else None,
159
202
  )
160
203
 
161
204
  def _parse_start_time(self, start_time: str | None) -> datetime | None:
@@ -0,0 +1,14 @@
1
+ from typing import Generator
2
+
3
+ from OTVision.detect.detected_frame_producer_factory import DetectedFrameProducerFactory
4
+ from OTVision.domain.detect_producer_consumer import DetectedFrameProducer
5
+ from OTVision.domain.frame import DetectedFrame
6
+
7
+
8
+ class SimpleDetectedFrameProducer(DetectedFrameProducer):
9
+
10
+ def __init__(self, producer_factory: DetectedFrameProducerFactory) -> None:
11
+ self._producer_factory = producer_factory
12
+
13
+ def produce(self) -> Generator[DetectedFrame, None, None]:
14
+ return self._producer_factory.create()
@@ -0,0 +1,43 @@
1
+ from typing import Generator
2
+
3
+ from OTVision.abstraction.pipes_and_filter import Filter
4
+ from OTVision.application.get_current_config import GetCurrentConfig
5
+ from OTVision.domain.frame import DetectedFrame, Frame
6
+ from OTVision.domain.input_source_detect import InputSourceDetect
7
+
8
+
9
+ class DetectedFrameProducerFactory:
10
+ def __init__(
11
+ self,
12
+ input_source: InputSourceDetect,
13
+ video_writer_filter: Filter[Frame, Frame],
14
+ detection_filter: Filter[Frame, DetectedFrame],
15
+ detected_frame_buffer: Filter[DetectedFrame, DetectedFrame],
16
+ get_current_config: GetCurrentConfig,
17
+ ) -> None:
18
+ self._input_source = input_source
19
+ self._video_writer_filter = video_writer_filter
20
+ self._detection_filter = detection_filter
21
+ self._detected_frame_buffer = detected_frame_buffer
22
+ self._get_current_config = get_current_config
23
+
24
+ def create(self) -> Generator[DetectedFrame, None, None]:
25
+ if self._get_current_config.get().detect.write_video:
26
+ return self.__create_with_video_writer()
27
+ return self.__create_without_video_writer()
28
+
29
+ def __create_without_video_writer(
30
+ self,
31
+ ) -> Generator[DetectedFrame, None, None]:
32
+ return self._detected_frame_buffer.filter(
33
+ self._detection_filter.filter(self._input_source.produce())
34
+ )
35
+
36
+ def __create_with_video_writer(
37
+ self,
38
+ ) -> Generator[DetectedFrame, None, None]:
39
+ return self._detected_frame_buffer.filter(
40
+ self._detection_filter.filter(
41
+ self._video_writer_filter.filter(self._input_source.produce())
42
+ )
43
+ )
@@ -0,0 +1,55 @@
1
+ from functools import cached_property
2
+
3
+ from OTVision.abstraction.observer import Subject
4
+ from OTVision.application.event.new_video_start import NewVideoStartEvent
5
+ from OTVision.detect.builder import DetectBuilder
6
+ from OTVision.detect.detected_frame_buffer import FlushEvent
7
+ from OTVision.detect.video_input_source import VideoSource
8
+ from OTVision.domain.video_writer import VideoWriter
9
+ from OTVision.plugin.ffmpeg_video_writer import (
10
+ FfmpegVideoWriter,
11
+ PixelFormat,
12
+ VideoFormat,
13
+ append_save_suffix_to_save_location,
14
+ )
15
+
16
+
17
+ class FileBasedDetectBuilder(DetectBuilder):
18
+
19
+ @cached_property
20
+ def input_source(self) -> VideoSource:
21
+ return VideoSource(
22
+ subject_flush=Subject[FlushEvent](),
23
+ subject_new_video_start=Subject[NewVideoStartEvent](),
24
+ get_current_config=self.get_current_config,
25
+ frame_rotator=self.frame_rotator,
26
+ timestamper_factory=self.timestamper_factory,
27
+ save_path_provider=self.detection_file_save_path_provider,
28
+ )
29
+
30
+ @cached_property
31
+ def video_file_writer(self) -> VideoWriter:
32
+ # Using save_location_strategy=keep_original_save_location is not supported for
33
+ # file-based detection. Otherwise, we would be overwriting the input source that
34
+ # we are reading from.
35
+ return FfmpegVideoWriter(
36
+ save_location_strategy=append_save_suffix_to_save_location,
37
+ encoding_speed=self.detect_config.encoding_speed,
38
+ input_format=VideoFormat.RAW,
39
+ output_format=VideoFormat.MP4,
40
+ input_pixel_format=PixelFormat.RGB24,
41
+ output_pixel_format=PixelFormat.YUV420P,
42
+ output_video_codec=self.detect_config.video_codec,
43
+ constant_rate_factor=self.detect_config.crf,
44
+ )
45
+
46
+ def register_observers(self) -> None:
47
+ if self.detect_config.write_video:
48
+ self.input_source.subject_new_video_start.register(
49
+ self.video_file_writer.notify_on_new_video_start
50
+ )
51
+ self.input_source.subject_flush.register(
52
+ self.video_file_writer.notify_on_flush_event
53
+ )
54
+ self.input_source.subject_flush.register(self.detected_frame_buffer.on_flush)
55
+ self.detected_frame_buffer.register(self.otdet_file_writer.write)
@@ -0,0 +1,69 @@
1
+ from functools import cached_property
2
+
3
+ from OTVision.abstraction.observer import Subject
4
+ from OTVision.application.config import StreamConfig
5
+ from OTVision.application.event.new_video_start import NewVideoStartEvent
6
+ from OTVision.detect.builder import DetectBuilder
7
+ from OTVision.detect.detected_frame_buffer import FlushEvent
8
+ from OTVision.detect.rtsp_input_source import Counter, RtspInputSource
9
+ from OTVision.domain.time import CurrentDatetimeProvider, DatetimeProvider
10
+ from OTVision.domain.video_writer import VideoWriter
11
+ from OTVision.plugin.ffmpeg_video_writer import (
12
+ FfmpegVideoWriter,
13
+ PixelFormat,
14
+ VideoFormat,
15
+ keep_original_save_location,
16
+ )
17
+
18
+ FLUSH_BUFFER_SIZE = 18000
19
+ FLUSH_BUFFER_SIZE = 1200
20
+
21
+
22
+ class RtspBasedDetectBuilder(DetectBuilder):
23
+ @property
24
+ def stream_config(self) -> StreamConfig:
25
+ config = self.get_current_config.get()
26
+ if config.stream is None:
27
+ raise ValueError(
28
+ "Stream config is not provided. "
29
+ "Running OTVision in streaming mode requires stream config"
30
+ )
31
+ return config.stream
32
+
33
+ @cached_property
34
+ def input_source(self) -> RtspInputSource:
35
+ return RtspInputSource(
36
+ subject_flush=Subject[FlushEvent](),
37
+ subject_new_video_start=Subject[NewVideoStartEvent](),
38
+ datetime_provider=self.datetime_provider,
39
+ frame_counter=Counter(),
40
+ get_current_config=self.get_current_config,
41
+ )
42
+
43
+ @cached_property
44
+ def datetime_provider(self) -> DatetimeProvider:
45
+ return CurrentDatetimeProvider()
46
+
47
+ @cached_property
48
+ def video_file_writer(self) -> VideoWriter:
49
+ return FfmpegVideoWriter(
50
+ save_location_strategy=keep_original_save_location,
51
+ encoding_speed=self.detect_config.encoding_speed,
52
+ input_format=VideoFormat.RAW,
53
+ output_format=VideoFormat.MP4,
54
+ input_pixel_format=PixelFormat.RGB24,
55
+ output_pixel_format=PixelFormat.YUV420P,
56
+ output_video_codec=self.detect_config.video_codec,
57
+ constant_rate_factor=self.detect_config.crf,
58
+ )
59
+
60
+ def register_observers(self) -> None:
61
+ if self.detect_config.write_video:
62
+ self.input_source.subject_new_video_start.register(
63
+ self.video_file_writer.notify_on_new_video_start
64
+ )
65
+ self.input_source.subject_flush.register(
66
+ self.video_file_writer.notify_on_flush_event
67
+ )
68
+ self.input_source.subject_flush.register(self.detected_frame_buffer.on_flush)
69
+ self.detected_frame_buffer.register(self.otdet_file_writer.write)