OTVision 0.6.4__py3-none-any.whl → 0.6.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. OTVision/abstraction/defaults.py +15 -0
  2. OTVision/application/config.py +475 -0
  3. OTVision/application/config_parser.py +280 -0
  4. OTVision/application/configure_logger.py +1 -1
  5. OTVision/application/detect/factory.py +1 -1
  6. OTVision/application/detect/update_detect_config_with_cli_args.py +2 -1
  7. OTVision/application/get_config.py +2 -1
  8. OTVision/application/get_current_config.py +1 -1
  9. OTVision/application/track/__init__.py +0 -0
  10. OTVision/application/track/get_track_cli_args.py +20 -0
  11. OTVision/application/track/update_current_track_config.py +42 -0
  12. OTVision/application/track/update_track_config_with_cli_args.py +52 -0
  13. OTVision/application/update_current_config.py +1 -1
  14. OTVision/config.py +61 -668
  15. OTVision/convert/convert.py +3 -3
  16. OTVision/detect/builder.py +27 -20
  17. OTVision/detect/cli.py +3 -3
  18. OTVision/detect/detected_frame_buffer.py +3 -0
  19. OTVision/detect/file_based_detect_builder.py +19 -0
  20. OTVision/detect/otdet.py +54 -1
  21. OTVision/detect/otdet_file_writer.py +3 -2
  22. OTVision/detect/rtsp_based_detect_builder.py +37 -0
  23. OTVision/detect/rtsp_input_source.py +199 -0
  24. OTVision/detect/timestamper.py +1 -1
  25. OTVision/detect/video_input_source.py +2 -1
  26. OTVision/detect/yolo.py +17 -1
  27. OTVision/domain/cli.py +31 -1
  28. OTVision/domain/current_config.py +1 -1
  29. OTVision/domain/object_detection.py +6 -1
  30. OTVision/domain/serialization.py +12 -0
  31. OTVision/domain/time.py +13 -0
  32. OTVision/helpers/files.py +14 -15
  33. OTVision/plugin/__init__.py +0 -0
  34. OTVision/plugin/yaml_serialization.py +20 -0
  35. OTVision/track/builder.py +132 -0
  36. OTVision/track/cli.py +128 -0
  37. OTVision/track/exporter/filebased_exporter.py +2 -1
  38. OTVision/track/id_generator.py +15 -0
  39. OTVision/track/model/track_exporter.py +2 -1
  40. OTVision/track/model/tracking_interfaces.py +6 -6
  41. OTVision/track/parser/frame_group_parser_plugins.py +35 -5
  42. OTVision/track/track.py +54 -133
  43. OTVision/track/tracker/filebased_tracking.py +8 -7
  44. OTVision/track/tracker/tracker_plugin_iou.py +14 -9
  45. OTVision/transform/transform.py +2 -2
  46. OTVision/version.py +1 -1
  47. otvision-0.6.5.dist-info/METADATA +182 -0
  48. {otvision-0.6.4.dist-info → otvision-0.6.5.dist-info}/RECORD +50 -33
  49. otvision-0.6.4.dist-info/METADATA +0 -49
  50. {otvision-0.6.4.dist-info → otvision-0.6.5.dist-info}/WHEEL +0 -0
  51. {otvision-0.6.4.dist-info → otvision-0.6.5.dist-info}/licenses/LICENSE +0 -0
OTVision/track/track.py CHANGED
@@ -1,144 +1,65 @@
1
1
  import logging
2
- import uuid
3
- from pathlib import Path
4
- from typing import Callable, Iterator
5
2
 
6
3
  from tqdm import tqdm
7
4
 
8
- from OTVision import dataformat
9
- from OTVision.config import (
10
- CONFIG,
11
- DETECT,
12
- FILETYPES,
13
- IOU,
14
- OVERWRITE,
15
- SIGMA_H,
16
- SIGMA_IOU,
17
- SIGMA_L,
18
- T_MIN,
19
- T_MISS_MAX,
20
- TRACK,
21
- )
5
+ from OTVision.application.config import Config
6
+ from OTVision.application.get_current_config import GetCurrentConfig
22
7
  from OTVision.helpers.files import get_files
23
8
  from OTVision.helpers.input_types import check_types
24
9
  from OTVision.helpers.log import LOGGER_NAME
25
- from OTVision.track.exporter.filebased_exporter import FinishedChunkTrackExporter
26
- from OTVision.track.parser.chunk_parser_plugins import JsonChunkParser
27
- from OTVision.track.parser.frame_group_parser_plugins import (
28
- TimeThresholdFrameGroupParser,
29
- )
30
- from OTVision.track.tracker.filebased_tracking import (
31
- GroupedFilesTracker,
32
- UnfinishedChunksBuffer,
33
- )
34
- from OTVision.track.tracker.tracker_plugin_iou import IouParameters, IouTracker
35
-
36
-
37
- def track_id_generator() -> Iterator[int]:
38
- ID: int = 0
39
- while True:
40
- ID += 1
41
- yield ID
42
-
10
+ from OTVision.track.id_generator import StrIdGenerator, tracking_run_uuid_generator
11
+ from OTVision.track.model.track_exporter import FinishedTracksExporter
12
+ from OTVision.track.tracker.filebased_tracking import UnfinishedChunksBuffer
43
13
 
44
14
  log = logging.getLogger(LOGGER_NAME)
