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.
Files changed (50) hide show
  1. coralnet_toolbox/Annotations/QtPolygonAnnotation.py +57 -12
  2. coralnet_toolbox/Annotations/QtRectangleAnnotation.py +44 -14
  3. coralnet_toolbox/Common/QtGraphicsUtility.py +18 -8
  4. coralnet_toolbox/Explorer/transformer_models.py +13 -2
  5. coralnet_toolbox/IO/QtExportMaskAnnotations.py +576 -402
  6. coralnet_toolbox/IO/QtImportImages.py +7 -15
  7. coralnet_toolbox/IO/QtOpenProject.py +15 -19
  8. coralnet_toolbox/Icons/system_monitor.png +0 -0
  9. coralnet_toolbox/MachineLearning/ImportDataset/QtBase.py +33 -8
  10. coralnet_toolbox/QtAnnotationWindow.py +4 -0
  11. coralnet_toolbox/QtEventFilter.py +5 -5
  12. coralnet_toolbox/QtImageWindow.py +4 -0
  13. coralnet_toolbox/QtMainWindow.py +104 -64
  14. coralnet_toolbox/QtProgressBar.py +1 -0
  15. coralnet_toolbox/QtSystemMonitor.py +370 -0
  16. coralnet_toolbox/Rasters/RasterManager.py +5 -2
  17. coralnet_toolbox/Results/ConvertResults.py +14 -8
  18. coralnet_toolbox/Results/ResultsProcessor.py +3 -2
  19. coralnet_toolbox/SAM/QtDeployGenerator.py +1 -1
  20. coralnet_toolbox/SAM/QtDeployPredictor.py +10 -0
  21. coralnet_toolbox/SeeAnything/QtDeployGenerator.py +324 -177
  22. coralnet_toolbox/SeeAnything/QtDeployPredictor.py +10 -6
  23. coralnet_toolbox/Tile/QtTileBatchInference.py +4 -4
  24. coralnet_toolbox/Tools/QtPatchTool.py +6 -2
  25. coralnet_toolbox/Tools/QtPolygonTool.py +5 -3
  26. coralnet_toolbox/Tools/QtRectangleTool.py +17 -9
  27. coralnet_toolbox/Tools/QtSAMTool.py +144 -91
  28. coralnet_toolbox/Tools/QtSeeAnythingTool.py +4 -0
  29. coralnet_toolbox/Tools/QtTool.py +79 -3
  30. coralnet_toolbox/Tools/QtWorkAreaTool.py +4 -0
  31. coralnet_toolbox/Transformers/Models/GroundingDINO.py +72 -0
  32. coralnet_toolbox/Transformers/Models/OWLViT.py +72 -0
  33. coralnet_toolbox/Transformers/Models/OmDetTurbo.py +68 -0
  34. coralnet_toolbox/Transformers/Models/QtBase.py +121 -0
  35. coralnet_toolbox/{AutoDistill → Transformers}/Models/__init__.py +1 -1
  36. coralnet_toolbox/{AutoDistill → Transformers}/QtBatchInference.py +15 -15
  37. coralnet_toolbox/{AutoDistill → Transformers}/QtDeployModel.py +18 -16
  38. coralnet_toolbox/{AutoDistill → Transformers}/__init__.py +1 -1
  39. coralnet_toolbox/__init__.py +1 -1
  40. coralnet_toolbox/utilities.py +0 -15
  41. {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/METADATA +9 -9
  42. {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/RECORD +46 -44
  43. coralnet_toolbox/AutoDistill/Models/GroundingDINO.py +0 -81
  44. coralnet_toolbox/AutoDistill/Models/OWLViT.py +0 -76
  45. coralnet_toolbox/AutoDistill/Models/OmDetTurbo.py +0 -75
  46. coralnet_toolbox/AutoDistill/Models/QtBase.py +0 -112
  47. {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/WHEEL +0 -0
  48. {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/entry_points.txt +0 -0
  49. {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/licenses/LICENSE.txt +0 -0
  50. {coralnet_toolbox-0.0.75.dist-info → coralnet_toolbox-0.0.77.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,72 @@
1
+ from dataclasses import dataclass
2
+
3
+ import torch
4
+
5
+ from ultralytics.engine.results import Results
6
+
7
+ from transformers import AutoProcessor, AutoModelForZeroShotObjectDetection
8
+
9
+ from autodistill.detection import CaptionOntology
10
+
11
+ from coralnet_toolbox.Transformers.Models.QtBase import QtBaseModel
12
+
13
+
14
+ # ----------------------------------------------------------------------------------------------------------------------
15
+ # Classes
16
+ # ----------------------------------------------------------------------------------------------------------------------
17
+
18
+
19
+ @dataclass
20
+ class GroundingDINOModel(QtBaseModel):
21
+ def __init__(self, ontology: CaptionOntology, model="SwinB", device: str = "cpu"):
22
+ super().__init__(ontology, device)
23
+
24
+ if model == "SwinB":
25
+ model_name = "IDEA-Research/grounding-dino-base"
26
+ else:
27
+ model_name = "IDEA-Research/grounding-dino-tiny"
28
+
29
+ self.processor = AutoProcessor.from_pretrained(model_name, use_fast=True)
30
+ self.model = AutoModelForZeroShotObjectDetection.from_pretrained(model_name).to(self.device)
31
+
32
+ def _process_predictions(self, image, texts, confidence):
33
+ """Process model predictions for a single image."""
34
+ inputs = self.processor(text=texts, images=image, return_tensors="pt").to(self.device)
35
+ outputs = self.model(**inputs)
36
+
37
+ results_processed = self.processor.post_process_grounded_object_detection(
38
+ outputs,
39
+ inputs.input_ids,
40
+ threshold=confidence,
41
+ target_sizes=[image.shape[:2]],
42
+ )[0]
43
+
44
+ boxes = results_processed["boxes"]
45
+ scores = results_processed["scores"]
46
+
47
+ # If no objects are detected, return an empty list to match the original behavior.
48
+ if scores.nelement() == 0:
49
+ return []
50
+
51
+ # Per original logic, assign all detections to class_id 0.
52
+ # TODO: We are only supporting a single class right now
53
+ class_ids = torch.zeros(scores.shape[0], 1, device=self.device)
54
+
55
+ # Combine boxes, scores, and class_ids into the (N, 6) tensor format
56
+ # required by the Results object: [x1, y1, x2, y2, confidence, class_id]
57
+ combined_data = torch.cat([
58
+ boxes,
59
+ scores.unsqueeze(1),
60
+ class_ids
61
+ ], dim=1)
62
+
63
+ # Create the dictionary mapping class indices to class names.
64
+ names = {idx: text for idx, text in enumerate(self.ontology.classes())}
65
+
66
+ # Create the Results object with a DETACHED tensor
67
+ result = Results(orig_img=image,
68
+ path=None,
69
+ names=names,
70
+ boxes=combined_data.detach().cpu())
71
+
72
+ return result
@@ -0,0 +1,72 @@
1
+ from dataclasses import dataclass
2
+
3
+ import torch
4
+
5
+ from ultralytics.engine.results import Results
6
+
7
+ from transformers import OwlViTForObjectDetection, OwlViTProcessor
8
+
9
+ from autodistill.detection import CaptionOntology
10
+
11
+ from coralnet_toolbox.Transformers.Models.QtBase import QtBaseModel
12
+
13
+
14
+ # ----------------------------------------------------------------------------------------------------------------------
15
+ # Classes
16
+ # ----------------------------------------------------------------------------------------------------------------------
17
+
18
+
19
+ @dataclass
20
+ class OWLViTModel(QtBaseModel):
21
+ def __init__(self, ontology: CaptionOntology, device: str = "cpu"):
22
+ super().__init__(ontology, device)
23
+
24
+ model_name = "google/owlvit-base-patch32"
25
+ self.processor = OwlViTProcessor.from_pretrained(model_name, use_fast=True)
26
+ self.model = OwlViTForObjectDetection.from_pretrained(model_name).to(self.device)
27
+
28
+ def _process_predictions(self, image, texts, confidence):
29
+ """
30
+ Process model predictions for a single image, converting directly
31
+ to an Ultralytics Results object without an intermediate Supervision object.
32
+ """
33
+ inputs = self.processor(text=texts, images=image, return_tensors="pt").to(self.device)
34
+ outputs = self.model(**inputs)
35
+
36
+ # Post-process the outputs to get detections.
37
+ # The confidence threshold is applied during this step.
38
+ results_processed = self.processor.post_process_object_detection(
39
+ outputs,
40
+ threshold=confidence,
41
+ target_sizes=[image.shape[:2]]
42
+ )[0]
43
+
44
+ boxes = results_processed["boxes"]
45
+ scores = results_processed["scores"]
46
+
47
+ # If no objects are detected, return an empty list to match the original behavior.
48
+ if scores.nelement() == 0:
49
+ return []
50
+
51
+ # Per original logic, assign all detections to class_id 0.
52
+ # TODO: We are only supporting a single class right now
53
+ class_ids = torch.zeros(scores.shape[0], 1, device=self.device)
54
+
55
+ # Combine boxes, scores, and class_ids into the (N, 6) tensor format
56
+ # required by the Results object: [x1, y1, x2, y2, confidence, class_id]
57
+ combined_data = torch.cat([
58
+ boxes,
59
+ scores.unsqueeze(1),
60
+ class_ids
61
+ ], dim=1)
62
+
63
+ # Create the dictionary mapping class indices to class names.
64
+ names = {idx: text for idx, text in enumerate(self.ontology.classes())}
65
+
66
+ # Create the Results object with a DETACHED tensor
67
+ result = Results(orig_img=image,
68
+ path=None,
69
+ names=names,
70
+ boxes=combined_data.detach().cpu())
71
+
72
+ return result
@@ -0,0 +1,68 @@
1
+ from dataclasses import dataclass
2
+
3
+ import torch
4
+
5
+ from ultralytics.engine.results import Results
6
+
7
+ from transformers import AutoProcessor, OmDetTurboForObjectDetection
8
+
9
+ from autodistill.detection import CaptionOntology
10
+
11
+ from coralnet_toolbox.Transformers.Models.QtBase import QtBaseModel
12
+
13
+
14
+ # ----------------------------------------------------------------------------------------------------------------------
15
+ # Classes
16
+ # ----------------------------------------------------------------------------------------------------------------------
17
+
18
+
19
+ @dataclass
20
+ class OmDetTurboModel(QtBaseModel):
21
+ def __init__(self, ontology: CaptionOntology, device: str = "cpu"):
22
+ super().__init__(ontology, device)
23
+
24
+ model_name = "omlab/omdet-turbo-swin-tiny-hf"
25
+ self.processor = AutoProcessor.from_pretrained(model_name, use_fast=True)
26
+ self.model = OmDetTurboForObjectDetection.from_pretrained(model_name).to(self.device)
27
+
28
+ def _process_predictions(self, image, texts, confidence):
29
+ """Process model predictions for a single image."""
30
+ inputs = self.processor(text=texts, images=image, return_tensors="pt").to(self.device)
31
+ outputs = self.model(**inputs)
32
+
33
+ results_processed = self.processor.post_process_grounded_object_detection(
34
+ outputs,
35
+ threshold=confidence,
36
+ target_sizes=[image.shape[:2]],
37
+ text_labels=texts,
38
+ )[0]
39
+
40
+ boxes = results_processed["boxes"]
41
+ scores = results_processed["scores"]
42
+
43
+ # If no objects are detected, return an empty list to match the original behavior.
44
+ if scores.nelement() == 0:
45
+ return []
46
+
47
+ # Per original logic, assign all detections to class_id 0.
48
+ # TODO: We are only supporting a single class right now
49
+ class_ids = torch.zeros(scores.shape[0], 1, device=self.device)
50
+
51
+ # Combine boxes, scores, and class_ids into the (N, 6) tensor format
52
+ # required by the Results object: [x1, y1, x2, y2, confidence, class_id]
53
+ combined_data = torch.cat([
54
+ boxes,
55
+ scores.unsqueeze(1),
56
+ class_ids
57
+ ], dim=1)
58
+
59
+ # Create the dictionary mapping class indices to class names.
60
+ names = {idx: text for idx, text in enumerate(self.ontology.classes())}
61
+
62
+ # Create the Results object with a DETACHED tensor
63
+ result = Results(orig_img=image,
64
+ path=None,
65
+ names=names,
66
+ boxes=combined_data.detach().cpu())
67
+
68
+ return result
@@ -0,0 +1,121 @@
1
+ from dataclasses import dataclass
2
+ from abc import ABC, abstractmethod
3
+
4
+ import cv2
5
+ import numpy as np
6
+
7
+ from ultralytics.engine.results import Results
8
+
9
+ from autodistill.detection import CaptionOntology, DetectionBaseModel
10
+ from autodistill.helpers import load_image
11
+
12
+ from coralnet_toolbox.Results import CombineResults
13
+
14
+
15
+ # ----------------------------------------------------------------------------------------------------------------------
16
+ # Classes
17
+ # ----------------------------------------------------------------------------------------------------------------------
18
+
19
+
20
+ @dataclass
21
+ class QtBaseModel(DetectionBaseModel, ABC):
22
+ """
23
+ Base class for Transformer foundation models that provides common functionality for
24
+ handling inputs, processing image data, and formatting detection results.
25
+ """
26
+ ontology: CaptionOntology
27
+
28
+ def __init__(self, ontology: CaptionOntology, device: str = "cpu"):
29
+ """
30
+ Initialize the base model with ontology and device.
31
+
32
+ Args:
33
+ ontology: The CaptionOntology containing class labels
34
+ device: The compute device (cpu, cuda, etc.)
35
+ """
36
+ self.ontology = ontology
37
+ self.device = device
38
+ self.processor = None
39
+ self.model = None
40
+
41
+ def _normalize_input(self, input) -> list[np.ndarray]:
42
+ """
43
+ Normalizes various input types into a list of images in CV2 (BGR) format.
44
+
45
+ Args:
46
+ input: Can be an image path, a list of paths, a numpy array, or a list of numpy arrays.
47
+
48
+ Returns:
49
+ A list of images, each as a numpy array in CV2 (BGR) format.
50
+ """
51
+ images = []
52
+ if isinstance(input, str):
53
+ # Single image path
54
+ images = [load_image(input, return_format="cv2")]
55
+ elif isinstance(input, np.ndarray):
56
+ # Single image numpy array (RGB) or a batch of images (NHWC, RGB)
57
+ if input.ndim == 3:
58
+ images = [cv2.cvtColor(input, cv2.COLOR_RGB2BGR)]
59
+ elif input.ndim == 4:
60
+ images = [cv2.cvtColor(img, cv2.COLOR_RGB2BGR) for img in input]
61
+ else:
62
+ raise ValueError(f"Unsupported numpy array dimensions: {input.ndim}")
63
+ elif isinstance(input, list):
64
+ if all(isinstance(i, str) for i in input):
65
+ # List of image paths
66
+ images = [load_image(path, return_format="cv2") for path in input]
67
+ elif all(isinstance(i, np.ndarray) for i in input):
68
+ # List of image arrays (RGB)
69
+ images = [cv2.cvtColor(img, cv2.COLOR_RGB2BGR) for img in input]
70
+ else:
71
+ raise ValueError("A list input must contain either all image paths or all numpy arrays.")
72
+ else:
73
+ raise TypeError(f"Unsupported input type: {type(input)}")
74
+
75
+ return images
76
+
77
+ @abstractmethod
78
+ def _process_predictions(self, image: np.ndarray, texts: list[str], confidence: float) -> Results:
79
+ """
80
+ Process model predictions for a single image.
81
+
82
+ Args:
83
+ image: The input image in CV2 (BGR) format.
84
+ texts: The text prompts from the ontology.
85
+ confidence: Confidence threshold.
86
+
87
+ Returns:
88
+ A single Ultralytics Results object, which may be empty if no detections are found.
89
+ """
90
+ pass
91
+
92
+ def predict(self, inputs, confidence=0.01) -> list[Results]:
93
+ """
94
+ Run inference on input images.
95
+
96
+ Args:
97
+ inputs: Can be an image path, a list of image paths, a numpy array, or a list of numpy arrays.
98
+ confidence: Detection confidence threshold.
99
+
100
+ Returns:
101
+ A list containing a single combined Ultralytics Results object with detections from all input images.
102
+ Returns an empty list if no detections are found in any image.
103
+ """
104
+ # Step 1: Normalize the input into a consistent list of images
105
+ normalized_inputs = self._normalize_input(inputs)
106
+
107
+ # Step 2: Prepare for inference
108
+ results = []
109
+ texts = self.ontology.prompts()
110
+
111
+ # Step 3: Loop through images and process predictions
112
+ for normalized_input in normalized_inputs:
113
+ result = self._process_predictions(normalized_input, texts, confidence)
114
+ if result:
115
+ results.append(result)
116
+
117
+ if len(results):
118
+ # Combine the results into one, then wrap in a list
119
+ results = CombineResults().combine_results(results)
120
+
121
+ return [results] if results else []
@@ -1,4 +1,4 @@
1
- # coralnet_toolbox/AutoDistill/Models/__init__.py
1
+ # coralnet_toolbox/Transformers/Models/__init__.py
2
2
 
3
3
  from .GroundingDINO import GroundingDINOModel
4
4
  from .OWLViT import OWLViTModel
@@ -13,14 +13,14 @@ from PyQt5.QtWidgets import (QApplication, QMessageBox, QCheckBox, QVBoxLayout,
13
13
 
14
14
 
15
15
  class BatchInferenceDialog(QDialog):
16
- """Dialog for performing batch inference on images using AutoDistill."""
16
+ """Dialog for performing batch inference on images using Transformers."""
17
17
 
18
18
  def __init__(self, main_window, parent=None):
19
19
  super().__init__(parent)
20
20
  self.main_window = main_window
21
21
  self.image_window = main_window.image_window
22
22
  self.annotation_window = main_window.annotation_window
23
- self.deploy_model_dialog = main_window.auto_distill_deploy_model_dialog
23
+ self.deploy_model_dialog = main_window.transformers_deploy_model_dialog
24
24
  self.loaded_models = self.deploy_model_dialog.loaded_model
25
25
 
26
26
  self.setWindowTitle("Batch Inference")
@@ -64,25 +64,25 @@ class BatchInferenceDialog(QDialog):
64
64
  self.image_options_group = QButtonGroup(self)
65
65
 
66
66
  # Create image selection options
67
- self.apply_filtered = QCheckBox("▼ Apply to filtered images")
68
- self.apply_prev = QCheckBox("↑ Apply to previous images")
69
- self.apply_next = QCheckBox("↓ Apply to next images")
70
- self.apply_all = QCheckBox("↕ Apply to all images")
67
+ self.apply_filtered_checkbox = QCheckBox("▼ Apply to filtered images")
68
+ self.apply_prev_checkbox = QCheckBox("↑ Apply to previous images")
69
+ self.apply_next_checkbox = QCheckBox("↓ Apply to next images")
70
+ self.apply_all_checkbox = QCheckBox("↕ Apply to all images")
71
71
  # Add options to button group
72
- self.image_options_group.addButton(self.apply_filtered)
73
- self.image_options_group.addButton(self.apply_prev)
74
- self.image_options_group.addButton(self.apply_next)
75
- self.image_options_group.addButton(self.apply_all)
72
+ self.image_options_group.addButton(self.apply_filtered_checkbox)
73
+ self.image_options_group.addButton(self.apply_prev_checkbox)
74
+ self.image_options_group.addButton(self.apply_next_checkbox)
75
+ self.image_options_group.addButton(self.apply_all_checkbox)
76
76
  # Make selections exclusive
77
77
  self.image_options_group.setExclusive(True)
78
78
  # Default selection
79
- self.apply_all.setChecked(True)
79
+ self.apply_all_checkbox.setChecked(True)
80
80
 
81
81
  # Add widgets to layout
82
- layout.addWidget(self.apply_filtered)
83
- layout.addWidget(self.apply_prev)
84
- layout.addWidget(self.apply_next)
85
- layout.addWidget(self.apply_all)
82
+ layout.addWidget(self.apply_filtered_checkbox)
83
+ layout.addWidget(self.apply_prev_checkbox)
84
+ layout.addWidget(self.apply_next_checkbox)
85
+ layout.addWidget(self.apply_all_checkbox)
86
86
 
87
87
  group_box.setLayout(layout)
88
88
  self.layout.addWidget(group_box)
@@ -18,6 +18,7 @@ from PyQt5.QtWidgets import (QApplication, QComboBox, QDialog,
18
18
  from coralnet_toolbox.QtProgressBar import ProgressBar
19
19
 
20
20
  from coralnet_toolbox.Results import ResultsProcessor
21
+ from coralnet_toolbox.Results import ConvertResults
21
22
  from coralnet_toolbox.Results import MapResults
22
23
 
23
24
  from coralnet_toolbox.utilities import rasterio_open
@@ -33,13 +34,13 @@ from coralnet_toolbox.Icons import get_icon
33
34
 
34
35
  class DeployModelDialog(QDialog):
35
36
  """
36
- Dialog for deploying and managing AutoDistill models.
37
+ Dialog for deploying and managing Transformers models.
37
38
  Allows users to load, configure, and deactivate models, as well as make predictions on images.
38
39
  """
39
40
 
40
41
  def __init__(self, main_window, parent=None):
41
42
  """
42
- Initialize the AutoDistillDeployModelDialog.
43
+ Initialize the TransformersDeployModelDialog.
43
44
 
44
45
  Args:
45
46
  main_window: The main application window.
@@ -52,7 +53,7 @@ class DeployModelDialog(QDialog):
52
53
  self.annotation_window = main_window.annotation_window
53
54
 
54
55
  self.setWindowIcon(get_icon("coral.png"))
55
- self.setWindowTitle("AutoDistill Deploy Model (Ctrl + 6)")
56
+ self.setWindowTitle("Transformers Deploy Model (Ctrl + 6)")
56
57
  self.resize(400, 325)
57
58
 
58
59
  # Initialize variables
@@ -66,6 +67,8 @@ class DeployModelDialog(QDialog):
66
67
  self.ontology = None
67
68
  self.class_mapping = {}
68
69
  self.ontology_pairs = []
70
+
71
+ self.task = 'detect'
69
72
 
70
73
  # Create the layout
71
74
  self.layout = QVBoxLayout(self)
@@ -422,8 +425,6 @@ class DeployModelDialog(QDialog):
422
425
  progress_bar.close()
423
426
  # Restore cursor
424
427
  QApplication.restoreOverrideCursor()
425
- # Exit the dialog box
426
- self.accept()
427
428
 
428
429
  def load_new_model(self, model_name):
429
430
  """
@@ -433,8 +434,17 @@ class DeployModelDialog(QDialog):
433
434
  model_name: Name of the model to load.
434
435
  uncertainty_thresh: Threshold for uncertainty.
435
436
  """
437
+
438
+ # Clear the model
439
+ self.loaded_model = None
440
+ self.model_name = None
441
+
442
+ # Clear cache
443
+ gc.collect()
444
+ torch.cuda.empty_cache()
445
+
436
446
  if "GroundingDINO" in model_name:
437
- from coralnet_toolbox.AutoDistill.Models.GroundingDINO import GroundingDINOModel
447
+ from coralnet_toolbox.Transformers.Models.GroundingDINO import GroundingDINOModel
438
448
 
439
449
  model = model_name.split("-")[1].strip()
440
450
  self.model_name = model_name
@@ -443,14 +453,14 @@ class DeployModelDialog(QDialog):
443
453
  device=self.main_window.device)
444
454
 
445
455
  elif "OmDetTurbo" in model_name:
446
- from coralnet_toolbox.AutoDistill.Models.OmDetTurbo import OmDetTurboModel
456
+ from coralnet_toolbox.Transformers.Models.OmDetTurbo import OmDetTurboModel
447
457
 
448
458
  self.model_name = model_name
449
459
  self.loaded_model = OmDetTurboModel(ontology=self.ontology,
450
460
  device=self.main_window.device)
451
461
 
452
462
  elif "OWLViT" in model_name:
453
- from coralnet_toolbox.AutoDistill.Models.OWLViT import OWLViTModel
463
+ from coralnet_toolbox.Transformers.Models.OWLViT import OWLViTModel
454
464
 
455
465
  self.model_name = model_name
456
466
  self.loaded_model = OWLViTModel(ontology=self.ontology,
@@ -495,7 +505,6 @@ class DeployModelDialog(QDialog):
495
505
  continue
496
506
 
497
507
  results = self._apply_model(inputs)
498
- results = self._update_results(results_processor, results, inputs, image_path)
499
508
  results = self._apply_sam(results, image_path)
500
509
  self._process_results(results_processor, results, image_path)
501
510
 
@@ -553,13 +562,6 @@ class DeployModelDialog(QDialog):
553
562
 
554
563
  return results_list
555
564
 
556
- def _update_results(self, results_processor, results, inputs, image_path):
557
- """Update the results to match Ultralytics format."""
558
- return [results_processor.from_supervision(results,
559
- inputs,
560
- image_path,
561
- self.class_mapping)]
562
-
563
565
  def _apply_sam(self, results_list, image_path):
564
566
  """Apply SAM to the results if needed."""
565
567
  # Check if SAM model is deployed and loaded
@@ -1,4 +1,4 @@
1
- # coralnet_toolbox/AutoDistill/__init__.py
1
+ # coralnet_toolbox/Transformers/__init__.py
2
2
 
3
3
  from .QtDeployModel import DeployModelDialog
4
4
  from .QtBatchInference import BatchInferenceDialog
@@ -1,6 +1,6 @@
1
1
  """Top-level package for CoralNet-Toolbox."""
2
2
 
3
- __version__ = "0.0.75"
3
+ __version__ = "0.0.77"
4
4
  __author__ = "Jordan Pierce"
5
5
  __email__ = "jordan.pierce@noaa.gov"
6
6
  __credits__ = "National Center for Coastal and Ocean Sciences (NCCOS)"
@@ -30,21 +30,6 @@ from coralnet_toolbox.QtProgressBar import ProgressBar
30
30
  # ----------------------------------------------------------------------------------------------------------------------
31
31
 
32
32
 
33
- def get_available_device():
34
- """
35
- Get available devices
36
-
37
- :return:
38
- """
39
- devices = ['cpu',]
40
- if torch.cuda.is_available():
41
- for i in range(torch.cuda.device_count()):
42
- devices.append(f'cuda:{i}')
43
- if torch.backends.mps.is_available():
44
- devices.append('mps')
45
- return devices
46
-
47
-
48
33
  @lru_cache(maxsize=32)
49
34
  def rasterio_open(image_path):
50
35
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: coralnet-toolbox
3
- Version: 0.0.75
3
+ Version: 0.0.77
4
4
  Summary: Tools for annotating and developing ML models for benthic imagery
5
5
  Author-email: Jordan Pierce <jordan.pierce@noaa.gov>
6
6
  License: MIT License
@@ -16,7 +16,7 @@ License-File: LICENSE.txt
16
16
  Requires-Dist: PyQt5>=5.15.11
17
17
  Requires-Dist: pyqtdarktheme
18
18
  Requires-Dist: pyqtgraph
19
- Requires-Dist: ultralytics>=8.3.152
19
+ Requires-Dist: ultralytics>=8.3.191
20
20
  Requires-Dist: lap>=0.5.12
21
21
  Requires-Dist: open-clip-torch>=2.20.0
22
22
  Requires-Dist: supervision>=0.24.0
@@ -27,7 +27,7 @@ Requires-Dist: pycocotools
27
27
  Requires-Dist: ujson
28
28
  Requires-Dist: timm==0.9.2
29
29
  Requires-Dist: autodistill
30
- Requires-Dist: transformers>=4.55.4
30
+ Requires-Dist: transformers>=4.56.0
31
31
  Requires-Dist: hf_xet
32
32
  Requires-Dist: x-segment-anything>=0.0.8
33
33
  Requires-Dist: yolo-tiling>=0.0.19
@@ -39,6 +39,8 @@ Requires-Dist: beautifulsoup4>=4.12.2
39
39
  Requires-Dist: webdriver_manager
40
40
  Requires-Dist: dill
41
41
  Requires-Dist: seaborn
42
+ Requires-Dist: GPUtil
43
+ Requires-Dist: psutil
42
44
  Provides-Extra: all
43
45
  Requires-Dist: coralnet-toolbox[extra]; extra == "all"
44
46
  Dynamic: license-file
@@ -114,6 +116,7 @@ For a complete installation guide (including CUDA setup), see the [Installation
114
116
  | **Overview** | Get the big picture | [📋 Read More](https://jordan-pierce.github.io/CoralNet-Toolbox/overview) |
115
117
  | **Installation** | Detailed setup instructions | [⚙️ Setup Guide](https://jordan-pierce.github.io/CoralNet-Toolbox/installation) |
116
118
  | **Usage** | Learn the tools | [🛠️ User Manual](https://jordan-pierce.github.io/CoralNet-Toolbox/usage) |
119
+ | **Hot Keys** | Keyboard shortcuts | [⌨️ Shortcuts](https://jordan-pierce.github.io/CoralNet-Toolbox/hot-keys) |
117
120
  | **Classification** | Community tutorial | [🧠 AI Tutorial](https://jordan-pierce.github.io/CoralNet-Toolbox/classify) |
118
121
 
119
122
  </div>
@@ -179,7 +182,7 @@ The toolbox integrates state-of-the-art models for efficient annotation workflow
179
182
  | **Framework** | **Models** | **Capability** |
180
183
  |:---:|:---:|:---:|
181
184
  | **YOLOE** | See Anything | Visual prompt detection |
182
- | **AutoDistill** | Grounding DINO • OWLViT • OmDetTurbo | Zero-shot detection |
185
+ | **Transformers** | Grounding DINO • OWLViT • OmDetTurbo | Zero-shot detection |
183
186
 
184
187
  </div>
185
188
 
@@ -277,12 +280,9 @@ uv pip install coralnet-toolbox
277
280
  ### 🚀 **Step 3: GPU Acceleration (Optional)**
278
281
  For CUDA-enabled systems:
279
282
  ```bash
280
- # Example for CUDA 11.8
281
- conda install nvidia/label/cuda-11.8.0::cuda-nvcc -y
282
- conda install nvidia/label/cuda-11.8.0::cuda-toolkit -y
283
-
283
+ # Example for CUDA 12.9
284
284
  # Install PyTorch with CUDA support
285
- uv pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 --upgrade
285
+ uv pip install torch torchvision --index-url https://download.pytorch.org/whl/cu129 --upgrade
286
286
  ```
287
287
 
288
288
  ### 🏃‍♂️ **Step 4: Launch**