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
@@ -7,6 +7,8 @@ from PyQt5.QtWidgets import (QVBoxLayout, QHBoxLayout, QPushButton, QComboBox, Q
7
7
  QLineEdit, QFileDialog, QFormLayout, QSpinBox, QDoubleSpinBox)
8
8
 
9
9
  from coralnet_toolbox.MachineLearning.Community.cfg import get_available_configs
10
+ from coralnet_toolbox.Explorer.transformer_models import TRANSFORMER_MODELS
11
+ from coralnet_toolbox.Explorer.yolo_models import YOLO_MODELS
10
12
 
11
13
  warnings.filterwarnings("ignore", category=DeprecationWarning)
12
14
 
@@ -444,15 +446,54 @@ class ModelSettingsWidget(QGroupBox):
444
446
  self.explorer_window = parent
445
447
 
446
448
  # --- Data for hierarchical selection ---
447
- self.standard_models_map = {
448
- 'YOLOv8': {'Nano': 'n', 'Small': 's', 'Medium': 'm', 'Large': 'l', 'X-Large': 'x'},
449
- 'YOLOv11': {'Nano': 'n', 'Small': 's', 'Medium': 'm', 'Large': 'l', 'X-Large': 'x'},
450
- 'YOLOv12': {'Nano': 'n', 'Small': 's', 'Medium': 'm', 'Large': 'l', 'X-Large': 'x'}
451
- }
449
+ # Convert YOLO_MODELS to a hierarchical structure for the UI
450
+ self.standard_models_map = self._create_hierarchical_model_map()
452
451
  self.community_configs = get_available_configs(task='classify')
452
+
453
+ # --- Models for feature extraction ---
454
+ self.transformer_models = TRANSFORMER_MODELS
455
+ self.yolo_models = YOLO_MODELS
453
456
 
454
457
  self.setup_ui()
455
458
 
459
+ def _create_hierarchical_model_map(self):
460
+ """Convert the flat YOLO_MODELS dictionary to a hierarchical structure."""
461
+ hierarchical_map = {}
462
+
463
+ # Process each model in YOLO_MODELS
464
+ for display_name, model_file in YOLO_MODELS.items():
465
+ # Parse the family and size from the display name
466
+ # Expected format: "YOLOvX (Size)"
467
+ parts = display_name.split(' ')
468
+ if len(parts) >= 2:
469
+ family = parts[0] # "YOLOv8", "YOLOv11", etc.
470
+ size = parts[1].strip('()') # "Nano", "Small", etc.
471
+
472
+ # Create the family entry if it doesn't exist
473
+ if family not in hierarchical_map:
474
+ hierarchical_map[family] = {}
475
+
476
+ # Extract the size code from the model filename
477
+ # For example, get 'n' from 'yolov8n-cls.pt'
478
+ if model_file.startswith(family.lower()):
479
+ size_code = model_file[len(family.lower())]
480
+ else:
481
+ # Default fallback if parsing fails
482
+ size_code = size[0].lower()
483
+
484
+ # Add the size entry to the family
485
+ hierarchical_map[family][size] = size_code
486
+
487
+ # If no models were processed, fallback to the default structure
488
+ if not hierarchical_map:
489
+ hierarchical_map = {
490
+ 'YOLOv8': {'Nano': 'n', 'Small': 's', 'Medium': 'm', 'Large': 'l', 'X-Large': 'x'},
491
+ 'YOLOv11': {'Nano': 'n', 'Small': 's', 'Medium': 'm', 'Large': 'l', 'X-Large': 'x'},
492
+ 'YOLOv12': {'Nano': 'n', 'Small': 's', 'Medium': 'm', 'Large': 'l', 'X-Large': 'x'}
493
+ }
494
+
495
+ return hierarchical_map
496
+
456
497
  def setup_ui(self):
457
498
  """Set up the UI with a tabbed interface for model selection."""
458
499
  main_layout = QVBoxLayout(self)
@@ -465,7 +506,7 @@ class ModelSettingsWidget(QGroupBox):
465
506
 
