matrice-analytics 0.1.2__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.

Potentially problematic release.


This version of matrice-analytics might be problematic. Click here for more details.

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