45
- STR_ID_GENERATOR = Callable[[], str]
46
-
47
-
48
- def tracker_metadata(
49
- sigma_l: float, sigma_h: float, sigma_iou: float, t_min: float, t_miss_max: float
50
- ) -> dict:
51
- return {
52
- dataformat.NAME: "IOU",
53
- dataformat.SIGMA_L: sigma_l,
54
- dataformat.SIGMA_H: sigma_h,
55
- dataformat.SIGMA_IOU: sigma_iou,
56
- dataformat.T_MIN: t_min,
57
- dataformat.T_MISS_MAX: t_miss_max,
58
- }
59
-
60
-
61
- def main(
62
- paths: list[Path],
63
- sigma_l: float = CONFIG[TRACK][IOU][SIGMA_L],
64
- sigma_h: float = CONFIG[TRACK][IOU][SIGMA_H],
65
- sigma_iou: float = CONFIG[TRACK][IOU][SIGMA_IOU],
66
- t_min: int = CONFIG[TRACK][IOU][T_MIN],
67
- t_miss_max: int = CONFIG[TRACK][IOU][T_MISS_MAX],
68
- overwrite: bool = CONFIG[TRACK][OVERWRITE],
69
- tracking_run_id_generator: STR_ID_GENERATOR = lambda: str(uuid.uuid4()),
70
- ) -> None:
71
- """Read detections from otdet file, perform tracking using iou tracker and
72
- save tracks to ottrk file.
73
-
74
- Args:
75
- paths (list[Path]): List of paths to detection files.
76
- sigma_l (float, optional): Lower confidence threshold. Detections with
77
- confidences below sigma_l are not even considered for tracking.
78
- Defaults to CONFIG["TRACK"]["IOU"]["SIGMA_L"].
79
- sigma_h (float, optional): Upper confidence threshold. Tracks are only
80
- considered as valid if they contain at least one detection with a confidence
81
- above sigma_h.
82
- Defaults to CONFIG["TRACK"]["IOU"]["SIGMA_H"].
83
- sigma_iou (float, optional): Intersection-Over-Union threshold. Two detections
84
- in subsequent frames are considered to belong to the same track if their IOU
85
- value exceeds sigma_iou and this is the highest IOU of all possible
86
- combination of detections.
87
- Defaults to CONFIG["TRACK"]["IOU"]["SIGMA_IOU"].
88
- t_min (int, optional): Minimum number of detections to count as a valid track.
89
- All tracks with less detections will be dissmissed.
90
- Defaults to CONFIG["TRACK"]["IOU"]["T_MIN"].
91
- t_miss_max (int, optional): Maximum number of missed detections before
92
- continuing a track. If more detections are missing, the track will not be
93
- continued.
94
- Defaults to CONFIG["TRACK"]["IOU"]["T_MISS_MAX"].
95
- overwrite (bool, optional): Whether or not to overwrite existing tracks files.
96
- Defaults to CONFIG["TRACK"]["OVERWRITE"].
97
- tracking_run_id_generator (IdGenerator): Generator used to create a unique id
98
- for this tracking run
99
- """
100
-
101
- check_types(sigma_l, sigma_h, sigma_iou, t_min, t_miss_max)
102
-
103
- filetypes = CONFIG[FILETYPES][DETECT]
104
- detections_files = get_files(paths=paths, filetypes=filetypes)
105
-
106
- start_msg = f"Start tracking of {len(detections_files)} detections files"
107
- log.info(start_msg)
108
- print(start_msg)
109
-
110
- if not detections_files:
111
- log.warning(f"No files of type '{filetypes}' found to track!")
112
- return
113
-
114
- iou_tracker: IouTracker = IouTracker(
115
- parameters=IouParameters(sigma_l, sigma_h, sigma_iou, t_min, t_miss_max)
116
- )
117
-
118
- chunk_parser = JsonChunkParser()
119
- group_parser = TimeThresholdFrameGroupParser(
120
- tracker_data=tracker_metadata(sigma_l, sigma_h, sigma_iou, t_min, t_miss_max)
121
- )
122
-
123
- file_tracker = GroupedFilesTracker(
124
- tracker=iou_tracker,
125
- chunk_parser=chunk_parser,
126
- frame_group_parser=group_parser,
127
- id_generator_factory=lambda _: track_id_generator(),
128
- overwrite=True,
129
- )
130
-
131
- buffer = UnfinishedChunksBuffer(
132
- tracker=file_tracker,
133
- keep_discarded=True,
134
- )
135
-
136
- exporter = FinishedChunkTrackExporter()
137
15
 
138
- tracking_run_id = tracking_run_id_generator()
139
- finished_chunk_stream = buffer.group_and_track(detections_files)
140
16
 
141
- finished_chunk_progress = tqdm(
142
- finished_chunk_stream, desc="export FrameChunk", total=len(detections_files)
143
- )
144
- exporter.export(tracking_run_id, iter(finished_chunk_progress), overwrite)
17
+ class OtvisionTrack:
18
+ @property
19
+ def config(self) -> Config:
20
+ return self._get_current_config.get()
21
+
22
+ def __init__(
23
+ self,
24
+ get_current_config: GetCurrentConfig,
25
+ track_exporter: FinishedTracksExporter,
26
+ unfinished_chunks_buffer: UnfinishedChunksBuffer,
27
+ tracking_run_id_generator: StrIdGenerator = tracking_run_uuid_generator,
28
+ ) -> None:
29
+ self._get_current_config = get_current_config
30
+ self._track_exporter = track_exporter
31
+ self._buffer = unfinished_chunks_buffer
32
+ self._tracking_run_id_generator = tracking_run_id_generator
33
+
34
+ def start(self) -> None:
35
+ check_types(
36
+ self.config.track.sigma_l,
37
+ self.config.track.sigma_h,
38
+ self.config.track.sigma_iou,
39
+ self.config.track.t_min,
40
+ self.config.track.t_miss_max,
41
+ )
42
+
43
+ detections_files = get_files(
44
+ paths=self.config.track.paths, filetypes=[self.config.filetypes.detect]
45
+ )
46
+
47
+ start_msg = f"Start tracking of {len(detections_files)} detections files"
48
+ log.info(start_msg)
49
+ print(start_msg)
50
+
51
+ if not detections_files:
52
+ log.warning(
53
+ f"No files of type '{self.config.filetypes.detect}' " "found to track!"
54
+ )
55
+ return
56
+
57
+ tracking_run_id = self._tracking_run_id_generator()
58
+ finished_chunk_stream = self._buffer.group_and_track(detections_files)
59
+
60
+ finished_chunk_progress = tqdm(
61
+ finished_chunk_stream, desc="export FrameChunk", total=len(detections_files)
62
+ )
63
+ self._track_exporter.export(
64
+ tracking_run_id, iter(finished_chunk_progress), self.config.track.overwrite
65
+ )
@@ -5,7 +5,8 @@ from typing import Callable, Iterator
5
5
  from more_itertools import peekable