466
507
  # 1. Main Category ComboBox
467
508
  self.category_combo = QComboBox()
468
- self.category_combo.addItems(["Color Features", "Standard Model", "Community Model"])
509
+ self.category_combo.addItems(["Color Features", "Standard Model", "Community Model", "Transformer Model"])
469
510
  self.model_select_layout.addRow("Category:", self.category_combo)
470
511
 
471
512
  # 2. Standard Model Options (initially hidden)
@@ -486,6 +527,12 @@ class ModelSettingsWidget(QGroupBox):
486
527
  self.community_model_widgets = [QLabel("Model:"), self.community_combo]
487
528
  self.model_select_layout.addRow(self.community_model_widgets[0], self.community_model_widgets[1])
488
529
 
530
+ # 4. Transformer Model Options (initially hidden)
531
+ self.transformer_combo = QComboBox()
532
+ self.transformer_combo.addItems(list(self.transformer_models.keys()))
533
+ self.transformer_model_widgets = [QLabel("Model:"), self.transformer_combo]
534
+ self.model_select_layout.addRow(self.transformer_model_widgets[0], self.transformer_model_widgets[1])
535
+
489
536
  self.tabs.addTab(model_select_tab, "Select Model")
490
537
 
491
538
  # === Tab 2: Existing Model from File ===
@@ -515,6 +562,7 @@ class ModelSettingsWidget(QGroupBox):
515
562
  feature_mode_layout = QFormLayout()
516
563
  self.feature_mode_combo = QComboBox()
517
564
  self.feature_mode_combo.addItems(["Predictions", "Embed Features"])
565
+ self.feature_mode_combo.setCurrentText("Embed Features") # Set default to Embed Features
518
566
  feature_mode_layout.addRow("Feature Mode:", self.feature_mode_combo)
519
567
  main_layout.addLayout(feature_mode_layout)
520
568
 
@@ -522,7 +570,7 @@ class ModelSettingsWidget(QGroupBox):
522
570
  self.category_combo.currentTextChanged.connect(self._on_category_changed)
523
571
  self.tabs.currentChanged.connect(self._on_selection_changed)
524
572
  for widget in [self.category_combo, self.family_combo, self.size_combo,
525
- self.community_combo, self.model_path_edit, self.feature_mode_combo]:
573
+ self.community_combo, self.transformer_combo, self.model_path_edit, self.feature_mode_combo]:
526
574
  if isinstance(widget, QComboBox):
527
575
  widget.currentTextChanged.connect(self._on_selection_changed)
528
576
  elif isinstance(widget, QLineEdit):
@@ -544,11 +592,14 @@ class ModelSettingsWidget(QGroupBox):
544
592
  """Show or hide sub-option widgets based on the selected category."""
545
593
  is_standard = (category == "Standard Model")
546
594
  is_community = (category == "Community Model")
595
+ is_transformer = (category == "Transformer Model")
547
596
 
548
597
  for widget in self.standard_model_widgets:
549
598
  widget.setVisible(is_standard)
550
599
  for widget in self.community_model_widgets:
551
600
  widget.setVisible(is_community)
601
+ for widget in self.transformer_model_widgets:
602
+ widget.setVisible(is_transformer)
552
603
 
553
604
  self._on_selection_changed()
554
605
 
@@ -569,15 +620,29 @@ class ModelSettingsWidget(QGroupBox):
569
620
  def _update_feature_mode_state(self):
570
621
  """Update the enabled state and tooltip of the feature mode field."""
571
622
  is_color_features = False
623
+ is_transformer = False
624
+ is_community = False # Add a new flag for community models
572
625
  current_tab_index = self.tabs.currentIndex()
573
626
 
574
627
  if current_tab_index == 0:
