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,309 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Configuration dataclasses for the SAM3 detector.
|
|
3
|
+
|
|
4
|
+
This module defines all configuration options for the SAM3 detector, including:
|
|
5
|
+
- Prompt configuration (text, box, point, hybrid modes)
|
|
6
|
+
- Detector configuration (model settings, thresholds, output options)
|
|
7
|
+
- Prompter configuration (for hybrid mode with other detectors)
|
|
8
|
+
|
|
9
|
+
Example usage:
|
|
10
|
+
>>> from seavision.engine.detectors.sam3.config import (
|
|
11
|
+
... SAM3DetectorConfig,
|
|
12
|
+
... PromptConfig,
|
|
13
|
+
... PromptType,
|
|
14
|
+
... )
|
|
15
|
+
>>>
|
|
16
|
+
>>> config = SAM3DetectorConfig(
|
|
17
|
+
... prompt_config=PromptConfig(
|
|
18
|
+
... prompt_type=PromptType.TEXT,
|
|
19
|
+
... text_prompts=["fish", "coral"],
|
|
20
|
+
... ),
|
|
21
|
+
... confidence_threshold=0.5,
|
|
22
|
+
... video_mode=True,
|
|
23
|
+
... )
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from dataclasses import dataclass, field
|
|
27
|
+
from enum import Enum, auto
|
|
28
|
+
from typing import Dict, List, Optional
|
|
29
|
+
import logging
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger(__name__)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class PromptType(Enum):
|
|
35
|
+
"""
|
|
36
|
+
Type of prompt to use for SAM3 segmentation.
|
|
37
|
+
|
|
38
|
+
Attributes:
|
|
39
|
+
TEXT: Natural language text prompts (e.g., "fish", "coral reef").
|
|
40
|
+
Uses SAM3's semantic understanding to find matching objects.
|
|
41
|
+
BOX: Bounding box prompts in xyxy format.
|
|
42
|
+
Finds objects within or similar to the provided boxes.
|
|
43
|
+
POINT: Point prompts with x, y coordinates.
|
|
44
|
+
Click-based prompts similar to SAM2. Note: Limited support
|
|
45
|
+
in SAM3SemanticPredictor.
|
|
46
|
+
DETECTOR: Hybrid mode using another detector to generate prompts.
|
|
47
|
+
The secondary detector provides candidate regions for SAM3
|
|
48
|
+
to refine or classify.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
TEXT = auto() # Text concepts
|
|
52
|
+
BOX = auto() # Bounding box exemplars
|
|
53
|
+
POINT = auto() # Point prompts (SAM2 style)
|
|
54
|
+
DETECTOR = auto() # Use another detector to generate prompts
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class HybridStrategy(Enum):
|
|
58
|
+
"""
|
|
59
|
+
Strategy for hybrid mode (PromptType.DETECTOR).
|
|
60
|
+
|
|
61
|
+
Defines how SAM3 uses the detections from the prompter detector.
|
|
62
|
+
|
|
63
|
+
Attributes:
|
|
64
|
+
BOX_REFINEMENT: Use detected boxes directly as SAM3 box prompts.
|
|
65
|
+
SAM3 generates refined segmentation masks for each box.
|
|
66
|
+
Good for improving mask quality from coarse detections.
|
|
67
|
+
CLASSIFY_REGIONS: Use text prompts to classify detected regions.
|
|
68
|
+
SAM3 applies semantic labels to the detected regions.
|
|
69
|
+
Requires text_prompts to be set in PrompterConfig.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
BOX_REFINEMENT = auto()
|
|
73
|
+
CLASSIFY_REGIONS = auto()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@dataclass
|
|
77
|
+
class PrompterConfig:
|
|
78
|
+
"""
|
|
79
|
+
Configuration for the prompt source in hybrid/detector mode.
|
|
80
|
+
|
|
81
|
+
In hybrid mode, another detector generates candidate boxes that become
|
|
82
|
+
prompts for SAM3. This allows combining fast detectors (motion/YOLO) with
|
|
83
|
+
SAM3's segmentation and semantic understanding.
|
|
84
|
+
|
|
85
|
+
Attributes:
|
|
86
|
+
detector_type: Type of detector to use ("motion", "yolo" or custom).
|
|
87
|
+
detector_config: Configuration dict passed to the detector.
|
|
88
|
+
strategy: How to combine detector output with SAM3.
|
|
89
|
+
text_prompts: Text prompts for CLASSIFY_REGIONS strategy.
|
|
90
|
+
min_iou_with_prompt: Minimum IoU between SAM3 output and original
|
|
91
|
+
detector box to keep the detection (filters false positives).
|
|
92
|
+
|
|
93
|
+
Example (motion + SAM3 refinement):
|
|
94
|
+
PrompterConfig(
|
|
95
|
+
detector_type="motion",
|
|
96
|
+
detector_config={"min_area": 200, "persistence_enabled": True},
|
|
97
|
+
strategy=HybridStrategy.BOX_REFINEMENT,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
Example (motion finds candidates, SAM3 classifies):
|
|
101
|
+
PrompterConfig(
|
|
102
|
+
detector_type="motion",
|
|
103
|
+
detector_config={"min_area": 100},
|
|
104
|
+
strategy=HybridStrategy.CLASSIFY_REGIONS,
|
|
105
|
+
text_prompts=["fish", "coral", "debris"], # What to look for
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
Example (YOLO + SAM3 masks):
|
|
109
|
+
PrompterConfig(
|
|
110
|
+
detector_type="yolo",
|
|
111
|
+
detector_config={"model": "yolov8n.pt", "conf": 0.25},
|
|
112
|
+
strategy=HybridStrategy.BOX_REFINEMENT,
|
|
113
|
+
)
|
|
114
|
+
"""
|
|
115
|
+
|
|
116
|
+
detector_type: str = "motion" # "motion", "yolo", or custom
|
|
117
|
+
detector_config: Dict = field(default_factory=dict)
|
|
118
|
+
strategy: HybridStrategy = HybridStrategy.BOX_REFINEMENT
|
|
119
|
+
text_prompts: List[str] = field(default_factory=list)
|
|
120
|
+
min_iou_with_prompt: float = 0.0
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@dataclass
|
|
124
|
+
class PromptConfig:
|
|
125
|
+
"""
|
|
126
|
+
Configuration for SAM3 prompting.
|
|
127
|
+
|
|
128
|
+
SAM3 supports multiple prompt types:
|
|
129
|
+
- Text: find all instances of concepts (e.g. "fish", "seal")
|
|
130
|
+
- Box exemplars: Find all similar objects to the boxed example
|
|
131
|
+
- Points: SAM2-style single object segmentation, segments the object at the
|
|
132
|
+
given point(s).
|
|
133
|
+
- Hybrid: Use another detector (e.g. motion, YOLO) to generate prompts
|
|
134
|
+
|
|
135
|
+
Attributes:
|
|
136
|
+
prompt_type: The type of prompt to use.
|
|
137
|
+
|
|
138
|
+
# For TEXT mode:
|
|
139
|
+
text_prompts: List of text concepts to segment, if using TEXT prompts.
|
|
140
|
+
|
|
141
|
+
# For BOX mode (manual exemplars):
|
|
142
|
+
box_prompts: List of bounding boxes as [x1, y1, x2, y2], if using BOX
|
|
143
|
+
prompts.
|
|
144
|
+
box_labels: Labels for box prompts (1=positive, 0=negative).
|
|
145
|
+
|
|
146
|
+
# For POINT mode:
|
|
147
|
+
point_prompts: List of points as [x, y], if using POINT prompts.
|
|
148
|
+
point_labels: Labels for point prompts (1=positive, 0=negative).
|
|
149
|
+
|
|
150
|
+
# For DETECTOR mode (hybrid):
|
|
151
|
+
prompter: Configuration for the prompt-generating detector.
|
|
152
|
+
|
|
153
|
+
# Video settings:
|
|
154
|
+
reprompt_interval: Interval (in frames) to re-generate prompts in video.
|
|
155
|
+
For frames between prompts, only existing objects are tracked. This
|
|
156
|
+
is faster than reprompting but means new objects will be missed.
|
|
157
|
+
reprompt_on_lost: Whether to reprompt when tracked objects are lost.
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
prompt_type: PromptType = PromptType.TEXT
|
|
161
|
+
|
|
162
|
+
# TEXT mode:
|
|
163
|
+
text_prompts: List[str] = field(default_factory=list)
|
|
164
|
+
|
|
165
|
+
# BOX mode:
|
|
166
|
+
box_prompts: List[List[float]] = field(default_factory=list)
|
|
167
|
+
box_labels: List[int] = field(default_factory=list)
|
|
168
|
+
|
|
169
|
+
# POINT mode:
|
|
170
|
+
point_prompts: List[List[float]] = field(default_factory=list)
|
|
171
|
+
point_labels: List[int] = field(default_factory=list)
|
|
172
|
+
|
|
173
|
+
# DETECTOR mode (hybrid):
|
|
174
|
+
prompter: Optional[PrompterConfig] = None
|
|
175
|
+
|
|
176
|
+
# Video settings:
|
|
177
|
+
reprompt_interval: int = 0
|
|
178
|
+
reprompt_on_lost: bool = False
|
|
179
|
+
|
|
180
|
+
def __post_init__(self):
|
|
181
|
+
"""Validate configuration."""
|
|
182
|
+
|
|
183
|
+
if self.prompt_type == PromptType.TEXT and not self.text_prompts:
|
|
184
|
+
raise ValueError("text_prompts required for TEXT mode.")
|
|
185
|
+
|
|
186
|
+
if self.prompt_type == PromptType.BOX and not self.box_prompts:
|
|
187
|
+
raise ValueError("box_prompts required for BOX mode.")
|
|
188
|
+
|
|
189
|
+
if self.prompt_type == PromptType.POINT and not self.point_prompts:
|
|
190
|
+
raise ValueError("point_prompts required for POINT mode.")
|
|
191
|
+
|
|
192
|
+
if self.prompt_type == PromptType.DETECTOR and self.prompter is None:
|
|
193
|
+
raise ValueError("prompter config required for DETECTOR mode.")
|
|
194
|
+
|
|
195
|
+
# Default box and point labels to positive:
|
|
196
|
+
if self.box_prompts and not self.box_labels:
|
|
197
|
+
self.box_labels = [1] * len(self.box_prompts)
|
|
198
|
+
if self.point_prompts and not self.point_labels:
|
|
199
|
+
self.point_labels = [1] * len(self.point_prompts)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@dataclass
|
|
203
|
+
class SAM3DetectorConfig:
|
|
204
|
+
"""
|
|
205
|
+
Configuration for the SAM3 detector with Ultralytics integration.
|
|
206
|
+
|
|
207
|
+
Attributes:
|
|
208
|
+
checkpoint: Path to the sam3.pt checkpoint.
|
|
209
|
+
device: Compute device ("cuda", "cpu", "mps", etc.).
|
|
210
|
+
half: Use FP16 for faster inference on supported devices.
|
|
211
|
+
|
|
212
|
+
prompts: Shorthand for text_prompts, creates PromptConfig internally.
|
|
213
|
+
prompt_config: Full prompt configuration (overrides prompts).
|
|
214
|
+
|
|
215
|
+
confidence_threshold: Minimum confidence for detections.
|
|
216
|
+
min_mask_area: Minimum area (in pixels) for valid masks.
|
|
217
|
+
max_mask_area: Maximum area (in pixels) for valid masks.
|
|
218
|
+
|
|
219
|
+
video_mode: Enable video tracking with memory.
|
|
220
|
+
output_masks: Include segmentation masks in output.
|
|
221
|
+
output_labels: Include concept labels in output.
|
|
222
|
+
|
|
223
|
+
imgsz: Image size for inference (width, height).
|
|
224
|
+
|
|
225
|
+
Example (simple text prompts):
|
|
226
|
+
SAM3DetectorConfig(prompts=["fish", "coral"])
|
|
227
|
+
|
|
228
|
+
Example (hybrid with motion):
|
|
229
|
+
SAM3DetectorConfig(
|
|
230
|
+
prompt_config=PromptConfig(
|
|
231
|
+
prompt_type=PromptType.DETECTOR,
|
|
232
|
+
prompter=PrompterConfig(
|
|
233
|
+
detector_type="motion",
|
|
234
|
+
strategy=HybridStrategy.CLASSIFY_REGIONS,
|
|
235
|
+
text_prompts=["fish"],
|
|
236
|
+
),
|
|
237
|
+
),
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
Example (hybrid with YOLO):
|
|
241
|
+
SAM3DetectorConfig(
|
|
242
|
+
prompt_config=PromptConfig(
|
|
243
|
+
prompt_type=PromptType.DETECTOR,
|
|
244
|
+
prompter=PrompterConfig(
|
|
245
|
+
detector_type="yolo",
|
|
246
|
+
detector_config={"model": "yolov8n.pt"},
|
|
247
|
+
strategy=HybridStrategy.BOX_REFINEMENT,
|
|
248
|
+
),
|
|
249
|
+
),
|
|
250
|
+
)
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
# Model settings
|
|
254
|
+
checkpoint: str = "./models/sam3.pt"
|
|
255
|
+
device: str = "cuda"
|
|
256
|
+
half: bool = True
|
|
257
|
+
|
|
258
|
+
# Prompting (simple)
|
|
259
|
+
prompts: List[str] = field(default_factory=list)
|
|
260
|
+
|
|
261
|
+
# Prompting (advanced)
|
|
262
|
+
prompt_config: Optional[PromptConfig] = None
|
|
263
|
+
|
|
264
|
+
# Detection filtering
|
|
265
|
+
confidence_threshold: float = 0.25
|
|
266
|
+
min_mask_area: int = 100
|
|
267
|
+
max_mask_area: int = 1000000
|
|
268
|
+
|
|
269
|
+
# Video settings
|
|
270
|
+
video_mode: bool = True
|
|
271
|
+
|
|
272
|
+
# Output options
|
|
273
|
+
output_masks: bool = False
|
|
274
|
+
output_labels: bool = True
|
|
275
|
+
|
|
276
|
+
# Inference settings
|
|
277
|
+
imgsz: int = 1024
|
|
278
|
+
|
|
279
|
+
def __post_init__(self):
|
|
280
|
+
"""Build prompt config from simple prompts if needed."""
|
|
281
|
+
|
|
282
|
+
# Only create PromptConfig if not already provided
|
|
283
|
+
if self.prompt_config is None:
|
|
284
|
+
if self.prompts:
|
|
285
|
+
# User provided simple prompts - create TEXT config
|
|
286
|
+
self.prompt_config = PromptConfig(
|
|
287
|
+
prompt_type=PromptType.TEXT,
|
|
288
|
+
text_prompts=self.prompts,
|
|
289
|
+
)
|
|
290
|
+
# If no prompts and no prompt_config, leave as None
|
|
291
|
+
# Detector will validate at runtime when process_frame is called
|
|
292
|
+
|
|
293
|
+
# Warn if cpu andFP16 used
|
|
294
|
+
if self.device == "cpu" and self.half:
|
|
295
|
+
logger.warning("FP16 (half=True) is not supported on CPU. Setting half=False.")
|
|
296
|
+
self.half = False
|
|
297
|
+
|
|
298
|
+
def get_ultralytics_overrides(self) -> Dict:
|
|
299
|
+
"""Get config dict for Ultralytics predictors."""
|
|
300
|
+
return {
|
|
301
|
+
"conf": self.confidence_threshold,
|
|
302
|
+
"task": "segment",
|
|
303
|
+
"mode": "predict",
|
|
304
|
+
"model": self.checkpoint,
|
|
305
|
+
"half": self.half,
|
|
306
|
+
"imgsz": self.imgsz,
|
|
307
|
+
"device": self.device,
|
|
308
|
+
"verbose": False,
|
|
309
|
+
}
|