seavision-python 0.1.1__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.
- seavision/__init__.py +3 -0
- seavision/defaults.py +38 -0
- seavision/edge/__init__.py +38 -0
- seavision/edge/bundle.py +189 -0
- seavision/edge/capture.py +107 -0
- seavision/edge/config.py +219 -0
- seavision/edge/postprocess.py +185 -0
- seavision/edge/runtime.py +416 -0
- seavision/edge/writer.py +167 -0
- seavision/engine/__init__.py +52 -0
- seavision/engine/detectors/__init__.py +90 -0
- seavision/engine/detectors/base.py +179 -0
- seavision/engine/detectors/motion/__init__.py +14 -0
- seavision/engine/detectors/motion/background.py +92 -0
- seavision/engine/detectors/motion/detector.py +218 -0
- seavision/engine/detectors/motion/stabiliser.py +174 -0
- seavision/engine/detectors/motion/tracker.py +174 -0
- seavision/engine/detectors/sam3/__init__.py +23 -0
- seavision/engine/detectors/sam3/config.py +309 -0
- seavision/engine/detectors/sam3/detector.py +1316 -0
- seavision/engine/detectors/sam3/native.py +490 -0
- seavision/engine/detectors/yolo/__init__.py +12 -0
- seavision/engine/detectors/yolo/config.py +39 -0
- seavision/engine/detectors/yolo/detector.py +236 -0
- seavision/engine/export/__init__.py +24 -0
- seavision/engine/export/config.py +160 -0
- seavision/engine/export/exporter.py +286 -0
- seavision/engine/export/validation.py +314 -0
- seavision/engine/postprocessor.py +738 -0
- seavision/engine/source/__init__.py +16 -0
- seavision/engine/source/base.py +87 -0
- seavision/engine/source/discovery.py +154 -0
- seavision/engine/source/local.py +155 -0
- seavision/engine/source/s3.py +231 -0
- seavision/engine/visualiser/__init__.py +62 -0
- seavision/engine/visualiser/annotator.py +382 -0
- seavision/engine/visualiser/config.py +127 -0
- seavision/engine/visualiser/loader.py +558 -0
- seavision/engine/visualiser/visualiser.py +402 -0
- seavision/engine/visualiser/writer.py +245 -0
- seavision/gui/__init__.py +0 -0
- seavision/gui/app.py +30 -0
- seavision/gui/main_window.py +891 -0
- seavision/gui/shared/__init__.py +0 -0
- seavision/gui/shared/conversion.py +55 -0
- seavision/gui/shared/session_utils.py +37 -0
- seavision/gui/validation/__init__.py +0 -0
- seavision/gui/validation/button_styles.py +144 -0
- seavision/gui/validation/detection_detail.py +164 -0
- seavision/gui/validation/detection_rect_item.py +486 -0
- seavision/gui/validation/detection_table.py +563 -0
- seavision/gui/validation/interactive_frame_scene.py +340 -0
- seavision/gui/validation/interactive_frame_view.py +252 -0
- seavision/gui/validation/s3_browser.py +645 -0
- seavision/gui/validation/seekable_source.py +262 -0
- seavision/gui/validation/session.py +376 -0
- seavision/gui/validation/tab.py +2503 -0
- seavision/gui/validation/transport_bar.py +172 -0
- seavision/gui/validation/validation_model.py +482 -0
- seavision/gui/validation/video_cache.py +215 -0
- seavision/gui/validation/video_list.py +140 -0
- seavision/gui/validation/video_viewer.py +150 -0
- seavision/gui/validation/video_worker.py +422 -0
- seavision/pipeline.py +856 -0
- seavision/resources/default.yaml +139 -0
- seavision/run_edge.py +96 -0
- seavision/run_export.py +176 -0
- seavision/run_pipeline.py +388 -0
- seavision_python-0.1.1.dist-info/METADATA +286 -0
- seavision_python-0.1.1.dist-info/RECORD +73 -0
- seavision_python-0.1.1.dist-info/WHEEL +5 -0
- seavision_python-0.1.1.dist-info/entry_points.txt +5 -0
- seavision_python-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Command line interface for the buoy detection pipeline."""
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import logging
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
import yaml
|
|
11
|
+
|
|
12
|
+
from .defaults import write_default_pipeline_config
|
|
13
|
+
from .engine import (
|
|
14
|
+
discover_local_videos,
|
|
15
|
+
discover_s3_videos,
|
|
16
|
+
OutputMode,
|
|
17
|
+
)
|
|
18
|
+
from .pipeline import (
|
|
19
|
+
DetectionPipeline,
|
|
20
|
+
PipelineConfig,
|
|
21
|
+
InputConfig,
|
|
22
|
+
setup_logging,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def parse_args() -> argparse.Namespace:
|
|
27
|
+
"""Parse command line arguments."""
|
|
28
|
+
|
|
29
|
+
parser = argparse.ArgumentParser(
|
|
30
|
+
description="Buoy detection pipeline - object detection in buoy footage.",
|
|
31
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
32
|
+
epilog="""
|
|
33
|
+
Example usage:
|
|
34
|
+
# Process local videos
|
|
35
|
+
seavision --input ./footage/ --output ./results/
|
|
36
|
+
|
|
37
|
+
# Process a single video
|
|
38
|
+
seavision --input ./footage/video.ts --output ./results/
|
|
39
|
+
|
|
40
|
+
# Write the packaged default config to a local file
|
|
41
|
+
seavision --write-default-config ./seavision-config.yaml
|
|
42
|
+
|
|
43
|
+
# Use a config file
|
|
44
|
+
seavision --config ./seavision-config.yaml
|
|
45
|
+
|
|
46
|
+
# Dry run (scan without processing)
|
|
47
|
+
seavision --input ./footage/ --dry-run
|
|
48
|
+
|
|
49
|
+
# Resume interrupted processing
|
|
50
|
+
seavision --input ./footage/ --output ./results/ --resume
|
|
51
|
+
|
|
52
|
+
# Quick preview (every 10th frame)
|
|
53
|
+
seavision --input ./footage/ --frame-skip 10
|
|
54
|
+
""",
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Input options
|
|
58
|
+
input_group = parser.add_argument_group("Input options")
|
|
59
|
+
input_group.add_argument(
|
|
60
|
+
"--input", "-i",
|
|
61
|
+
type=str,
|
|
62
|
+
help="Path to video file or directory containing videos.",
|
|
63
|
+
)
|
|
64
|
+
input_group.add_argument(
|
|
65
|
+
"--pattern", "-p",
|
|
66
|
+
type=str,
|
|
67
|
+
default="*.ts",
|
|
68
|
+
help="Glob pattern for matching videos in a directory (default: *.ts).",
|
|
69
|
+
)
|
|
70
|
+
input_group.add_argument(
|
|
71
|
+
"--source-type",
|
|
72
|
+
type=str,
|
|
73
|
+
choices=["local", "s3"],
|
|
74
|
+
default=None,
|
|
75
|
+
help="Video source type (default: local). Can be set in config file.",
|
|
76
|
+
)
|
|
77
|
+
input_group.add_argument(
|
|
78
|
+
"--s3-bucket",
|
|
79
|
+
type=str,
|
|
80
|
+
help="S3 bucket name (for s3 source type).",
|
|
81
|
+
)
|
|
82
|
+
input_group.add_argument(
|
|
83
|
+
"--s3-prefix",
|
|
84
|
+
type=str,
|
|
85
|
+
help="S3 prefix/path (for s3 source type).",
|
|
86
|
+
)
|
|
87
|
+
input_group.add_argument(
|
|
88
|
+
"--s3-profile",
|
|
89
|
+
type=str,
|
|
90
|
+
help="AWS SSO profile name (for s3 source type).",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Output options
|
|
94
|
+
output_group = parser.add_argument_group("Output options")
|
|
95
|
+
output_group.add_argument(
|
|
96
|
+
"--output", "-o",
|
|
97
|
+
type=str,
|
|
98
|
+
default="./output",
|
|
99
|
+
help="Output directory for detection CSV files (default: ./output).",
|
|
100
|
+
)
|
|
101
|
+
output_group.add_argument(
|
|
102
|
+
"--single-file",
|
|
103
|
+
action="store_true",
|
|
104
|
+
help="Write all detections to a single CSV file instead of per-video.",
|
|
105
|
+
)
|
|
106
|
+
output_group.add_argument(
|
|
107
|
+
"--overwrite",
|
|
108
|
+
action="store_true",
|
|
109
|
+
help="Overwrite existing output files.",
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Processing options
|
|
113
|
+
proc_group = parser.add_argument_group("Processing options")
|
|
114
|
+
proc_group.add_argument(
|
|
115
|
+
"--frame-skip",
|
|
116
|
+
type=int,
|
|
117
|
+
default=1,
|
|
118
|
+
help="Process every Nth frame (default: 1, all frames).",
|
|
119
|
+
)
|
|
120
|
+
proc_group.add_argument(
|
|
121
|
+
"--resume",
|
|
122
|
+
action="store_true",
|
|
123
|
+
help="Skip videos that already have output files.",
|
|
124
|
+
)
|
|
125
|
+
proc_group.add_argument(
|
|
126
|
+
"--dry-run",
|
|
127
|
+
action="store_true",
|
|
128
|
+
help="Scan videos and report statistics without processing.",
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
# Detector options
|
|
132
|
+
det_group = parser.add_argument_group("Detector options")
|
|
133
|
+
det_group.add_argument(
|
|
134
|
+
"--detector",
|
|
135
|
+
type=str,
|
|
136
|
+
default="motion",
|
|
137
|
+
help="Detector type to use (default: motion).",
|
|
138
|
+
)
|
|
139
|
+
det_group.add_argument(
|
|
140
|
+
"--min-area",
|
|
141
|
+
type=int,
|
|
142
|
+
help="Minimum contour area in pixels (motion detector).",
|
|
143
|
+
)
|
|
144
|
+
det_group.add_argument(
|
|
145
|
+
"--max-area",
|
|
146
|
+
type=int,
|
|
147
|
+
help="Maximum contour area in pixels (motion detector).",
|
|
148
|
+
)
|
|
149
|
+
det_group.add_argument(
|
|
150
|
+
"--no-stabilisation",
|
|
151
|
+
action="store_true",
|
|
152
|
+
help="Disable frame stabilisation (motion detector).",
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Config file
|
|
156
|
+
parser.add_argument(
|
|
157
|
+
"--config", "-c",
|
|
158
|
+
type=str,
|
|
159
|
+
help="Path to YAML configuration file. CLI args override config file values.",
|
|
160
|
+
)
|
|
161
|
+
parser.add_argument(
|
|
162
|
+
"--write-default-config",
|
|
163
|
+
type=str,
|
|
164
|
+
help=(
|
|
165
|
+
"Write the packaged default YAML configuration to the given path "
|
|
166
|
+
"and exit."
|
|
167
|
+
),
|
|
168
|
+
)
|
|
169
|
+
parser.add_argument(
|
|
170
|
+
"--force-write-default-config",
|
|
171
|
+
action="store_true",
|
|
172
|
+
help="Allow --write-default-config to overwrite an existing file.",
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
# Logging
|
|
176
|
+
parser.add_argument(
|
|
177
|
+
"--verbose", "-v",
|
|
178
|
+
action="store_true",
|
|
179
|
+
help="Enable verbose (debug) logging.",
|
|
180
|
+
)
|
|
181
|
+
parser.add_argument(
|
|
182
|
+
"--quiet", "-q",
|
|
183
|
+
action="store_true",
|
|
184
|
+
help="Suppress info logging, only show warnings and errors.",
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
return parser.parse_args()
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def load_config_file(config_path: str) -> dict:
|
|
191
|
+
"""
|
|
192
|
+
Load configuration from a YAML file.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
config_path: Path to the YAML configuration file.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Dictionary with configuration values.
|
|
199
|
+
|
|
200
|
+
Raises:
|
|
201
|
+
FileNotFoundError: If the config file doesn't exist.
|
|
202
|
+
"""
|
|
203
|
+
path = Path(config_path)
|
|
204
|
+
if not path.exists():
|
|
205
|
+
raise FileNotFoundError(f"Config file not found: {config_path}")
|
|
206
|
+
|
|
207
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
208
|
+
return yaml.safe_load(f) or {}
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def build_config(args: argparse.Namespace) -> PipelineConfig:
|
|
212
|
+
"""
|
|
213
|
+
Build PipelineConfig from CLI arguments and optional config file.
|
|
214
|
+
|
|
215
|
+
Precendence: CLI args > config file > defaults.
|
|
216
|
+
|
|
217
|
+
Args:
|
|
218
|
+
args: Parsed command line arguments.
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
PipelineConfig object with merged configuration.
|
|
222
|
+
"""
|
|
223
|
+
# Start with defaults or config file
|
|
224
|
+
if args.config:
|
|
225
|
+
config_data = load_config_file(args.config)
|
|
226
|
+
config = PipelineConfig.from_dict(config_data)
|
|
227
|
+
else:
|
|
228
|
+
config = PipelineConfig()
|
|
229
|
+
|
|
230
|
+
# Override with CLI arguments
|
|
231
|
+
if args.frame_skip != 1:
|
|
232
|
+
config.input = InputConfig(frame_skip=args.frame_skip)
|
|
233
|
+
|
|
234
|
+
if args.output:
|
|
235
|
+
config.output.output_dir = args.output
|
|
236
|
+
if args.single_file:
|
|
237
|
+
config.output.output_mode = OutputMode.SINGLE_FILE
|
|
238
|
+
if args.overwrite:
|
|
239
|
+
config.output.overwrite = True
|
|
240
|
+
|
|
241
|
+
if args.resume:
|
|
242
|
+
config.resume = True
|
|
243
|
+
|
|
244
|
+
# Detector config overrides
|
|
245
|
+
if args.detector:
|
|
246
|
+
config.detector.type = args.detector
|
|
247
|
+
|
|
248
|
+
detector_overrides = {}
|
|
249
|
+
if args.min_area is not None:
|
|
250
|
+
detector_overrides["min_area"] = args.min_area
|
|
251
|
+
if args.max_area is not None:
|
|
252
|
+
detector_overrides["max_area"] = args.max_area
|
|
253
|
+
if args.no_stabilisation:
|
|
254
|
+
detector_overrides["stabilisation_enabled"] = False
|
|
255
|
+
|
|
256
|
+
if detector_overrides:
|
|
257
|
+
# Merge with existing detector config
|
|
258
|
+
config.detector.config.update(detector_overrides)
|
|
259
|
+
|
|
260
|
+
return config
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def discover_sources(args: argparse.Namespace, config_data: Optional[dict] = None):
|
|
264
|
+
"""
|
|
265
|
+
Discover video sources based on CLI arguments and config file.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
args: Parsed command-line arguments.
|
|
269
|
+
config_data: Configuration data from YAML file (optional).
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
List of VideoSource instances.
|
|
273
|
+
|
|
274
|
+
Raises:
|
|
275
|
+
ValueError: If no input path is specified.
|
|
276
|
+
"""
|
|
277
|
+
config_data = config_data or {}
|
|
278
|
+
input_config = config_data.get("input", {})
|
|
279
|
+
s3_config = input_config.get("s3", {})
|
|
280
|
+
|
|
281
|
+
# Determine input path (CLI takes precedence)
|
|
282
|
+
input_path = args.input or input_config.get("path")
|
|
283
|
+
if not input_path:
|
|
284
|
+
raise ValueError(
|
|
285
|
+
"No input specified. Use --input or set input.path in config file."
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
# Determine source type (CLI takes precedence)
|
|
289
|
+
source_type = args.source_type or input_config.get("source_type", "local")
|
|
290
|
+
|
|
291
|
+
# Determine pattern (CLI takes precedence)
|
|
292
|
+
pattern = args.pattern if args.pattern != "*.ts" else input_config.get("pattern", "*.ts")
|
|
293
|
+
|
|
294
|
+
if source_type == "local":
|
|
295
|
+
return discover_local_videos(input_path, pattern)
|
|
296
|
+
elif source_type == "s3":
|
|
297
|
+
# Get S3 settings (CLI takes precedence over config)
|
|
298
|
+
bucket = args.s3_bucket or s3_config.get("bucket") or input_path
|
|
299
|
+
prefix = args.s3_prefix or s3_config.get("prefix", "")
|
|
300
|
+
profile = args.s3_profile or s3_config.get("profile_name")
|
|
301
|
+
|
|
302
|
+
return discover_s3_videos(
|
|
303
|
+
bucket=bucket,
|
|
304
|
+
prefix=prefix,
|
|
305
|
+
pattern=pattern,
|
|
306
|
+
profile_name=profile
|
|
307
|
+
)
|
|
308
|
+
else:
|
|
309
|
+
raise ValueError(f"Unknown source type: {source_type}")
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def main() -> int:
|
|
313
|
+
"""
|
|
314
|
+
Main entry point for the CLI.
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
Exit code (0 for success, non-zero for errors).
|
|
318
|
+
"""
|
|
319
|
+
args = parse_args()
|
|
320
|
+
|
|
321
|
+
# Set up logging
|
|
322
|
+
if args.verbose:
|
|
323
|
+
log_level = logging.DEBUG
|
|
324
|
+
elif args.quiet:
|
|
325
|
+
log_level = logging.WARNING
|
|
326
|
+
else:
|
|
327
|
+
log_level = logging.INFO
|
|
328
|
+
setup_logging(log_level)
|
|
329
|
+
|
|
330
|
+
logger = logging.getLogger(__name__)
|
|
331
|
+
|
|
332
|
+
if args.write_default_config:
|
|
333
|
+
try:
|
|
334
|
+
output_path = write_default_pipeline_config(
|
|
335
|
+
args.write_default_config,
|
|
336
|
+
overwrite=args.force_write_default_config,
|
|
337
|
+
)
|
|
338
|
+
except FileExistsError as e:
|
|
339
|
+
print(str(e))
|
|
340
|
+
print(
|
|
341
|
+
"Use --force-write-default-config to overwrite the existing file."
|
|
342
|
+
)
|
|
343
|
+
return 1
|
|
344
|
+
|
|
345
|
+
print(f"Default configuration written to: {output_path}")
|
|
346
|
+
return 0
|
|
347
|
+
|
|
348
|
+
try:
|
|
349
|
+
# Load config file if specified
|
|
350
|
+
config_data = {}
|
|
351
|
+
if args.config:
|
|
352
|
+
config_data = load_config_file(args.config)
|
|
353
|
+
|
|
354
|
+
# Build configuration
|
|
355
|
+
config = build_config(args)
|
|
356
|
+
|
|
357
|
+
# Discover video sources
|
|
358
|
+
sources = discover_sources(args, config_data)
|
|
359
|
+
logger.info("Discovered %d video source(s).", len(sources))
|
|
360
|
+
|
|
361
|
+
# Create and run pipeline
|
|
362
|
+
pipeline = DetectionPipeline(config)
|
|
363
|
+
result = pipeline.process_sources(sources, dry_run=args.dry_run)
|
|
364
|
+
|
|
365
|
+
# Print results
|
|
366
|
+
print()
|
|
367
|
+
print(result.summary())
|
|
368
|
+
|
|
369
|
+
# Return appropriate exit code
|
|
370
|
+
if hasattr(result, "videos_failed") and result.videos_failed > 0: # pyright: ignore[reportAttributeAccessIssue]
|
|
371
|
+
return 1 # Some videos failed
|
|
372
|
+
return 0
|
|
373
|
+
|
|
374
|
+
except FileNotFoundError as e:
|
|
375
|
+
logger.error(str(e))
|
|
376
|
+
return 1
|
|
377
|
+
except ValueError as e:
|
|
378
|
+
logger.error(str(e))
|
|
379
|
+
return 1
|
|
380
|
+
except KeyboardInterrupt:
|
|
381
|
+
logger.info("Interrupted by user.")
|
|
382
|
+
return 130
|
|
383
|
+
except Exception as e: # pylint: disable=broad-exception-caught
|
|
384
|
+
logger.exception("Unexpected error: %s", e)
|
|
385
|
+
return 1
|
|
386
|
+
|
|
387
|
+
if __name__ == "__main__":
|
|
388
|
+
sys.exit(main())
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: seavision-python
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Human-in-the-loop Computer Vision for Marine Environments
|
|
5
|
+
Author: Mario Lambrette
|
|
6
|
+
License: Proprietary
|
|
7
|
+
Project-URL: Homepage, https://github.com/mariolambrette/SeaVision
|
|
8
|
+
Project-URL: Documentation, https://github.com/mariolambrette/SeaVision/tree/Main/docs
|
|
9
|
+
Project-URL: Source, https://github.com/mariolambrette/SeaVision
|
|
10
|
+
Project-URL: Issues, https://github.com/mariolambrette/SeaVision/issues
|
|
11
|
+
Keywords: computer-vision,detection,marine,SAM3
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: numpy<2.0,>=1.21
|
|
20
|
+
Requires-Dist: opencv-python-headless>=4.8
|
|
21
|
+
Requires-Dist: PyYAML>=6.0
|
|
22
|
+
Requires-Dist: tqdm>=4.60
|
|
23
|
+
Provides-Extra: s3
|
|
24
|
+
Requires-Dist: boto3>=1.26; extra == "s3"
|
|
25
|
+
Provides-Extra: gui
|
|
26
|
+
Requires-Dist: boto3>=1.26; extra == "gui"
|
|
27
|
+
Requires-Dist: PySide6<6.9,>=6.5; extra == "gui"
|
|
28
|
+
Requires-Dist: psutil>=5.9; extra == "gui"
|
|
29
|
+
Provides-Extra: edge
|
|
30
|
+
Requires-Dist: onnxruntime>=1.16; extra == "edge"
|
|
31
|
+
Provides-Extra: export
|
|
32
|
+
Requires-Dist: onnxruntime>=1.16; extra == "export"
|
|
33
|
+
Requires-Dist: ultralytics>=8.3.237; extra == "export"
|
|
34
|
+
Provides-Extra: sam3
|
|
35
|
+
Requires-Dist: pillow>=10.0; extra == "sam3"
|
|
36
|
+
Requires-Dist: torch>=2.0; extra == "sam3"
|
|
37
|
+
Requires-Dist: torchvision>=0.20; extra == "sam3"
|
|
38
|
+
Requires-Dist: transformers>=4.47; extra == "sam3"
|
|
39
|
+
Requires-Dist: ultralytics>=8.3.237; extra == "sam3"
|
|
40
|
+
Provides-Extra: all
|
|
41
|
+
Requires-Dist: boto3>=1.26; extra == "all"
|
|
42
|
+
Requires-Dist: onnxruntime>=1.16; extra == "all"
|
|
43
|
+
Requires-Dist: pillow>=10.0; extra == "all"
|
|
44
|
+
Requires-Dist: psutil>=5.9; extra == "all"
|
|
45
|
+
Requires-Dist: PySide6<6.9,>=6.5; extra == "all"
|
|
46
|
+
Requires-Dist: torch>=2.0; extra == "all"
|
|
47
|
+
Requires-Dist: torchvision>=0.20; extra == "all"
|
|
48
|
+
Requires-Dist: transformers>=4.47; extra == "all"
|
|
49
|
+
Requires-Dist: ultralytics>=8.3.237; extra == "all"
|
|
50
|
+
Provides-Extra: dev
|
|
51
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
52
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
53
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
54
|
+
Requires-Dist: twine>=5.1; extra == "dev"
|
|
55
|
+
|
|
56
|
+
<p align="left">
|
|
57
|
+
<img src="https://raw.githubusercontent.com/mariolambrette/SeaVision/Main/assets/seavision_logo.jpg" alt="Logo" width="200"/>
|
|
58
|
+
</p>
|
|
59
|
+
|
|
60
|
+
# SeaVision
|
|
61
|
+
|
|
62
|
+
## Human-in-the-loop Computer Vision for Marine Environments
|
|
63
|
+
|
|
64
|
+
> [!WARNING]
|
|
65
|
+
> Documentation is currently out of date.
|
|
66
|
+
> The packaging, release, and edge-deployment flows have changed recently, and
|
|
67
|
+
> some instructions in this README and the linked docs may still describe older
|
|
68
|
+
> clone-first or pre-release workflows. Treat the published release artifacts
|
|
69
|
+
> and current CLI behavior as the source of truth until the docs are refreshed.
|
|
70
|
+
|
|
71
|
+
SeaVision offers a practical computer vision workflow for marine monitoring. It supports the development of accurate,
|
|
72
|
+
custom detection models for specific deployment scenarios. The main workflow is:
|
|
73
|
+
|
|
74
|
+
1. Deploy a generic detector (e.g. motion detection, SAM3-based semantic detection, etc.) on recorded footage.
|
|
75
|
+
2. Use the provided GUI to validate and refine detections into a training dataset.
|
|
76
|
+
3. Train a custom YOLO detection model.
|
|
77
|
+
4. Deploy the trained model on a desktop workstation or edge device with the provided export functionality.
|
|
78
|
+
|
|
79
|
+
If you are new to the project, start with the [Start Here guide](./docs/Start_Here.md).
|
|
80
|
+
|
|
81
|
+
## Start Here (New Users)
|
|
82
|
+
|
|
83
|
+
If you are not a computer vision specialist, use this short path first:
|
|
84
|
+
|
|
85
|
+
1. Read the [Start Here guide](./docs/Start_Here.md) for a plain-language workflow and glossary.
|
|
86
|
+
2. Install SeaVision in GUI mode: `python -m pip install ".[gui]"`.
|
|
87
|
+
3. Run `seavision-gui` and create a new session with `Ctrl+N`.
|
|
88
|
+
4. Follow the GUI [Getting Started guide](./docs/gui/Getting%20started.md).
|
|
89
|
+
|
|
90
|
+
## Installation
|
|
91
|
+
|
|
92
|
+
### Prerequisites
|
|
93
|
+
|
|
94
|
+
- Python 3.12
|
|
95
|
+
- pip
|
|
96
|
+
|
|
97
|
+
### Install from a cloned repository
|
|
98
|
+
|
|
99
|
+
Before installing the package, you must currently clone this repository. Run the following in a
|
|
100
|
+
bash terminal:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
git clone https://github.com/mariolambrette/SeaVision
|
|
104
|
+
cd SeaVision
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
It is recommended to install SeaVision in a dedicated environment. If you are a [conda](https://www.anaconda.com/docs/getting-started/anaconda/install/overview) user, run
|
|
108
|
+
the following:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
conda create seavision
|
|
112
|
+
conda activate seavision
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
You can now install SeaVision using pip:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pip install ".[<extras>]"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
SeaVision can be installed in various modes, each of which supports different modes of functionality. See below for a full
|
|
122
|
+
description of all installation modes.
|
|
123
|
+
|
|
124
|
+
### Install Matrix (User Types)
|
|
125
|
+
|
|
126
|
+
Use the install command that matches your use case.
|
|
127
|
+
|
|
128
|
+
| User type | Install command | Primary CLI command(s) |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| Detection-only users (local videos) | `python -m pip install .` | `seavision` |
|
|
131
|
+
| Detection users with videos in S3 bucket | `python -m pip install ".[s3]"` | `seavision` |
|
|
132
|
+
| GUI users (includes S3 support) | `python -m pip install ".[gui]"` | `seavision-gui` |
|
|
133
|
+
| Edge device operators (runtime only) | `python -m pip install ".[edge]"` | `seavision-edge` |
|
|
134
|
+
| Export users (prepare edge artifacts) | `python -m pip install ".[export]"` | `seavision-export` |
|
|
135
|
+
| Advanced/full users | `python -m pip install ".[all]"` | `seavision`, `seavision-gui`, `seavision-export`, `seavision-edge` |
|
|
136
|
+
|
|
137
|
+
Most users should use either `python -m pip install ".[gui]"` for desktop-only usage or `python -m pip install ".[all]"` if they are
|
|
138
|
+
also likely to use edge deployment functionality. Other installation methods may provide lighter dependencies in specific scenarios.
|
|
139
|
+
|
|
140
|
+
You can verify your installation by running [test commands](#install-verification)
|
|
141
|
+
|
|
142
|
+
### Development install
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
python -m venv venv
|
|
146
|
+
venv\Scripts\activate.bat
|
|
147
|
+
python -m pip install -e ".[dev]"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
For release/distribution policy and compatibility targets, see:
|
|
151
|
+
|
|
152
|
+
- [Distribution and compatibility policy](./docs/release/Distribution_and_Compatibility.md)
|
|
153
|
+
|
|
154
|
+
### Optional GPU acceleration
|
|
155
|
+
|
|
156
|
+
The above install allows you to run all SeaVision functionality but does not
|
|
157
|
+
provide support for GPU-accelerated processing. Some methods (e.g. SAM3-based
|
|
158
|
+
detection) will be significantly faster if a GPU is available. You will need to
|
|
159
|
+
install GPU-specific dependencies manually based on your hardware.
|
|
160
|
+
|
|
161
|
+
For example, to run on an NVIDIA RTX 5090 GPU with cuda 13 you could install
|
|
162
|
+
the following:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
pip install torch>=2.9.0 torchvision>=0.20.0 --index-url https://download.pytorch.org/whl/cu130 --force-reinstall
|
|
166
|
+
```
|
|
167
|
+
You can find more information on PyTorch compatibility
|
|
168
|
+
[here](https://pytorch.org/get-started/locally/).
|
|
169
|
+
|
|
170
|
+
### AWS S3 Access (Optional)
|
|
171
|
+
|
|
172
|
+
The pipeline supports streaming video directly from AWS. In order to access this
|
|
173
|
+
feature you will need to configure an AWS SSO profile. For more information on
|
|
174
|
+
how to do this and integrate AWS streaming into the SeaVision workflow, see the
|
|
175
|
+
[AWS setup documentation](./docs/AWS_SETUP.md)
|
|
176
|
+
|
|
177
|
+
## Install verification
|
|
178
|
+
|
|
179
|
+
Run the command that matches your installed mode:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
# Detection CLI
|
|
183
|
+
seavision --help
|
|
184
|
+
|
|
185
|
+
# GUI
|
|
186
|
+
seavision-gui
|
|
187
|
+
|
|
188
|
+
# Export CLI
|
|
189
|
+
seavision-export --help
|
|
190
|
+
|
|
191
|
+
# Edge CLI
|
|
192
|
+
seavision-edge --help
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Quick start
|
|
196
|
+
|
|
197
|
+
### 1. Run the detection pipeline
|
|
198
|
+
|
|
199
|
+
The full detection pipeline can be run with a CLI command, which can optionally be configured
|
|
200
|
+
with a [YAML file](./config/default.yaml)
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# Local files
|
|
204
|
+
seavision --input ./data/footage/ --output ./results/
|
|
205
|
+
|
|
206
|
+
# With config file
|
|
207
|
+
seavision --config config/default.yaml
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### 2. Launch the GUI
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
seavision-gui
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 3. Export for edge deployment
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
seavision-export --weights models/fish.pt --output ./deployment --target onnx
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### 4. Run on an edge device
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
seavision-edge --artifact-dir ./deployment/artifact
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Troubleshooting quick checks
|
|
229
|
+
|
|
230
|
+
| Problem | Likely cause | Quick check | Fix |
|
|
231
|
+
|---|---|---|---|
|
|
232
|
+
| `seavision: command not found` | Package not installed in active environment | `python -m pip show seavision` | Activate the right environment and reinstall using the install matrix |
|
|
233
|
+
| `seavision-gui: command not found` | GUI extra not installed | `python -m pip show PySide6` | `python -m pip install ".[gui]"` |
|
|
234
|
+
| `seavision-edge: command not found` | Edge extra not installed | `python -m pip show onnxruntime` | `python -m pip install ".[edge]"` |
|
|
235
|
+
| Import error for `boto3` when using S3 | S3 dependency missing | `python -m pip show boto3` | `python -m pip install ".[s3]"` or `python -m pip install ".[gui]"` |
|
|
236
|
+
| GUI starts but S3 login fails | AWS credentials/session not configured | `aws sts get-caller-identity` | Run `aws sso login --profile <profile-name>` and retry |
|
|
237
|
+
| Edge run fails at startup validation | Artifact dir incomplete or invalid | `seavision-edge --artifact-dir <path>` output | Re-run `seavision-export` and copy the full artifact directory again |
|
|
238
|
+
|
|
239
|
+
## Configuration
|
|
240
|
+
|
|
241
|
+
The SeaVision pipeline can be fully customised using YAML config files. For
|
|
242
|
+
a documented example of a config file see the
|
|
243
|
+
[default configuration](./config/default.yaml)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
## Edge Deployment
|
|
247
|
+
|
|
248
|
+
Users may wish to deploy models developed or refined using SeaVision to an edge
|
|
249
|
+
device. Full support is provided for deploying trained model weight files
|
|
250
|
+
(`*.pt`) on Raspberry Pi.
|
|
251
|
+
|
|
252
|
+
Edge deployment creates SeaVision detection files directly on the Pi which may
|
|
253
|
+
save compute time, power and data transfer requirements. Users can optionally
|
|
254
|
+
export periodic validation clips alongside the detections. See below for
|
|
255
|
+
detailed documentation:
|
|
256
|
+
|
|
257
|
+
If you are new to the deployment workflow, use this order:
|
|
258
|
+
|
|
259
|
+
1. [Edge deployment overview](./docs/edge/README.md)
|
|
260
|
+
2. [Concepts and Terms](./docs/edge/Concepts%20and%20Terms.md)
|
|
261
|
+
3. [Prerequisites Checklist](./docs/edge/Prerequisites%20Checklist.md)
|
|
262
|
+
4. [Operator Quickstart](./docs/edge/Operator%20Quickstart.md)
|
|
263
|
+
5. [Troubleshooting](./docs/edge/Troubleshooting.md)
|
|
264
|
+
|
|
265
|
+
Use the technical references only when you are preparing the deployment files
|
|
266
|
+
or troubleshooting the package structure:
|
|
267
|
+
|
|
268
|
+
- [Deploy to Raspberry Pi](./docs/edge/Deploy%20to%20Raspberry%20Pi.md)
|
|
269
|
+
- [Troubleshooting](./docs/edge/Troubleshooting.md)
|
|
270
|
+
- [Wheel runtime workflow](./docs/edge/Wheel%20Runtime.md)
|
|
271
|
+
- [Model artifact layout](./docs/edge/Model%20Artifacts.md)
|
|
272
|
+
- [Rollback runbook](./docs/edge/Rollback%20Runbook.md)
|
|
273
|
+
|
|
274
|
+
## Documentation
|
|
275
|
+
|
|
276
|
+
- [Start Here guide](./docs/Start_Here.md)
|
|
277
|
+
- [Class and API reference](./docs/Class_reference.md)
|
|
278
|
+
- [Architecture and class diagrams](./docs/Class_diagram.md)
|
|
279
|
+
- [AWS setup guide](./docs/AWS_SETUP.md)
|
|
280
|
+
- [Edge deployment docs](./docs/edge/README.md)
|
|
281
|
+
- [GUI docs](./docs/gui/README.md)
|
|
282
|
+
|
|
283
|
+
## Project Status
|
|
284
|
+
|
|
285
|
+
Note that this project is under active development and features may not yet
|
|
286
|
+
work as intended.
|