575
- is_color_features = (self.category_combo.currentText() == "Color Features")
628
+ category = self.category_combo.currentText()
629
+ is_color_features = (category == "Color Features")
630
+ is_transformer = (category == "Transformer Model")
631
+ is_community = (category == "Community Model") # Check for Community Model
632
+
633
+ # Disable feature mode for Color Features, Transformer Models, and Community Models
634
+ self.feature_mode_combo.setEnabled(not (is_color_features or is_transformer or is_community))
576
635
 
577
- self.feature_mode_combo.setEnabled(not is_color_features)
636
+ # If disabled categories are selected, force the combo to "Embed Features"
637
+ if is_color_features or is_transformer or is_community:
638
+ self.feature_mode_combo.setCurrentText("Embed Features")
578
639
 
579
640
  if is_color_features:
580
641
  self.feature_mode_combo.setToolTip("Feature Mode is not applicable for Color Features.")
642
+ elif is_transformer:
643
+ self.feature_mode_combo.setToolTip("Transformer models always output embedding features.")
644
+ elif is_community:
645
+ self.feature_mode_combo.setToolTip("Community models always output embedding features.")
581
646
  else:
582
647
  self.feature_mode_combo.setToolTip(
583
648
  "Choose 'Predictions' for class probabilities (for uncertainty analysis)\n"
@@ -589,10 +654,13 @@ class ModelSettingsWidget(QGroupBox):
589
654
  current_tab_index = self.tabs.currentIndex()
590
655
  model_name = ""
591
656
 
657
+ # Standard Model Tab
592
658
  if current_tab_index == 0:
593
659
  category = self.category_combo.currentText()
660
+
594
661
  if category == "Color Features":
595
662
  model_name = "Color Features"
663
+
596
664
  elif category == "Standard Model":
597
665
  family_text = self.family_combo.currentText()
598
666
  size_text = self.size_combo.currentText()
@@ -601,16 +669,34 @@ class ModelSettingsWidget(QGroupBox):
601
669
  if not family_text or not size_text:
602
670
  return "", "N/A" # Return a safe default
603
671
 
604
- family_key = family_text.lower().replace('-', '')
605
- size_key = self.standard_models_map[family_text][size_text]
606
- model_name = f"{family_key}{size_key}-cls.pt"
672
+ # Create the display name format to look up in YOLO_MODELS
673
+ display_name = f"{family_text} ({size_text})"
674
+ if display_name in self.yolo_models:
675
+ model_name = self.yolo_models[display_name]
676
+ else:
677
+ # Fallback to the old method if not found
678
+ family_key = family_text.lower().replace('-', '')
679
+ size_key = self.standard_models_map[family_text][size_text]
680
+ model_name = f"{family_key}{size_key}-cls.pt"
607
681
 
608
682
  elif category == "Community Model":
609
- model_name = self.community_combo.currentText()
683
+ model_display_name = self.community_combo.currentText()
684
+ # Use the path (value) instead of the name (key) for community models
685
+ if self.community_configs and model_display_name in self.community_configs:
686
+ model_name = self.community_configs[model_display_name]
687
+ else:
688
+ model_name = model_display_name # Fallback to using the display name
689
+
690
+ elif category == "Transformer Model":
691
+ # Get the HuggingFace model ID from the transformer models map
692
+ selected_display_name = self.transformer_combo.currentText()
693
+ model_name = self.transformer_models.get(selected_display_name, selected_display_name)
694
+
695
+ # Custom Model Tab
610
696
  elif current_tab_index == 1:
611
697
  model_name = self.model_path_edit.text()
612
698
 
613
- feature_mode = self.feature_mode_combo.currentText() if self.feature_mode_combo.isEnabled() else "N/A"
699
+ feature_mode = self.feature_mode_combo.currentText()
614
700
  return model_name, feature_mode
615
701
 
616
702
 
@@ -748,4 +834,4 @@ class EmbeddingSettingsWidget(QGroupBox):
748
834
  if hasattr(self.explorer_window, '_clear_selections'):
749
835
  self.explorer_window._clear_selections()
750
836
 
751
- self.explorer_window.run_embedding_pipeline()
837
+ self.explorer_window.run_embedding_pipeline()