coralnet-toolbox 0.0.74__py2.py3-none-any.whl → 0.0.75__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 (25) hide show
  1. coralnet_toolbox/Explorer/QtDataItem.py +52 -22
  2. coralnet_toolbox/Explorer/QtExplorer.py +277 -1600
  3. coralnet_toolbox/Explorer/QtSettingsWidgets.py +101 -15
  4. coralnet_toolbox/Explorer/QtViewers.py +1568 -0
  5. coralnet_toolbox/Explorer/transformer_models.py +59 -0
  6. coralnet_toolbox/Explorer/yolo_models.py +112 -0
  7. coralnet_toolbox/MachineLearning/ImportDataset/QtBase.py +239 -147
  8. coralnet_toolbox/MachineLearning/VideoInference/YOLO3D/run.py +102 -16
  9. coralnet_toolbox/QtAnnotationWindow.py +16 -10
  10. coralnet_toolbox/QtImageWindow.py +3 -7
  11. coralnet_toolbox/Rasters/RasterTableModel.py +20 -0
  12. coralnet_toolbox/SAM/QtDeployGenerator.py +1 -4
  13. coralnet_toolbox/SAM/QtDeployPredictor.py +1 -3
  14. coralnet_toolbox/SeeAnything/QtDeployGenerator.py +131 -106
  15. coralnet_toolbox/SeeAnything/QtDeployPredictor.py +45 -3
  16. coralnet_toolbox/Tools/QtPolygonTool.py +42 -3
  17. coralnet_toolbox/Tools/QtRectangleTool.py +30 -0
  18. coralnet_toolbox/__init__.py +1 -1
  19. coralnet_toolbox/utilities.py +21 -0
  20. {coralnet_toolbox-0.0.74.dist-info → coralnet_toolbox-0.0.75.dist-info}/METADATA +6 -3
  21. {coralnet_toolbox-0.0.74.dist-info → coralnet_toolbox-0.0.75.dist-info}/RECORD +25 -22
  22. {coralnet_toolbox-0.0.74.dist-info → coralnet_toolbox-0.0.75.dist-info}/WHEEL +0 -0
  23. {coralnet_toolbox-0.0.74.dist-info → coralnet_toolbox-0.0.75.dist-info}/entry_points.txt +0 -0
  24. {coralnet_toolbox-0.0.74.dist-info → coralnet_toolbox-0.0.75.dist-info}/licenses/LICENSE.txt +0 -0
  25. {coralnet_toolbox-0.0.74.dist-info → coralnet_toolbox-0.0.75.dist-info}/top_level.txt +0 -0
@@ -121,24 +121,45 @@ class AnnotationImageWidget(QWidget):
121
121
  self.setToolTip(self.data_item.get_tooltip_text())
122
122
 
123
123
  def recalculate_aspect_ratio(self):
124
- """Calculate aspect ratio from annotation geometry without loading image."""
124
+ """Calculate and store the annotation's aspect ratio."""
125
+ annotation = self.data_item.annotation
126
+
127
+ # Try to use the cropped_bbox attribute first
128
+ if hasattr(annotation, 'cropped_bbox'):
129
+ min_x, min_y, max_x, max_y = annotation.cropped_bbox
130
+ width = max_x - min_x
131
+ height = max_y - min_y
132
+
133
+ if height > 0:
134
+ self.aspect_ratio = width / height
135
+ return
136
+
137
+ # Fallback to bounding box methods
125
138
  try:
126
- if hasattr(self.annotation, 'rect'): # RectangleAnnotation
127
- rect = self.annotation.rect
128
- if rect.height() > 0:
129
- self.aspect_ratio = rect.width() / rect.height()
130
- elif hasattr(self.annotation, 'size'): # PatchAnnotation
131
- self.aspect_ratio = 1.0
132
- elif hasattr(self.annotation, 'polygon'): # PolygonAnnotation
133
- rect = self.annotation.polygon.boundingRect()
134
- if rect.height() > 0:
135
- self.aspect_ratio = rect.width() / rect.height()
136
- else:
137
- # Fallback for other types or if geometry is not available
138
- self.aspect_ratio = 1.0
139
- except Exception as e:
140
- print(f"Could not determine aspect ratio for {self.annotation.id}: {e}")
141
- self.aspect_ratio = 1.0
139
+ top_left = annotation.get_bounding_box_top_left()
140
+ bottom_right = annotation.get_bounding_box_bottom_right()
141
+
142
+ if top_left and bottom_right:
143
+ width = bottom_right.x() - top_left.x()
144
+ height = bottom_right.y() - top_left.y()
145
+
146
+ if height > 0:
147
+ self.aspect_ratio = width / height
148
+ return
149
+ except (AttributeError, TypeError):
150
+ pass
151
+
152
+ # Last resort: try to get aspect ratio from the cropped image
153
+ try:
154
+ pixmap = annotation.get_cropped_image()
155
+ if pixmap and not pixmap.isNull() and pixmap.height() > 0:
156
+ self.aspect_ratio = pixmap.width() / pixmap.height()
157
+ return
158
+ except (AttributeError, TypeError):
159
+ pass
160
+
161
+ # Default to square if we can't determine aspect ratio
162
+ self.aspect_ratio = 1.0
142
163
 
143
164
  def load_image(self):
144
165
  """Loads the image pixmap if it hasn't been loaded yet."""
@@ -356,16 +377,25 @@ class AnnotationDataItem:
356
377
  return "<br>".join(tooltip_parts)
357
378
 
358
379
  def get_effective_confidence(self):
359
- """Get the effective confidence value."""
380
+ """
381
+ Get the effective confidence value, handling scalar, array, and vector predictions.
382
+ """
360
383
  # First check if prediction probabilities are available from model predictions
361
384
  if hasattr(self, 'prediction_probabilities') and self.prediction_probabilities is not None:
362
- if len(self.prediction_probabilities) > 0:
363
- # Use the maximum probability for confidence sorting
364
- return float(np.max(self.prediction_probabilities))
365
-
385
+ probs = self.prediction_probabilities
386
+ try:
387
+ # This will succeed for lists and multi-element numpy arrays
388
+ if len(probs) > 0:
389
+ return float(np.max(probs))
390
+ except TypeError:
391
+ # This will catch the error if `len()` is called on a scalar or 0-D array.
392
+ # In this case, the value of `probs` itself is the confidence score.
393
+ return float(probs)
394
+
366
395
  # Fallback to existing confidence values
367
396
  if self.annotation.verified and hasattr(self.annotation, 'user_confidence') and self.annotation.user_confidence:
368
397
  return list(self.annotation.user_confidence.values())[0]
369
398
  elif hasattr(self.annotation, 'machine_confidence') and self.annotation.machine_confidence:
370
399
  return list(self.annotation.machine_confidence.values())[0]
400
+
371
401
  return 0.0