6
6
  from tqdm import tqdm
7
7
 
8
- from OTVision.config import CONFIG, DEFAULT_FILETYPE, OVERWRITE, TRACK
8
+ from OTVision.application.config import DEFAULT_FILETYPE, OVERWRITE, TRACK
9
+ from OTVision.config import CONFIG
9
10
  from OTVision.domain.detection import TrackId
10
11
  from OTVision.domain.frame import DetectedFrame, FrameNo, IsLastFrame, TrackedFrame
11
12
  from OTVision.helpers.log import LOGGER_NAME
@@ -17,7 +18,7 @@ from OTVision.track.model.filebased.frame_chunk import (
17
18
  )
18
19
  from OTVision.track.model.filebased.frame_group import FrameGroup, FrameGroupParser
19
20
  from OTVision.track.model.tracking_interfaces import (
20
- ID_GENERATOR,
21
+ IdGenerator,
21
22
  Tracker,
22
23
  UnfinishedTracksBuffer,
23
24
  )
@@ -35,7 +36,7 @@ class ChunkBasedTracker(Tracker):
35
36
  def track_frame(
36
37
  self,
37
38
  frames: DetectedFrame,
38
- id_generator: ID_GENERATOR,
39
+ id_generator: IdGenerator,
39
40
  ) -> TrackedFrame:
40
41
  return self._tracker.track_frame(frames, id_generator)
41
42
 
@@ -43,7 +44,7 @@ class ChunkBasedTracker(Tracker):
43
44
  self,
44
45
  chunk: FrameChunk,
45
46
  is_last_chunk: bool,
46
- id_generator: ID_GENERATOR,
47
+ id_generator: IdGenerator,
47
48
  ) -> TrackedChunk:
48
49
  frames_progress = tqdm(
49
50
  chunk.frames, desc="track Frame", total=len(chunk.frames), leave=False
@@ -63,14 +64,14 @@ class ChunkBasedTracker(Tracker):
63
64
  file: Path,
64
65
  frame_group: FrameGroup,
65
66
  is_last_file: bool,
66
- id_generator: ID_GENERATOR,
67
+ id_generator: IdGenerator,
67
68
  frame_offset: int = 0,
68
69
  ) -> TrackedChunk:
69
70
  chunk = self._chunk_parser.parse(file, frame_group, frame_offset)
70
71
  return self.track_chunk(chunk, is_last_file, id_generator)
71
72
 
72
73
 
73
- ID_GENERATOR_FACTORY = Callable[[FrameGroup], ID_GENERATOR]
74
+ IdGeneratorFactory = Callable[[FrameGroup], IdGenerator]
74
75
 
75
76
 
76
77
  class GroupedFilesTracker(ChunkBasedTracker):
@@ -80,7 +81,7 @@ class GroupedFilesTracker(ChunkBasedTracker):
80
81
  tracker: Tracker,
81
82
  chunk_parser: ChunkParser,
82
83
  frame_group_parser: FrameGroupParser,
83
- id_generator_factory: ID_GENERATOR_FACTORY,
84
+ id_generator_factory: IdGeneratorFactory,
84
85
  overwrite: bool = CONFIG[TRACK][OVERWRITE],
85
86
  file_type: str = CONFIG[DEFAULT_FILETYPE][TRACK],
86
87
  ) -> None:
@@ -1,8 +1,10 @@
1
1
  from dataclasses import dataclass
2
2
 
3
+ from OTVision.application.config import TrackConfig
4
+ from OTVision.application.get_current_config import GetCurrentConfig
3
5
  from OTVision.domain.detection import Detection, TrackedDetection, TrackId
4
6
  from OTVision.domain.frame import DetectedFrame, FrameNo, TrackedFrame
5
- from OTVision.track.model.tracking_interfaces import ID_GENERATOR, Tracker
7
+ from OTVision.track.model.tracking_interfaces import IdGenerator, Tracker
6
8
 
7
9
 
8
10
  @dataclass(frozen=True)
