config.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. """
  2. Configuration Module
  3. Centralized configuration for paths, constants, and settings.
  4. """
  5. import os
  6. from pathlib import Path
  7. from typing import Dict, Tuple
  8. # ==================== PATHS ====================
  9. # Base paths
  10. PROJECT_ROOT = Path(__file__).parent.parent # Points to dudong-v2/
  11. # Model paths
  12. MODELS_DIR = PROJECT_ROOT / "model_files"
  13. # Use the directory containing all the model files
  14. AUDIO_MODEL_PATH = PROJECT_ROOT / "model_files" / "audio"
  15. DEFECT_MODEL_PATH = PROJECT_ROOT / "model_files" / "best.pt"
  16. LOCULE_MODEL_PATH = PROJECT_ROOT / "model_files" / "locule.pt"
  17. MATURITY_MODEL_PATH = PROJECT_ROOT / "model_files" / "multispectral" / "maturity" / "final_model.pt"
  18. # Image paths
  19. IMAGES_DIR = PROJECT_ROOT / "assets" / "logos"
  20. # Test data paths (optional - can be removed if not needed)
  21. UNSEEN_DIR = PROJECT_ROOT / "unseen"
  22. UNSEEN_AUDIO_UNRIPE = UNSEEN_DIR / "unripe"
  23. UNSEEN_AUDIO_MIDRIPE = UNSEEN_DIR / "midripe"
  24. UNSEEN_QUALITY = UNSEEN_DIR / "quality"
  25. # Data storage paths
  26. DATA_DIR = PROJECT_ROOT / "data"
  27. DATABASE_PATH = DATA_DIR / "database.db"
  28. ANALYSES_DIR = DATA_DIR / "analyses"
  29. # ==================== MODEL SETTINGS ====================
  30. # Device configuration
  31. DEVICE_PRIORITY = ["cuda", "cpu"] # Try CUDA first, fallback to CPU
  32. # Model versions (for display)
  33. MODEL_VERSIONS = {
  34. "ripeness": "",
  35. "quality": "",
  36. "defect": "",
  37. "maturity": "",
  38. }
  39. # Audio model settings
  40. AUDIO_SAMPLE_RATE = 16000
  41. AUDIO_DESIRED_SAMPLES = 16000
  42. AUDIO_FRAME_LENGTH = 255
  43. AUDIO_FRAME_STEP = 128
  44. # YOLO model settings
  45. YOLO_CONFIDENCE_THRESHOLD = 0.2
  46. YOLO_IMAGE_SIZE = 640
  47. # Maturity model settings
  48. MATURITY_MASK_BAND_INDEX = 4 # Band index for masking (860nm)
  49. MATURITY_IMG_SIZE = 256 # Target image size after preprocessing
  50. MATURITY_IMG_PAD = 8 # Padding for cropping
  51. # ==================== CLASS DEFINITIONS ====================
  52. # Ripeness classes (matching the three-class model from notebook)
  53. RIPENESS_CLASSES = ["unripe", "ripe", "overripe"]
  54. # Defect detection classes and colors (BGR format for OpenCV)
  55. DEFECT_CLASS_COLORS: Dict[int, Tuple[int, int, int]] = {
  56. 0: (255, 34, 134), # Minor defects - Pink/Magenta
  57. 1: (0, 252, 199), # No defects - Cyan/Turquoise
  58. 2: (86, 0, 254), # Reject - Purple
  59. }
  60. DEFECT_CLASS_NAMES = {
  61. 0: "Minor Defects",
  62. 1: "No Defects",
  63. 2: "Reject",
  64. }
  65. # Locule segmentation colors (BGR format) - ROYGBIV
  66. LOCULE_COLORS: list[Tuple[int, int, int]] = [
  67. (0, 0, 255), # Red
  68. (0, 165, 255), # Orange
  69. (0, 255, 255), # Yellow
  70. (0, 255, 0), # Green
  71. (255, 0, 0), # Blue
  72. (130, 0, 75), # Indigo
  73. (211, 0, 148), # Violet
  74. ]
  75. # ==================== UI SETTINGS ====================
  76. # Window settings
  77. WINDOW_TITLE = "DuDONG Grading System"
  78. WINDOW_WIDTH = 1920
  79. WINDOW_HEIGHT = 1080
  80. DEVICE_ID = "MAIN-001"
  81. # UI Colors (for PyQt styling)
  82. UI_COLORS = {
  83. # Primary colors
  84. "primary_dark": "#2c3e50",
  85. "primary_light": "#34495e",
  86. "accent_blue": "#3498db",
  87. "accent_green": "#27ae60",
  88. # Status colors
  89. "online": "#27ae60",
  90. "offline": "#e74c3c",
  91. "updating": "#f39c12",
  92. # Background colors
  93. "bg_light": "#f8f9fa",
  94. "bg_white": "#ffffff",
  95. "bg_panel": "#ecf0f1",
  96. # Text colors
  97. "text_dark": "#2c3e50",
  98. "text_medium": "#7f8c8d",
  99. "text_light": "#bdc3c7",
  100. # Button colors
  101. "btn_green": "#27ae60",
  102. "btn_green_hover": "#229954",
  103. "btn_blue": "#3498db",
  104. "btn_blue_hover": "#2980b9",
  105. "btn_orange": "#f39c12",
  106. "btn_orange_hover": "#e67e22",
  107. "btn_purple": "#9b59b6",
  108. "btn_purple_hover": "#8e44ad",
  109. "btn_red": "#e74c3c",
  110. "btn_red_hover": "#c0392b",
  111. # Grade colors
  112. "grade_a": "#27ae60",
  113. "grade_b": "#3498db",
  114. "grade_c": "#e74c3c",
  115. }
  116. # Status indicator sizes
  117. STATUS_INDICATOR_SIZE = 12
  118. STATUS_INDICATOR_RADIUS = 6
  119. # Table settings
  120. TABLE_ROW_HEIGHT = 45
  121. TABLE_RECENT_RESULTS_COUNT = 5
  122. TABLE_MAX_RESULTS_MEMORY = 100
  123. # Feed display sizes
  124. FEED_MIN_WIDTH = 150
  125. FEED_MIN_HEIGHT = 110
  126. # Image display sizes
  127. RESULT_IMAGE_WIDTH = 621
  128. RESULT_IMAGE_HEIGHT = 441
  129. # ==================== THREADING SETTINGS ====================
  130. # Thread pool settings
  131. MAX_THREAD_COUNT = None # None = use default (CPU count)
  132. # ==================== PERFORMANCE SETTINGS ====================
  133. # Spectrogram figure size
  134. SPECTROGRAM_FIG_SIZE = (8, 1.9)
  135. SPECTROGRAM_DPI = 100
  136. # ==================== LOGGING SETTINGS ====================
  137. # Log level
  138. LOG_LEVEL = "INFO"
  139. LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
  140. # ==================== FILE DIALOG FILTERS ====================
  141. FILE_FILTERS = {
  142. "audio": "Audio Files (*.wav *.mp3 *.flac *.ogg *.m4a *.aac *.wma);;WAV Files (*.wav);;MP3 Files (*.mp3);;FLAC Files (*.flac);;OGG Files (*.ogg);;M4A Files (*.m4a);;AAC Files (*.aac);;WMA Files (*.wma);;All Files (*.*)",
  143. "image": "Image Files (*.jpg *.jpeg *.png *.JPG *.JPEG *.PNG)",
  144. "tiff": "TIFF Files (*.tif *.tiff *.TIF *.TIFF);;All Files (*.*)",
  145. "all_media": "All Files (*.*)",
  146. }
  147. # Default directories for file dialogs
  148. DEFAULT_DIRS = {
  149. "audio": str(UNSEEN_DIR),
  150. "image": str(PROJECT_ROOT),
  151. }
  152. # ==================== HELPER FUNCTIONS ====================
  153. def get_device() -> str:
  154. """
  155. Get the best available device for model inference.
  156. Returns:
  157. str: Device name ('cuda' or 'cpu')
  158. """
  159. import torch
  160. for device in DEVICE_PRIORITY:
  161. if device == "cuda" and torch.cuda.is_available():
  162. return "cuda"
  163. return "cpu"
  164. def get_gpu_info() -> str:
  165. """
  166. Get GPU information for display.
  167. Returns:
  168. str: GPU information string
  169. """
  170. import torch
  171. if torch.cuda.is_available():
  172. gpu_name = torch.cuda.get_device_name(0)
  173. return f"GPU: {gpu_name}"
  174. return "GPU: Not Available (Using CPU)"
  175. def ensure_paths_exist() -> None:
  176. """Create necessary directories if they don't exist."""
  177. # Create necessary directories
  178. for directory in [IMAGES_DIR, UNSEEN_DIR, DATA_DIR, ANALYSES_DIR]:
  179. directory.mkdir(parents=True, exist_ok=True)
  180. def validate_model_paths() -> Dict[str, bool]:
  181. """
  182. Check if all required model files exist.
  183. Returns:
  184. Dict[str, bool]: Dictionary of model availability
  185. """
  186. return {
  187. "audio": AUDIO_MODEL_PATH.exists(),
  188. "defect": DEFECT_MODEL_PATH.exists(),
  189. "locule": LOCULE_MODEL_PATH.exists(),
  190. "maturity": MATURITY_MODEL_PATH.exists(),
  191. }
  192. # ==================== INITIALIZATION ====================
  193. # Ensure paths exist when module is imported
  194. ensure_paths_exist()