coralnet-toolbox 0.0.71__py2.py3-none-any.whl → 0.0.73__py2.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.
- coralnet_toolbox/Annotations/QtRectangleAnnotation.py +31 -2
- coralnet_toolbox/AutoDistill/QtDeployModel.py +23 -12
- coralnet_toolbox/Explorer/QtDataItem.py +53 -21
- coralnet_toolbox/Explorer/QtExplorer.py +581 -276
- coralnet_toolbox/Explorer/QtFeatureStore.py +15 -0
- coralnet_toolbox/Explorer/QtSettingsWidgets.py +49 -7
- coralnet_toolbox/MachineLearning/DeployModel/QtDetect.py +22 -11
- coralnet_toolbox/MachineLearning/DeployModel/QtSegment.py +22 -10
- coralnet_toolbox/MachineLearning/ExportDataset/QtBase.py +61 -24
- coralnet_toolbox/MachineLearning/ExportDataset/QtClassify.py +5 -1
- coralnet_toolbox/MachineLearning/ExportDataset/QtDetect.py +19 -6
- coralnet_toolbox/MachineLearning/ExportDataset/QtSegment.py +21 -8
- coralnet_toolbox/QtAnnotationWindow.py +52 -16
- coralnet_toolbox/QtEventFilter.py +8 -2
- coralnet_toolbox/QtImageWindow.py +17 -18
- coralnet_toolbox/QtLabelWindow.py +1 -1
- coralnet_toolbox/QtMainWindow.py +203 -8
- coralnet_toolbox/Rasters/QtRaster.py +59 -7
- coralnet_toolbox/Rasters/RasterTableModel.py +34 -6
- coralnet_toolbox/SAM/QtBatchInference.py +0 -2
- coralnet_toolbox/SAM/QtDeployGenerator.py +22 -11
- coralnet_toolbox/SeeAnything/QtBatchInference.py +19 -221
- coralnet_toolbox/SeeAnything/QtDeployGenerator.py +1016 -0
- coralnet_toolbox/SeeAnything/QtDeployPredictor.py +69 -53
- coralnet_toolbox/SeeAnything/QtTrainModel.py +115 -45
- coralnet_toolbox/SeeAnything/__init__.py +2 -0
- coralnet_toolbox/Tools/QtResizeSubTool.py +6 -1
- coralnet_toolbox/Tools/QtSAMTool.py +150 -7
- coralnet_toolbox/Tools/QtSeeAnythingTool.py +220 -55
- coralnet_toolbox/Tools/QtSelectSubTool.py +6 -4
- coralnet_toolbox/Tools/QtSelectTool.py +48 -6
- coralnet_toolbox/Tools/QtWorkAreaTool.py +25 -13
- coralnet_toolbox/__init__.py +1 -1
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.73.dist-info}/METADATA +1 -1
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.73.dist-info}/RECORD +39 -38
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.73.dist-info}/WHEEL +0 -0
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.73.dist-info}/entry_points.txt +0 -0
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.73.dist-info}/licenses/LICENSE.txt +0 -0
- {coralnet_toolbox-0.0.71.dist-info → coralnet_toolbox-0.0.73.dist-info}/top_level.txt +0 -0
@@ -40,23 +40,17 @@ class BatchInferenceDialog(QDialog):
|
|
40
40
|
|
41
41
|
self.setWindowIcon(get_icon("eye.png"))
|
42
42
|
self.setWindowTitle("Batch Inference")
|
43
|
-
self.resize(
|
43
|
+
self.resize(400, 100)
|
44
44
|
|
45
|
-
self.
|
45
|
+
self.deploy_generator_dialog = None
|
46
46
|
self.loaded_model = None
|
47
47
|
|
48
|
-
|
49
|
-
self.source_image_path = None
|
50
|
-
self.source_label = None
|
51
|
-
# Target images
|
52
|
-
self.target_images = []
|
48
|
+
self.image_paths = []
|
53
49
|
|
54
50
|
self.layout = QVBoxLayout(self)
|
55
51
|
|
56
52
|
# Setup the info layout
|
57
53
|
self.setup_info_layout()
|
58
|
-
# Setup the source layout
|
59
|
-
self.setup_source_layout()
|
60
54
|
# Setup the image options layout
|
61
55
|
self.setup_options_layout()
|
62
56
|
# Setup the buttons layout
|
@@ -69,11 +63,8 @@ class BatchInferenceDialog(QDialog):
|
|
69
63
|
:param event: Show event
|
70
64
|
"""
|
71
65
|
super().showEvent(event)
|
72
|
-
self.
|
73
|
-
self.loaded_model = self.
|
74
|
-
|
75
|
-
# Update the source images (now assuming sources are valid)
|
76
|
-
self.update_source_images()
|
66
|
+
self.deploy_generator_dialog = self.main_window.see_anything_deploy_generator_dialog
|
67
|
+
self.loaded_model = self.deploy_generator_dialog.loaded_model
|
77
68
|
|
78
69
|
def setup_info_layout(self):
|
79
70
|
"""
|
@@ -92,26 +83,6 @@ class BatchInferenceDialog(QDialog):
|
|
92
83
|
group_box.setLayout(layout)
|
93
84
|
self.layout.addWidget(group_box)
|
94
85
|
|
95
|
-
def setup_source_layout(self):
|
96
|
-
"""
|
97
|
-
Set up the layout with source image and label selection.
|
98
|
-
Contains dropdown combo boxes for selecting the source image and label.
|
99
|
-
"""
|
100
|
-
group_box = QGroupBox("Source Selection")
|
101
|
-
layout = QFormLayout()
|
102
|
-
|
103
|
-
# Create the source image combo box
|
104
|
-
self.source_image_combo_box = QComboBox()
|
105
|
-
self.source_image_combo_box.currentIndexChanged.connect(self.update_source_labels)
|
106
|
-
layout.addRow("Source Image:", self.source_image_combo_box)
|
107
|
-
|
108
|
-
# Create the source label combo box
|
109
|
-
self.source_label_combo_box = QComboBox()
|
110
|
-
layout.addRow("Source Label:", self.source_label_combo_box)
|
111
|
-
|
112
|
-
group_box.setLayout(layout)
|
113
|
-
self.layout.addWidget(group_box)
|
114
|
-
|
115
86
|
def setup_options_layout(self):
|
116
87
|
"""
|
117
88
|
Set up the layout with image options.
|
@@ -159,202 +130,37 @@ class BatchInferenceDialog(QDialog):
|
|
159
130
|
|
160
131
|
self.layout.addWidget(button_box)
|
161
132
|
|
162
|
-
def has_valid_sources(self):
|
163
|
-
"""
|
164
|
-
Check if there are any valid source images with polygon or rectangle annotations.
|
165
|
-
|
166
|
-
:return: True if valid sources exist, False otherwise
|
167
|
-
"""
|
168
|
-
# Check if there are any images
|
169
|
-
if not self.image_window.raster_manager.image_paths:
|
170
|
-
QMessageBox.information(None,
|
171
|
-
"No Images",
|
172
|
-
"No images available for batch inference.")
|
173
|
-
return False
|
174
|
-
|
175
|
-
# Check for images with valid annotations
|
176
|
-
for image_path in self.image_window.raster_manager.image_paths:
|
177
|
-
# Get annotations for this image
|
178
|
-
annotations = self.annotation_window.get_image_annotations(image_path)
|
179
|
-
|
180
|
-
# Check if there's at least one valid polygon/rectangle annotation
|
181
|
-
for annotation in annotations:
|
182
|
-
if isinstance(annotation, PolygonAnnotation) or isinstance(annotation, RectangleAnnotation):
|
183
|
-
return True
|
184
|
-
|
185
|
-
QMessageBox.information(None,
|
186
|
-
"No Valid Annotations",
|
187
|
-
"No images have polygon or rectangle annotations for batch inference.")
|
188
|
-
return False
|
189
|
-
|
190
|
-
def check_valid_sources(self):
|
191
|
-
"""
|
192
|
-
Check if there are any valid source images with polygon or rectangle annotations.
|
193
|
-
|
194
|
-
:return: True if valid sources exist, False otherwise
|
195
|
-
"""
|
196
|
-
# Check if there are any images
|
197
|
-
if not self.image_window.raster_manager.image_paths:
|
198
|
-
QMessageBox.information(self,
|
199
|
-
"No Images",
|
200
|
-
"No images available for batch inference.")
|
201
|
-
return False
|
202
|
-
|
203
|
-
# Check for images with valid annotations
|
204
|
-
for image_path in self.image_window.raster_manager.image_paths:
|
205
|
-
# Get annotations for this image
|
206
|
-
annotations = self.annotation_window.get_image_annotations(image_path)
|
207
|
-
|
208
|
-
# Check if there's at least one valid polygon/rectangle annotation
|
209
|
-
for annotation in annotations:
|
210
|
-
if isinstance(annotation, PolygonAnnotation) or isinstance(annotation, RectangleAnnotation):
|
211
|
-
return True
|
212
|
-
|
213
|
-
QMessageBox.information(self,
|
214
|
-
"No Valid Annotations",
|
215
|
-
"No images have polygon or rectangle annotations for batch inference.")
|
216
|
-
return False
|
217
|
-
|
218
|
-
def update_source_images(self):
|
219
|
-
"""
|
220
|
-
Updates the source image combo box with images that have at least one label
|
221
|
-
with a valid polygon or rectangle annotation.
|
222
|
-
|
223
|
-
:return: True if valid source images were found, False otherwise
|
224
|
-
"""
|
225
|
-
self.source_image_combo_box.clear()
|
226
|
-
valid_images_found = False
|
227
|
-
|
228
|
-
# Get all image paths from the raster_manager
|
229
|
-
for image_path in self.image_window.raster_manager.image_paths:
|
230
|
-
# Get annotations for this image
|
231
|
-
annotations = self.annotation_window.get_image_annotations(image_path)
|
232
|
-
|
233
|
-
# Check if there's at least one valid polygon/rectangle annotation
|
234
|
-
valid_annotation_found = False
|
235
|
-
for annotation in annotations:
|
236
|
-
if isinstance(annotation, PolygonAnnotation) or isinstance(annotation, RectangleAnnotation):
|
237
|
-
valid_annotation_found = True
|
238
|
-
break
|
239
|
-
|
240
|
-
if valid_annotation_found:
|
241
|
-
# Get the basename (filename)
|
242
|
-
basename = os.path.basename(image_path)
|
243
|
-
# Add item to combo box with full path as data
|
244
|
-
self.source_image_combo_box.addItem(basename, image_path)
|
245
|
-
valid_images_found = True
|
246
|
-
|
247
|
-
if not valid_images_found:
|
248
|
-
QMessageBox.information(self,
|
249
|
-
"No Source Images",
|
250
|
-
"No images available for batch inference.")
|
251
|
-
# Close the dialog since batch inference can't proceed
|
252
|
-
QApplication.processEvents() # Process pending events
|
253
|
-
self.reject()
|
254
|
-
return False
|
255
|
-
|
256
|
-
# Update the combo box to have the selected image first
|
257
|
-
if self.annotation_window.current_image_path in self.image_window.raster_manager.image_paths:
|
258
|
-
self.source_image_combo_box.setCurrentText(os.path.basename(self.annotation_window.current_image_path))
|
259
|
-
|
260
|
-
# Update the source labels given changes in the source images
|
261
|
-
return self.update_source_labels()
|
262
|
-
|
263
|
-
def update_source_labels(self):
|
264
|
-
"""
|
265
|
-
Updates the source label combo box with labels that have at least one
|
266
|
-
polygon or rectangle annotation from the current image.
|
267
|
-
|
268
|
-
:return: True if valid source labels were found, False otherwise
|
269
|
-
"""
|
270
|
-
self.source_label_combo_box.clear()
|
271
|
-
|
272
|
-
source_image_path = self.source_image_combo_box.currentData()
|
273
|
-
if not source_image_path:
|
274
|
-
return False
|
275
|
-
|
276
|
-
# Get annotations for this image
|
277
|
-
annotations = self.annotation_window.get_image_annotations(source_image_path)
|
278
|
-
|
279
|
-
# Create a dict of labels with valid annotations
|
280
|
-
valid_labels = {}
|
281
|
-
for annotation in annotations:
|
282
|
-
if isinstance(annotation, PolygonAnnotation) or isinstance(annotation, RectangleAnnotation):
|
283
|
-
valid_labels[annotation.label.short_label_code] = annotation.label
|
284
|
-
|
285
|
-
# Add valid labels to combo box
|
286
|
-
for label_code, label_obj in valid_labels.items():
|
287
|
-
self.source_label_combo_box.addItem(label_code, label_obj)
|
288
|
-
|
289
|
-
if not valid_labels:
|
290
|
-
QMessageBox.information(self,
|
291
|
-
"No Valid Labels",
|
292
|
-
"No labels with polygon or rectangle annotations available for batch inference.")
|
293
|
-
# Close the dialog since batch inference can't proceed
|
294
|
-
QApplication.processEvents() # Process pending events
|
295
|
-
self.reject()
|
296
|
-
return False
|
297
|
-
|
298
|
-
return True
|
299
|
-
|
300
|
-
def get_source_annotations(self):
|
301
|
-
"""Return a list of polygon and rectangle annotations for the
|
302
|
-
source image belonging to the selected label."""
|
303
|
-
source_image_path = self.source_image_combo_box.currentData()
|
304
|
-
source_label = self.source_label_combo_box.currentData()
|
305
|
-
|
306
|
-
# Get annotations for this image
|
307
|
-
annotations = self.annotation_window.get_image_annotations(source_image_path)
|
308
|
-
|
309
|
-
# Filter annotations by label
|
310
|
-
source_annotations = []
|
311
|
-
for annotation in annotations:
|
312
|
-
if annotation.label.short_label_code == source_label.short_label_code:
|
313
|
-
source_annotations.append(annotation.cropped_bbox)
|
314
|
-
|
315
|
-
return np.array(source_annotations)
|
316
|
-
|
317
133
|
def get_selected_image_paths(self):
|
318
134
|
"""
|
319
135
|
Get the selected image paths based on the options.
|
320
|
-
|
321
|
-
|
136
|
+
|
322
137
|
:return: List of selected image paths
|
323
138
|
"""
|
324
|
-
# Get the source image path to exclude
|
325
|
-
source_image_path = self.source_image_combo_box.currentData()
|
326
|
-
|
327
139
|
# Current image path showing
|
328
140
|
current_image_path = self.annotation_window.current_image_path
|
329
141
|
if not current_image_path:
|
330
142
|
return []
|
331
|
-
|
143
|
+
|
332
144
|
# Determine which images to export annotations for
|
333
145
|
if self.apply_filtered_checkbox.isChecked():
|
334
|
-
|
146
|
+
return self.image_window.table_model.filtered_paths
|
335
147
|
elif self.apply_prev_checkbox.isChecked():
|
336
148
|
if current_image_path in self.image_window.table_model.filtered_paths:
|
337
149
|
current_index = self.image_window.table_model.get_row_for_path(current_image_path)
|
338
|
-
|
150
|
+
return self.image_window.table_model.filtered_paths[:current_index + 1]
|
339
151
|
else:
|
340
|
-
|
152
|
+
return [current_image_path]
|
341
153
|
elif self.apply_next_checkbox.isChecked():
|
342
154
|
if current_image_path in self.image_window.table_model.filtered_paths:
|
343
155
|
current_index = self.image_window.table_model.get_row_for_path(current_image_path)
|
344
|
-
|
156
|
+
return self.image_window.table_model.filtered_paths[current_index:]
|
345
157
|
else:
|
346
|
-
|
158
|
+
return [current_image_path]
|
347
159
|
elif self.apply_all_checkbox.isChecked():
|
348
|
-
|
160
|
+
return self.image_window.raster_manager.image_paths
|
349
161
|
else:
|
350
162
|
# Only apply to the current image
|
351
|
-
|
352
|
-
|
353
|
-
# Remove the source image path if it's in the selected paths
|
354
|
-
if source_image_path and source_image_path in selected_paths:
|
355
|
-
selected_paths.remove(source_image_path)
|
356
|
-
|
357
|
-
return selected_paths
|
163
|
+
return [current_image_path]
|
358
164
|
|
359
165
|
def apply(self):
|
360
166
|
"""
|
@@ -364,14 +170,8 @@ class BatchInferenceDialog(QDialog):
|
|
364
170
|
QApplication.setOverrideCursor(Qt.WaitCursor)
|
365
171
|
|
366
172
|
try:
|
367
|
-
# Get the source image path and label
|
368
|
-
self.source_image_path = self.source_image_combo_box.currentData()
|
369
|
-
self.source_label = self.source_label_combo_box.currentData()
|
370
|
-
# Get the source annotations
|
371
|
-
self.source_annotations = self.get_source_annotations()
|
372
173
|
# Get the selected image paths
|
373
|
-
self.
|
374
|
-
# Perform batch inference
|
174
|
+
self.image_paths = self.get_selected_image_paths()
|
375
175
|
self.batch_inference()
|
376
176
|
|
377
177
|
except Exception as e:
|
@@ -385,17 +185,15 @@ class BatchInferenceDialog(QDialog):
|
|
385
185
|
def batch_inference(self):
|
386
186
|
"""
|
387
187
|
Perform batch inference on the selected images.
|
388
|
-
|
389
188
|
"""
|
390
189
|
# Make predictions on each image's annotations
|
391
190
|
progress_bar = ProgressBar(self, title="Batch Inference")
|
392
191
|
progress_bar.show()
|
393
|
-
progress_bar.start_progress(len(self.
|
192
|
+
progress_bar.start_progress(len(self.image_paths))
|
394
193
|
|
395
194
|
if self.loaded_model is not None:
|
396
|
-
self.
|
397
|
-
|
398
|
-
refer_annotations=self.source_annotations,
|
399
|
-
target_images=self.target_images)
|
195
|
+
self.deploy_generator_dialog.predict(image_paths=self.image_paths)
|
196
|
+
|
400
197
|
progress_bar.stop_progress()
|
401
198
|
progress_bar.close()
|
199
|
+
|