matrice-analytics 0.1.60__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 (196) hide show
  1. matrice_analytics/__init__.py +28 -0
  2. matrice_analytics/boundary_drawing_internal/README.md +305 -0
  3. matrice_analytics/boundary_drawing_internal/__init__.py +45 -0
  4. matrice_analytics/boundary_drawing_internal/boundary_drawing_internal.py +1207 -0
  5. matrice_analytics/boundary_drawing_internal/boundary_drawing_tool.py +429 -0
  6. matrice_analytics/boundary_drawing_internal/boundary_tool_template.html +1036 -0
  7. matrice_analytics/boundary_drawing_internal/data/.gitignore +12 -0
  8. matrice_analytics/boundary_drawing_internal/example_usage.py +206 -0
  9. matrice_analytics/boundary_drawing_internal/usage/README.md +110 -0
  10. matrice_analytics/boundary_drawing_internal/usage/boundary_drawer_launcher.py +102 -0
  11. matrice_analytics/boundary_drawing_internal/usage/simple_boundary_launcher.py +107 -0
  12. matrice_analytics/post_processing/README.md +455 -0
  13. matrice_analytics/post_processing/__init__.py +732 -0
  14. matrice_analytics/post_processing/advanced_tracker/README.md +650 -0
  15. matrice_analytics/post_processing/advanced_tracker/__init__.py +17 -0
  16. matrice_analytics/post_processing/advanced_tracker/base.py +99 -0
  17. matrice_analytics/post_processing/advanced_tracker/config.py +77 -0
  18. matrice_analytics/post_processing/advanced_tracker/kalman_filter.py +370 -0
  19. matrice_analytics/post_processing/advanced_tracker/matching.py +195 -0
  20. matrice_analytics/post_processing/advanced_tracker/strack.py +230 -0
  21. matrice_analytics/post_processing/advanced_tracker/tracker.py +367 -0
  22. matrice_analytics/post_processing/config.py +146 -0
  23. matrice_analytics/post_processing/core/__init__.py +63 -0
  24. matrice_analytics/post_processing/core/base.py +704 -0
  25. matrice_analytics/post_processing/core/config.py +3291 -0
  26. matrice_analytics/post_processing/core/config_utils.py +925 -0
  27. matrice_analytics/post_processing/face_reg/__init__.py +43 -0
  28. matrice_analytics/post_processing/face_reg/compare_similarity.py +556 -0
  29. matrice_analytics/post_processing/face_reg/embedding_manager.py +950 -0
  30. matrice_analytics/post_processing/face_reg/face_recognition.py +2234 -0
  31. matrice_analytics/post_processing/face_reg/face_recognition_client.py +606 -0
  32. matrice_analytics/post_processing/face_reg/people_activity_logging.py +321 -0
  33. matrice_analytics/post_processing/ocr/__init__.py +0 -0
  34. matrice_analytics/post_processing/ocr/easyocr_extractor.py +250 -0
  35. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/__init__.py +9 -0
  36. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/__init__.py +4 -0
  37. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/cli.py +33 -0
  38. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/dataset_stats.py +139 -0
  39. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/export.py +398 -0
  40. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/train.py +447 -0
  41. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/utils.py +129 -0
  42. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/valid.py +93 -0
  43. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/validate_dataset.py +240 -0
  44. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_augmentation.py +176 -0
  45. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/cli/visualize_predictions.py +96 -0
  46. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/__init__.py +3 -0
  47. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/process.py +246 -0
  48. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/types.py +60 -0
  49. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/core/utils.py +87 -0
  50. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/__init__.py +3 -0
  51. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/config.py +82 -0
  52. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/hub.py +141 -0
  53. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/inference/plate_recognizer.py +323 -0
  54. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/py.typed +0 -0
  55. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/__init__.py +0 -0
  56. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/__init__.py +0 -0
  57. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/augmentation.py +101 -0
  58. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/data/dataset.py +97 -0
  59. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/__init__.py +0 -0
  60. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/config.py +114 -0
  61. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/layers.py +553 -0
  62. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/loss.py +55 -0
  63. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/metric.py +86 -0
  64. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_builders.py +95 -0
  65. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/model/model_schema.py +395 -0
  66. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/__init__.py +0 -0
  67. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/backend_utils.py +38 -0
  68. matrice_analytics/post_processing/ocr/fast_plate_ocr_py38/train/utilities/utils.py +214 -0
  69. matrice_analytics/post_processing/ocr/postprocessing.py +270 -0
  70. matrice_analytics/post_processing/ocr/preprocessing.py +52 -0
  71. matrice_analytics/post_processing/post_processor.py +1175 -0
  72. matrice_analytics/post_processing/test_cases/__init__.py +1 -0
  73. matrice_analytics/post_processing/test_cases/run_tests.py +143 -0
  74. matrice_analytics/post_processing/test_cases/test_advanced_customer_service.py +841 -0
  75. matrice_analytics/post_processing/test_cases/test_basic_counting_tracking.py +523 -0
  76. matrice_analytics/post_processing/test_cases/test_comprehensive.py +531 -0
  77. matrice_analytics/post_processing/test_cases/test_config.py +852 -0
  78. matrice_analytics/post_processing/test_cases/test_customer_service.py +585 -0
  79. matrice_analytics/post_processing/test_cases/test_data_generators.py +583 -0
  80. matrice_analytics/post_processing/test_cases/test_people_counting.py +510 -0
  81. matrice_analytics/post_processing/test_cases/test_processor.py +524 -0
  82. matrice_analytics/post_processing/test_cases/test_usecases.py +165 -0
  83. matrice_analytics/post_processing/test_cases/test_utilities.py +356 -0
  84. matrice_analytics/post_processing/test_cases/test_utils.py +743 -0
  85. matrice_analytics/post_processing/usecases/Histopathological_Cancer_Detection_img.py +604 -0
  86. matrice_analytics/post_processing/usecases/__init__.py +267 -0
  87. matrice_analytics/post_processing/usecases/abandoned_object_detection.py +797 -0
  88. matrice_analytics/post_processing/usecases/advanced_customer_service.py +1601 -0
  89. matrice_analytics/post_processing/usecases/age_detection.py +842 -0
  90. matrice_analytics/post_processing/usecases/age_gender_detection.py +1085 -0
  91. matrice_analytics/post_processing/usecases/anti_spoofing_detection.py +656 -0
  92. matrice_analytics/post_processing/usecases/assembly_line_detection.py +841 -0
  93. matrice_analytics/post_processing/usecases/banana_defect_detection.py +624 -0
  94. matrice_analytics/post_processing/usecases/basic_counting_tracking.py +667 -0
  95. matrice_analytics/post_processing/usecases/blood_cancer_detection_img.py +881 -0
  96. matrice_analytics/post_processing/usecases/car_damage_detection.py +834 -0
  97. matrice_analytics/post_processing/usecases/car_part_segmentation.py +946 -0
  98. matrice_analytics/post_processing/usecases/car_service.py +1601 -0
  99. matrice_analytics/post_processing/usecases/cardiomegaly_classification.py +864 -0
  100. matrice_analytics/post_processing/usecases/cell_microscopy_segmentation.py +897 -0
  101. matrice_analytics/post_processing/usecases/chicken_pose_detection.py +648 -0
  102. matrice_analytics/post_processing/usecases/child_monitoring.py +814 -0
  103. matrice_analytics/post_processing/usecases/color/clip.py +660 -0
  104. matrice_analytics/post_processing/usecases/color/clip_processor/merges.txt +48895 -0
  105. matrice_analytics/post_processing/usecases/color/clip_processor/preprocessor_config.json +28 -0
  106. matrice_analytics/post_processing/usecases/color/clip_processor/special_tokens_map.json +30 -0
  107. matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer.json +245079 -0
  108. matrice_analytics/post_processing/usecases/color/clip_processor/tokenizer_config.json +32 -0
  109. matrice_analytics/post_processing/usecases/color/clip_processor/vocab.json +1 -0
  110. matrice_analytics/post_processing/usecases/color/color_map_utils.py +70 -0
  111. matrice_analytics/post_processing/usecases/color/color_mapper.py +468 -0
  112. matrice_analytics/post_processing/usecases/color_detection.py +1936 -0
  113. matrice_analytics/post_processing/usecases/color_map_utils.py +70 -0
  114. matrice_analytics/post_processing/usecases/concrete_crack_detection.py +827 -0
  115. matrice_analytics/post_processing/usecases/crop_weed_detection.py +781 -0
  116. matrice_analytics/post_processing/usecases/customer_service.py +1008 -0
  117. matrice_analytics/post_processing/usecases/defect_detection_products.py +936 -0
  118. matrice_analytics/post_processing/usecases/distracted_driver_detection.py +822 -0
  119. matrice_analytics/post_processing/usecases/drone_traffic_monitoring.py +585 -0
  120. matrice_analytics/post_processing/usecases/drowsy_driver_detection.py +829 -0
  121. matrice_analytics/post_processing/usecases/dwell_detection.py +829 -0
  122. matrice_analytics/post_processing/usecases/emergency_vehicle_detection.py +827 -0
  123. matrice_analytics/post_processing/usecases/face_emotion.py +813 -0
  124. matrice_analytics/post_processing/usecases/face_recognition.py +827 -0
  125. matrice_analytics/post_processing/usecases/fashion_detection.py +835 -0
  126. matrice_analytics/post_processing/usecases/field_mapping.py +902 -0
  127. matrice_analytics/post_processing/usecases/fire_detection.py +1146 -0
  128. matrice_analytics/post_processing/usecases/flare_analysis.py +836 -0
  129. matrice_analytics/post_processing/usecases/flower_segmentation.py +1006 -0
  130. matrice_analytics/post_processing/usecases/gas_leak_detection.py +837 -0
  131. matrice_analytics/post_processing/usecases/gender_detection.py +832 -0
  132. matrice_analytics/post_processing/usecases/human_activity_recognition.py +871 -0
  133. matrice_analytics/post_processing/usecases/intrusion_detection.py +1672 -0
  134. matrice_analytics/post_processing/usecases/leaf.py +821 -0
  135. matrice_analytics/post_processing/usecases/leaf_disease.py +840 -0
  136. matrice_analytics/post_processing/usecases/leak_detection.py +837 -0
  137. matrice_analytics/post_processing/usecases/license_plate_detection.py +1188 -0
  138. matrice_analytics/post_processing/usecases/license_plate_monitoring.py +1781 -0
  139. matrice_analytics/post_processing/usecases/litter_monitoring.py +717 -0
  140. matrice_analytics/post_processing/usecases/mask_detection.py +869 -0
  141. matrice_analytics/post_processing/usecases/natural_disaster.py +907 -0
  142. matrice_analytics/post_processing/usecases/parking.py +787 -0
  143. matrice_analytics/post_processing/usecases/parking_space_detection.py +822 -0
  144. matrice_analytics/post_processing/usecases/pcb_defect_detection.py +888 -0
  145. matrice_analytics/post_processing/usecases/pedestrian_detection.py +808 -0
  146. matrice_analytics/post_processing/usecases/people_counting.py +706 -0
  147. matrice_analytics/post_processing/usecases/people_counting_bckp.py +1683 -0
  148. matrice_analytics/post_processing/usecases/people_tracking.py +1842 -0
  149. matrice_analytics/post_processing/usecases/pipeline_detection.py +605 -0
  150. matrice_analytics/post_processing/usecases/plaque_segmentation_img.py +874 -0
  151. matrice_analytics/post_processing/usecases/pothole_segmentation.py +915 -0
  152. matrice_analytics/post_processing/usecases/ppe_compliance.py +645 -0
  153. matrice_analytics/post_processing/usecases/price_tag_detection.py +822 -0
  154. matrice_analytics/post_processing/usecases/proximity_detection.py +1901 -0
  155. matrice_analytics/post_processing/usecases/road_lane_detection.py +623 -0
  156. matrice_analytics/post_processing/usecases/road_traffic_density.py +832 -0
  157. matrice_analytics/post_processing/usecases/road_view_segmentation.py +915 -0
  158. matrice_analytics/post_processing/usecases/shelf_inventory_detection.py +583 -0
  159. matrice_analytics/post_processing/usecases/shoplifting_detection.py +822 -0
  160. matrice_analytics/post_processing/usecases/shopping_cart_analysis.py +899 -0
  161. matrice_analytics/post_processing/usecases/skin_cancer_classification_img.py +864 -0
  162. matrice_analytics/post_processing/usecases/smoker_detection.py +833 -0
  163. matrice_analytics/post_processing/usecases/solar_panel.py +810 -0
  164. matrice_analytics/post_processing/usecases/suspicious_activity_detection.py +1030 -0
  165. matrice_analytics/post_processing/usecases/template_usecase.py +380 -0
  166. matrice_analytics/post_processing/usecases/theft_detection.py +648 -0
  167. matrice_analytics/post_processing/usecases/traffic_sign_monitoring.py +724 -0
  168. matrice_analytics/post_processing/usecases/underground_pipeline_defect_detection.py +775 -0
  169. matrice_analytics/post_processing/usecases/underwater_pollution_detection.py +842 -0
  170. matrice_analytics/post_processing/usecases/vehicle_monitoring.py +1029 -0
  171. matrice_analytics/post_processing/usecases/warehouse_object_segmentation.py +899 -0
  172. matrice_analytics/post_processing/usecases/waterbody_segmentation.py +923 -0
  173. matrice_analytics/post_processing/usecases/weapon_detection.py +771 -0
  174. matrice_analytics/post_processing/usecases/weld_defect_detection.py +615 -0
  175. matrice_analytics/post_processing/usecases/wildlife_monitoring.py +898 -0
  176. matrice_analytics/post_processing/usecases/windmill_maintenance.py +834 -0
  177. matrice_analytics/post_processing/usecases/wound_segmentation.py +856 -0
  178. matrice_analytics/post_processing/utils/__init__.py +150 -0
  179. matrice_analytics/post_processing/utils/advanced_counting_utils.py +400 -0
  180. matrice_analytics/post_processing/utils/advanced_helper_utils.py +317 -0
  181. matrice_analytics/post_processing/utils/advanced_tracking_utils.py +461 -0
  182. matrice_analytics/post_processing/utils/alerting_utils.py +213 -0
  183. matrice_analytics/post_processing/utils/category_mapping_utils.py +94 -0
  184. matrice_analytics/post_processing/utils/color_utils.py +592 -0
  185. matrice_analytics/post_processing/utils/counting_utils.py +182 -0
  186. matrice_analytics/post_processing/utils/filter_utils.py +261 -0
  187. matrice_analytics/post_processing/utils/format_utils.py +293 -0
  188. matrice_analytics/post_processing/utils/geometry_utils.py +300 -0
  189. matrice_analytics/post_processing/utils/smoothing_utils.py +358 -0
  190. matrice_analytics/post_processing/utils/tracking_utils.py +234 -0
  191. matrice_analytics/py.typed +0 -0
  192. matrice_analytics-0.1.60.dist-info/METADATA +481 -0
  193. matrice_analytics-0.1.60.dist-info/RECORD +196 -0
  194. matrice_analytics-0.1.60.dist-info/WHEEL +5 -0
  195. matrice_analytics-0.1.60.dist-info/licenses/LICENSE.txt +21 -0
  196. matrice_analytics-0.1.60.dist-info/top_level.txt +1 -0
