coralnet-toolbox 0.0.75__py2.py3-none-any.whl → 0.0.77__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/QtPolygonAnnotation.py +57 -12
- coralnet_toolbox/Annotations/QtRectangleAnnotation.py +44 -14
- coralnet_toolbox/Common/QtGraphicsUtility.py +18 -8
- coralnet_toolbox/Explorer/transformer_models.py +13 -2
- coralnet_toolbox/IO/QtExportMaskAnnotations.py +576 -402
- coralnet_toolbox/IO/QtImportImages.py +7 -15
- coralnet_toolbox/IO/QtOpenProject.py +15 -19
- coralnet_toolbox/Icons/system_monitor.png +0 -0
- coralnet_toolbox/MachineLearning/ImportDataset/QtBase.py +33 -8
- coralnet_toolbox/QtAnnotationWindow.py +4 -0
- coralnet_toolbox/QtEventFilter.py +5 -5
- coralnet_toolbox/QtImageWindow.py +4 -0
- coralnet_toolbox/QtMainWindow.py +104 -64
- coralnet_toolbox/QtProgressBar.py +1 -0
- coralnet_toolbox/QtSystemMonitor.py +370 -0
- coralnet_toolbox/Rasters/RasterManager.py +5 -2
- coralnet_toolbox/Results/ConvertResults.py +14 -8
- coralnet_toolbox/Results/ResultsProcessor.py +3 -2
- coralnet_toolbox/SAM/QtDeployGenerator.py +1 -1
- coralnet_toolbox/SAM/QtDeployPredictor.py +10 -0
- coralnet_toolbox/SeeAnything/QtDeployGenerator.py +324 -177
- coralnet_toolbox/SeeAnything/QtDeployPredictor.py +10 -6
- coralnet_toolbox/Tile/QtTileBatchInference.py +4 -4
- coralnet_toolbox/Tools/QtPatchTool.py +6 -2
- coralnet_toolbox/Tools/QtPolygonTool.py +5 -3
- coralnet_toolbox/Tools/QtRectangleTool.py +17 -9
- coralnet_toolbox/Tools/QtSAMTool.py +144 -91
- coralnet_toolbox/Tools/QtSeeAnythingTool.py +4 -0
- coralnet_toolbox/Tools/QtTool.py +79 -3
- coralnet_toolbox/Tools/QtWorkAreaTool.py +4 -0
- coralnet_toolbox/Transformers/Models/GroundingDINO.py +72 -0
- coralnet_toolbox/Transformers/Models/OWLViT.py +72 -0
- coralnet_toolbox/Transformers/Models/OmDetTurbo.py +68 -0
- coralnet_toolbox/Transformers/Models/QtBase.py +121 -0
- coralnet_toolbox/{AutoDistill → Transformers}/Models/__init__.py +1 -1
- coralnet_toolbox/{AutoDistill → Transformers}/QtBatchInference.py +15 -15
- coralnet_toolbox/{AutoDistill → Transformers}/QtDeployModel.py +18 -16
- coralnet_toolbox/{AutoDistill → Transformers}/__init__.py +1 -1
- coralnet_toolbox/__init__.py +1 -1
- coralnet_toolbox/utilities.py +0 -15
- {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/METADATA +9 -9
- {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/RECORD +46 -44
- coralnet_toolbox/AutoDistill/Models/GroundingDINO.py +0 -81
- coralnet_toolbox/AutoDistill/Models/OWLViT.py +0 -76
- coralnet_toolbox/AutoDistill/Models/OmDetTurbo.py +0 -75
- coralnet_toolbox/AutoDistill/Models/QtBase.py +0 -112
- {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/WHEEL +0 -0
- {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/entry_points.txt +0 -0
- {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/licenses/LICENSE.txt +0 -0
- {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/top_level.txt +0 -0
@@ -306,20 +306,30 @@ class PolygonAnnotation(Annotation):
|
|
306
306
|
self.set_cropped_bbox()
|
307
307
|
# Get the bounding box of the polygon
|
308
308
|
min_x, min_y, max_x, max_y = self.cropped_bbox
|
309
|
-
|
309
|
+
|
310
|
+
# Ensure min/max values are correctly ordered
|
311
|
+
min_x, max_x = min(min_x, max_x), max(min_x, max_x)
|
312
|
+
min_y, max_y = min(min_y, max_y), max(min_y, max_y)
|
313
|
+
|
314
|
+
# Clamp values to image bounds
|
315
|
+
min_x = max(0, min(rasterio_src.width - 1, min_x))
|
316
|
+
min_y = max(0, min(rasterio_src.height - 1, min_y))
|
317
|
+
max_x = max(min_x + 1, min(rasterio_src.width, max_x))
|
318
|
+
max_y = max(min_y + 1, min(rasterio_src.height, max_y))
|
319
|
+
|
310
320
|
# Calculate the window for rasterio
|
311
321
|
window = Window(
|
312
|
-
col_off=
|
313
|
-
row_off=
|
314
|
-
width=
|
315
|
-
height=
|
322
|
+
col_off=int(min_x),
|
323
|
+
row_off=int(min_y),
|
324
|
+
width=int(max_x - min_x),
|
325
|
+
height=int(max_y - min_y)
|
316
326
|
)
|
317
|
-
|
327
|
+
|
318
328
|
# Convert rasterio to QImage
|
319
329
|
q_image = rasterio_to_cropped_image(self.rasterio_src, window)
|
320
330
|
# Convert QImage to QPixmap
|
321
331
|
self.cropped_image = QPixmap.fromImage(q_image)
|
322
|
-
|
332
|
+
|
323
333
|
self.annotationUpdated.emit(self) # Notify update
|
324
334
|
|
325
335
|
def create_graphics_item(self, scene: QGraphicsScene):
|
@@ -423,7 +433,7 @@ class PolygonAnnotation(Annotation):
|
|
423
433
|
self.update_graphics_item()
|
424
434
|
self.annotationUpdated.emit(self) # Notify update
|
425
435
|
|
426
|
-
def update_annotation_size(self,
|
436
|
+
def update_annotation_size(self, scale_factor: float):
|
427
437
|
"""
|
428
438
|
Grow/shrink the polygon and its holes by scaling vertices radially from the centroid.
|
429
439
|
"""
|
@@ -433,18 +443,53 @@ class PolygonAnnotation(Annotation):
|
|
433
443
|
return
|
434
444
|
|
435
445
|
# 1. Use the true geometric centroid as the pivot for scaling.
|
436
|
-
# This is correctly calculated by the new set_centroid() method.
|
437
446
|
centroid_x = self.center_xy.x()
|
438
447
|
centroid_y = self.center_xy.y()
|
439
448
|
|
440
|
-
# 2. Determine the scale factor
|
449
|
+
# 2. Determine the scale factor.
|
441
450
|
step = 0.01 # Adjust for finer or coarser changes
|
442
|
-
if
|
451
|
+
if scale_factor > 1.0:
|
443
452
|
scale = 1.0 + step
|
444
|
-
elif
|
453
|
+
elif scale_factor < 1.0:
|
445
454
|
scale = 1.0 - step
|
446
455
|
else:
|
447
456
|
scale = 1.0
|
457
|
+
|
458
|
+
# Check for image boundaries before scaling
|
459
|
+
if hasattr(self, 'rasterio_src'):
|
460
|
+
# Before scaling, check if any point would go beyond image boundaries
|
461
|
+
img_width = self.rasterio_src.width
|
462
|
+
img_height = self.rasterio_src.height
|
463
|
+
padding = 10 # pixels of padding
|
464
|
+
|
465
|
+
# Check outer boundary points
|
466
|
+
for p in self.points:
|
467
|
+
dx = p.x() - centroid_x
|
468
|
+
dy = p.y() - centroid_y
|
469
|
+
new_x = centroid_x + dx * scale
|
470
|
+
new_y = centroid_y + dy * scale
|
471
|
+
|
472
|
+
if new_x < -padding or \
|
473
|
+
new_y < -padding or \
|
474
|
+
new_x > img_width + padding or \
|
475
|
+
new_y > img_height + padding:
|
476
|
+
# Point would be out of bounds, don't scale
|
477
|
+
return
|
478
|
+
|
479
|
+
# Check holes points too
|
480
|
+
for hole in self.holes:
|
481
|
+
for p in hole:
|
482
|
+
dx = p.x() - centroid_x
|
483
|
+
dy = p.y() - centroid_y
|
484
|
+
new_x = centroid_x + dx * scale
|
485
|
+
new_y = centroid_y + dy * scale
|
486
|
+
|
487
|
+
if new_x < -padding or \
|
488
|
+
new_y < -padding or \
|
489
|
+
new_x > img_width + padding or \
|
490
|
+
new_y > img_height + padding:
|
491
|
+
# Point would be out of bounds, don't scale
|
492
|
+
return
|
448
493
|
|
449
494
|
# 3. Scale the outer boundary points.
|
450
495
|
new_points = []
|
@@ -213,23 +213,29 @@ class RectangleAnnotation(Annotation):
|
|
213
213
|
# Get the bounding box of the rectangle
|
214
214
|
min_x, min_y, max_x, max_y = self.cropped_bbox
|
215
215
|
|
216
|
-
# Ensure min/max values are correctly ordered
|
216
|
+
# Ensure min/max values are correctly ordered
|
217
217
|
min_x, max_x = min(min_x, max_x), max(min_x, max_x)
|
218
218
|
min_y, max_y = min(min_y, max_y), max(min_y, max_y)
|
219
|
-
|
219
|
+
|
220
|
+
# Clamp values to image bounds
|
221
|
+
min_x = max(0, min(rasterio_src.width - 1, min_x))
|
222
|
+
min_y = max(0, min(rasterio_src.height - 1, min_y))
|
223
|
+
max_x = max(min_x + 1, min(rasterio_src.width, max_x))
|
224
|
+
max_y = max(min_y + 1, min(rasterio_src.height, max_y))
|
225
|
+
|
220
226
|
# Calculate the window for rasterio
|
221
227
|
window = Window(
|
222
|
-
col_off=
|
223
|
-
row_off=
|
224
|
-
width=
|
225
|
-
height=
|
228
|
+
col_off=int(min_x),
|
229
|
+
row_off=int(min_y),
|
230
|
+
width=int(max_x - min_x),
|
231
|
+
height=int(max_y - min_y)
|
226
232
|
)
|
227
|
-
|
233
|
+
|
228
234
|
# Convert rasterio to QImage
|
229
235
|
q_image = rasterio_to_cropped_image(self.rasterio_src, window)
|
230
236
|
# Convert QImage to QPixmap
|
231
237
|
self.cropped_image = QPixmap.fromImage(q_image)
|
232
|
-
|
238
|
+
|
233
239
|
self.annotationUpdated.emit(self) # Notify update
|
234
240
|
|
235
241
|
def create_graphics_item(self, scene: QGraphicsScene):
|
@@ -282,13 +288,37 @@ class RectangleAnnotation(Annotation):
|
|
282
288
|
# Clear the machine confidence
|
283
289
|
self.update_user_confidence(self.label)
|
284
290
|
|
285
|
-
#
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
291
|
+
# Calculate new dimensions
|
292
|
+
current_width = self.bottom_right.x() - self.top_left.x()
|
293
|
+
current_height = self.bottom_right.y() - self.top_left.y()
|
294
|
+
new_width = current_width * scale_factor
|
295
|
+
new_height = current_height * scale_factor
|
296
|
+
|
297
|
+
# Calculate tentative new corners
|
298
|
+
new_left = self.center_xy.x() - new_width / 2
|
299
|
+
new_top = self.center_xy.y() - new_height / 2
|
300
|
+
new_right = self.center_xy.x() + new_width / 2
|
301
|
+
new_bottom = self.center_xy.y() + new_height / 2
|
302
|
+
|
303
|
+
# Check if we're within valid image bounds (or use a reasonable padding)
|
304
|
+
# Assuming we have access to the image dimensions
|
305
|
+
if hasattr(self, 'rasterio_src'):
|
306
|
+
img_width = self.rasterio_src.width
|
307
|
+
img_height = self.rasterio_src.height
|
308
|
+
|
309
|
+
# Apply reasonable bounds with some margin
|
310
|
+
padding = 10 # pixels
|
311
|
+
if new_left < -padding or new_top < -padding or new_right > img_width + padding or new_bottom > img_height + padding:
|
312
|
+
# Don't resize beyond these limits
|
313
|
+
return
|
314
|
+
|
315
|
+
# Update the rectangle coordinates
|
316
|
+
self.top_left = QPointF(new_left, new_top)
|
317
|
+
self.bottom_right = QPointF(new_right, new_bottom)
|
318
|
+
|
319
|
+
# Update graphics and notify
|
290
320
|
self.update_graphics_item()
|
291
|
-
self.annotationUpdated.emit(self)
|
321
|
+
self.annotationUpdated.emit(self)
|
292
322
|
|
293
323
|
def resize(self, handle: str, new_pos: QPointF):
|
294
324
|
"""Resize the annotation based on the handle and new position."""
|
@@ -1,18 +1,17 @@
|
|
1
1
|
import warnings
|
2
2
|
|
3
|
-
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
4
|
-
warnings.filterwarnings("ignore", category=UserWarning)
|
5
|
-
|
6
|
-
import os
|
7
3
|
|
4
|
+
from PyQt5.QtCore import Qt
|
5
|
+
from PyQt5.QtGui import QPen, QColor
|
8
6
|
from PyQt5.QtWidgets import (QVBoxLayout, QLabel, QGroupBox, QFormLayout,
|
9
7
|
QDoubleSpinBox, QComboBox, QSpinBox, QHBoxLayout,
|
10
8
|
QWidget, QStackedWidget, QGridLayout, QMessageBox,
|
11
9
|
QDialog, QListWidget, QPushButton, QFileDialog,
|
12
|
-
QGraphicsView)
|
13
|
-
|
10
|
+
QGraphicsView, QGraphicsLineItem)
|
11
|
+
|
14
12
|
|
15
|
-
|
13
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
14
|
+
warnings.filterwarnings("ignore", category=UserWarning)
|
16
15
|
|
17
16
|
|
18
17
|
# ----------------------------------------------------------------------------------------------------------------------
|
@@ -161,4 +160,15 @@ class GraphicsUtility:
|
|
161
160
|
|
162
161
|
view_width = round(extent.width())
|
163
162
|
view_height = round(extent.height())
|
164
|
-
return max(2, min(5, max(view_width, view_height) // 1000))
|
163
|
+
return max(2, min(5, max(view_width, view_height) // 1000))
|
164
|
+
|
165
|
+
@staticmethod
|
166
|
+
def create_guide_line(start_point, end_point):
|
167
|
+
"""Create a semi-transparent guide line for crosshairs."""
|
168
|
+
line = QGraphicsLineItem(start_point.x(), start_point.y(), end_point.x(), end_point.y())
|
169
|
+
pen = QPen(QColor(255, 255, 255, 180)) # Semi-transparent white
|
170
|
+
pen.setWidth(1)
|
171
|
+
pen.setStyle(Qt.DashLine)
|
172
|
+
line.setPen(pen)
|
173
|
+
line.setZValue(1000) # Ensure it's drawn on top of other elements
|
174
|
+
return line
|
@@ -7,12 +7,23 @@ Qt dependencies.
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
TRANSFORMER_MODELS = {
|
10
|
+
'ResNet-50': 'microsoft/resnet-50',
|
11
|
+
'ResNet-101': 'microsoft/resnet-101',
|
10
12
|
'DINOv2 (Small)': 'facebook/dinov2-small',
|
11
13
|
'DINOv2 (Base)': 'facebook/dinov2-base',
|
12
14
|
'DINOv2 (Large)': 'facebook/dinov2-large',
|
15
|
+
'DINOv2 (Giant)': 'facebook/dinov2-giant',
|
16
|
+
'DINOv2 (Giant ImageNet1k)': 'facebook/dinov2-giant-imagenet1k-1-layer',
|
13
17
|
'DINOv3 ConvNext (Tiny)': 'facebook/dinov3-convnext-tiny-pretrain-lvd1689m',
|
14
|
-
'
|
15
|
-
'
|
18
|
+
'DINOv3 ConvNext (Small)': 'facebook/dinov3-convnext-small-pretrain-lvd1689m',
|
19
|
+
'DINOv3 ConvNext (Base)': 'facebook/dinov3-convnext-base-pretrain-lvd1689m',
|
20
|
+
'DINOv3 ConvNext (Large)': 'facebook/dinov3-convnext-large-pretrain-lvd1689m',
|
21
|
+
'DINOv3 ViT (Small/16)': 'facebook/dinov3-vits16-pretrain-lvd1689m',
|
22
|
+
'DINOv3 ViT (Small/16+)': 'facebook/dinov3-vits16plus-pretrain-lvd1689m',
|
23
|
+
'DINOv3 ViT (Base/16)': 'facebook/dinov3-vitb16-pretrain-lvd1689m',
|
24
|
+
'DINOv3 ViT (Large/16)': 'facebook/dinov3-vitl16-pretrain-lvd1689m',
|
25
|
+
'DINOv3 ViT (Huge/16+)': 'facebook/dinov3-vith16plus-pretrain-lvd1689m',
|
26
|
+
'DINOv3 ViT (7B/16)': 'facebook/dinov3-vit7b16-pretrain-lvd1689m',
|
16
27
|
'Swin Transformer (Tiny)': 'microsoft/swin-tiny-patch4-window7-224',
|
17
28
|
'Swin Transformer (Base)': 'microsoft/swin-base-patch4-window7-224',
|
18
29
|
'ViT (Base)': 'google/vit-base-patch16-224',
|