@@ -138,34 +140,37 @@ def iou(
138
140
 
139
141
 
140
142
  class IouTracker(Tracker):
143
+ @property
144
+ def config(self) -> TrackConfig:
145
+ return self._get_current_config.get().track
141
146
 
142
- def __init__(self, parameters: IouParameters):
147
+ def __init__(self, get_current_config: GetCurrentConfig):
143
148
  super().__init__()
144
- self.parameters = parameters
149
+ self._get_current_config = get_current_config
145
150
  self.active_tracks: list[ActiveIouTrack] = []
146
151
 
147
152
  @property
148
153
  def sigma_l(self) -> float:
149
- return self.parameters.sigma_l
154
+ return self.config.iou.sigma_l
150
155
 
151
156
  @property
152
157
  def sigma_h(self) -> float:
153
- return self.parameters.sigma_h
158
+ return self.config.iou.sigma_h
154
159
 
155
160
  @property
156
161
  def sigma_iou(self) -> float:
157
- return self.parameters.sigma_iou
162
+ return self.config.iou.sigma_iou
158
163
 
159
164
  @property
160
165
  def t_min(self) -> int:
161
- return self.parameters.t_min
166
+ return self.config.iou.t_min
162
167
 
163
168
  @property
164
169
  def t_miss_max(self) -> int:
165
- return self.parameters.t_miss_max
170
+ return self.config.iou.t_miss_max
166
171
 
167
172
  def track_frame(
168
- self, frame: DetectedFrame, id_generator: ID_GENERATOR
173
+ self, frame: DetectedFrame, id_generator: IdGenerator
169
174
  ) -> TrackedFrame:
170
175
 
171
176
  detections = [d for d in frame.detections if d.conf >= self.sigma_l]
@@ -31,8 +31,7 @@ import numpy as np
31
31
  import pandas as pd
32
32
  from tqdm import tqdm
33
33
 
34
- from OTVision.config import (
35
- CONFIG,
34
+ from OTVision.application.config import (
36
35
  DEFAULT_FILETYPE,
37
36
  FILETYPES,
38
37
  OVERWRITE,
@@ -40,6 +39,7 @@ from OTVision.config import (
40
39
  TRACK,
41
40
  TRANSFORM,
42
41
  )
42
+ from OTVision.config import CONFIG
43
43
  from OTVision.helpers.files import (
44
44
  get_files,
45
45
  get_metadata,
OTVision/version.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "v0.6.4"
1
+ __version__ = "v0.6.5"
2
2
 
3
3
 
4
4
  def otdet_version() -> str:
@@ -0,0 +1,182 @@
1
+ Metadata-Version: 2.4
2
+ Name: OTVision
3
+ Version: 0.6.5
4
+ Summary: OTVision is a core module of the OpenTrafficCam framework to perform object detection and tracking.
5
+ Project-URL: Homepage, https://opentrafficcam.org/
6
+ Project-URL: Documentation, https://opentrafficcam.org/overview/
7
+ Project-URL: Repository, https://github.com/OpenTrafficCam/OTVision
8
+ Project-URL: Issues, https://github.com/OpenTrafficCam/OTVision/issues
9
+ Project-URL: Changelog, https://github.com/OpenTrafficCam/OTVision/releases
10
+ Author-email: OpenTrafficCam contributors <team@opentrafficcam.org>, platomo GmbH <info@platomo.de>
11
+ License-Expression: GPL-3.0-only
12
+ License-File: LICENSE
13
+ Keywords: OpenTrafficCam,Traffic Analysis,Traffic Counting,Trajectories
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Requires-Python: >=3.11
19
+ Requires-Dist: av==13.0.0
20
+ Requires-Dist: fire==0.7.0
21
+ Requires-Dist: geopandas==1.0.1
22
+ Requires-Dist: ijson==3.3.0
23
+ Requires-Dist: more-itertools==10.5.0
24
+ Requires-Dist: moviepy==1.0.3
25
+ Requires-Dist: numpy==1.26.4; sys_platform == 'win32'
26
+ Requires-Dist: numpy==2.1.1; sys_platform != 'win32'
27
+ Requires-Dist: opencv-python==4.10.0.84
28
+ Requires-Dist: pandas==2.2.3
29
+ Requires-Dist: pyyaml==6.0.2
30
+ Requires-Dist: setuptools==74.0.0
31
+ Requires-Dist: torch==2.3.1
32
+ Requires-Dist: torchvision==0.18.1
33
+ Requires-Dist: tqdm==4.67.1
34
+ Requires-Dist: ujson==5.10.0
35
+ Requires-Dist: ultralytics==8.3.94
36
+ Description-Content-Type: text/markdown
37
+
38
+ # OTVision
39
+
40
+ [![PyPI version](https://img.shields.io/pypi/v/OTVision.svg)](https://pypi.org/project/OTVision/)
41
+ [![Tests](https://github.com/OpenTrafficCam/OTVision/actions/workflows/test.yml/badge.svg?tag=latest)](https://github.com/OpenTrafficCam/OTVision/actions/workflows/test.yml?query=tag%3Alatest)
42
+ [![Tests](https://github.com/OpenTrafficCam/OTVision/actions/workflows/build-release.yml/badge.svg)](https://github.com/OpenTrafficCam/OTVision/actions/workflows/build-release.yml)
43
+
44
+ OTVision is a core module of the [OpenTrafficCam framework](https://github.com/OpenTrafficCam) designed to detect and track objects (road users) in videos recorded by [OTCamera](https://github.com/OpenTrafficCam/OTCamera) or other camera systems. The resulting trajectories can be used for traffic analysis using [OTAnalytics](https://github.com/OpenTrafficCam/OTAnalytics).
45
+
46
+ ## Features
47
+
48
+ - **Video Conversion**: Convert video files (h264 to mp4) with options to set frame rate and rotation
49
+ - **Object Detection**: Detect road users in videos using state-of-the-art YOLO models
50
+ - **Object Tracking**: Track detected objects through video frames using IOU-based tracking algorithms
51
+ - **Coordinate Transformation**: Transform pixel coordinates to real-world UTM coordinates
52
+
53
+ ## Requirements
54
+
55
+ ### System Requirements
56
+
57
+ - Python 3.12 or higher
58
+ - CUDA-capable GPU (recommended for faster processing)
59
+ - Dependencies listed in [requirements.txt](requirements.txt)
60
+
61
+ ## Installation
62
+
63
+ ### Installation from GitHub Releases
64
+
65
+ Pre-built releases are available on GitHub for easy installation:
66
+
67
+ 1. Go to the [OTVision Releases page](https://github.com/OpenTrafficCam/OTVision/releases) on GitHub
68
+ 2. Download the appropriate release for your platform:
69
+ - **Windows**: Choose between `otvision-win.zip` (standard) or `otvision-win-cuda.zip` (with CUDA support)
70
+ - **Linux**: Choose between `otvision-linux.zip` (standard) or `otvision-linux-cuda.zip` (with CUDA support)
71
+ - **macOS**: Choose `OTVision-macos.zip`
72
+ 3. Extract the downloaded ZIP file
73
+ 4. Run the installation script:
74
+ - On Windows: Double-click `install.cmd`
75
+ - On Linux: Run `./install.sh`
76
+ - On macOS: Double-click `install.command`
77
+
78
+ ### Manual Installation
79
+
80
+ 1. Clone the repository:
81
+
82
+ ```bash
83
+ git clone https://github.com/OpenTrafficCam/OTVision.git
84
+ cd OTVision
85
+ ```
86
+
87
+ 2. Install the package:
88
+ - On Windows:
89
+ ```cmd
90
+ install.cmd
91
+ ```
92
+ - On Linux/macOS:
93
+ ```bash
94
+ ./install.sh
95
+ ```
96
+
97
+ ### Manual Development Installation
98
+
99
+ For development purposes, if you want to contribute to the project:
100
+
101
+ 1. Clone the repository:
102
+
103
+ ```bash
104
+ git clone https://github.com/OpenTrafficCam/OTVision.git
105
+ cd OTVision
106
+ ```
107
+
108
+ 2. Install the development version:
109
+ - On Windows:
110
+ ```cmd
111
+ install_dev.cmd
112
+ ```
113
+ - On Linux/macOS:
114
+ ```bash
115
+ ./install_dev.sh
116
+ ```
117
+
118
+ ## Usage
119
+
120
+ OTVision provides several command-line scripts for different functionalities:
121
+
122
+ ### Video Conversion
123
+
124
+ Convert video files (e.g., h264 to mp4):
125
+
126
+ ```bash
127
+ python convert.py --paths /path/to/videos/*.h264 --input-fps 20.0 --rotation 0
128
+ ```
129
+
130
+ ### Object Detection
131
+
132
+ Detect objects in videos:
133
+
134
+ ```bash
135
+ python detect.py --paths /path/to/videos/*.mp4 --weights yolov8s
136
+ ```
137
+
138
+ ### Object Tracking
139
+
140
+ Track detected objects:
141
+
142
+ ```bash
143
+ python track.py --paths /path/to/detections/*.otdet
144
+ ```
145
+
146
+ ### Coordinate Transformation
147
+
148
+ Transform pixel coordinates to UTM coordinates:
149
+
150
+ ```bash
151
+ python transform.py --paths /path/to/tracks/*.ottrk --refpts-file /path/to/reference_points.json
152
+ ```
153
+
154
+ ### Configuration
155
+
156
+ OTVision can be configured using a YAML configuration file. A default configuration is provided in `user_config.otvision.yaml`. You can specify a custom configuration file using the `--config` option:
157
+
158
+ ```bash
159
+ python detect.py --config /path/to/custom_config.yaml
160
+ ```
161
+
162
+ ## Documentation
163
+
164
+ For detailed documentation, visit:
165
+
166
+ - [OTVision Documentation](https://opentrafficcam.org/OTVision/)
167
+ - [Getting Started Guide](https://opentrafficcam.org/OTVision/gettingstarted/firstuse/)
168
+ - [Requirements](https://opentrafficcam.org/OTVision/gettingstarted/requirements/)
169
+ - [Installation Guide](https://opentrafficcam.org/OTVision/gettingstarted/installation/)
170
+
171
+ ## Contributing
172
+
173
+ We appreciate your support in the form of both code and comments. Please have a look at the [contribute](https://opentrafficcam.org/contribute) section of the OpenTrafficCam documentation for guidelines on how to contribute to the project.
174
+
175
+ ## License
176
+
177
+ This software is licensed under the [GPL-3.0 License](LICENSE).
178
+
179
+ ## Contact
180
+
181
+ - GitHub: [https://github.com/OpenTrafficCam](https://github.com/OpenTrafficCam)
182
+ - Email: [team@opentrafficcam.org](mailto:team@opentrafficcam.org)
@@ -1,78 +1,95 @@
1
1
  OTVision/__init__.py,sha256=CLnfgTlVHM4_nzDacvy06Z_Crc3hU6usd0mUyEvBf24,781
2
- OTVision/config.py,sha256=x_Bh3mrfV434puVchuG0zLsTtjIl-_C0-ZbmRW3tyFM,24371
2
+ OTVision/config.py,sha256=0ecnI0N2rS2q0Ld6gBpK4iU2iyuUw683XWjj4g-L1m4,5336
3
3
  OTVision/dataformat.py,sha256=BHF7qHzyNb80hI1EKfwcdJ9bgG_X4bp_hCXzdg7_MSA,1941
4
- OTVision/version.py,sha256=yVwTz7eqQw6SQVvUKkYsgB6HAwAyCSDykNLqZF7h1bA,175
4
+ OTVision/version.py,sha256=pPG0EpzyxpxNsBhpPGGgivl4nunilLlKyXa5gBTSYYo,175
5
5
  OTVision/abstraction/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ OTVision/abstraction/defaults.py,sha256=ftETDe25gmr563RPSbG6flcEiNiHnRb0iXK1Zj_zdNg,442
6
7
  OTVision/abstraction/observer.py,sha256=ZFGxUUjI3wUpf5ogXg2yDe-QjCcXre6SxH5zOogOx2U,1350
7
8
  OTVision/abstraction/pipes_and_filter.py,sha256=rzYaWDalXnlMbfpkgI91a0FL0q1llUlCRuIQsidYDv8,940
8
9
  OTVision/application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
10
  OTVision/application/buffer.py,sha256=eoK3Rfvc_72cQD3EAASzmxhznjmnIFFh3LX9fqAzXyU,1166
10
- OTVision/application/configure_logger.py,sha256=RmRgYkvSXWqpFX3N2n0h2LDna3uL8AY-yfVZU66t5q4,611
11
+ OTVision/application/config.py,sha256=FFNmwiwZnAqDax8xIJhVhW_wK1FKrhaSzBgYXjcAoq0,13080
12
+ OTVision/application/config_parser.py,sha256=CLBTEKDqREbEpf6-N7ZDPu8EV4OgWbaGfAJAPWLbhwA,9162
13
+ OTVision/application/configure_logger.py,sha256=1TzHB-zm7vGTPtUp7m28ne4WxOyiUYeChLZU-ZPyOVQ,623
11
14
  OTVision/application/frame_count_provider.py,sha256=zN_75IM-w9Xlc5rT8OArhiWhPHR8mUfFhdzhSmQQuaM,693
12
- OTVision/application/get_config.py,sha256=fRJZUWJvlTed6qriw82-B-05CAqfBma6NQ23WrKqYdE,771
13
- OTVision/application/get_current_config.py,sha256=RPVexRhJxY4ul8sU0W2OJaj98eTJxMlP-CiioQZCpEI,299
14
- OTVision/application/update_current_config.py,sha256=1p-F00myUofn-S97NMMfJ9SbemJiLKc_FS3ob_27YjM,321
15
+ OTVision/application/get_config.py,sha256=kFRTFQ1eLzBZCIkLrsf0wk7pWIlnUQRXvoZsl0QttVM,829
16
+ OTVision/application/get_current_config.py,sha256=iqtY10FRpn2FgLsasejjlyPFP3NrQJNKkEGo8PE5tc8,311
17
+ OTVision/application/update_current_config.py,sha256=iW1rpCClTHn8tnmVSpLVxdEB0nh1O_JCyxEqog0r0NU,333
15
18
  OTVision/application/detect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
19
  OTVision/application/detect/current_object_detector.py,sha256=J4U5k1s902agN90FYR4M_gO8MYYa_5XkYGREjStWCxQ,1343
17
20
  OTVision/application/detect/current_object_detector_metadata.py,sha256=xai0UBEzxr-rxXCc8mTmNDECds7mdsw2sem5HZxvQ4Q,1017
18
21
  OTVision/application/detect/detected_frame_factory.py,sha256=Rl6ElFYulgWPK_XZQSXZcT6caF8hvfzMKsOFefYO_pY,963
19
22
  OTVision/application/detect/detected_frame_producer.py,sha256=LD4AnQG04YGE68TpxmaRuWRZeCZfhp8oixk6SHTru7c,906
20
23
  OTVision/application/detect/detection_file_save_path_provider.py,sha256=nUyzgR7imrH8PkUl_72kdUDiolPXq1_RQqbpFwLI5Cs,2165
21
- OTVision/application/detect/factory.py,sha256=UWQHqpaT6FyhMTzTIBSGR06_Hxo8HKM2-IlSpP_djYA,926
24
+ OTVision/application/detect/factory.py,sha256=UCnLtgpWdNqwwjW0v2yzKF9Gacx6gewjTyy43wXs2Jg,938
22
25
  OTVision/application/detect/get_detect_cli_args.py,sha256=gezr17im8SwbuXW1suCodWRrFs8lSljNKu76SbWBgkY,265
23
26
  OTVision/application/detect/timestamper.py,sha256=us9l1GaPnSfMrUZQ5UEDBPX787ypeUiUtpOZm3JpgM0,653
24
- OTVision/application/detect/update_detect_config_with_cli_args.py,sha256=NP4asZx792JivYnH-9jDj72yjITkyObiJcWObf13M4U,3723
27
+ OTVision/application/detect/update_detect_config_with_cli_args.py,sha256=_8vaFfqqtq1tjj8twArqPKOmQBiCzdBnEKhSRNjX_yQ,3769
28
+ OTVision/application/track/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ OTVision/application/track/get_track_cli_args.py,sha256=uebHGDB6xzttak_Z4Nos08Ay69QKT2JypfHwn1dLpIM,553
30
+ OTVision/application/track/update_current_track_config.py,sha256=pCFNuGl6rqpsUUGm2i1kjLSuuITVXv2R79Xf81n45as,1667
31
+ OTVision/application/track/update_track_config_with_cli_args.py,sha256=5MDr2ih4xHzZ0kI6TSQ2C4mcWsPXW2PB80kA22-M_5I,2273
25
32
  OTVision/convert/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
- OTVision/convert/convert.py,sha256=vRIFcrAUf9MUWAuvF_q7JQ9aN89B1ouBOCtXrCLuDp8,11013
33
+ OTVision/convert/convert.py,sha256=UUfzpbtMlxlJgKE6XeT5nyNqK26-K02bQDhq3o7KrXE,11050
27
34
  OTVision/detect/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- OTVision/detect/builder.py,sha256=ZFSUnDmx742DqxuEG3N8Hf7ynvE0jLkxvRYAApbB3zA,6967
29
- OTVision/detect/cli.py,sha256=qsmbt43j0KAyj8XVuo-QEHxQZJ80DVmpDGZ-d1lE14I,6025
35
+ OTVision/detect/builder.py,sha256=P2RbTTffetz0gBfNKKYBOKuXEJyGRk3HDyclYAXBGxY,7166
36
+ OTVision/detect/cli.py,sha256=_fB_4UH_AhxUFxKDgzErieiviUZ1u51Zb66YRIXUXVE,6052
30
37
  OTVision/detect/detect.py,sha256=YaVS-DJXdEmh-OzwE31UPNl2uk7mcFyO_CKKTgMeiuM,1328
31
- OTVision/detect/detected_frame_buffer.py,sha256=BsyPQ9nI6QdN40ZZKA-eXTxRU_noYuDsH2UhzSdVkQY,1444
32
- OTVision/detect/otdet.py,sha256=6yYSNHayzBBVu4PBaMobkh7jBhQKQ6KbnQPOefwoJh8,4508
33
- OTVision/detect/otdet_file_writer.py,sha256=9xeBD5I44Yp3DblZWpnOQuBVRWDQ2eObyevmBid2Wyw,4252
38
+ OTVision/detect/detected_frame_buffer.py,sha256=TrLbImpvCm1B09Z3c000e2uDO5WguyVwoMmFAqH8Zvk,1505
39
+ OTVision/detect/file_based_detect_builder.py,sha256=C6BqVuknbJzX-B4N4nSwJgEpt9Nf79Oen8H6so9AflU,754
40
+ OTVision/detect/otdet.py,sha256=-8rZGY9NVRAwIHeVcNCjm665SmnW5UVIO_PSKdHegDA,6274
41
+ OTVision/detect/otdet_file_writer.py,sha256=l4NRWwMywiho4KOhrzxpJqAklyzE6nOtxpkt1kyy3Ss,4318
34
42
  OTVision/detect/pyav_frame_count_provider.py,sha256=w7p9iM3F2fljV8SD7q491gQhIHANbVczqtalcUiKj-E,453
35
- OTVision/detect/timestamper.py,sha256=4wsbkv-ex4zGhPCcYWqQQ2JbqVVPCmVzoT2U6efsy-o,5232
36
- OTVision/detect/video_input_source.py,sha256=dVH2gPRV5yW4mpoIK6S0iQKWZJCwIhMnPLabJwDtbWI,8495
37
- OTVision/detect/yolo.py,sha256=YkeE1A-NULsOgx0y2SH16nzBNBYAAd-TdQLzYGfuBH8,9845
43
+ OTVision/detect/rtsp_based_detect_builder.py,sha256=5-jg4ivJhiWi3PVIILVThorDNKg-i4Z-rFqZ2n01RDY,1322
44
+ OTVision/detect/rtsp_input_source.py,sha256=U0yY-t56wxyh1j-7R48Dbrb4bTGYnCwIAiuHZjM2EGw,6568
45
+ OTVision/detect/timestamper.py,sha256=lexX7zahtoyg0tnyu5lkiqHvauewqBCLe0DPXBR10YY,5244
46
+ OTVision/detect/video_input_source.py,sha256=vaf1RfoeXnOqrk76xvcrX_UsAseNKeKXkg73Aurj3NI,8555
47
+ OTVision/detect/yolo.py,sha256=Ksj8X7DZmONalaMB_iz-AtXwhEk4Fu7nZNzrXpqfhQw,10451
38
48
  OTVision/detect/plugin_av/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
49
  OTVision/detect/plugin_av/rotate_frame.py,sha256=4wJqTYI2HRlfa4p2Ffap33vLmKIzE_EwFvQraEkQ4R8,1055
40
50
  OTVision/domain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
- OTVision/domain/cli.py,sha256=XRIDSv4TJvXxwJw1UVznHSpaeUIRiikCabyGuiwh_2o,1049
42
- OTVision/domain/current_config.py,sha256=TKb6Nuei8n2v6k873w0AkDNAnvSwqphdi5h6hlZ4Y5k,274
51
+ OTVision/domain/cli.py,sha256=VNZZ_zc1x6RzndQlOFp5HSeWTg_VAiF1G3IhYymdrzA,1781
52
+ OTVision/domain/current_config.py,sha256=Q38NCktoGNU1Z_miXNoJXLH8-NDbVszwVOMGR1aAwWM,286
43
53
  OTVision/domain/detect_producer_consumer.py,sha256=gD7NwscQZLmCxMDZpZkGql0oMrpGHDBBNvdTXs58Vvw,855
44
54
  OTVision/domain/detection.py,sha256=SZLP-87XE3NcTkeYz7GTqp4oPMiqI1P5gILp1_yHtxY,3761
45
55
  OTVision/domain/frame.py,sha256=qHduCRbBTgzGLIuu7MlLWvhzphPlD3V0nrjlEApmr00,6211
46
56
  OTVision/domain/input_source_detect.py,sha256=9DzkTg5dh7_KmxE9oxdmxrcTYhvZY8hHLZwhrh7Gz2o,1245
47
- OTVision/domain/object_detection.py,sha256=k2VoQlaUhnpAUtX-OdbgDdt4qN0o7zjFGA5rZn1gneY,1251
57
+ OTVision/domain/object_detection.py,sha256=kyrTbP9sZBKtGo54vCNfluDMM8wpWZST9Oqf8m8Q1y4,1394
58
+ OTVision/domain/serialization.py,sha256=S7gb648z_W8U3Fb6TSk7hVU4qHlGwOZ7D6FeYSLXQwM,257
59
+ OTVision/domain/time.py,sha256=gVjhWNRhYKDp11CcCYHlymlWbhGEIFjWlUwVDat77eY,327
48
60
  OTVision/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
61
  OTVision/helpers/date.py,sha256=XK0fmXMombQ2CJ2_RXjk-bc-R8qqXRK2rDmCMBi0_G0,854
50
- OTVision/helpers/files.py,sha256=g_ix1e_ti1ZlW4zOulvkUiupcE8KJV_OHGNGXQTQ71I,18478
62
+ OTVision/helpers/files.py,sha256=G7zoOHzWIYrMmkjgHJHkZbh2hcGtnwZomuspthG2GsE,18444
51
63
  OTVision/helpers/formats.py,sha256=YLo_QLA2nhVREyv5N-xNW20c4nIL7DIF40E1lrsAyLE,4365
52
64
  OTVision/helpers/input_types.py,sha256=d94IYX0e-ersz3bl8xy9SklGUom-LjPUQ-BRsOmpH68,649
53
65
  OTVision/helpers/log.py,sha256=fOSMTXQRQ3_3zzYL8pDlx85IXPwyDsI2WGpK-V_R47Q,4985
54
66
  OTVision/helpers/machine.py,sha256=8Bz_Eg7PS0IL4riOVeJcEIi5D9E8Ju8-JomTkW975p8,2166
55
67
  OTVision/helpers/video.py,sha256=xyI35CiWXqoeGd3HeLhZUPxrLz8GccWyzHusxoweJr4,1480
68
+ OTVision/plugin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
+ OTVision/plugin/yaml_serialization.py,sha256=LjJ_QLJPClRwsaw7ooagWT7LBW08OvSb527jbex1qIQ,557
56
70
  OTVision/track/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
- OTVision/track/track.py,sha256=hrmvwIR4nV6wA8DUuYPSCrDXr7cAP13WXo_gZDBX7hE,5054
71
+ OTVision/track/builder.py,sha256=kHGV8Bb7Uh_SbVP1-tT5p68yzBqiWEeLmjM_P6wnE3A,4868
72
+ OTVision/track/cli.py,sha256=Lzmij9vMuaArB8MerDcGlaefwKMgRWNWov1YLGWA6SI,4294
73
+ OTVision/track/id_generator.py,sha256=qv9SZnI72sXc5ePBIke8TAB6trVs0RU1vgiAqFtpxoo,287
74
+ OTVision/track/track.py,sha256=7v_qJ-J3RoU6MNLSVjwM61TFjki6YyctSOhzvE8Z8WY,2303
58
75
  OTVision/track/exporter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
- OTVision/track/exporter/filebased_exporter.py,sha256=7LFoHcqrlNCd0KDQZA5qI2sZFlxecazJ6sBwdVvvdWE,947
76
+ OTVision/track/exporter/filebased_exporter.py,sha256=sdaWY4CxjawyeEKG329T92Bodf1E8wjnXuXocv0Ppgo,986
60
77
  OTVision/track/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
- OTVision/track/model/track_exporter.py,sha256=FUuMsdNqWmjqRQasqB6A_0h73NAt-Mt8V93O_ajCHf4,3228
62
- OTVision/track/model/tracking_interfaces.py,sha256=UCCikNv3RQScyHj0Db9jvDS3RaxZXPKLmS1VAYynZ4U,10785
78
+ OTVision/track/model/track_exporter.py,sha256=ZzpQJB6e599tapRB-vTbhCltflnPVdgmLwCELRRV9Z8,3267
79
+ OTVision/track/model/tracking_interfaces.py,sha256=wZONk_wHn72RRYBgcetGX7NzN_lfVuoa8BJ7RANF6N4,10779
63
80
  OTVision/track/model/filebased/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
81
  OTVision/track/model/filebased/frame_chunk.py,sha256=rXhQCHXWGJbePy5ZW3JZCdltGz5mZxFdcrW0mgez-2k,6771
65
82
  OTVision/track/model/filebased/frame_group.py,sha256=f-hXS1Vc5U_qf2cgNbYVeSTZ3dg5NUJhasOEHuuX1HE,2977
66
83
  OTVision/track/parser/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
84
  OTVision/track/parser/chunk_parser_plugins.py,sha256=ojBv_mCOXABmygxz5mhXzeysur3ECmT4a4VlGkeT11k,3108
68
- OTVision/track/parser/frame_group_parser_plugins.py,sha256=N5jS6Aq2Aq4gc0ouX0UOBqCUagNLRQRjS_81k_OzZi4,4575
85
+ OTVision/track/parser/frame_group_parser_plugins.py,sha256=TWnGhM-N7ldN8LHZ1YYecEjn4xo2o91PyOGgr4Jzh9M,5479
69
86
  OTVision/track/tracker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- OTVision/track/tracker/filebased_tracking.py,sha256=bYE1_NX08dy3KDrBpD8aTobtQqg9Id8h4WudZgUEZ5Q,6546
71
- OTVision/track/tracker/tracker_plugin_iou.py,sha256=4e4DUOClwn8cYYyloUj2ux7DTCVeAs7WMptmAeDMNWY,7234
87
+ OTVision/track/tracker/filebased_tracking.py,sha256=H3WYbsSca-67898diBoixpLjBqQDnOSiqnbvvySE6fc,6576
88
+ OTVision/track/tracker/tracker_plugin_iou.py,sha256=PQOB3fXlNKSTEGK7HFfaUfTRgXSY1ZhlVmjk1VWugFU,7484
72
89
  OTVision/transform/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
90
  OTVision/transform/get_homography.py,sha256=29waW61uzCCB7tlBAS2zck9sliAxZqnjjOa4jOOHHIc,5970
74
91
  OTVision/transform/reference_points_picker.py,sha256=LOmwzCaqbJnXVhaTSaZtkCzTMDamYjbTpY8I99pN0rg,16578
75
- OTVision/transform/transform.py,sha256=cv8HIX-uPYVQWLGHU-8OrkQjJ2cOh3GIZ13wqeI431w,12455
92
+ OTVision/transform/transform.py,sha256=2FmTHoPimwb6ymDZW-KiWBsESHidQvYUCoWlWbb-ABM,12490
76
93
  OTVision/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
94
  OTVision/view/view.py,sha256=sBFGfr-lf8lG1BTaQ3Iu46GpZGhaVhSrqg8p5XUPJ4I,3302
78
95
  OTVision/view/view_convert.py,sha256=NUtmrmAAFCYdQS1U2av_eYUScXugQYjhD3e3H0pro6Q,5157
@@ -81,7 +98,7 @@ OTVision/view/view_helpers.py,sha256=a5yV_6ZxO5bxsSymOmxdHqzOEv0VFq4wFBopVRGuVRo
81
98
  OTVision/view/view_track.py,sha256=vmfMqpbUfnzg_EsWiL-IIKNOApVF09dzSojHpUfYY6M,5393
82
99
  OTVision/view/view_transform.py,sha256=HvRd8g8geKRy0OoiZUDn_oC3SJC5nuXhZf3uZelfGKg,5473
83
100
  OTVision/view/helpers/OTC.ico,sha256=G9kwlDtgBXmXO3yxW6Z-xVFV2q4nUGuz9E1VPHSu_I8,21662
84
- otvision-0.6.4.dist-info/METADATA,sha256=CRrwlIK6lpWLhfxKM2iDakGS3T2wpFkMsmbyfk52ASA,2361
85
- otvision-0.6.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
86
- otvision-0.6.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
87
- otvision-0.6.4.dist-info/RECORD,,
101
+ otvision-0.6.5.dist-info/METADATA,sha256=-YE_U1NlesErB101C72im0uWFlf_7ItDmD0YIg5cVvY,6262
102
+ otvision-0.6.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
103
+ otvision-0.6.5.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
104
+ otvision-0.6.5.dist-info/RECORD,,