@@ -0,0 +1,3291 @@
1
+ """
2
+ Configuration system for post-processing operations.
3
+
4
+ This module provides a clean, type-safe configuration system using dataclasses
5
+ with built-in validation, serialization support, and pythonic configuration management.
6
+ """
7
+
8
+ from dataclasses import dataclass, field, fields
9
+ from typing import Any, Dict, List, Optional, Union, get_type_hints
10
+ from pathlib import Path
11
+ import json
12
+ import yaml
13
+ import logging
14
+ from abc import ABC, abstractmethod
15
+
16
+ from .base import ConfigProtocol
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class ConfigValidationError(Exception):
22
+ """Raised when configuration validation fails."""
23
+ pass
24
+
25
+
26
+ @dataclass
27
+ class BaseConfig(ConfigProtocol):
28
+ """Base configuration class with common functionality and validation."""
29
+
30
+ # Core identification
31
+ category: str = ""
32
+ usecase: str = ""
33
+
34
+ # Common processing parameters
35
+ confidence_threshold: Optional[float] = 0.5
36
+ enable_tracking: bool = False
37
+ enable_analytics: bool = True
38
+
39
+ # Performance settings
40
+ batch_size: Optional[int] = None
41
+ max_objects: Optional[int] = 1000
42
+
43
+ # Additional parameters
44
+ extra_params: Dict[str, Any] = field(default_factory=dict)
45
+
46
+ def validate(self) -> List[str]:
47
+ """Validate configuration and return list of error messages."""
48
+ errors = []
49
+
50
+ # Validate confidence threshold
51
+ if self.confidence_threshold is not None:
52
+ if not 0.0 <= self.confidence_threshold <= 1.0:
53
+ errors.append("confidence_threshold must be between 0.0 and 1.0")
54
+
55
+ # Validate max_objects
56
+ if self.max_objects is not None and self.max_objects <= 0:
57
+ errors.append("max_objects must be positive")
58
+
59
+ # Validate batch_size
60
+ if self.batch_size is not None and self.batch_size <= 0:
61
+ errors.append("batch_size must be positive")
62
+
63
+ return errors
64
+
65
+ def to_dict(self) -> Dict[str, Any]:
66
+ """Convert to dictionary for serialization."""
67
+ result = {}
68
+
69
+ # Get all fields
70
+ for field_info in fields(self):
71
+ value = getattr(self, field_info.name)
72
+ if value is not None:
73
+ # Handle nested configs
74
+ if hasattr(value, 'to_dict'):
75
+ result[field_info.name] = value.to_dict()
76
+ elif isinstance(value, dict):
77
+ # Handle dictionaries with potential nested configs
78
+ nested_dict = {}
79
+ for k, v in value.items():
80
+ if hasattr(v, 'to_dict'):
81
+ nested_dict[k] = v.to_dict()
82
+ else:
83
+ nested_dict[k] = v
84
+ result[field_info.name] = nested_dict
85
+ else:
86
+ result[field_info.name] = value
87
+
88
+ # Merge extra_params at top level
89
+ if self.extra_params:
90
+ result.update(self.extra_params)
91
+
92
+ return result
93
+
94
+ @classmethod
95
+ def from_dict(cls, data: Dict[str, Any]) -> 'BaseConfig':
96
+ """Create config from dictionary with type conversion."""
97
+ # Get field names and types for this class
98
+ field_names = {f.name: f.type for f in fields(cls)}
99
+
100
+ # Separate known fields from extra parameters
101
+ known_params = {}
102
+ extra_params = {}
103
+
104
+ for k, v in data.items():
105
+ if k in field_names:
106
+ known_params[k] = v
107
+ else:
108
+ extra_params[k] = v
109
+
110
+ if extra_params:
111
+ known_params['extra_params'] = extra_params
112
+
113
+ return cls(**known_params)
114
+
115
+
116
+ @dataclass
117
+ class ZoneConfig:
118
+ """Configuration for zone-based processing."""
119
+
120
+ # Zone definitions (name -> polygon points)
121
+ zones: Dict[str, List[List[float]]] = field(default_factory=dict)
122
+
123
+ # Zone-specific settings
124
+ zone_confidence_thresholds: Dict[str, float] = field(default_factory=dict)
125
+ zone_categories: Dict[str, List[str]] = field(default_factory=dict)
126
+
127
+ def validate(self) -> List[str]:
128
+ """Validate zone configuration."""
129
+ errors = []
130
+
131
+ for zone_name, polygon in self.zones.items():
132
+ if len(polygon) < 3:
133
+ errors.append(f"Zone '{zone_name}' must have at least 3 points")
134
+
135
+ for i, point in enumerate(polygon):
136
+ if len(point) != 2:
137
+ errors.append(f"Zone '{zone_name}' point {i} must have exactly 2 coordinates")
138
+
139
+ # Validate zone confidence thresholds
140
+ for zone_name, threshold in self.zone_confidence_thresholds.items():
141
+ if zone_name not in self.zones:
142
+ errors.append(f"Zone confidence threshold defined for unknown zone '{zone_name}'")
143
+ if not 0.0 <= threshold <= 1.0:
144
+ errors.append(f"Zone '{zone_name}' confidence threshold must be between 0.0 and 1.0")
145
+
146
+ return errors
147
+
148
+ def to_dict(self) -> Dict[str, Any]:
149
+ """Convert to dictionary."""
150
+ return {
151
+ "zones": self.zones,
152
+ "zone_confidence_thresholds": self.zone_confidence_thresholds,
153
+ "zone_categories": self.zone_categories
154
+ }
155
+
156
+ # --- Legacy/dict-like compatibility helpers ---
157
+ def _as_legacy_dict(self) -> Dict[str, Any]:
158
+ return {
159
+ "zones": self.zones,
160
+ "zone_confidence_thresholds": self.zone_confidence_thresholds,
161
+ "zone_categories": self.zone_categories,
162
+ }
163
+
164
+ def __getitem__(self, key: str) -> Any: # Support config.zone_config['zones']
165
+ return self._as_legacy_dict()[key]
166
+
167
+ def get(self, key: str, default: Any = None) -> Any:
168
+ return self._as_legacy_dict().get(key, default)
169
+
170
+ def keys(self):
171
+ return self._as_legacy_dict().keys()
172
+
173
+ def items(self):
174
+ return self._as_legacy_dict().items()
175
+
176
+ def __contains__(self, key: object) -> bool:
177
+ return key in self._as_legacy_dict()
178
+
179
+ def __iter__(self):
180
+ return iter(self._as_legacy_dict())
181
+
182
+ def __len__(self) -> int:
183
+ return len(self._as_legacy_dict())
184
+
185
+ @dataclass
186
+ class TrackingConfig:
187
+ """Configuration for tracking operations."""
188
+
189
+ # Tracking method and parameters
190
+ tracking_method: str = "kalman"
191
+ max_age: int = 30
192
+ min_hits: int = 3
193
+ iou_threshold: float = 0.3
194
+
195
+ # Target classes for tracking
196
+ target_classes: List[str] = field(default_factory=list)
197
+
198
+ # Advanced tracking settings
199
+ use_appearance_features: bool = False
200
+ appearance_threshold: float = 0.7
201
+
202
+ def validate(self) -> List[str]:
203
+ """Validate tracking configuration."""
204
+ errors = []
205
+
206
+ valid_methods = ["kalman", "sort", "deepsort", "bytetrack"]
207
+ if self.tracking_method not in valid_methods:
208
+ errors.append(f"tracking_method must be one of {valid_methods}")
209
+
210
+ if self.max_age <= 0:
211
+ errors.append("max_age must be positive")
212
+
213
+ if self.min_hits <= 0:
214
+ errors.append("min_hits must be positive")
215
+
216
+ if not 0.0 <= self.iou_threshold <= 1.0:
217
+ errors.append("iou_threshold must be between 0.0 and 1.0")
218
+
219
+ if not 0.0 <= self.appearance_threshold <= 1.0:
220
+ errors.append("appearance_threshold must be between 0.0 and 1.0")
221
+
222
+ return errors
223
+
224
+ def to_dict(self) -> Dict[str, Any]:
225
+ """Convert to dictionary."""
226
+ return {
227
+ "tracking_method": self.tracking_method,
228
+ "max_age": self.max_age,
229
+ "min_hits": self.min_hits,
230
+ "iou_threshold": self.iou_threshold,
231
+ "target_classes": self.target_classes,
232
+ "use_appearance_features": self.use_appearance_features,
233
+ "appearance_threshold": self.appearance_threshold
234
+ }
235
+
236
+
237
+ @dataclass
238
+ class AlertConfig:
239
+ """Configuration for alerting system."""
240
+
241
+ # Threshold-based alerts
242
+ count_thresholds: Dict[str, int] = field(default_factory=dict)
243
+ occupancy_thresholds: Dict[str, int] = field(default_factory=dict)
244
+
245
+ # Time-based alerts
246
+ dwell_time_threshold: Optional[float] = None
247
+ service_time_threshold: Optional[float] = None
248
+
249
+ # Alert settings
250
+ alert_cooldown: float = 60.0 # seconds
251
+
252
+ # enable_webhook_alerts: bool = False
253
+ # webhook_url: Optional[str] = None
254
+ # enable_email_alerts: bool = False
255
+ # email_recipients: List[str] = field(default_factory=list)
256
+
257
+ alert_type: List[str] = field(default_factory=lambda: ['Default']) #webhook, email, sms, slack, telegram, whatsapp, etc.
258
+ alert_value: List[str] = field(default_factory=lambda: ['JSON']) #webhook_url, email_recipients, etc.
259
+ alert_incident_category: List[str] = field(default_factory=lambda: ['Incident Alert'])
260
+ #alert_settings: Optional[Dict[str, Any]] = {alert_type: None}
261
+
262
+ def validate(self) -> List[str]:
263
+ """Validate alert configuration."""
264
+ errors = []
265
+
266
+ # Validate thresholds are positive
267
+ for category, threshold in self.count_thresholds.items():
268
+ if threshold <= 0:
269
+ errors.append(f"Count threshold for '{category}' must be positive")
270
+
271
+ for zone, threshold in self.occupancy_thresholds.items():
272
+ if threshold <= 0:
273
+ errors.append(f"Occupancy threshold for zone '{zone}' must be positive")
274
+
275
+ # Validate time thresholds
276
+ if self.dwell_time_threshold is not None and self.dwell_time_threshold <= 0:
277
+ errors.append("dwell_time_threshold must be positive")
278
+
279
+ if self.service_time_threshold is not None and self.service_time_threshold <= 0:
280
+ errors.append("service_time_threshold must be positive")
281
+
282
+ if self.alert_cooldown <= 0:
283
+ errors.append("alert_cooldown must be positive")
284
+
285
+ if len(self.alert_incident_category)!=len(self.alert_type) or len(self.alert_incident_category)!=len(self.alert_value):
286
+ errors.append("Details for all alerts is required")
287
+
288
+ if self.alert_type[0]!='Default':
289
+ for i in range(len(self.alert_type)):
290
+ normalized = self.alert_type[i].lower()
291
+ # Validate webhook settings
292
+ if normalized=="webhook" and not self.alert_value:
293
+ errors.append("webhook_url is required")
294
+
295
+ elif normalized=="email" and not self.alert_value:
296
+ errors.append("email_recipients is required")
297
+
298
+ elif normalized=="phone" and not self.alert_value:
299
+ errors.append("phone_number is required")
300
+ if len(self.alert_type)==1 and self.alert_type[0]=='Default':
301
+ self.alert_value=["JSON"]
302
+
303
+ return errors
304
+
305
+ def to_dict(self) -> Dict[str, Any]:
306
+ """Convert to dictionary."""
307
+ return {
308
+ "count_thresholds": self.count_thresholds,
309
+ "occupancy_thresholds": self.occupancy_thresholds,
310
+ "dwell_time_threshold": self.dwell_time_threshold,
311
+ "service_time_threshold": self.service_time_threshold,
312
+ "alert_cooldown": self.alert_cooldown,
313
+ "alert_type": self.alert_type,
314
+ "alert_value": self.alert_value
315
+ }
316
+
317
+ # --- Legacy/dict-like compatibility helpers ---
318
+ def _as_legacy_dict(self) -> Dict[str, Any]:
319
+ return {
320
+ "count_thresholds": self.count_thresholds,
321
+ "occupancy_thresholds": self.occupancy_thresholds,
322
+ "dwell_time_threshold": self.dwell_time_threshold,
323
+ "service_time_threshold": self.service_time_threshold,
324
+ "alert_cooldown": self.alert_cooldown,
325
+ "alert_type": self.alert_type,
326
+ "alert_value": self.alert_value,
327
+ "alert_incident_category": self.alert_incident_category,
328
+ }
329
+
330
+ def __getitem__(self, key: str) -> Any:
331
+ return self._as_legacy_dict()[key]
332
+
333
+ def get(self, key: str, default: Any = None) -> Any:
334
+ return self._as_legacy_dict().get(key, default)
335
+
336
+ def keys(self):
337
+ return self._as_legacy_dict().keys()
338
+
339
+ def items(self):
340
+ return self._as_legacy_dict().items()
341
+
342
+ def __contains__(self, key: object) -> bool:
343
+ return key in self._as_legacy_dict()
344
+
345
+ def __iter__(self):
346
+ return iter(self._as_legacy_dict())
347
+
348
+ def __len__(self) -> int:
349
+ return len(self._as_legacy_dict())
350
+
351
+
352
+ @dataclass
353
+ class PeopleCountingConfig(BaseConfig):
354
+ """Configuration for people counting use case."""
355
+
356
+ # Smoothing configuration
357
+ enable_smoothing: bool = True
358
+ smoothing_algorithm: str = "observability" # "window" or "observability"
359
+ smoothing_window_size: int = 20
360
+ smoothing_cooldown_frames: int = 5
361
+ smoothing_confidence_range_factor: float = 0.5
362
+
363
+ # Zone configuration
364
+ zone_config: Optional[ZoneConfig] = None
365
+
366
+ # Counting parameters
367
+ enable_unique_counting: bool = True
368
+ time_window_minutes: int = 60
369
+
370
+ # Category mapping
371
+ person_categories: List[str] = field(default_factory=lambda: ["person", "people"])
372
+ index_to_category: Optional[Dict[int, str]] = None
373
+
374
+ # Alert configuration
375
+ alert_config: Optional[AlertConfig] = None
376
+
377
+ target_categories: List[str] = field(
378
+ default_factory=lambda: [
379
+ 'person', 'people', 'human', 'man', 'woman', 'male', 'female']
380
+ )
381
+
382
+ def validate(self) -> List[str]:
383
+ """Validate people counting configuration."""
384
+ errors = super().validate()
385
+
386
+ if self.time_window_minutes <= 0:
387
+ errors.append("time_window_minutes must be positive")
388
+
389
+ if not self.person_categories:
390
+ errors.append("person_categories cannot be empty")
391
+
392
+ # Validate nested configurations
393
+ if self.zone_config:
394
+ errors.extend(self.zone_config.validate())
395
+
396
+ if self.alert_config:
397
+ errors.extend(self.alert_config.validate())
398
+
399
+ return errors
400
+
401
+
402
+ @dataclass
403
+ class IntrusionConfig(BaseConfig):
404
+ """Configuration for intrusion detection use case."""
405
+
406
+ # Smoothing configuration
407
+ enable_smoothing: bool = True
408
+ smoothing_algorithm: str = "observability" # "window" or "observability"
409
+ smoothing_window_size: int = 20
410
+ smoothing_cooldown_frames: int = 5
411
+ smoothing_confidence_range_factor: float = 0.5
412
+
413
+ # Zone configuration
414
+ zone_config: Optional[ZoneConfig] = None
415
+
416
+ # Counting parameters
417
+ enable_unique_counting: bool = True
418
+ time_window_minutes: int = 60
419
+
420
+ # Category mapping
421
+ person_categories: List[str] = field(default_factory=lambda: ["person"])
422
+ index_to_category: Optional[Dict[int, str]] = None
423
+
424
+ # Alert configuration
425
+ alert_config: Optional[AlertConfig] = None
426
+
427
+ def validate(self) -> List[str]:
428
+ """Validate intrusion detection configuration."""
429
+ errors = super().validate()
430
+
431
+ if self.time_window_minutes <= 0:
432
+ errors.append("time_window_minutes must be positive")
433
+
434
+ if not self.person_categories:
435
+ errors.append("person_categories cannot be empty")
436
+
437
+ # Validate nested configurations
438
+ if self.zone_config:
439
+ errors.extend(self.zone_config.validate())
440
+
441
+ if self.alert_config:
442
+ errors.extend(self.alert_config.validate())
443
+
444
+ return errors
445
+
446
+
447
+ @dataclass
448
+ class ProximityConfig(BaseConfig):
449
+ """Configuration for intrusion detection use case."""
450
+
451
+ # Smoothing configuration
452
+ enable_smoothing: bool = True
453
+ smoothing_algorithm: str = "observability" # "window" or "observability"
454
+ smoothing_window_size: int = 20
455
+ smoothing_cooldown_frames: int = 5
456
+ smoothing_confidence_range_factor: float = 0.5
457
+
458
+ # Zone configuration
459
+ zone_config: Optional[ZoneConfig] = None
460
+
461
+ # Counting parameters
462
+ enable_unique_counting: bool = True
463
+ time_window_minutes: int = 60
464
+
465
+ proximity_threshold_meters: float = 1.0
466
+ proximity_threshold_pixels: float = 250.0
467
+ meters_per_pixel: float = 0.0028
468
+ scene_width_meters: float = 0.0
469
+ scene_height_meters: float = 0.0
470
+
471
+ # Category mapping
472
+ person_categories: List[str] = field(default_factory=lambda: ["person"])
473
+ index_to_category: Optional[Dict[int, str]] = None
474
+
475
+ # Alert configuration
476
+ alert_config: Optional[AlertConfig] = None
477
+
478
+ def validate(self) -> List[str]:
479
+ """Validate proximity detection configuration."""
480
+ errors = super().validate()
481
+
482
+ if self.time_window_minutes <= 0:
483
+ errors.append("time_window_minutes must be positive")
484
+
485
+ if not self.person_categories:
486
+ errors.append("person_categories cannot be empty")
487
+
488
+ # Validate nested configurations
489
+ if self.zone_config:
490
+ errors.extend(self.zone_config.validate())
491
+
492
+ if self.alert_config:
493
+ errors.extend(self.alert_config.validate())
494
+
495
+ return errors
496
+
497
+
498
+ @dataclass
499
+ class CustomerServiceConfig(BaseConfig):
500
+ """Configuration for customer service use case."""
501
+
502
+ # Area definitions
503
+ customer_areas: Dict[str, List[List[float]]] = field(default_factory=dict)
504
+ staff_areas: Dict[str, List[List[float]]] = field(default_factory=dict)
505
+ service_areas: Dict[str, List[List[float]]] = field(default_factory=dict)
506
+
507
+ # Category identification
508
+ staff_categories: List[str] = field(default_factory=lambda: ["staff", "employee"])
509
+ customer_categories: List[str] = field(default_factory=lambda: ["customer", "person"])
510
+
511
+ # Service parameters
512
+ service_proximity_threshold: float = 100.0
513
+ max_service_time: float = 1800.0 # 30 minutes
514
+ buffer_time: float = 2.0
515
+
516
+ # Tracking configuration
517
+ tracking_config: Optional[TrackingConfig] = None
518
+
519
+ # Alert configuration
520
+ alert_config: Optional[AlertConfig] = None
521
+
522
+ # Additional analytics options
523
+ enable_journey_analysis: bool = False
524
+ enable_queue_analytics: bool = False
525
+
526
+ def validate(self) -> List[str]:
527
+ """Validate customer service configuration."""
528
+ errors = super().validate()
529
+
530
+ if self.service_proximity_threshold <= 0:
531
+ errors.append("service_proximity_threshold must be positive")
532
+
533
+ if self.max_service_time <= 0:
534
+ errors.append("max_service_time must be positive")
535
+
536
+ if self.buffer_time < 0:
537
+ errors.append("buffer_time must be non-negative")
538
+
539
+ # Validate category lists
540
+ if not self.staff_categories:
541
+ errors.append("staff_categories cannot be empty")
542
+
543
+ if not self.customer_categories:
544
+ errors.append("customer_categories cannot be empty")
545
+
546
+ # Validate area polygons
547
+ all_areas = {**self.customer_areas, **self.staff_areas, **self.service_areas}
548
+ for area_name, polygon in all_areas.items():
549
+ if len(polygon) < 3:
550
+ errors.append(f"Area '{area_name}' must have at least 3 points")
551
+
552
+ for i, point in enumerate(polygon):
553
+ if len(point) != 2:
554
+ errors.append(f"Area '{area_name}' point {i} must have exactly 2 coordinates")
555
+
556
+ # Validate nested configurations
557
+ if self.tracking_config:
558
+ errors.extend(self.tracking_config.validate())
559
+
560
+ if self.alert_config:
561
+ errors.extend(self.alert_config.validate())
562
+
563
+ return errors
564
+
565
+ @dataclass
566
+ class CarServiceConfig(BaseConfig):
567
+ """Configuration for car service use case."""
568
+
569
+ # Area definitions
570
+ car_areas: Dict[str, List[List[float]]] = field(default_factory=dict)
571
+ staff_areas: Dict[str, List[List[float]]] = field(default_factory=dict)
572
+ service_areas: Dict[str, List[List[float]]] = field(default_factory=dict)
573
+
574
+ # Category identification
575
+ staff_categories: List[str] = field(default_factory=lambda: ["staff", "employee"])
576
+ car_categories: List[str] = field(default_factory=lambda: ["car"])
577
+
578
+ # Service parameters
579
+ service_proximity_threshold: float = 100.0
580
+ max_service_time: float = 1800.0 # 30 minutes
581
+ buffer_time: float = 2.0
582
+
583
+ # Tracking configuration
584
+ tracking_config: Optional[TrackingConfig] = None
585
+
586
+ # Alert configuration
587
+ alert_config: Optional[AlertConfig] = None
588
+
589
+ # Additional analytics options
590
+ enable_journey_analysis: bool = False
591
+ enable_queue_analytics: bool = False
592
+
593
+ def validate(self) -> List[str]:
594
+ """Validate customer service configuration."""
595
+ errors = super().validate()
596
+
597
+ if self.service_proximity_threshold <= 0:
598
+ errors.append("service_proximity_threshold must be positive")
599
+
600
+ if self.max_service_time <= 0:
601
+ errors.append("max_service_time must be positive")
602
+
603
+ if self.buffer_time < 0:
604
+ errors.append("buffer_time must be non-negative")
605
+
606
+ # Validate category lists
607
+ if not self.staff_categories:
608
+ errors.append("staff_categories cannot be empty")
609
+
610
+ if not self.car_categories:
611
+ errors.append("car_categories cannot be empty")
612
+
613
+ # Validate area polygons
614
+ all_areas = {**self.car_categories, **self.staff_areas, **self.service_areas}
615
+ for area_name, polygon in all_areas.items():
616
+ if len(polygon) < 0:
617
+ errors.append(f"Area '{area_name}' must have at least 0 points")
618
+
619
+ for i, point in enumerate(polygon):
620
+ if len(point) != 2:
621
+ errors.append(f"Area '{area_name}' point {i} must have exactly 2 coordinates")
622
+
623
+ # Validate nested configurations
624
+ if self.tracking_config:
625
+ errors.extend(self.tracking_config.validate())
626
+
627
+ if self.alert_config:
628
+ errors.extend(self.alert_config.validate())
629
+
630
+ return errors
631
+
632
+
633
+ @dataclass
634
+ class LineConfig:
635
+ """Configuration for line crossing detection."""
636
+
637
+ # Line definition
638
+ points: List[List[float]] = field(default_factory=list) # Two points defining the line [[x1, y1], [x2, y2]]
639
+
640
+ # Line-specific settings
641
+ side1_label: str = field(default_factory=lambda: "Side1") # Label for one side of the line
642
+ side2_label: str = field(default_factory=lambda: "Side2") # Label for the other side of the line
643
+ crossing_categories: List[str] = field(default_factory=list) # Categories to track for crossing
644
+
645
+ def validate(self) -> List[str]:
646
+ """Validate line configuration."""
647
+ errors = []
648
+
649
+ # Validate line points
650
+ if len(self.points) != 2:
651
+ errors.append("points must contain exactly 2 points")
652
+
653
+ for i, point in enumerate(self.points):
654
+ if not isinstance(point, (list, tuple)) or len(point) != 2:
655
+ errors.append(f"Point {i} must have exactly 2 coordinates [x, y]")
656
+ for j, coord in enumerate(point):
657
+ if not isinstance(coord, (int, float)):
658
+ errors.append(f"Point {i} coordinate {j} must be a number")
659
+
660
+ # Validate side labels
661
+ if not self.side1_label:
662
+ errors.append("side1_label must be a non-empty string")
663
+ if not self.side2_label:
664
+ errors.append("side2_label must be a non-empty string")
665
+ if self.side1_label == self.side2_label:
666
+ errors.append("side1_label and side2_label must be different")
667
+
668
+ # Validate crossing categories
669
+ if not self.crossing_categories:
670
+ errors.append("crossing_categories cannot be empty")
671
+
672
+ return errors
673
+
674
+ def to_dict(self) -> Dict[str, Any]:
675
+ """Convert to dictionary."""
676
+ return {
677
+ "points": self.points,
678
+ "side1_label": self.side1_label,
679
+ "side2_label": self.side2_label,
680
+ "crossing_categories": self.crossing_categories
681
+ }
682
+
683
+ # --- Legacy/dict-like compatibility helpers ---
684
+ def _as_legacy_dict(self) -> Dict[str, Any]:
685
+ return {
686
+ "points": self.points,
687
+ "side1_label": self.side1_label,
688
+ "side2_label": self.side2_label,
689
+ "crossing_categories": self.crossing_categories
690
+ }
691
+
692
+ def __getitem__(self, key: str) -> Any: # Support config.line_config['points']
693
+ return self._as_legacy_dict()[key]
694
+
695
+ def get(self, key: str, default: Any = None) -> Any:
696
+ return self._as_legacy_dict().get(key, default)
697
+
698
+ def keys(self):
699
+ return self._as_legacy_dict().keys()
700
+
701
+ def items(self):
702
+ return self._as_legacy_dict().items()
703
+
704
+ def __contains__(self, key: object) -> bool:
705
+ return key in self._as_legacy_dict()
706
+
707
+ def __iter__(self):
708
+ return iter(self._as_legacy_dict())
709
+
710
+ def __len__(self) -> int:
711
+ return len(self._as_legacy_dict())
712
+
713
+
714
+ @dataclass
715
+ class PeopleTrackingConfig:
716
+ """Configuration for the People Tracking Use Case."""
717
+
718
+ confidence_threshold: float = field(default_factory=lambda: 0.5) # Minimum confidence for detections
719
+
720
+ # Category identification
721
+ person_categories: List[str] = field(default_factory=lambda: []) # Categories representing people
722
+
723
+ # Zone configuration
724
+ zone_config: Optional[ZoneConfig] = None # Zone definitions and thresholds
725
+
726
+ # Line crossing configuration
727
+ line_config: Optional[LineConfig] = None # Line crossing definitions and labels
728
+
729
+ # Tracking configuration
730
+ tracking_config: Optional[TrackingConfig] = None # Tracking parameters
731
+
732
+ # Alert configuration
733
+ alert_config: Optional[AlertConfig] = None # Alert thresholds and settings
734
+
735
+ # Category mapping
736
+ index_to_category: Dict[int, str] = field(default_factory=dict) # Map model indices to categories
737
+
738
+ # Additional analytics options
739
+ enable_analytics: bool = field(default_factory=lambda: True) # Enable business analytics
740
+ enable_zone_analytics: bool = field(default_factory=lambda: False) # Enable zone-specific analytics
741
+ enable_crossing_analytics: bool = field(default_factory=lambda: False) # Enable line crossing analytics
742
+
743
+ def validate(self) -> List[str]:
744
+ """Validate people tracking configuration."""
745
+ errors = []
746
+
747
+
748
+ # Validate person categories
749
+ if not self.person_categories:
750
+ errors.append("person_categories cannot be empty")
751
+
752
+ # Validate index_to_category
753
+ if self.index_to_category:
754
+ for index, category in self.index_to_category.items():
755
+ if not isinstance(index, int):
756
+ errors.append(f"index_to_category key '{index}' must be an integer")
757
+ if not isinstance(category, str) or not category:
758
+ errors.append(f"index_to_category value for key '{index}' must be a non-empty string")
759
+
760
+ # Validate nested configurations
761
+ if self.zone_config:
762
+ try:
763
+ zone_errors = self.zone_config.validate()
764
+ errors.extend(zone_errors)
765
+ except AttributeError:
766
+ errors.append("zone_config must have a validate method")
767
+
768
+ if self.line_config:
769
+ try:
770
+ line_errors = self.line_config.validate()
771
+ errors.extend(line_errors)
772
+ except AttributeError:
773
+ errors.append("line_config must have a validate method")
774
+
775
+ if self.tracking_config:
776
+ try:
777
+ tracking_errors = self.tracking_config.validate()
778
+ errors.extend(tracking_errors)
779
+ except AttributeError:
780
+ errors.append("tracking_config must have a validate method")
781
+
782
+ if self.alert_config:
783
+ try:
784
+ alert_errors = self.alert_config.validate()
785
+ errors.extend(alert_errors)
786
+ except AttributeError:
787
+ errors.append("alert_config must have a validate method")
788
+
789
+ return errors
790
+
791
+
792
+ def filter_config_kwargs(config_class: type, kwargs: Dict[str, Any]) -> Dict[str, Any]:
793
+ """
794
+ Filter kwargs to only include parameters that are valid for the config class.
795
+
796
+ Args:
797
+ config_class: The config class to create
798
+ kwargs: Dictionary of parameters to filter
799
+
800
+ Returns:
801
+ Dict[str, Any]: Filtered kwargs containing only valid parameters
802
+ """
803
+ if not hasattr(config_class, '__dataclass_fields__'):
804
+ # Not a dataclass, return kwargs as-is
805
+ return kwargs
806
+
807
+ # Get valid field names from the dataclass
808
+ valid_fields = set(config_class.__dataclass_fields__.keys())
809
+
810
+ # Filter kwargs to only include valid fields
811
+ filtered_kwargs = {}
812
+ ignored_params = []
813
+
814
+ for key, value in kwargs.items():
815
+ if key in valid_fields:
816
+ filtered_kwargs[key] = value
817
+ else:
818
+ ignored_params.append(key)
819
+
820
+ # Log ignored parameters for debugging
821
+ if ignored_params:
822
+ logger.debug(
823
+ f"Ignoring non-config parameters for {config_class.__name__}: {ignored_params}"
824
+ )
825
+
826
+ return filtered_kwargs
827
+
828
+
829
+ class ConfigManager:
830
+ """Centralized configuration management for post-processing operations."""
831
+
832
+ def __init__(self):
833
+ """Initialize configuration manager."""
834
+ self._config_classes = {
835
+ "people_counting": PeopleCountingConfig,
836
+ "customer_service": CustomerServiceConfig,
837
+ "advanced_customer_service": CustomerServiceConfig,
838
+ "intrusion_detection": IntrusionConfig,
839
+ "proximity_detection": ProximityConfig,
840
+ "basic_counting_tracking": None, # Will be set later to avoid circular import
841
+ "license_plate_detection": None, # Will be set later to avoid circular import
842
+ "ppe_compliance_detection": None,
843
+ "color_detection": None, # Will be set later to avoid circular import
844
+ "video_color_classification": None, # Alias for color_detection
845
+ "drone_traffic_monitoring": None,
846
+ "vehicle_monitoring" : None,
847
+ "fire_smoke_detection": None,
848
+ "flare_analysis" : None,
849
+ "mask_detection": None,
850
+ "pipeline_detection": None,
851
+ "parking_space_detection": None,
852
+ "car_damage_detection":None,
853
+ "weld_defect_detection" : None,
854
+ "banana_defect_detection" : None,
855
+ "chicken_pose_detection" : None,
856
+ "traffic_sign_monitoring" : None,
857
+ "theft_detection" : None,
858
+ "gender_detection": None,
859
+ "solar_panel": None,
860
+ "crop_weed_detection": None,
861
+ "emergency_vehicle_detection": None,
862
+ "shoplifting_detection":None,
863
+ "price_tag_detection": None,
864
+ "child_monitoring": None,
865
+ "weapon_detection" : None,
866
+ "concrete_crack_detection": None,
867
+ "fashion_detection": None,
868
+ "pothole_segmentation": None,
869
+ "warehouse_object_segmentation": None,
870
+ "shopping_cart_analysis": None,
871
+ "defect_detection_products": None,
872
+ 'assembly_line_detection': None,
873
+ 'anti_spoofing_detection' : None,
874
+ 'shelf_inventory' : None,
875
+ 'wound_segmentation': None,
876
+ 'leaf_disease_detection': None,
877
+ 'field_mapping': None,
878
+ 'car_part_segmentation': None,
879
+ 'lane_detection' : None,
880
+ 'windmill_maintenance': None,
881
+ 'face_emotion': None,
882
+ 'flower_segmentation': None,
883
+ 'smoker_detection': None,
884
+ 'road_traffic_density': None,
885
+ 'road_view_segmentation': None,
886
+ 'face_recognition': None,
887
+ 'drowsy_driver_detection': None,
888
+ 'waterbody_segmentation': None,
889
+ 'litter_detection' :None,
890
+ 'abandoned_object_detection' : None,
891
+ 'litter_detection':None,
892
+ 'leak_detection': None,
893
+ 'human_activity_recognition': None,
894
+ 'gas_leak_detection': None,
895
+ 'license_plate_monitor' : None,
896
+ 'dwell' : None,
897
+ 'age_gender_detection': None,
898
+ 'wildlife_monitoring': None,
899
+ 'people_tracking' : PeopleTrackingConfig,
900
+ 'pcb_defect_detection': None,
901
+ 'underground_pipeline_defect' : None,
902
+ 'suspicious_activity_detection': None,
903
+ 'natural_disaster_detection': None,
904
+
905
+ #Put all image based usecases here::
906
+ 'blood_cancer_detection_img': None,
907
+ 'skin_cancer_classification_img': None,
908
+ 'plaque_segmentation_img': None,
909
+ 'cardiomegaly_classification': None,
910
+ 'histopathological_cancer_detection' : None,
911
+ 'cell_microscopy_segmentation': None,
912
+ }
913
+
914
+ def register_config_class(self, usecase: str, config_class: type) -> None:
915
+ """Register a configuration class for a use case."""
916
+ self._config_classes[usecase] = config_class
917
+
918
+ def _get_license_plate_config_class(self):
919
+ """Get LicensePlateConfig class to avoid circular imports."""
920
+ try:
921
+ from ..usecases.license_plate_detection import LicensePlateConfig
922
+ return LicensePlateConfig
923
+ except ImportError:
924
+ return None
925
+ def _get_wound_segmentation_config_class(self):
926
+ """Get LicensePlateConfig class to avoid circular imports."""
927
+ try:
928
+ from ..usecases.wound_segmentation import WoundConfig
929
+ return WoundConfig
930
+ except ImportError:
931
+ return None
932
+ def _get_leaf_disease_config_class(self):
933
+ """Get LicensePlateConfig class to avoid circular imports."""
934
+ try:
935
+ from ..usecases.leaf_disease import LeafDiseaseDetectionConfig
936
+ return LeafDiseaseDetectionConfig
937
+ except ImportError:
938
+ return None
939
+ def _get_field_mapping_config_class(self):
940
+ """Get LicensePlateConfig class to avoid circular imports."""
941
+ try:
942
+ from ..usecases.field_mapping import FieldMappingConfig
943
+ return FieldMappingConfig
944
+ except ImportError:
945
+ return None
946
+
947
+ def vehicle_monitoring_config_class(self):
948
+ """Get vehicle monitoring class to avoid circular imports."""
949
+ try:
950
+ from ..usecases.vehicle_monitoring import VehicleMonitoringConfig
951
+ return VehicleMonitoringConfig
952
+ except ImportError:
953
+ return None
954
+
955
+ def drone_traffic_monitoring_config_class(self):
956
+ """Get drone traffic monitoring class to avoid circular imports."""
957
+ try:
958
+ from ..usecases.drone_traffic_monitoring import VehiclePeopleDroneMonitoringConfig
959
+ return VehiclePeopleDroneMonitoringConfig
960
+ except ImportError:
961
+ return None
962
+
963
+ def banana_defect_detection_config_class(self):
964
+ """Get Banana monitoring class to avoid circular imports."""
965
+ try:
966
+ from ..usecases.banana_defect_detection import BananaMonitoringConfig
967
+ return BananaMonitoringConfig
968
+ except ImportError:
969
+ return None
970
+
971
+ def lane_detection_config_class(self):
972
+ """Get road lane monitoring class to avoid circular imports."""
973
+ try:
974
+ from ..usecases.road_lane_detection import LaneDetectionConfig
975
+ return LaneDetectionConfig
976
+ except ImportError:
977
+ return None
978
+
979
+ def shelf_inventory_config_class(self):
980
+ """Get inventory monitoring class to avoid circular imports."""
981
+ try:
982
+ from ..usecases.shelf_inventory_detection import ShelfInventoryUseCase
983
+ return ShelfInventoryUseCase
984
+ except ImportError:
985
+ return None
986
+
987
+ def anti_spoofing_detection_config_class(self):
988
+ """Get Anti-Spoofing class to avoid circular imports."""
989
+ try:
990
+ from ..usecases.anti_spoofing_detection import AntiSpoofingDetectionConfig
991
+ return AntiSpoofingDetectionConfig
992
+ except ImportError:
993
+ return None
994
+
995
+ def theft_detection_config_class(self):
996
+ """Get theft detection class to avoid circular imports."""
997
+ try:
998
+ from ..usecases.theft_detection import TheftDetectionConfig
999
+ return TheftDetectionConfig
1000
+ except ImportError:
1001
+ return None
1002
+
1003
+ def weapon_tracking_config_class(self):
1004
+ """Get weapon detection class to avoid circular imports."""
1005
+ try:
1006
+ from ..usecases.weapon_detection import WeaponDetectionConfig
1007
+ return WeaponDetectionConfig
1008
+ except ImportError:
1009
+ return None
1010
+
1011
+ def traffic_sign_monitoring_config_class(self):
1012
+ """Get traffic sign monitoring class to avoid circular imports."""
1013
+ try:
1014
+ from ..usecases.traffic_sign_monitoring import TrafficSignMonitoringConfig
1015
+ return TrafficSignMonitoringConfig
1016
+ except ImportError:
1017
+ return None
1018
+
1019
+ def chicken_pose_detection_config_class(self):
1020
+ """Get Chicken pose monitoring class to avoid circular imports."""
1021
+ try:
1022
+ from ..usecases.chicken_pose_detection import ChickenPoseDetectionConfig
1023
+ return ChickenPoseDetectionConfig
1024
+ except ImportError:
1025
+ return None
1026
+
1027
+ def _get_fire_smoke_detection_config_class(self):
1028
+ """Register a configuration class for a use case."""
1029
+ try:
1030
+ from ..usecases.fire_detection import FireSmokeConfig
1031
+ return FireSmokeConfig
1032
+ except ImportError:
1033
+ return None
1034
+
1035
+ def _get_shoplifting_detection_config_class(self):
1036
+ """Register a configuration class for a use case."""
1037
+ try:
1038
+ from ..usecases.shoplifting_detection import ShopliftingDetectionConfig
1039
+ return ShopliftingDetectionConfig
1040
+ except ImportError:
1041
+ return None
1042
+
1043
+
1044
+ def _get_car_damage_config_class(self):
1045
+ """Register a configuration class for a use case."""
1046
+ try:
1047
+ from ..usecases.car_damage_detection import CarDamageConfig
1048
+ return CarDamageConfig
1049
+ except ImportError:
1050
+ return None
1051
+
1052
+
1053
+ def _get_parking_space_detection_config_class(self):
1054
+ """Register a configuration class for a use case."""
1055
+ try:
1056
+ from ..usecases.parking_space_detection import ParkingSpaceConfig
1057
+ return ParkingSpaceConfig
1058
+ except ImportError:
1059
+ return None
1060
+
1061
+ def _get_mask_detection_config_class(self):
1062
+ """Register a configuration class for a use case."""
1063
+ try:
1064
+ from ..usecases.mask_detection import MaskDetectionConfig
1065
+ return MaskDetectionConfig
1066
+ except ImportError:
1067
+ return None
1068
+
1069
+ def _get_pipeline_detection_config_class(self):
1070
+ """Register a configuration class for a use case."""
1071
+ try:
1072
+ from ..usecases.pipeline_detection import PipelineDetectionConfig
1073
+ return PipelineDetectionConfig
1074
+ except ImportError:
1075
+ return None
1076
+
1077
+ def _get_pothole_segmentation_config_class(self):
1078
+ """Register a configuration class for a use case."""
1079
+ try:
1080
+ from ..usecases.pothole_segmentation import PotholeConfig
1081
+ return PotholeConfig
1082
+ except ImportError:
1083
+ return None
1084
+
1085
+ def flare_analysis_config_class(self):
1086
+ """Register a configuration class for a use case."""
1087
+ try:
1088
+ from ..usecases.flare_analysis import FlareAnalysisConfig
1089
+ return FlareAnalysisConfig
1090
+ except ImportError:
1091
+ return None
1092
+
1093
+ def face_emotion_config_class(self):
1094
+ """Register a configuration class for a use case."""
1095
+ try:
1096
+ from ..usecases.face_emotion import FaceEmotionConfig
1097
+ return FaceEmotionConfig
1098
+ except ImportError:
1099
+ return None
1100
+
1101
+ def underwater_pollution_detection_config_class(self):
1102
+ """Register a configuration class for a use case."""
1103
+ try:
1104
+ from ..usecases.underwater_pollution_detection import UnderwaterPlasticConfig
1105
+ return UnderwaterPlasticConfig
1106
+ except ImportError:
1107
+ return None
1108
+
1109
+ def pedestrian_detection_config_class(self):
1110
+ """Register a configuration class for a use case."""
1111
+ try:
1112
+ from ..usecases.pedestrian_detection import PedestrianDetectionConfig
1113
+ return PedestrianDetectionConfig
1114
+ except ImportError:
1115
+ return None
1116
+
1117
+ def age_detection_config_class(self):
1118
+ """Register a configuration class for a use case."""
1119
+ try:
1120
+ from ..usecases.age_detection import AgeDetectionConfig
1121
+ return AgeDetectionConfig
1122
+ except ImportError:
1123
+ return None
1124
+
1125
+ def weld_defect_detection_config_class(self):
1126
+ """Register a configuration class for a use case."""
1127
+ try:
1128
+ from ..usecases.weld_defect_detection import WeldDefectConfig
1129
+ return WeldDefectConfig
1130
+ except ImportError:
1131
+ return None
1132
+
1133
+ def price_tag_detection_config_class(self):
1134
+ """Register a configuration class for a use case."""
1135
+ try:
1136
+ from ..usecases.price_tag_detection import PriceTagConfig
1137
+ return PriceTagConfig
1138
+ except ImportError:
1139
+ return None
1140
+
1141
+ def distracted_driver_detection_config_class(self):
1142
+ """Register a configuration class for a use case."""
1143
+ try:
1144
+ from ..usecases.distracted_driver_detection import DistractedDriverConfig
1145
+ return DistractedDriverConfig
1146
+ except ImportError:
1147
+ return None
1148
+
1149
+ def emergency_vehicle_detection_config_class(self):
1150
+ """Register a configuration class for a use case."""
1151
+ try:
1152
+ from ..usecases.emergency_vehicle_detection import EmergencyVehicleConfig
1153
+ return EmergencyVehicleConfig
1154
+ except ImportError:
1155
+ return None
1156
+
1157
+ def solar_panel_config_class(self):
1158
+ """Register a configuration class for a use case."""
1159
+ try:
1160
+ from ..usecases.solar_panel import SolarPanelConfig
1161
+ return SolarPanelConfig
1162
+ except ImportError:
1163
+ return None
1164
+
1165
+ def crop_weed_detection_config_class(self):
1166
+ """Register a configuration class for a use case."""
1167
+ try:
1168
+ from ..usecases.crop_weed_detection import CropWeedDetectionConfig
1169
+ return CropWeedDetectionConfig
1170
+ except ImportError:
1171
+ return None
1172
+
1173
+ def child_monitoring_config_class(self):
1174
+ """Register a configuration class for a use case."""
1175
+ try:
1176
+ from ..usecases.child_monitoring import ChildMonitoringConfig
1177
+ return ChildMonitoringConfig
1178
+ except ImportError:
1179
+ return None
1180
+
1181
+ def gender_detection_config_class(self):
1182
+ """Register a configuration class for a use case."""
1183
+ try:
1184
+ from ..usecases.gender_detection import GenderDetectionConfig
1185
+ return GenderDetectionConfig
1186
+ except ImportError:
1187
+ return None
1188
+
1189
+ def concrete_crack_detection_config_class(self):
1190
+ """Register a configuration class for a use case."""
1191
+ try:
1192
+ from ..usecases.concrete_crack_detection import ConcreteCrackConfig
1193
+ return ConcreteCrackConfig
1194
+ except ImportError:
1195
+ return None
1196
+
1197
+ def fashion_detection_config_class(self):
1198
+ """Register a configuration class for a use case."""
1199
+ try:
1200
+ from ..usecases.fashion_detection import FashionDetectionConfig
1201
+ return FashionDetectionConfig
1202
+ except ImportError:
1203
+ return None
1204
+
1205
+ def warehouse_object_segmentation_config_class(self):
1206
+ """Register a configuration class for a use case."""
1207
+ try:
1208
+ from ..usecases.warehouse_object_segmentation import WarehouseObjectConfig
1209
+ return WarehouseObjectConfig
1210
+ except ImportError:
1211
+ return None
1212
+
1213
+ def shopping_cart_analysis_config_class(self):
1214
+ """Register a configuration class for a use case."""
1215
+ try:
1216
+ from ..usecases.shopping_cart_analysis import ShoppingCartAnalysisConfig
1217
+ return ShoppingCartAnalysisConfig
1218
+ except ImportError:
1219
+ return None
1220
+
1221
+ def defect_detection_products_config_class(self):
1222
+ """Register a configuration class for a use case."""
1223
+ try:
1224
+ from ..usecases.defect_detection_products import BottleDefectConfig
1225
+ return BottleDefectConfig
1226
+ except ImportError:
1227
+ return None
1228
+
1229
+ def assembly_line_detection_config_class(self):
1230
+ """Register a configuration class for a use case."""
1231
+ try:
1232
+ from ..usecases.assembly_line_detection import AssemblyLineConfig
1233
+ return AssemblyLineConfig
1234
+ except ImportError:
1235
+ return None
1236
+
1237
+ def car_part_segmentation_config_class(self):
1238
+ """Register a configuration class for a use case."""
1239
+ try:
1240
+ from ..usecases.car_part_segmentation import CarPartSegmentationConfig
1241
+ return CarPartSegmentationConfig
1242
+ except ImportError:
1243
+ return None
1244
+
1245
+ def windmill_maintenance_config_class(self):
1246
+ """Register a configuration class for a use case."""
1247
+ try:
1248
+ from ..usecases.windmill_maintenance import WindmillMaintenanceConfig
1249
+ return WindmillMaintenanceConfig
1250
+ except ImportError:
1251
+ return None
1252
+
1253
+ def flower_segmentation_config_class(self):
1254
+ """Register a configuration class for a use case."""
1255
+ try:
1256
+ from ..usecases.flower_segmentation import FlowerConfig
1257
+ return FlowerConfig
1258
+ except ImportError:
1259
+ return None
1260
+
1261
+ def smoker_detection_config_class(self):
1262
+ """Register a configuration class for a use case."""
1263
+ try:
1264
+ from ..usecases.smoker_detection import SmokerDetectionConfig
1265
+ return SmokerDetectionConfig
1266
+ except ImportError:
1267
+ return None
1268
+
1269
+ def road_traffic_density_config_class(self):
1270
+ """Register a configuration class for a use case."""
1271
+ try:
1272
+ from ..usecases.road_traffic_density import RoadTrafficConfig
1273
+ return RoadTrafficConfig
1274
+ except ImportError:
1275
+ return None
1276
+
1277
+ def road_view_segmentation_config_class(self):
1278
+ """Register a configuration class for a use case."""
1279
+ try:
1280
+ from ..usecases.road_view_segmentation import RoadViewSegmentationConfig
1281
+ return RoadViewSegmentationConfig
1282
+ except ImportError:
1283
+ return None
1284
+
1285
+ def face_recognition_config_class(self):
1286
+ """Register a configuration class for a use case."""
1287
+ try:
1288
+ # from ..usecases.face_recognition import FaceRecognitionConfig
1289
+ # return FaceRecognitionConfig
1290
+ from ..face_reg.face_recognition import FaceRecognitionEmbeddingConfig
1291
+
1292
+ return FaceRecognitionEmbeddingConfig
1293
+ except ImportError:
1294
+ return None
1295
+
1296
+ def drowsy_driver_detection_config_class(self):
1297
+ """Register a configuration class for a use case."""
1298
+ try:
1299
+ from ..usecases.drowsy_driver_detection import DrowsyDriverConfig
1300
+ return DrowsyDriverConfig
1301
+ except ImportError:
1302
+ return None
1303
+
1304
+ def waterbody_segmentation_config_class(self):
1305
+ """Register a configuration class for a use case."""
1306
+ try:
1307
+ from ..usecases.waterbody_segmentation import WaterBodyConfig
1308
+ return WaterBodyConfig
1309
+ except ImportError:
1310
+ return None
1311
+
1312
+ def litter_detection_config_class(self):
1313
+ """Get Litter monitoring class to avoid circular imports."""
1314
+ try:
1315
+ from ..usecases.litter_monitoring import LitterDetectionConfig
1316
+ return LitterDetectionConfig
1317
+ except ImportError:
1318
+ return None
1319
+
1320
+
1321
+ def abandoned_object_detection_config_class(self):
1322
+ """Get monitoring class to avoid circular imports."""
1323
+ try:
1324
+ from ..usecases.abandoned_object_detection import AbandonedObjectConfig
1325
+ return AbandonedObjectConfig
1326
+ except ImportError:
1327
+ return None
1328
+
1329
+ def leak_detection_config_class(self):
1330
+ """Get Leak detection class to avoid circular imports."""
1331
+ try:
1332
+ from ..usecases.leak_detection import LeakDetectionConfig
1333
+ return LeakDetectionConfig
1334
+ except ImportError:
1335
+ return None
1336
+
1337
+ def human_activity_recognition_config_class(self):
1338
+ """Register a configuration class for a use case."""
1339
+ try:
1340
+ from ..usecases.human_activity_recognition import HumanActivityConfig
1341
+ return HumanActivityConfig
1342
+ except ImportError:
1343
+ return None
1344
+
1345
+ def license_plate_monitor_config_class(self):
1346
+ """Register a configuration class for a use case."""
1347
+ try:
1348
+ from ..usecases.license_plate_monitoring import LicensePlateMonitorConfig
1349
+ return LicensePlateMonitorConfig
1350
+ except ImportError:
1351
+ return None
1352
+
1353
+ def dwell_config_class(self):
1354
+ """Register a configuration class for a use case."""
1355
+ try:
1356
+ from ..usecases.dwell_detection import DwellConfig
1357
+ return DwellConfig
1358
+ except ImportError:
1359
+ return None
1360
+
1361
+ def gas_leak_detection_config_class(self):
1362
+ """Register a configuration class for a use case."""
1363
+ try:
1364
+ from ..usecases.gas_leak_detection import GasLeakDetectionConfig
1365
+ return GasLeakDetectionConfig
1366
+ except ImportError:
1367
+ return None
1368
+
1369
+ def age_gender_detection_config_class(self):
1370
+ """Register a configuration class for a use case."""
1371
+ try:
1372
+ from ..usecases.age_gender_detection import AgeGenderConfig
1373
+ return AgeGenderConfig
1374
+ except ImportError:
1375
+ return None
1376
+
1377
+ def wildlife_monitoring_config_class(self):
1378
+ """Register a configuration class for a use case."""
1379
+ try:
1380
+ from ..usecases.wildlife_monitoring import WildLifeMonitoringConfig
1381
+ return WildLifeMonitoringConfig
1382
+ except ImportError:
1383
+ return None
1384
+
1385
+ def pcb_defect_detection_config_class(self):
1386
+ """Register a configuration class for a use case."""
1387
+ try:
1388
+ from ..usecases.pcb_defect_detection import PCBDefectConfig
1389
+ return PCBDefectConfig
1390
+ except ImportError:
1391
+ return None
1392
+
1393
+ def suspicious_activity_detection_config_class(self):
1394
+ """Register a configuration class for a use case."""
1395
+ try:
1396
+ from ..usecases.suspicious_activity_detection import SusActivityConfig
1397
+ return SusActivityConfig
1398
+ except ImportError:
1399
+ return None
1400
+
1401
+ def natural_disaster_detection_config_class(self):
1402
+ """Register a configuration class for a use case."""
1403
+ try:
1404
+ from ..usecases.natural_disaster import NaturalDisasterConfig
1405
+ return NaturalDisasterConfig
1406
+ except ImportError:
1407
+ return None
1408
+
1409
+ #put all image based usecases here::
1410
+ def blood_cancer_detection_config_class(self):
1411
+ """Register a configuration class for a use case."""
1412
+ try:
1413
+ from ..usecases.blood_cancer_detection_img import BloodCancerDetectionConfig
1414
+ return BloodCancerDetectionConfig
1415
+ except ImportError:
1416
+ return None
1417
+
1418
+ def plaque_segmentation_config_class(self):
1419
+ """Register a configuration class for a use case."""
1420
+ try:
1421
+ from ..usecases.plaque_segmentation_img import PlaqueSegmentationConfig
1422
+ return PlaqueSegmentationConfig
1423
+ except ImportError:
1424
+ return None
1425
+
1426
+ def skin_cancer_classification_config_class(self):
1427
+ """Register a configuration class for a use case."""
1428
+ try:
1429
+ from ..usecases.skin_cancer_classification_img import SkinCancerClassificationConfig
1430
+ return SkinCancerClassificationConfig
1431
+ except ImportError:
1432
+ return None
1433
+
1434
+ def cardiomegaly_classification_config_class(self):
1435
+ """Register a configuration class for a use case."""
1436
+ try:
1437
+ from ..usecases.cardiomegaly_classification import CardiomegalyConfig
1438
+ return CardiomegalyConfig
1439
+ except ImportError:
1440
+ return None
1441
+
1442
+ def histopathological_cancer_detection_config_class(self):
1443
+ """Register a configuration class for a use case."""
1444
+ try:
1445
+ from ..usecases.Histopathological_Cancer_Detection_img import HistopathologicalCancerDetectionConfig
1446
+ return HistopathologicalCancerDetectionConfig
1447
+ except ImportError:
1448
+ return None
1449
+
1450
+ def cell_microscopy_segmentation_config_class(self):
1451
+ """Register a configuration class for a use case."""
1452
+ try:
1453
+ from ..usecases.cell_microscopy_segmentation import CellMicroscopyConfig
1454
+ return CellMicroscopyConfig
1455
+ except ImportError:
1456
+ return None
1457
+
1458
+ def underground_pipeline_defect_config_class(self):
1459
+ """Register a configuration class for a use case."""
1460
+ try:
1461
+ from ..usecases.underground_pipeline_defect_detection import UndergroundPipelineDefectConfig
1462
+ return UndergroundPipelineDefectConfig
1463
+ except ImportError:
1464
+ return None
1465
+
1466
+ def _filter_kwargs_for_config(self, config_class: type, kwargs: Dict[str, Any]) -> Dict[str, Any]:
1467
+ """
1468
+ Filter kwargs to only include valid parameters for the config class.
1469
+
1470
+ Args:
1471
+ config_class: The config class
1472
+ kwargs: Dictionary of parameters
1473
+
1474
+ Returns:
1475
+ Filtered kwargs
1476
+ """
1477
+ return filter_config_kwargs(config_class, kwargs)
1478
+
1479
+ def create_config(self, usecase: str, category: Optional[str] = None, **kwargs) -> BaseConfig:
1480
+ """
1481
+ Create configuration for a specific use case.
1482
+
1483
+ Args:
1484
+ usecase: Use case name
1485
+ category: Optional category override
1486
+ **kwargs: Configuration parameters
1487
+
1488
+ Returns:
1489
+ BaseConfig: Created configuration
1490
+
1491
+ Raises:
1492
+ ConfigValidationError: If configuration is invalid
1493
+ """
1494
+ # Filter out common non-config parameters that should never be passed to configs
1495
+ common_non_config_params = [
1496
+ 'deployment_id', 'stream_key', 'stream_id', 'camera_id', 'server_id',
1497
+ 'inference_id', 'timestamp', 'frame_id', 'frame_number', 'request_id',
1498
+ 'user_id', 'tenant_id', 'organization_id', 'app_name', 'app_id'
1499
+ ]
1500
+ for param in common_non_config_params:
1501
+ if param in kwargs:
1502
+ logger.debug(f"Removing non-config parameter '{param}' from config creation")
1503
+ kwargs.pop(param, None)
1504
+
1505
+ if usecase == "people_counting":
1506
+ # Handle nested configurations
1507
+ zone_config = kwargs.pop("zone_config", None)
1508
+ if zone_config and isinstance(zone_config, dict):
1509
+ zone_config = ZoneConfig(**zone_config)
1510
+
1511
+ alert_config = kwargs.pop("alert_config", None)
1512
+ if alert_config and isinstance(alert_config, dict):
1513
+ alert_config = AlertConfig(**alert_config)
1514
+
1515
+ # Filter kwargs to only include valid parameters
1516
+ filtered_kwargs = self._filter_kwargs_for_config(PeopleCountingConfig, kwargs)
1517
+
1518
+ config = PeopleCountingConfig(
1519
+ category=category or "general",
1520
+ usecase=usecase,
1521
+ zone_config=zone_config,
1522
+ alert_config=alert_config,
1523
+ **filtered_kwargs
1524
+ )
1525
+
1526
+
1527
+ elif usecase == "people_tracking":
1528
+ # Handle nested configurations
1529
+ zone_config = kwargs.pop("zone_config", None)
1530
+ if zone_config and isinstance(zone_config, dict):
1531
+ zone_config = ZoneConfig(**zone_config)
1532
+
1533
+ alert_config = kwargs.pop("alert_config", None)
1534
+ if alert_config and isinstance(alert_config, dict):
1535
+ alert_config = AlertConfig(**alert_config)
1536
+
1537
+ # Filter kwargs to only include valid parameters
1538
+ filtered_kwargs = self._filter_kwargs_for_config(PeopleTrackingConfig, kwargs)
1539
+
1540
+ config = PeopleTrackingConfig(
1541
+ category=category or "general",
1542
+ usecase=usecase,
1543
+ zone_config=zone_config,
1544
+ alert_config=alert_config,
1545
+ **filtered_kwargs
1546
+ )
1547
+
1548
+ elif usecase == "intrusion_detection":
1549
+ # Handle nested configurations
1550
+ zone_config = kwargs.pop("zone_config", None)
1551
+ if zone_config and isinstance(zone_config, dict):
1552
+ zone_config = ZoneConfig(**zone_config)
1553
+
1554
+ alert_config = kwargs.pop("alert_config", None)
1555
+ if alert_config and isinstance(alert_config, dict):
1556
+ alert_config = AlertConfig(**alert_config)
1557
+
1558
+ # Filter kwargs to only include valid parameters
1559
+ filtered_kwargs = self._filter_kwargs_for_config(IntrusionConfig, kwargs)
1560
+
1561
+ config = IntrusionConfig(
1562
+ category=category or "security",
1563
+ usecase=usecase,
1564
+ zone_config=zone_config,
1565
+ alert_config=alert_config,
1566
+ **filtered_kwargs
1567
+ )
1568
+
1569
+ elif usecase == "proximity_detection":
1570
+ # Handle nested configurations
1571
+ zone_config = kwargs.pop("zone_config", None)
1572
+ if zone_config and isinstance(zone_config, dict):
1573
+ zone_config = ZoneConfig(**zone_config)
1574
+
1575
+ alert_config = kwargs.pop("alert_config", None)
1576
+ if alert_config and isinstance(alert_config, dict):
1577
+ alert_config = AlertConfig(**alert_config)
1578
+
1579
+ # Filter kwargs to only include valid parameters
1580
+ filtered_kwargs = self._filter_kwargs_for_config(ProximityConfig, kwargs)
1581
+
1582
+ config = ProximityConfig(
1583
+ category=category or "security",
1584
+ usecase=usecase,
1585
+ zone_config=zone_config,
1586
+ alert_config=alert_config,
1587
+ **filtered_kwargs
1588
+ )
1589
+
1590
+ elif usecase in ["customer_service", "advanced_customer_service"]:
1591
+ # Handle nested configurations
1592
+ tracking_config = kwargs.pop("tracking_config", None)
1593
+ if tracking_config and isinstance(tracking_config, dict):
1594
+ tracking_config = TrackingConfig(**tracking_config)
1595
+
1596
+ alert_config = kwargs.pop("alert_config", None)
1597
+ if alert_config and isinstance(alert_config, dict):
1598
+ alert_config = AlertConfig(**alert_config)
1599
+
1600
+ # Filter kwargs to only include valid parameters
1601
+ filtered_kwargs = self._filter_kwargs_for_config(CustomerServiceConfig, kwargs)
1602
+
1603
+ config = CustomerServiceConfig(
1604
+ category=category or "sales",
1605
+ usecase=usecase,
1606
+ tracking_config=tracking_config,
1607
+ alert_config=alert_config,
1608
+ **filtered_kwargs
1609
+ )
1610
+ elif usecase == "basic_counting_tracking":
1611
+ # Import here to avoid circular import
1612
+ from ..usecases.basic_counting_tracking import BasicCountingTrackingConfig
1613
+
1614
+ # Handle nested configurations
1615
+ tracking_config = kwargs.pop("tracking_config", None)
1616
+ if tracking_config and isinstance(tracking_config, dict):
1617
+ tracking_config = TrackingConfig(**tracking_config)
1618
+
1619
+ alert_config = kwargs.pop("alert_config", None)
1620
+ if alert_config and isinstance(alert_config, dict):
1621
+ alert_config = AlertConfig(**alert_config)
1622
+
1623
+ # Extract basic counting tracking specific parameters
1624
+ target_categories = kwargs.pop("target_categories", None)
1625
+ zones = kwargs.pop("zones", None)
1626
+ tracking_method = kwargs.pop("tracking_method", "kalman")
1627
+ max_age = kwargs.pop("max_age", 30)
1628
+ min_hits = kwargs.pop("min_hits", 3)
1629
+ count_thresholds = kwargs.pop("count_thresholds", None)
1630
+ zone_thresholds = kwargs.pop("zone_thresholds", None)
1631
+ alert_cooldown = kwargs.pop("alert_cooldown", 60.0)
1632
+ enable_unique_counting = kwargs.pop("enable_unique_counting", True)
1633
+
1634
+ # Filter kwargs to only include valid parameters
1635
+ filtered_kwargs = self._filter_kwargs_for_config(BasicCountingTrackingConfig, kwargs)
1636
+
1637
+ config = BasicCountingTrackingConfig(
1638
+ category=category or "general",
1639
+ usecase=usecase,
1640
+ target_categories=target_categories,
1641
+ zones=zones,
1642
+ tracking_method=tracking_method,
1643
+ max_age=max_age,
1644
+ min_hits=min_hits,
1645
+ count_thresholds=count_thresholds,
1646
+ zone_thresholds=zone_thresholds,
1647
+ alert_cooldown=alert_cooldown,
1648
+ enable_unique_counting=enable_unique_counting,
1649
+ **filtered_kwargs
1650
+ )
1651
+ elif usecase == "license_plate_detection":
1652
+ # Import here to avoid circular import
1653
+ from ..usecases.license_plate_detection import LicensePlateConfig
1654
+
1655
+ # Handle nested configurations
1656
+ alert_config = kwargs.pop("alert_config", None)
1657
+ if alert_config and isinstance(alert_config, dict):
1658
+ alert_config = AlertConfig(**alert_config)
1659
+
1660
+ # Filter kwargs to only include valid parameters
1661
+ filtered_kwargs = self._filter_kwargs_for_config(LicensePlateConfig, kwargs)
1662
+
1663
+ config = LicensePlateConfig(
1664
+ category=category or "vehicle",
1665
+ usecase=usecase,
1666
+ alert_config=alert_config,
1667
+ **filtered_kwargs
1668
+ )
1669
+ elif usecase == "parking_space_detection":
1670
+ # Import here to avoid circular import
1671
+ from ..usecases.parking_space_detection import ParkingSpaceConfig
1672
+
1673
+ # Handle nested configurations
1674
+ alert_config = kwargs.pop("alert_config", None)
1675
+ if alert_config and isinstance(alert_config, dict):
1676
+ alert_config = AlertConfig(**alert_config)
1677
+
1678
+ # Filter kwargs to only include valid parameters
1679
+ filtered_kwargs = self._filter_kwargs_for_config(ParkingSpaceConfig, kwargs)
1680
+
1681
+ config = ParkingSpaceConfig(
1682
+ category=category or "parking_space",
1683
+ usecase=usecase,
1684
+ alert_config=alert_config,
1685
+ **filtered_kwargs
1686
+ )
1687
+ elif usecase == "field_mapping":
1688
+ # Import here to avoid circular import
1689
+ from ..usecases.field_mapping import FieldMappingConfig
1690
+
1691
+ # Handle nested configurations
1692
+ alert_config = kwargs.pop("alert_config", None)
1693
+ if alert_config and isinstance(alert_config, dict):
1694
+ alert_config = AlertConfig(**alert_config)
1695
+
1696
+ # Filter kwargs to only include valid parameters
1697
+ filtered_kwargs = self._filter_kwargs_for_config(FieldMappingConfig, kwargs)
1698
+
1699
+ config = FieldMappingConfig(
1700
+ category=category or "infrastructure",
1701
+ usecase=usecase,
1702
+ alert_config=alert_config,
1703
+ **filtered_kwargs
1704
+ )
1705
+
1706
+ elif usecase == "leaf_disease_detection":
1707
+ # Import here to avoid circular import
1708
+ from ..usecases.leaf_disease import LeafDiseaseDetectionConfig
1709
+
1710
+ # Handle nested configurations
1711
+ alert_config = kwargs.pop("alert_config", None)
1712
+ if alert_config and isinstance(alert_config, dict):
1713
+ alert_config = AlertConfig(**alert_config)
1714
+
1715
+ # Filter kwargs to only include valid parameters
1716
+ filtered_kwargs = self._filter_kwargs_for_config(LeafDiseaseDetectionConfig, kwargs)
1717
+
1718
+ config = LeafDiseaseDetectionConfig(
1719
+ category=category or "agriculture",
1720
+ usecase=usecase,
1721
+ alert_config=alert_config,
1722
+ **kwargs
1723
+ )
1724
+ elif usecase == "mask_detection":
1725
+ # Import here to avoid circular import
1726
+ from ..usecases.mask_detection import MaskDetectionConfig
1727
+
1728
+ # Handle nested configurations
1729
+ alert_config = kwargs.pop("alert_config", None)
1730
+ if alert_config and isinstance(alert_config, dict):
1731
+ alert_config = AlertConfig(**alert_config)
1732
+
1733
+ config = MaskDetectionConfig(
1734
+ category=category or "mask_detection",
1735
+ usecase=usecase,
1736
+ alert_config=alert_config,
1737
+ **kwargs
1738
+ )
1739
+ elif usecase == "pipeline_detection":
1740
+ from ..usecases.pipeline_detection import PipelineDetectionConfig
1741
+
1742
+ alert_config = kwargs.pop("alert_config", None)
1743
+ if alert_config and isinstance(alert_config, dict):
1744
+ alert_config = AlertConfig(**alert_config)
1745
+
1746
+ config = PipelineDetectionConfig(
1747
+ category=category or "pipeline_detection",
1748
+ usecase=usecase,
1749
+ alert_config=alert_config,
1750
+ **kwargs
1751
+ )
1752
+ elif usecase == "shoplifting_detection":
1753
+ # Import here to avoid circular import
1754
+ from ..usecases.shoplifting_detection import ShopliftingDetectionConfig
1755
+
1756
+ # Handle nested configurations
1757
+ alert_config = kwargs.pop("alert_config", None)
1758
+ if alert_config and isinstance(alert_config, dict):
1759
+ alert_config = AlertConfig(**alert_config)
1760
+
1761
+ config = ShopliftingDetectionConfig(
1762
+ category=category or "mask_detection",
1763
+ usecase=usecase,
1764
+ alert_config=alert_config,
1765
+ **kwargs
1766
+ )
1767
+
1768
+ elif usecase == "fire_smoke_detection":
1769
+ # Import here to avoid circular import
1770
+ from ..usecases.fire_detection import FireSmokeConfig
1771
+
1772
+ # Handle nested configurations
1773
+ alert_config = kwargs.pop("alert_config", None)
1774
+ if alert_config and isinstance(alert_config, dict):
1775
+ alert_config = AlertConfig(**alert_config)
1776
+
1777
+ config = FireSmokeConfig(
1778
+ category=category or "normal",
1779
+ usecase=usecase,
1780
+ alert_config=alert_config,
1781
+ **kwargs
1782
+ )
1783
+
1784
+ elif usecase == "solar_panel":
1785
+ # Import here to avoid circular import
1786
+ from ..usecases.solar_panel import SolarPanelConfig
1787
+
1788
+ # Handle nested configurations
1789
+ alert_config = kwargs.pop("alert_config", None)
1790
+ if alert_config and isinstance(alert_config, dict):
1791
+ alert_config = AlertConfig(**alert_config)
1792
+
1793
+ config = SolarPanelConfig(
1794
+ category=category or "energy",
1795
+ usecase=usecase,
1796
+ alert_config=alert_config,
1797
+ **kwargs
1798
+ )
1799
+ elif usecase == "wound_segmentation":
1800
+ # Import here to avoid circular import
1801
+ from ..usecases.wound_segmentation import WoundConfig
1802
+
1803
+ # Handle nested configurations
1804
+ alert_config = kwargs.pop("alert_config", None)
1805
+ if alert_config and isinstance(alert_config, dict):
1806
+ alert_config = AlertConfig(**alert_config)
1807
+
1808
+ config = WoundConfig(
1809
+ category=category or "energy",
1810
+ usecase=usecase,
1811
+ alert_config=alert_config,
1812
+ **kwargs
1813
+ )
1814
+
1815
+ elif usecase == "car_damage_detection":
1816
+ # Import here to avoid circular import
1817
+ from ..usecases.car_damage_detection import CarDamageConfig
1818
+
1819
+ # Handle nested configurations
1820
+ alert_config = kwargs.pop("alert_config", None)
1821
+ if alert_config and isinstance(alert_config, dict):
1822
+ alert_config = AlertConfig(**alert_config)
1823
+
1824
+ config = CarDamageConfig(
1825
+ category=category or "normal",
1826
+ usecase=usecase,
1827
+ alert_config=alert_config,
1828
+ **kwargs
1829
+ )
1830
+
1831
+ elif usecase == "pothole_segmentation":
1832
+ # Import here to avoid circular import
1833
+ from ..usecases.pothole_segmentation import PotholeConfig
1834
+
1835
+ # Handle nested configurations
1836
+ alert_config = kwargs.pop("alert_config", None)
1837
+ if alert_config and isinstance(alert_config, dict):
1838
+ alert_config = AlertConfig(**alert_config)
1839
+
1840
+ config = PotholeConfig(
1841
+ category=category or "normal",
1842
+ usecase=usecase,
1843
+ alert_config=alert_config,
1844
+ **kwargs
1845
+ )
1846
+
1847
+
1848
+ elif usecase == "flare_analysis":
1849
+ # Import here to avoid circular import
1850
+ from ..usecases.flare_analysis import FlareAnalysisConfig
1851
+
1852
+ # Handle nested configurations
1853
+ alert_config = kwargs.pop("alert_config", None)
1854
+ if alert_config and isinstance(alert_config, dict):
1855
+ alert_config = AlertConfig(**alert_config)
1856
+
1857
+ config = FlareAnalysisConfig(
1858
+ category=category or "normal",
1859
+ usecase=usecase,
1860
+ alert_config=alert_config,
1861
+ **kwargs
1862
+ )
1863
+
1864
+ elif usecase == "chicken_pose_detection":
1865
+ # Import here to avoid circular import
1866
+ from ..usecases.chicken_pose_detection import ChickenPoseDetectionConfig
1867
+
1868
+ # Handle nested configurations
1869
+ alert_config = kwargs.pop("alert_config", None)
1870
+ if alert_config and isinstance(alert_config, dict):
1871
+ alert_config = AlertConfig(**alert_config)
1872
+
1873
+ config = ChickenPoseDetectionConfig(
1874
+ category=category or "agriculture",
1875
+ usecase=usecase,
1876
+ alert_config=alert_config,
1877
+ **kwargs
1878
+ )
1879
+
1880
+ elif usecase == "fruit_monitoring":
1881
+ # Import here to avoid circular import
1882
+ from ..usecases.banana_defect_detection import BananaMonitoringConfig
1883
+
1884
+ # Handle nested configurations
1885
+ alert_config = kwargs.pop("alert_config", None)
1886
+ if alert_config and isinstance(alert_config, dict):
1887
+ alert_config = AlertConfig(**alert_config)
1888
+
1889
+ config = BananaMonitoringConfig(
1890
+ category=category or "agriculture",
1891
+ usecase=usecase,
1892
+ alert_config=alert_config,
1893
+ **kwargs
1894
+ )
1895
+ elif usecase == "abandoned_object_detection":
1896
+ # Import here to avoid circular import
1897
+ from ..usecases.abandoned_object_detection import AbandonedObjectConfig
1898
+
1899
+ # Handle nested configurations
1900
+ alert_config = kwargs.pop("alert_config", None)
1901
+ if alert_config and isinstance(alert_config, dict):
1902
+ alert_config = AlertConfig(**alert_config)
1903
+
1904
+ config = AbandonedObjectConfig(
1905
+ category=category or "security",
1906
+ usecase=usecase,
1907
+ alert_config=alert_config,
1908
+ **kwargs
1909
+ )
1910
+
1911
+ elif usecase == "lane_detection":
1912
+ # Import here to avoid circular import
1913
+ from ..usecases.road_lane_detection import LaneDetectionConfig
1914
+
1915
+ # Handle nested configurations
1916
+ alert_config = kwargs.pop("alert_config", None)
1917
+ if alert_config and isinstance(alert_config, dict):
1918
+ alert_config = AlertConfig(**alert_config)
1919
+
1920
+ config = LaneDetectionConfig(
1921
+ category=category or "traffic",
1922
+ usecase=usecase,
1923
+ alert_config=alert_config,
1924
+ **kwargs
1925
+ )
1926
+
1927
+ elif usecase == "shelf_inventory":
1928
+ # Import here to avoid circular import
1929
+ from ..usecases.shelf_inventory_detection import ShelfInventoryConfig
1930
+
1931
+ # Handle nested configurations
1932
+ alert_config = kwargs.pop("alert_config", None)
1933
+ if alert_config and isinstance(alert_config, dict):
1934
+ alert_config = AlertConfig(**alert_config)
1935
+
1936
+ config = ShelfInventoryConfig(
1937
+ category=category or "retail",
1938
+ usecase=usecase,
1939
+ alert_config=alert_config,
1940
+ **kwargs
1941
+ )
1942
+
1943
+ elif usecase == "anti_spoofing_detection":
1944
+ # Import here to avoid circular import
1945
+ from ..usecases.anti_spoofing_detection import AntiSpoofingDetectionConfig
1946
+
1947
+ # Handle nested configurations
1948
+ alert_config = kwargs.pop("alert_config", None)
1949
+ if alert_config and isinstance(alert_config, dict):
1950
+ alert_config = AlertConfig(**alert_config)
1951
+
1952
+ config = AntiSpoofingDetectionConfig(
1953
+ category=category or "security",
1954
+ usecase=usecase,
1955
+ alert_config=alert_config,
1956
+ **kwargs
1957
+ )
1958
+
1959
+ elif usecase == "theft_detection":
1960
+ # Import here to avoid circular import
1961
+ from ..usecases.theft_detection import TheftDetectionConfig
1962
+
1963
+ # Handle nested configurations
1964
+ alert_config = kwargs.pop("alert_config", None)
1965
+ if alert_config and isinstance(alert_config, dict):
1966
+ alert_config = AlertConfig(**alert_config)
1967
+
1968
+ config = TheftDetectionConfig(
1969
+ category=category or "security",
1970
+ usecase=usecase,
1971
+ alert_config=alert_config,
1972
+ **kwargs
1973
+ )
1974
+
1975
+ elif usecase == "weapon_detection":
1976
+ # Import here to avoid circular import
1977
+ from ..usecases.weapon_detection import WeaponDetectionConfig
1978
+
1979
+ # Handle nested configurations
1980
+ alert_config = kwargs.pop("alert_config", None)
1981
+ if alert_config and isinstance(alert_config, dict):
1982
+ alert_config = AlertConfig(**alert_config)
1983
+
1984
+ config = WeaponDetectionConfig(
1985
+ category=category or "security",
1986
+ usecase=usecase,
1987
+ alert_config=alert_config,
1988
+ **kwargs
1989
+ )
1990
+
1991
+ elif usecase == "traffic_sign_monitoring":
1992
+ # Import here to avoid circular import
1993
+ from ..usecases.traffic_sign_monitoring import TrafficSignMonitoringConfig
1994
+
1995
+ # Handle nested configurations
1996
+ alert_config = kwargs.pop("alert_config", None)
1997
+ if alert_config and isinstance(alert_config, dict):
1998
+ alert_config = AlertConfig(**alert_config)
1999
+
2000
+ config = TrafficSignMonitoringConfig(
2001
+ category=category or "traffic",
2002
+ usecase=usecase,
2003
+ alert_config=alert_config,
2004
+ **kwargs
2005
+ )
2006
+
2007
+ elif usecase == "vehicle_monitoring":
2008
+ # Import here to avoid circular import
2009
+ from ..usecases.vehicle_monitoring import VehicleMonitoringConfig
2010
+
2011
+ # Handle nested configurations
2012
+ alert_config = kwargs.pop("alert_config", None)
2013
+ if alert_config and isinstance(alert_config, dict):
2014
+ alert_config = AlertConfig(**alert_config)
2015
+
2016
+ config = VehicleMonitoringConfig(
2017
+ category=category or "traffic",
2018
+ usecase=usecase,
2019
+ alert_config=alert_config,
2020
+ **kwargs
2021
+ )
2022
+
2023
+ elif usecase == "drone_traffic_monitoring":
2024
+ # Import here to avoid circular import
2025
+ from ..usecases.drone_traffic_monitoring import VehiclePeopleDroneMonitoringConfig
2026
+
2027
+ # Handle nested configurations
2028
+ alert_config = kwargs.pop("alert_config", None)
2029
+ if alert_config and isinstance(alert_config, dict):
2030
+ alert_config = AlertConfig(**alert_config)
2031
+
2032
+ config = VehiclePeopleDroneMonitoringConfig(
2033
+ category=category or "traffic",
2034
+ usecase=usecase,
2035
+ alert_config=alert_config,
2036
+ **kwargs
2037
+ )
2038
+
2039
+ elif usecase == "ppe_compliance_detection":
2040
+ # Import here to avoid circular import
2041
+ from ..usecases.ppe_compliance import PPEComplianceConfig
2042
+ # Handle nested configurations
2043
+ alert_config = kwargs.pop("alert_config", None)
2044
+ if alert_config and isinstance(alert_config, dict):
2045
+ alert_config = AlertConfig(**alert_config)
2046
+ config = PPEComplianceConfig(
2047
+ category=category or "ppe",
2048
+ usecase=usecase,
2049
+ alert_config=alert_config,
2050
+ **kwargs
2051
+ )
2052
+ elif usecase == "color_detection":
2053
+ # Import here to avoid circular import
2054
+ from ..usecases.color_detection import ColorDetectionConfig
2055
+
2056
+ # Handle nested configurations
2057
+ alert_config = kwargs.pop("alert_config", None)
2058
+ if alert_config and isinstance(alert_config, dict):
2059
+ alert_config = AlertConfig(**alert_config)
2060
+
2061
+ # Filter kwargs to only include valid parameters
2062
+ filtered_kwargs = self._filter_kwargs_for_config(ColorDetectionConfig, kwargs)
2063
+
2064
+ config = ColorDetectionConfig(
2065
+ category=category or "visual_appearance",
2066
+ usecase=usecase,
2067
+ alert_config=alert_config,
2068
+ **filtered_kwargs
2069
+ )
2070
+ elif usecase == "video_color_classification":
2071
+ # Alias for color_detection - Import here to avoid circular import
2072
+ from ..usecases.color_detection import ColorDetectionConfig
2073
+
2074
+ # Handle nested configurations
2075
+ alert_config = kwargs.pop("alert_config", None)
2076
+ if alert_config and isinstance(alert_config, dict):
2077
+ alert_config = AlertConfig(**alert_config)
2078
+
2079
+ # Filter kwargs to only include valid parameters
2080
+ filtered_kwargs = self._filter_kwargs_for_config(ColorDetectionConfig, kwargs)
2081
+
2082
+ config = ColorDetectionConfig(
2083
+ category=category or "visual_appearance",
2084
+ usecase="color_detection", # Use canonical name internally
2085
+ alert_config=alert_config,
2086
+ **filtered_kwargs
2087
+ )
2088
+ elif usecase == "ppe_compliance_detection":
2089
+ # Import here to avoid circular import
2090
+ from ..usecases.ppe_compliance import PPEComplianceConfig
2091
+ # Handle nested configurations
2092
+ alert_config = kwargs.pop("alert_config", None)
2093
+ if alert_config and isinstance(alert_config, dict):
2094
+ alert_config = AlertConfig(**alert_config)
2095
+ config = PPEComplianceConfig(
2096
+ category=category or "ppe",
2097
+ usecase=usecase,
2098
+ alert_config=alert_config,
2099
+ **kwargs
2100
+ )
2101
+ elif usecase == "face_emotion":
2102
+ # Import here to avoid circular import
2103
+ from ..usecases.face_emotion import FaceEmotionConfig
2104
+
2105
+ # Handle nested configurations
2106
+ alert_config = kwargs.pop("alert_config", None)
2107
+ if alert_config and isinstance(alert_config, dict):
2108
+ alert_config = AlertConfig(**alert_config)
2109
+
2110
+ config = FaceEmotionConfig(
2111
+ category=category or "general",
2112
+ usecase=usecase,
2113
+ alert_config=alert_config,
2114
+ **kwargs
2115
+ )
2116
+
2117
+ elif usecase == "pedestrian_detection":
2118
+ # Import here to avoid circular import
2119
+ from ..usecases.pedestrian_detection import PedestrianDetectionConfig
2120
+
2121
+ # Handle nested configurations
2122
+ alert_config = kwargs.pop("alert_config", None)
2123
+ if alert_config and isinstance(alert_config, dict):
2124
+ alert_config = AlertConfig(**alert_config)
2125
+ config = PedestrianDetectionConfig(
2126
+ category=category or "pedestrian",
2127
+ usecase=usecase,
2128
+ alert_config=alert_config,
2129
+ **kwargs
2130
+ )
2131
+
2132
+
2133
+ elif usecase == "underwater_pollution_detection":
2134
+ # Import here to avoid circular import
2135
+ from ..usecases.underwater_pollution_detection import UnderwaterPlasticConfig
2136
+ alert_config = kwargs.pop("alert_config", None)
2137
+ if alert_config and isinstance(alert_config, dict):
2138
+ alert_config = AlertConfig(**alert_config)
2139
+ config = UnderwaterPlasticConfig(
2140
+ category=category or "pollution",
2141
+ usecase=usecase,
2142
+ alert_config=alert_config,
2143
+ **kwargs
2144
+ )
2145
+ elif usecase == "weld_defect_detection":
2146
+ # Import here to avoid circular import
2147
+ from ..usecases.weld_defect_detection import WeldDefectConfig
2148
+ alert_config = kwargs.pop("alert_config", None)
2149
+ if alert_config and isinstance(alert_config, dict):
2150
+ alert_config = AlertConfig(**alert_config)
2151
+ config = WeldDefectConfig(
2152
+ category=category or "weld",
2153
+ usecase=usecase,
2154
+ alert_config=alert_config,
2155
+ **kwargs
2156
+ )
2157
+
2158
+ elif usecase == "age_detection":
2159
+ # Import here to avoid circular import
2160
+ from ..usecases.age_detection import AgeDetectionConfig
2161
+
2162
+ # Handle nested configurations
2163
+ alert_config = kwargs.pop("alert_config", None)
2164
+ if alert_config and isinstance(alert_config, dict):
2165
+ alert_config = AlertConfig(**alert_config)
2166
+
2167
+ config = AgeDetectionConfig(
2168
+ category=category or "general",
2169
+ usecase=usecase,
2170
+ alert_config=alert_config,
2171
+ **kwargs
2172
+ )
2173
+
2174
+ elif usecase == "price_tag_detection":
2175
+ # Import here to avoid circular import
2176
+ from ..usecases.price_tag_detection import PriceTagConfig
2177
+
2178
+ # Handle nested configurations
2179
+ alert_config = kwargs.pop("alert_config", None)
2180
+ if alert_config and isinstance(alert_config, dict):
2181
+ alert_config = AlertConfig(**alert_config)
2182
+
2183
+ config = PriceTagConfig(
2184
+ category=category or "retail",
2185
+ usecase=usecase,
2186
+ alert_config=alert_config,
2187
+ **kwargs
2188
+ )
2189
+ elif usecase == "distracted_driver_detection":
2190
+ # Import here to avoid circular import
2191
+ from ..usecases.distracted_driver_detection import DistractedDriverConfig
2192
+
2193
+ # Handle nested configurations
2194
+ alert_config = kwargs.pop("alert_config", None)
2195
+ if alert_config and isinstance(alert_config, dict):
2196
+ alert_config = AlertConfig(**alert_config)
2197
+
2198
+ config = DistractedDriverConfig(
2199
+ category=category or "automobile",
2200
+ usecase=usecase,
2201
+ alert_config=alert_config,
2202
+ **kwargs
2203
+ )
2204
+
2205
+ elif usecase == "emergency_vehicle_detection":
2206
+ # Import here to avoid circular import
2207
+ from ..usecases.emergency_vehicle_detection import EmergencyVehicleConfig
2208
+
2209
+ # Handle nested configurations
2210
+ alert_config = kwargs.pop("alert_config", None)
2211
+ if alert_config and isinstance(alert_config, dict):
2212
+ alert_config = AlertConfig(**alert_config)
2213
+
2214
+ config = EmergencyVehicleConfig(
2215
+ category=category or "traffic",
2216
+ usecase=usecase,
2217
+ alert_config=alert_config,
2218
+ **kwargs
2219
+ )
2220
+
2221
+ elif usecase == "crop_weed_detection":
2222
+ # Import here to avoid circular import
2223
+ from ..usecases.crop_weed_detection import CropWeedDetectionConfig
2224
+
2225
+ # Handle nested configurations
2226
+ alert_config = kwargs.pop("alert_config", None)
2227
+ if alert_config and isinstance(alert_config, dict):
2228
+ alert_config = AlertConfig(**alert_config)
2229
+
2230
+ config = CropWeedDetectionConfig(
2231
+ category=category or "agriculture",
2232
+ usecase=usecase,
2233
+ alert_config=alert_config,
2234
+ **kwargs
2235
+ )
2236
+
2237
+ elif usecase == "child_monitoring":
2238
+ # Import here to avoid circular import
2239
+ from ..usecases.child_monitoring import ChildMonitoringConfig
2240
+
2241
+ # Handle nested configurations
2242
+ alert_config = kwargs.pop("alert_config", None)
2243
+ if alert_config and isinstance(alert_config, dict):
2244
+ alert_config = AlertConfig(**alert_config)
2245
+
2246
+ config = ChildMonitoringConfig(
2247
+ category=category or "security",
2248
+ usecase=usecase,
2249
+ alert_config=alert_config,
2250
+ **kwargs
2251
+ )
2252
+
2253
+ elif usecase == "gender_detection":
2254
+ # Import here to avoid circular import
2255
+ from ..usecases.gender_detection import GenderDetectionConfig
2256
+
2257
+ # Handle nested configurations
2258
+ alert_config = kwargs.pop("alert_config", None)
2259
+ if alert_config and isinstance(alert_config, dict):
2260
+ alert_config = AlertConfig(**alert_config)
2261
+
2262
+ config = GenderDetectionConfig(
2263
+ category=category or "general",
2264
+ usecase=usecase,
2265
+ alert_config=alert_config,
2266
+ **kwargs
2267
+ )
2268
+
2269
+ elif usecase == "concrete_crack_detection":
2270
+ # Import here to avoid circular import
2271
+ from ..usecases.concrete_crack_detection import ConcreteCrackConfig
2272
+
2273
+ # Handle nested configurations
2274
+ alert_config = kwargs.pop("alert_config", None)
2275
+ if alert_config and isinstance(alert_config, dict):
2276
+ alert_config = AlertConfig(**alert_config)
2277
+
2278
+ config = ConcreteCrackConfig(
2279
+ category=category or "general",
2280
+ usecase=usecase,
2281
+ alert_config=alert_config,
2282
+ **kwargs
2283
+ )
2284
+
2285
+ elif usecase == "fashion_detection":
2286
+ # Import here to avoid circular import
2287
+ from ..usecases.fashion_detection import FashionDetectionConfig
2288
+
2289
+ # Handle nested configurations
2290
+ alert_config = kwargs.pop("alert_config", None)
2291
+ if alert_config and isinstance(alert_config, dict):
2292
+ alert_config = AlertConfig(**alert_config)
2293
+
2294
+ config = FashionDetectionConfig(
2295
+ category=category or "retail",
2296
+ usecase=usecase,
2297
+ alert_config=alert_config,
2298
+ **kwargs
2299
+ )
2300
+
2301
+ elif usecase == "warehouse_object_segmentation":
2302
+ # Import here to avoid circular import
2303
+ from ..usecases.warehouse_object_segmentation import WarehouseObjectConfig
2304
+
2305
+ # Handle nested configurations
2306
+ alert_config = kwargs.pop("alert_config", None)
2307
+ if alert_config and isinstance(alert_config, dict):
2308
+ alert_config = AlertConfig(**alert_config)
2309
+
2310
+ config = WarehouseObjectConfig(
2311
+ category=category or "retail",
2312
+ usecase=usecase,
2313
+ alert_config=alert_config,
2314
+ **kwargs
2315
+ )
2316
+
2317
+ elif usecase == "shopping_cart_analysis":
2318
+ # Import here to avoid circular import
2319
+ from ..usecases.shopping_cart_analysis import ShoppingCartConfig
2320
+
2321
+ # Handle nested configurations
2322
+ alert_config = kwargs.pop("alert_config", None)
2323
+ if alert_config and isinstance(alert_config, dict):
2324
+ alert_config = AlertConfig(**alert_config)
2325
+
2326
+ config = ShoppingCartConfig(
2327
+ category=category or "retail",
2328
+ usecase=usecase,
2329
+ alert_config=alert_config,
2330
+ **kwargs
2331
+ )
2332
+
2333
+ elif usecase == "defect_detection_products":
2334
+ # Import here to avoid circular import
2335
+ from ..usecases.defect_detection_products import BottleDefectConfig
2336
+
2337
+ # Handle nested configurations
2338
+ alert_config = kwargs.pop("alert_config", None)
2339
+ if alert_config and isinstance(alert_config, dict):
2340
+ alert_config = AlertConfig(**alert_config)
2341
+
2342
+ config = BottleDefectConfig(
2343
+ category=category or "retail",
2344
+ usecase=usecase,
2345
+ alert_config=alert_config,
2346
+ **kwargs
2347
+ )
2348
+
2349
+ elif usecase == "assembly_line_detection":
2350
+ # Import here to avoid circular import
2351
+ from ..usecases.assembly_line_detection import AssemblyLineConfig
2352
+
2353
+ # Handle nested configurations
2354
+ alert_config = kwargs.pop("alert_config", None)
2355
+ if alert_config and isinstance(alert_config, dict):
2356
+ alert_config = AlertConfig(**alert_config)
2357
+
2358
+ config = AssemblyLineConfig(
2359
+ category=category or "manufacturing",
2360
+ usecase=usecase,
2361
+ alert_config=alert_config,
2362
+ **kwargs
2363
+ )
2364
+
2365
+ elif usecase == "car_part_segmentation":
2366
+ # Import here to avoid circular import
2367
+ from ..usecases.car_part_segmentation import CarPartSegmentationConfig
2368
+
2369
+ # Handle nested configurations
2370
+ alert_config = kwargs.pop("alert_config", None)
2371
+ if alert_config and isinstance(alert_config, dict):
2372
+ alert_config = AlertConfig(**alert_config)
2373
+
2374
+ config = CarPartSegmentationConfig(
2375
+ category=category or "automobile",
2376
+ usecase=usecase,
2377
+ alert_config=alert_config,
2378
+ **kwargs
2379
+ )
2380
+
2381
+ elif usecase == "windmill_maintenance":
2382
+ # Import here to avoid circular import
2383
+ from ..usecases.windmill_maintenance import WindmillMaintenanceConfig
2384
+
2385
+ # Handle nested configurations
2386
+ alert_config = kwargs.pop("alert_config", None)
2387
+ if alert_config and isinstance(alert_config, dict):
2388
+ alert_config = AlertConfig(**alert_config)
2389
+
2390
+ config = WindmillMaintenanceConfig(
2391
+ category=category or "manufacturing",
2392
+ usecase=usecase,
2393
+ alert_config=alert_config,
2394
+ **kwargs
2395
+ )
2396
+
2397
+ elif usecase == "flower_segmentation":
2398
+ # Import here to avoid circular import
2399
+ from ..usecases.flower_segmentation import FlowerConfig
2400
+
2401
+ # Handle nested configurations
2402
+ alert_config = kwargs.pop("alert_config", None)
2403
+ if alert_config and isinstance(alert_config, dict):
2404
+ alert_config = AlertConfig(**alert_config)
2405
+
2406
+ config = FlowerConfig(
2407
+ category=category or "agriculture",
2408
+ usecase=usecase,
2409
+ alert_config=alert_config,
2410
+ **kwargs
2411
+ )
2412
+
2413
+ elif usecase == "smoker_detection":
2414
+ # Import here to avoid circular import
2415
+ from ..usecases.smoker_detection import SmokerDetectionConfig
2416
+
2417
+ # Handle nested configurations
2418
+ alert_config = kwargs.pop("alert_config", None)
2419
+ if alert_config and isinstance(alert_config, dict):
2420
+ alert_config = AlertConfig(**alert_config)
2421
+
2422
+ config = SmokerDetectionConfig(
2423
+ category=category or "general",
2424
+ usecase=usecase,
2425
+ alert_config=alert_config,
2426
+ **kwargs
2427
+ )
2428
+
2429
+ elif usecase == "road_traffic_density":
2430
+ # Import here to avoid circular import
2431
+ from ..usecases.road_traffic_density import RoadTrafficConfig
2432
+
2433
+ # Handle nested configurations
2434
+ alert_config = kwargs.pop("alert_config", None)
2435
+ if alert_config and isinstance(alert_config, dict):
2436
+ alert_config = AlertConfig(**alert_config)
2437
+
2438
+ config = RoadTrafficConfig(
2439
+ category=category or "automobile",
2440
+ usecase=usecase,
2441
+ alert_config=alert_config,
2442
+ **kwargs
2443
+ )
2444
+
2445
+ elif usecase == "road_view_segmentation":
2446
+ # Import here to avoid circular import
2447
+ from ..usecases.road_view_segmentation import RoadViewSegmentationConfig
2448
+
2449
+ # Handle nested configurations
2450
+ alert_config = kwargs.pop("alert_config", None)
2451
+ if alert_config and isinstance(alert_config, dict):
2452
+ alert_config = AlertConfig(**alert_config)
2453
+
2454
+ config = RoadViewSegmentationConfig(
2455
+ category=category or "automobile",
2456
+ usecase=usecase,
2457
+ alert_config=alert_config,
2458
+ **kwargs
2459
+ )
2460
+
2461
+ elif usecase == "face_recognition":
2462
+ # Import here to avoid circular import
2463
+ from ..face_reg.face_recognition import FaceRecognitionEmbeddingConfig
2464
+
2465
+ # Handle nested configurations
2466
+ alert_config = kwargs.pop("alert_config", None)
2467
+ if alert_config and isinstance(alert_config, dict):
2468
+ alert_config = AlertConfig(**alert_config)
2469
+
2470
+ config = FaceRecognitionEmbeddingConfig(
2471
+ category=category or "security",
2472
+ usecase=usecase,
2473
+ alert_config=alert_config,
2474
+ **kwargs
2475
+ )
2476
+ return config
2477
+ elif usecase == "drowsy_driver_detection":
2478
+ # Import here to avoid circular import
2479
+ from ..usecases.drowsy_driver_detection import DrowsyDriverConfig
2480
+
2481
+ # Handle nested configurations
2482
+ alert_config = kwargs.pop("alert_config", None)
2483
+ if alert_config and isinstance(alert_config, dict):
2484
+ alert_config = AlertConfig(**alert_config)
2485
+
2486
+ config = DrowsyDriverConfig(
2487
+ category=category or "automobile",
2488
+ usecase=usecase,
2489
+ alert_config=alert_config,
2490
+ **kwargs
2491
+ )
2492
+
2493
+ elif usecase == "waterbody_segmentation":
2494
+ # Import here to avoid circular import
2495
+ from ..usecases.waterbody_segmentation import WaterBodyConfig
2496
+
2497
+ # Handle nested configurations
2498
+ alert_config = kwargs.pop("alert_config", None)
2499
+ if alert_config and isinstance(alert_config, dict):
2500
+ alert_config = AlertConfig(**alert_config)
2501
+
2502
+ config = WaterBodyConfig(
2503
+ category=category or "agriculture",
2504
+ usecase=usecase,
2505
+ alert_config=alert_config,
2506
+ **kwargs
2507
+ )
2508
+
2509
+ elif usecase == "litter_detection":
2510
+ # Import here to avoid circular import
2511
+ from ..usecases.litter_monitoring import LitterDetectionConfig
2512
+
2513
+ # Handle nested configurations
2514
+ alert_config = kwargs.pop("alert_config", None)
2515
+ if alert_config and isinstance(alert_config, dict):
2516
+ alert_config = AlertConfig(**alert_config)
2517
+
2518
+ config = LitterDetectionConfig(
2519
+ category=category or "litter_detection",
2520
+ usecase=usecase,
2521
+ alert_config=alert_config,
2522
+ **kwargs
2523
+ )
2524
+
2525
+ elif usecase == "leak_detection":
2526
+ # Import here to avoid circular import
2527
+ from ..usecases.leak_detection import LeakDetectionConfig
2528
+
2529
+ # Handle nested configurations
2530
+ alert_config = kwargs.pop("alert_config", None)
2531
+ if alert_config and isinstance(alert_config, dict):
2532
+ alert_config = AlertConfig(**alert_config)
2533
+
2534
+ config = LeakDetectionConfig(
2535
+ category=category or "oil_gas",
2536
+ usecase=usecase,
2537
+ alert_config=alert_config,
2538
+ **kwargs
2539
+ )
2540
+
2541
+ elif usecase == "human_activity_recognition":
2542
+ # Import here to avoid circular import
2543
+ from ..usecases.human_activity_recognition import HumanActivityConfig
2544
+
2545
+ alert_config = kwargs.pop("alert_config", None)
2546
+ if alert_config and isinstance(alert_config, dict):
2547
+ alert_config = AlertConfig(**alert_config)
2548
+
2549
+ config = HumanActivityConfig(
2550
+ category=category or "general",
2551
+ usecase=usecase,
2552
+ alert_config=alert_config,
2553
+ **kwargs
2554
+ )
2555
+
2556
+ elif usecase == "gas_leak_detection":
2557
+ # Import here to avoid circular import
2558
+ from ..usecases.gas_leak_detection import GasLeakDetectionConfig
2559
+
2560
+ # Handle nested configurations
2561
+ alert_config = kwargs.pop("alert_config", None)
2562
+ if alert_config and isinstance(alert_config, dict):
2563
+ alert_config = AlertConfig(**alert_config)
2564
+
2565
+ config = GasLeakDetectionConfig(
2566
+ category=category or "oil_gas",
2567
+ usecase=usecase,
2568
+ alert_config=alert_config,
2569
+ **kwargs
2570
+ )
2571
+
2572
+ elif usecase == "license_plate_monitor":
2573
+ # Import here to avoid circular import
2574
+ from ..usecases.license_plate_monitoring import LicensePlateMonitorConfig
2575
+
2576
+ # Handle nested configurations
2577
+ alert_config = kwargs.pop("alert_config", None)
2578
+ if alert_config and isinstance(alert_config, dict):
2579
+ alert_config = AlertConfig(**alert_config)
2580
+
2581
+ # Filter kwargs to only include valid parameters
2582
+ filtered_kwargs = self._filter_kwargs_for_config(LicensePlateMonitorConfig, kwargs)
2583
+
2584
+ config = LicensePlateMonitorConfig(
2585
+ category=category or "license_plate_monitor",
2586
+ usecase=usecase,
2587
+ alert_config=alert_config,
2588
+ **filtered_kwargs
2589
+ )
2590
+
2591
+ elif usecase == "dwell":
2592
+ # Import here to avoid circular import
2593
+ from ..usecases.dwell_detection import DwellConfig
2594
+
2595
+ # Handle nested configurations
2596
+ alert_config = kwargs.pop("alert_config", None)
2597
+ if alert_config and isinstance(alert_config, dict):
2598
+ alert_config = AlertConfig(**alert_config)
2599
+
2600
+ config = DwellConfig(
2601
+ category=category or "general",
2602
+ usecase=usecase,
2603
+ alert_config=alert_config,
2604
+ **kwargs
2605
+ )
2606
+
2607
+ elif usecase == "age_gender_detection":
2608
+ # Import here to avoid circular import
2609
+ from ..usecases.age_gender_detection import AgeGenderConfig
2610
+
2611
+ # Handle nested configurations
2612
+ alert_config = kwargs.pop("alert_config", None)
2613
+ if alert_config and isinstance(alert_config, dict):
2614
+ alert_config = AlertConfig(**alert_config)
2615
+
2616
+ config = AgeGenderConfig(
2617
+ category=category or "age_gender_detection",
2618
+ usecase=usecase,
2619
+ alert_config=alert_config,
2620
+ **kwargs
2621
+ )
2622
+
2623
+ elif usecase == "wildlife_monitoring":
2624
+ # Import here to avoid circular import
2625
+ from ..usecases.wildlife_monitoring import WildLifeMonitoringConfig
2626
+
2627
+ # Handle nested configurations
2628
+ alert_config = kwargs.pop("alert_config", None)
2629
+ if alert_config and isinstance(alert_config, dict):
2630
+ alert_config = AlertConfig(**alert_config)
2631
+
2632
+ config = WildLifeMonitoringConfig(
2633
+ category=category or "environmental",
2634
+ usecase=usecase,
2635
+ alert_config=alert_config,
2636
+ **kwargs
2637
+ )
2638
+
2639
+ elif usecase == "pcb_defect_detection":
2640
+ # Import here to avoid circular import
2641
+ from ..usecases.pcb_defect_detection import PCBDefectConfig
2642
+
2643
+ # Handle nested configurations
2644
+ alert_config = kwargs.pop("alert_config", None)
2645
+ if alert_config and isinstance(alert_config, dict):
2646
+ alert_config = AlertConfig(**alert_config)
2647
+
2648
+ config = PCBDefectConfig(
2649
+ category=category or "manufacturing",
2650
+ usecase=usecase,
2651
+ alert_config=alert_config,
2652
+ **kwargs
2653
+ )
2654
+
2655
+ elif usecase == "suspicious_activity_detection":
2656
+ # Import here to avoid circular import
2657
+ from ..usecases.suspicious_activity_detection import SusActivityConfig
2658
+
2659
+ # Handle nested configurations
2660
+ alert_config = kwargs.pop("alert_config", None)
2661
+ if alert_config and isinstance(alert_config, dict):
2662
+ alert_config = AlertConfig(**alert_config)
2663
+
2664
+ config = SusActivityConfig(
2665
+ category=category or "security",
2666
+ usecase=usecase,
2667
+ alert_config=alert_config,
2668
+ **kwargs
2669
+ )
2670
+
2671
+ elif usecase == "natural_disaster_detection":
2672
+ # Import here to avoid circular import
2673
+ from ..usecases.natural_disaster import NaturalDisasterConfig
2674
+
2675
+ # Handle nested configurations
2676
+ alert_config = kwargs.pop("alert_config", None)
2677
+ if alert_config and isinstance(alert_config, dict):
2678
+ alert_config = AlertConfig(**alert_config)
2679
+
2680
+ config = NaturalDisasterConfig(
2681
+ category=category or "environmental",
2682
+ usecase=usecase,
2683
+ alert_config=alert_config,
2684
+ **kwargs
2685
+ )
2686
+
2687
+ #Add IMAGE based usecases here::
2688
+ elif usecase == "blood_cancer_detection_img":
2689
+ # Import here to avoid circular import
2690
+ from ..usecases.blood_cancer_detection_img import BloodCancerDetectionConfig
2691
+
2692
+ # Handle nested configurations
2693
+ alert_config = kwargs.pop("alert_config", None)
2694
+ if alert_config and isinstance(alert_config, dict):
2695
+ alert_config = AlertConfig(**alert_config)
2696
+
2697
+ config = BloodCancerDetectionConfig(
2698
+ category=category or "healthcare",
2699
+ usecase=usecase,
2700
+ alert_config=alert_config,
2701
+ **kwargs
2702
+ )
2703
+ elif usecase == "skin_cancer_classification_img":
2704
+ # Import here to avoid circular import
2705
+ from ..usecases.skin_cancer_classification_img import SkinCancerClassificationConfig
2706
+
2707
+ # Handle nested configurations
2708
+ alert_config = kwargs.pop("alert_config", None)
2709
+ if alert_config and isinstance(alert_config, dict):
2710
+ alert_config = AlertConfig(**alert_config)
2711
+
2712
+ config = SkinCancerClassificationConfig(
2713
+ category=category or "healthcare",
2714
+ usecase=usecase,
2715
+ alert_config=alert_config,
2716
+ **kwargs
2717
+ )
2718
+ elif usecase == "plaque_segmentation_img":
2719
+ # Import here to avoid circular import
2720
+ from ..usecases.plaque_segmentation_img import PlaqueSegmentationConfig
2721
+
2722
+ # Handle nested configurations
2723
+ alert_config = kwargs.pop("alert_config", None)
2724
+ if alert_config and isinstance(alert_config, dict):
2725
+ alert_config = AlertConfig(**alert_config)
2726
+
2727
+ config = PlaqueSegmentationConfig(
2728
+ category=category or "healthcare",
2729
+ usecase=usecase,
2730
+ alert_config=alert_config,
2731
+ **kwargs
2732
+ )
2733
+ elif usecase == "cardiomegaly_classification":
2734
+ # Import here to avoid circular import
2735
+ from ..usecases.cardiomegaly_classification import CardiomegalyConfig
2736
+
2737
+ # Handle nested configurations
2738
+ alert_config = kwargs.pop("alert_config", None)
2739
+ if alert_config and isinstance(alert_config, dict):
2740
+ alert_config = AlertConfig(**alert_config)
2741
+
2742
+ config = CardiomegalyConfig(
2743
+ category=category or "healthcare",
2744
+ usecase=usecase,
2745
+ alert_config=alert_config,
2746
+ **kwargs
2747
+ )
2748
+ elif usecase == "histopathological_cancer_detection":
2749
+ # Import here to avoid circular import
2750
+ from ..usecases.Histopathological_Cancer_Detection_img import HistopathologicalCancerDetectionConfig
2751
+
2752
+ # Handle nested configurations
2753
+ alert_config = kwargs.pop("alert_config", None)
2754
+ if alert_config and isinstance(alert_config, dict):
2755
+ alert_config = AlertConfig(**alert_config)
2756
+
2757
+ config = HistopathologicalCancerDetectionConfig(
2758
+ category=category or "healthcare",
2759
+ usecase=usecase,
2760
+ alert_config=alert_config,
2761
+ **kwargs
2762
+ )
2763
+ elif usecase == "cell_microscopy_segmentation":
2764
+ # Import here to avoid circular import
2765
+ from ..usecases.cell_microscopy_segmentation import CellMicroscopyConfig
2766
+
2767
+ # Handle nested configurations
2768
+ alert_config = kwargs.pop("alert_config", None)
2769
+ if alert_config and isinstance(alert_config, dict):
2770
+ alert_config = AlertConfig(**alert_config)
2771
+
2772
+ config = CellMicroscopyConfig(
2773
+ category=category or "healthcare",
2774
+ usecase=usecase,
2775
+ alert_config=alert_config,
2776
+ **kwargs
2777
+ )
2778
+
2779
+
2780
+ elif usecase == "underground_pipeline_defect":
2781
+ # Import here to avoid circular import
2782
+ from ..usecases.underground_pipeline_defect_detection import UndergroundPipelineDefectConfig
2783
+
2784
+ # Handle nested configurations
2785
+ alert_config = kwargs.pop("alert_config", None)
2786
+ if alert_config and isinstance(alert_config, dict):
2787
+ alert_config = AlertConfig(**alert_config)
2788
+
2789
+ config = UndergroundPipelineDefectConfig(
2790
+ category=category or "underground_pipeline_defect",
2791
+ usecase=usecase,
2792
+ alert_config=alert_config,
2793
+ **kwargs
2794
+ )
2795
+
2796
+ else:
2797
+ raise ConfigValidationError(f"Unknown use case: {usecase}")
2798
+
2799
+ # Validate configuration
2800
+ errors = config.validate()
2801
+ if errors:
2802
+ raise ConfigValidationError(f"Configuration validation failed: {errors}")
2803
+
2804
+ return config
2805
+
2806
+ def load_from_file(self, file_path: Union[str, Path]) -> BaseConfig:
2807
+ """
2808
+ Load configuration from file.
2809
+
2810
+ Args:
2811
+ file_path: Path to configuration file (JSON or YAML)
2812
+
2813
+ Returns:
2814
+ BaseConfig: Configuration object
2815
+
2816
+ Raises:
2817
+ ConfigValidationError: If file cannot be loaded or validation fails
2818
+ """
2819
+ file_path = Path(file_path)
2820
+
2821
+ if not file_path.exists():
2822
+ raise ConfigValidationError(f"Configuration file not found: {file_path}")
2823
+
2824
+ try:
2825
+ # Load data based on file extension
2826
+ if file_path.suffix.lower() == '.json':
2827
+ with open(file_path, 'r') as f:
2828
+ data = json.load(f)
2829
+ elif file_path.suffix.lower() in ['.yml', '.yaml']:
2830
+ with open(file_path, 'r') as f:
2831
+ data = yaml.safe_load(f)
2832
+ else:
2833
+ raise ConfigValidationError(f"Unsupported file format: {file_path.suffix}")
2834
+
2835
+ # Extract usecase and category
2836
+ usecase = data.get('usecase')
2837
+ if not usecase:
2838
+ raise ConfigValidationError("Configuration file must specify 'usecase'")
2839
+
2840
+ category = data.get('category', 'general')
2841
+
2842
+ # Remove category and usecase from data to avoid duplication
2843
+ data_copy = data.copy()
2844
+ data_copy.pop('category', None)
2845
+ data_copy.pop('usecase', None)
2846
+
2847
+ # Create config
2848
+ return self.create_config(usecase, category, **data_copy)
2849
+
2850
+ except (json.JSONDecodeError, yaml.YAMLError) as e:
2851
+ raise ConfigValidationError(f"Failed to parse configuration file: {str(e)}")
2852
+ except Exception as e:
2853
+ raise ConfigValidationError(f"Failed to load configuration: {str(e)}")
2854
+
2855
+ def save_to_file(self, config: BaseConfig, file_path: Union[str, Path], format: str = "json") -> None:
2856
+ """
2857
+ Save configuration to file.
2858
+
2859
+ Args:
2860
+ config: Configuration object
2861
+ file_path: Output file path
2862
+ format: Output format ('json' or 'yaml')
2863
+
2864
+ Raises:
2865
+ ConfigValidationError: If format is unsupported or saving fails
2866
+ """
2867
+ file_path = Path(file_path)
2868
+
2869
+ try:
2870
+ data = config.to_dict()
2871
+
2872
+ if format.lower() == 'json':
2873
+ with open(file_path, 'w') as f:
2874
+ json.dump(data, f, indent=2)
2875
+ elif format.lower() in ['yml', 'yaml']:
2876
+ with open(file_path, 'w') as f:
2877
+ yaml.dump(data, f, default_flow_style=False, indent=2)
2878
+ else:
2879
+ raise ConfigValidationError(f"Unsupported format: {format}")
2880
+
2881
+ except Exception as e:
2882
+ raise ConfigValidationError(f"Failed to save configuration: {str(e)}")
2883
+
2884
+ def get_config_template(self, usecase: str) -> Dict[str, Any]:
2885
+ """Get configuration template for a use case."""
2886
+ if usecase == "basic_counting_tracking":
2887
+ # Import here to avoid circular import
2888
+ from ..usecases.basic_counting_tracking import BasicCountingTrackingConfig
2889
+ default_config = BasicCountingTrackingConfig()
2890
+ return default_config.to_dict()
2891
+ elif usecase == "license_plate_detection":
2892
+ # Import here to avoid circular import
2893
+ from ..usecases.license_plate_detection import LicensePlateConfig
2894
+ default_config = LicensePlateConfig()
2895
+ return default_config.to_dict()
2896
+ elif usecase == "field_mapping":
2897
+ # Import here to avoid circular import
2898
+ from ..usecases.field_mapping import FieldMappingConfig
2899
+ default_config = FieldMappingConfig()
2900
+ return default_config.to_dict()
2901
+ elif usecase == "parking_space_detection":
2902
+ # Import here to avoid circular import
2903
+ from ..usecases.parking_space_detection import ParkingSpaceConfig
2904
+ default_config = ParkingSpaceConfig()
2905
+ return default_config.to_dict()
2906
+ elif usecase == "mask_detection":
2907
+ # Import here to avoid circular import
2908
+ from ..usecases.mask_detection import MaskDetectionConfig
2909
+ default_config = MaskDetectionConfig()
2910
+ return default_config.to_dict()
2911
+
2912
+ elif usecase == "pipeline_detection":
2913
+ from ..usecases.pipeline_detection import PipelineDetectionConfig
2914
+ default_config = PipelineDetectionConfig()
2915
+ return default_config.to_dict()
2916
+
2917
+ elif usecase == "fire_smoke_detection":
2918
+ # Import here to avoid circular import
2919
+ from ..usecases.fire_detection import FireSmokeConfig
2920
+ default_config = FireSmokeConfig()
2921
+ return default_config.to_dict()
2922
+
2923
+ elif usecase == "wound_segmentation":
2924
+ # Import here to avoid circular import
2925
+ from ..usecases.wound_segmentation import WoundConfig
2926
+ default_config = WoundConfig()
2927
+ return default_config.to_dict()
2928
+
2929
+ elif usecase == "shoplifting_detection":
2930
+ # Import here to avoid circular import
2931
+ from ..usecases.shoplifting_detection import ShopliftingDetectionConfig
2932
+ default_config = ShopliftingDetectionConfig()
2933
+ return default_config.to_dict()
2934
+
2935
+ elif usecase == "solar_panel":
2936
+ # Import here to avoid circular import
2937
+ from ..usecases.solar_panel import SolarPanelConfig
2938
+ default_config = SolarPanelConfig()
2939
+ return default_config.to_dict()
2940
+
2941
+ elif usecase == "car_damage_detection":
2942
+ # Import here to avoid circular import
2943
+ from ..usecases.car_damage_detection import CarDamageConfig
2944
+ default_config = CarDamageConfig()
2945
+ return default_config.to_dict()
2946
+
2947
+ elif usecase == "pothole_segmentation":
2948
+ # Import here to avoid circular import
2949
+ from ..usecases.pothole_segmentation import PotholeConfig
2950
+ default_config = PotholeConfig()
2951
+ return default_config.to_dict()
2952
+
2953
+ elif usecase == "leaf_disease_detection":
2954
+ # Import here to avoid circular import
2955
+ from ..usecases.leaf_disease import LeafDiseaseDetectionConfig
2956
+ default_config = LeafDiseaseDetectionConfig()
2957
+ return default_config.to_dict()
2958
+
2959
+ elif usecase == "vehicle_monitoring":
2960
+ # Import here to avoid circular import
2961
+ from ..usecases.vehicle_monitoring import VehicleMonitoringConfig
2962
+ default_config = VehicleMonitoringConfig()
2963
+ return default_config.to_dict()
2964
+
2965
+ elif usecase == "drone_traffic_monitoring":
2966
+ # Import here to avoid circular import
2967
+ from ..usecases.drone_traffic_monitoring import VehiclePeopleDroneMonitoringConfig
2968
+ default_config = VehiclePeopleDroneMonitoringConfig()
2969
+ return default_config.to_dict()
2970
+
2971
+ elif usecase == "chicken_pose_detection":
2972
+ # Import here to avoid circular import
2973
+ from ..usecases.chicken_pose_detection import ChickenPoseDetectionConfig
2974
+ default_config = ChickenPoseDetectionConfig()
2975
+ return default_config.to_dict()
2976
+
2977
+ elif usecase == "fruit_monitoring":
2978
+ # Import here to avoid circular import
2979
+ from ..usecases.banana_defect_detection import BananaMonitoringConfig
2980
+ default_config = BananaMonitoringConfig()
2981
+ return default_config.to_dict()
2982
+
2983
+ elif usecase == "lane_detection":
2984
+ # Import here to avoid circular import
2985
+ from ..usecases.road_lane_detection import LaneDetectionConfig
2986
+ default_config = LaneDetectionConfig()
2987
+ return default_config.to_dict()
2988
+
2989
+ elif usecase == "shelf_inventory":
2990
+ # Import here to avoid circular import
2991
+ from ..usecases.shelf_inventory_detection import ShelfInventoryConfig
2992
+ default_config = ShelfInventoryConfig()
2993
+ return default_config.to_dict()
2994
+
2995
+ elif usecase == "anti_spoofing_detection":
2996
+ # Import here to avoid circular import
2997
+ from ..usecases.anti_spoofing_detection import AntiSpoofingDetectionConfig
2998
+ default_config = AntiSpoofingDetectionConfig()
2999
+ return default_config.to_dict()
3000
+
3001
+ elif usecase == "traffic_sign_monitoring":
3002
+ # Import here to avoid circular import
3003
+ from ..usecases.traffic_sign_monitoring import TrafficSignMonitoringConfig
3004
+ default_config = TrafficSignMonitoringConfig()
3005
+ return default_config.to_dict()
3006
+
3007
+ elif usecase == "theft_detection":
3008
+ # Import here to avoid circular import
3009
+ from ..usecases.theft_detection import TheftDetectionConfig
3010
+ default_config = TheftDetectionConfig()
3011
+ return default_config.to_dict()
3012
+
3013
+ elif usecase == "weapon_detection":
3014
+ # Import here to avoid circular import
3015
+ from ..usecases.weapon_detection import WeaponDetectionConfig
3016
+ default_config = WeaponDetectionConfig()
3017
+ return default_config.to_dict()
3018
+
3019
+ elif usecase == "weld_defect_detection":
3020
+ # Import here to avoid circular import
3021
+ from ..usecases.weld_defect_detection import WeldDefectConfig
3022
+ default_config = WeldDefectConfig()
3023
+ return default_config.to_dict()
3024
+ elif usecase == "video_color_classification":
3025
+ from ..usecases.color_detection import ColorDetectionConfig
3026
+ default_config = ColorDetectionConfig()
3027
+ return default_config.to_dict()
3028
+ elif usecase == "color_detection":
3029
+ # Import here to avoid circular import
3030
+ from ..usecases.color_detection import ColorDetectionConfig
3031
+ default_config = ColorDetectionConfig()
3032
+ return default_config.to_dict()
3033
+ elif usecase == "flare_analysis":
3034
+ # Import here to avoid circular import
3035
+ from ..usecases.flare_analysis import FlareAnalysisConfig
3036
+ default_config = FlareAnalysisConfig()
3037
+ return default_config.to_dict()
3038
+ elif usecase == "ppe_compliance_detection":
3039
+ # Import here to avoid circular import
3040
+ from ..usecases.ppe_compliance import PPEComplianceConfig
3041
+ default_config = PPEComplianceConfig()
3042
+ return default_config.to_dict()
3043
+ elif usecase == "face_emotion":
3044
+ # Import here to avoid circular import
3045
+ from ..usecases.face_emotion import FaceEmotionConfig
3046
+ default_config = FaceEmotionConfig()
3047
+ return default_config.to_dict()
3048
+ elif usecase == "underwater_pollution_detection":
3049
+ # Import here to avoid circular import
3050
+ from ..usecases.underwater_pollution_detection import UnderwaterPlasticConfig
3051
+ default_config = UnderwaterPlasticConfig()
3052
+ return default_config.to_dict()
3053
+ elif usecase == "pedestrian_detection":
3054
+ # Import here to avoid circular import
3055
+ from ..usecases.pedestrian_detection import PedestrianDetectionConfig
3056
+ default_config = PedestrianDetectionConfig()
3057
+ return default_config.to_dict()
3058
+ elif usecase == "age_detection":
3059
+ # Import here to avoid circular import
3060
+ from ..usecases.age_detection import AgeDetectionConfig
3061
+ default_config = AgeDetectionConfig()
3062
+ return default_config.to_dict()
3063
+ elif usecase == "price_tag_detection":
3064
+ # Import here to avoid circular import
3065
+ from ..usecases.price_tag_detection import PriceTagConfig
3066
+ default_config = PriceTagConfig()
3067
+ return default_config.to_dict()
3068
+ elif usecase == "distracted_driver_detection":
3069
+ # Import here to avoid circular import
3070
+ from ..usecases.distracted_driver_detection import DistractedDriverConfig
3071
+ default_config = DistractedDriverConfig()
3072
+ return default_config.to_dict()
3073
+ elif usecase == "emergency_vehicle_detection":
3074
+ # Import here to avoid circular import
3075
+ from ..usecases.emergency_vehicle_detection import EmergencyVehicleConfig
3076
+ default_config = EmergencyVehicleConfig()
3077
+ return default_config.to_dict()
3078
+ elif usecase == "crop_weed_detection":
3079
+ # Import here to avoid circular import
3080
+ from ..usecases.crop_weed_detection import CropWeedDetectionConfig
3081
+ default_config = CropWeedDetectionConfig()
3082
+ return default_config.to_dict()
3083
+ elif usecase == "child_monitoring":
3084
+ # Import here to avoid circular import
3085
+ from ..usecases.child_monitoring import ChildMonitoringConfig
3086
+ default_config = ChildMonitoringConfig()
3087
+ return default_config.to_dict()
3088
+ elif usecase == "gender_detection":
3089
+ # Import here to avoid circular import
3090
+ from ..usecases.gender_detection import GenderDetectionConfig
3091
+ default_config = GenderDetectionConfig()
3092
+ return default_config.to_dict()
3093
+ elif usecase == "concrete_crack_detection":
3094
+ # Import here to avoid circular import
3095
+ from ..usecases.concrete_crack_detection import ConcreteCrackConfig
3096
+ default_config = ConcreteCrackConfig()
3097
+ return default_config.to_dict()
3098
+ elif usecase == "fashion_detection":
3099
+ # Import here to avoid circular import
3100
+ from ..usecases.fashion_detection import FashionDetectionConfig
3101
+ default_config = FashionDetectionConfig()
3102
+ return default_config.to_dict()
3103
+ elif usecase == "warehouse_object_segmentation":
3104
+ # Import here to avoid circular import
3105
+ from ..usecases.warehouse_object_segmentation import WarehouseObjectConfig
3106
+ default_config = WarehouseObjectConfig()
3107
+ return default_config.to_dict()
3108
+ elif usecase == "shopping_cart_analysis":
3109
+ # Import here to avoid circular import
3110
+ from ..usecases.shopping_cart_analysis import ShoppingCartConfig
3111
+ default_config = ShoppingCartConfig()
3112
+ return default_config.to_dict()
3113
+ elif usecase == "defect_detection_products":
3114
+ # Import here to avoid circular import
3115
+ from ..usecases.defect_detection_products import BottleDefectConfig
3116
+ default_config = BottleDefectConfig()
3117
+ return default_config.to_dict()
3118
+ elif usecase == "assembly_line_detection":
3119
+ # Import here to avoid circular import
3120
+ from ..usecases.assembly_line_detection import AssemblyLineConfig
3121
+ default_config = AssemblyLineConfig()
3122
+ return default_config.to_dict()
3123
+ elif usecase == "car_part_segmentation":
3124
+ # Import here to avoid circular import
3125
+ from ..usecases.car_part_segmentation import CarPartSegmentationConfig
3126
+ default_config = CarPartSegmentationConfig()
3127
+ return default_config.to_dict()
3128
+ elif usecase == "windmill_maintenance":
3129
+ # Import here to avoid circular import
3130
+ from ..usecases.windmill_maintenance import WindmillMaintenanceConfig
3131
+ default_config = WindmillMaintenanceConfig()
3132
+ return default_config.to_dict()
3133
+ elif usecase == "flower_segmentation":
3134
+ # Import here to avoid circular import
3135
+ from ..usecases.flower_segmentation import FlowerConfig
3136
+ default_config = FlowerConfig()
3137
+ return default_config.to_dict()
3138
+ elif usecase == "smoker_detection":
3139
+ # Import here to avoid circular import
3140
+ from ..usecases.smoker_detection import SmokerDetectionConfig
3141
+ default_config = SmokerDetectionConfig()
3142
+ return default_config.to_dict()
3143
+ elif usecase == "road_traffic_density":
3144
+ # Import here to avoid circular import
3145
+ from ..usecases.road_traffic_density import RoadTrafficConfig
3146
+ default_config = RoadTrafficConfig()
3147
+ return default_config.to_dict()
3148
+ elif usecase == "road_view_segmentation":
3149
+ # Import here to avoid circular import
3150
+ from ..usecases.road_view_segmentation import RoadViewSegmentationConfig
3151
+ default_config = RoadViewSegmentationConfig()
3152
+ return default_config.to_dict()
3153
+ elif usecase == "face_recognition":
3154
+ # Import here to avoid circular import
3155
+ from ..face_reg.face_recognition import FaceRecognitionEmbeddingConfig
3156
+ default_config = FaceRecognitionEmbeddingConfig()
3157
+ return default_config.to_dict()
3158
+ elif usecase == "drowsy_driver_detection":
3159
+ # Import here to avoid circular import
3160
+ from ..usecases.drowsy_driver_detection import DrowsyDriverConfig
3161
+ default_config = DrowsyDriverConfig()
3162
+ return default_config.to_dict()
3163
+ elif usecase == "waterbody_segmentation":
3164
+ # Import here to avoid circular import
3165
+ from ..usecases.waterbody_segmentation import WaterBodyConfig
3166
+ default_config = WaterBodyConfig()
3167
+ return default_config.to_dict()
3168
+
3169
+ elif usecase == "litter_detection":
3170
+ # Import here to avoid circular import
3171
+ from ..usecases.litter_monitoring import LitterDetectionConfig
3172
+ default_config = LitterDetectionConfig()
3173
+ return default_config.to_dict()
3174
+
3175
+ elif usecase == "abandoned_object_detection":
3176
+ # Import here to avoid circular import
3177
+ from ..usecases.abandoned_object_detection import AbandonedObjectConfig
3178
+ default_config = AbandonedObjectConfig()
3179
+ return default_config.to_dict()
3180
+ elif usecase == "leak_detection":
3181
+ # Import here to avoid circular import
3182
+ from ..usecases.leak_detection import LeakDetectionConfig
3183
+ default_config = LeakDetectionConfig()
3184
+ return default_config.to_dict()
3185
+ elif usecase == "human_activity_recognition":
3186
+ # Import here to avoid circular import
3187
+ from ..usecases.human_activity_recognition import HumanActivityConfig
3188
+ default_config = HumanActivityConfig()
3189
+ return default_config.to_dict()
3190
+ elif usecase == "gas_leak_detection":
3191
+ # Import here to avoid circular import
3192
+ from ..usecases.gas_leak_detection import GasLeakDetectionConfig
3193
+ default_config = GasLeakDetectionConfig()
3194
+ return default_config.to_dict()
3195
+
3196
+ elif usecase == "license_plate_monitor":
3197
+ # Import here to avoid circular import
3198
+ from ..usecases.license_plate_monitoring import LicensePlateMonitorConfig
3199
+ default_config = LicensePlateMonitorConfig()
3200
+ return default_config.to_dict()
3201
+
3202
+ elif usecase == "dwell":
3203
+ # Import here to avoid circular import
3204
+ from ..usecases.dwell_detection import DwellConfig
3205
+ default_config = DwellConfig()
3206
+ return default_config.to_dict()
3207
+
3208
+ elif usecase == "age_gender_detection":
3209
+ # Import here to avoid circular import
3210
+ from ..usecases.age_gender_detection import AgeGenderConfig
3211
+ default_config = AgeGenderConfig()
3212
+ return default_config.to_dict()
3213
+
3214
+ elif usecase == "wildlife_monitoring":
3215
+ # Import here to avoid circular import
3216
+ from ..usecases.wildlife_monitoring import WildLifeMonitoringConfig
3217
+ default_config = WildLifeMonitoringConfig()
3218
+ return default_config.to_dict()
3219
+
3220
+ elif usecase == "pcb_defect_detection":
3221
+ # Import here to avoid circular import
3222
+ from ..usecases.pcb_defect_detection import PCBDefectConfig
3223
+ default_config = PCBDefectConfig()
3224
+ return default_config.to_dict()
3225
+
3226
+ elif usecase == "suspicious_activity_detection":
3227
+ # Import here to avoid circular import
3228
+ from ..usecases.suspicious_activity_detection import SusActivityConfig
3229
+ default_config = SusActivityConfig()
3230
+ return default_config.to_dict()
3231
+
3232
+ elif usecase == "natural_disaster_detection":
3233
+ # Import here to avoid circular import
3234
+ from ..usecases.natural_disaster import NaturalDisasterConfig
3235
+ default_config = NaturalDisasterConfig()
3236
+ return default_config.to_dict()
3237
+
3238
+ elif usecase == "underground_pipeline_defect":
3239
+ # Import here to avoid circular import
3240
+ from ..usecases.underground_pipeline_defect_detection import UndergroundPipelineDefectConfig
3241
+ default_config = UndergroundPipelineDefectConfig()
3242
+ return default_config.to_dict()
3243
+
3244
+ #Add all image based usecases here
3245
+ elif usecase == "blood_cancer_detection_img":
3246
+ # Import here to avoid circular import
3247
+ from ..usecases.blood_cancer_detection_img import BloodCancerDetectionConfig
3248
+ default_config = BloodCancerDetectionConfig()
3249
+ return default_config.to_dict()
3250
+ elif usecase == "skin_cancer_classification_img":
3251
+ # Import here to avoid circular import
3252
+ from ..usecases.skin_cancer_classification_img import SkinCancerClassificationConfig
3253
+ default_config = SkinCancerClassificationConfig()
3254
+ return default_config.to_dict()
3255
+ elif usecase == "plaque_segmentation_img":
3256
+ # Import here to avoid circular import
3257
+ from ..usecases.plaque_segmentation_img import PlaqueSegmentationConfig
3258
+ default_config = PlaqueSegmentationConfig()
3259
+ return default_config.to_dict()
3260
+ elif usecase == "cardiomegaly_classification":
3261
+ # Import here to avoid circular import
3262
+ from ..usecases.cardiomegaly_classification import CardiomegalyConfig
3263
+ default_config = CardiomegalyConfig()
3264
+ return default_config.to_dict()
3265
+ elif usecase == "histopathological_cancer_detection":
3266
+ # Import here to avoid circular import
3267
+ from ..usecases.Histopathological_Cancer_Detection_img import HistopathologicalCancerDetectionConfig
3268
+ default_config = HistopathologicalCancerDetectionConfig()
3269
+ return default_config.to_dict()
3270
+ elif usecase == "cell_microscopy_segmentation":
3271
+ # Import here to avoid circular import
3272
+ from ..usecases.cell_microscopy_segmentation import CellMicroscopyConfig
3273
+ default_config = CellMicroscopyConfig()
3274
+ return default_config.to_dict()
3275
+
3276
+ elif usecase not in self._config_classes:
3277
+ raise ConfigValidationError(f"Unsupported use case: {usecase}")
3278
+
3279
+
3280
+
3281
+ config_class = self._config_classes[usecase]
3282
+ default_config = config_class()
3283
+ return default_config.to_dict()
3284
+
3285
+ def list_supported_usecases(self) -> List[str]:
3286
+ """List all supported use cases."""
3287
+ return list(self._config_classes.keys())
3288
+
3289
+
3290
+ # Global configuration manager instance
3291
+ config_manager = ConfigManager()