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.
Files changed (73) hide show
  1. seavision/__init__.py +3 -0
  2. seavision/defaults.py +38 -0
  3. seavision/edge/__init__.py +38 -0
  4. seavision/edge/bundle.py +189 -0
  5. seavision/edge/capture.py +107 -0
  6. seavision/edge/config.py +219 -0
  7. seavision/edge/postprocess.py +185 -0
  8. seavision/edge/runtime.py +416 -0
  9. seavision/edge/writer.py +167 -0
  10. seavision/engine/__init__.py +52 -0
  11. seavision/engine/detectors/__init__.py +90 -0
  12. seavision/engine/detectors/base.py +179 -0
  13. seavision/engine/detectors/motion/__init__.py +14 -0
  14. seavision/engine/detectors/motion/background.py +92 -0
  15. seavision/engine/detectors/motion/detector.py +218 -0
  16. seavision/engine/detectors/motion/stabiliser.py +174 -0
  17. seavision/engine/detectors/motion/tracker.py +174 -0
  18. seavision/engine/detectors/sam3/__init__.py +23 -0
  19. seavision/engine/detectors/sam3/config.py +309 -0
  20. seavision/engine/detectors/sam3/detector.py +1316 -0
  21. seavision/engine/detectors/sam3/native.py +490 -0
  22. seavision/engine/detectors/yolo/__init__.py +12 -0
  23. seavision/engine/detectors/yolo/config.py +39 -0
  24. seavision/engine/detectors/yolo/detector.py +236 -0
  25. seavision/engine/export/__init__.py +24 -0
  26. seavision/engine/export/config.py +160 -0
  27. seavision/engine/export/exporter.py +286 -0
  28. seavision/engine/export/validation.py +314 -0
  29. seavision/engine/postprocessor.py +738 -0
  30. seavision/engine/source/__init__.py +16 -0
  31. seavision/engine/source/base.py +87 -0
  32. seavision/engine/source/discovery.py +154 -0
  33. seavision/engine/source/local.py +155 -0
  34. seavision/engine/source/s3.py +231 -0
  35. seavision/engine/visualiser/__init__.py +62 -0
  36. seavision/engine/visualiser/annotator.py +382 -0
  37. seavision/engine/visualiser/config.py +127 -0
  38. seavision/engine/visualiser/loader.py +558 -0
  39. seavision/engine/visualiser/visualiser.py +402 -0
  40. seavision/engine/visualiser/writer.py +245 -0
  41. seavision/gui/__init__.py +0 -0
  42. seavision/gui/app.py +30 -0
  43. seavision/gui/main_window.py +891 -0
  44. seavision/gui/shared/__init__.py +0 -0
  45. seavision/gui/shared/conversion.py +55 -0
  46. seavision/gui/shared/session_utils.py +37 -0
  47. seavision/gui/validation/__init__.py +0 -0
  48. seavision/gui/validation/button_styles.py +144 -0
  49. seavision/gui/validation/detection_detail.py +164 -0
  50. seavision/gui/validation/detection_rect_item.py +486 -0
  51. seavision/gui/validation/detection_table.py +563 -0
  52. seavision/gui/validation/interactive_frame_scene.py +340 -0
  53. seavision/gui/validation/interactive_frame_view.py +252 -0
  54. seavision/gui/validation/s3_browser.py +645 -0
  55. seavision/gui/validation/seekable_source.py +262 -0
  56. seavision/gui/validation/session.py +376 -0
  57. seavision/gui/validation/tab.py +2503 -0
  58. seavision/gui/validation/transport_bar.py +172 -0
  59. seavision/gui/validation/validation_model.py +482 -0
  60. seavision/gui/validation/video_cache.py +215 -0
  61. seavision/gui/validation/video_list.py +140 -0
  62. seavision/gui/validation/video_viewer.py +150 -0
  63. seavision/gui/validation/video_worker.py +422 -0
  64. seavision/pipeline.py +856 -0
  65. seavision/resources/default.yaml +139 -0
  66. seavision/run_edge.py +96 -0
  67. seavision/run_export.py +176 -0
  68. seavision/run_pipeline.py +388 -0
  69. seavision_python-0.1.1.dist-info/METADATA +286 -0
  70. seavision_python-0.1.1.dist-info/RECORD +73 -0
  71. seavision_python-0.1.1.dist-info/WHEEL +5 -0
  72. seavision_python-0.1.1.dist-info/entry_points.txt +5 -0
  73. 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
+ }