MohdUmar0223 commited on
Commit
9e30f75
·
verified ·
1 Parent(s): a8b5c00

Update services/vision/service.py

Browse files
Files changed (1) hide show
  1. services/vision/service.py +119 -0
services/vision/service.py CHANGED
@@ -141,12 +141,21 @@ async def detect_pollution_sources(image: Image.Image) -> dict:
141
  all_detections = florence_detections + dino_detections
142
  pollution_sources, source_count, severity = _categorize_detections(all_detections)
143
 
 
 
 
 
 
144
  return {
145
  "scene_description": scene_description,
146
  "detections": all_detections,
147
  "pollution_sources_found": pollution_sources,
148
  "source_count": source_count,
149
  "severity": severity,
 
 
 
 
150
  "model": "florence-2-base + grounding-dino-tiny",
151
  "device_used": get_device(),
152
  }
@@ -343,3 +352,113 @@ def _categorize_detections(detections: list[dict]) -> tuple[list[str], dict[str,
343
  severity = "high"
344
 
345
  return sorted(list(pollution_sources)), source_count, severity
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  all_detections = florence_detections + dino_detections
142
  pollution_sources, source_count, severity = _categorize_detections(all_detections)
143
 
144
+ # Compute advanced dynamic intelligence metrics from raw model inputs
145
+ land_use, potential_contributors, source_attribution, recommended_actions = _calculate_geospatial_metrics(
146
+ scene_description, all_detections
147
+ )
148
+
149
  return {
150
  "scene_description": scene_description,
151
  "detections": all_detections,
152
  "pollution_sources_found": pollution_sources,
153
  "source_count": source_count,
154
  "severity": severity,
155
+ "land_use": land_use,
156
+ "potential_contributors": potential_contributors,
157
+ "source_attribution": source_attribution,
158
+ "recommended_actions": recommended_actions,
159
  "model": "florence-2-base + grounding-dino-tiny",
160
  "device_used": get_device(),
161
  }
 
352
  severity = "high"
353
 
354
  return sorted(list(pollution_sources)), source_count, severity
355
+
356
+
357
+ def _calculate_geospatial_metrics(scene_description: str, detections: list[dict]) -> tuple[dict, dict, dict, list[str]]:
358
+ """
359
+ Dynamically analyze the scene description and detections to calculate:
360
+ - land_use
361
+ - potential_contributors
362
+ - source_attribution
363
+ - recommended_actions
364
+ """
365
+ desc_lower = scene_description.lower()
366
+
367
+ # Initialize basic frequencies
368
+ scores = {
369
+ "commercial": 1,
370
+ "residential": 1,
371
+ "green": 1,
372
+ "barren": 1,
373
+ "road": 1
374
+ }
375
+
376
+ # Analyze scene description keywords
377
+ if "commercial" in desc_lower or "building" in desc_lower or "complex" in desc_lower:
378
+ scores["commercial"] += 3
379
+ if "residential" in desc_lower or "house" in desc_lower or "apartment" in desc_lower or "suburb" in desc_lower:
380
+ scores["residential"] += 3
381
+ if "green" in desc_lower or "tree" in desc_lower or "forest" in desc_lower or "vegetation" in desc_lower or "park" in desc_lower:
382
+ scores["green"] += 3
383
+ if "barren" in desc_lower or "soil" in desc_lower or "sand" in desc_lower or "open land" in desc_lower or "dust" in desc_lower:
384
+ scores["barren"] += 3
385
+ if "road" in desc_lower or "highway" in desc_lower or "street" in desc_lower or "bridge" in desc_lower or "vehicle" in desc_lower:
386
+ scores["road"] += 3
387
+
388
+ # Add frequencies from object detections
389
+ for det in detections:
390
+ lbl = det["label"].lower()
391
+ if "construction" in lbl:
392
+ scores["barren"] += 4
393
+ scores["commercial"] += 2
394
+ if "factory" in lbl or "chimney" in lbl or "industrial" in lbl:
395
+ scores["commercial"] += 5
396
+ if "road" in lbl or "car" in lbl or "truck" in lbl or "vehicle" in lbl or "bus" in lbl:
397
+ scores["road"] += 4
398
+ if "tree" in lbl or "vegetation" in lbl or "green" in lbl:
399
+ scores["green"] += 4
400
+
401
+ total_score = sum(scores.values())
402
+
403
+ # Convert to dynamic percentages
404
+ comm_pct = int(round((scores["commercial"] / total_score) * 100))
405
+ res_pct = int(round((scores["residential"] / total_score) * 100))
406
+ green_pct = int(round((scores["green"] / total_score) * 100))
407
+ barren_pct = int(round((scores["barren"] / total_score) * 100))
408
+ road_pct = 100 - (comm_pct + res_pct + green_pct + barren_pct)
409
+ if road_pct < 0:
410
+ comm_pct += road_pct
411
+ road_pct = 0
412
+
413
+ land_use = {
414
+ "Commercial Zone": f"{comm_pct}%",
415
+ "Residential Zone": f"{res_pct}%",
416
+ "Green Cover": f"{green_pct}%",
417
+ "Open/Barren Land": f"{barren_pct}%",
418
+ "Road Infrastructure": f"{road_pct}%"
419
+ }
420
+
421
+ # Calculate potential contributors & attribution
422
+ has_traffic = any(x in desc_lower or any(x in d["label"].lower() for d in detections) for x in ["road", "car", "truck", "vehicle", "bus"])
423
+ has_const = any(x in desc_lower or any(x in d["label"].lower() for d in detections) for x in ["construction", "building", "crane"])
424
+ has_ind = any(x in desc_lower or any(x in d["label"].lower() for d in detections) for x in ["factory", "chimney", "industrial", "smoke"])
425
+
426
+ potential_contributors = {
427
+ "Traffic Density": "High" if has_traffic else "Medium" if scores["road"] > 2 else "Low",
428
+ "Construction Activity": "High" if has_const else "Medium" if scores["barren"] > 2 else "Low",
429
+ "Low Vegetation Cover": "High" if green_pct < 15 else "Medium" if green_pct < 25 else "Low",
430
+ "Industrial Probability": "High" if has_ind else "Medium" if "industrial" in desc_lower else "Low"
431
+ }
432
+
433
+ # Dynamic attribution calculation based on contributor score weights
434
+ traffic_weight = 40 if has_traffic else 15
435
+ dust_weight = 35 if has_const else 15
436
+ ind_weight = 30 if has_ind else 10
437
+ other_weight = 10
438
+
439
+ total_weight = traffic_weight + dust_weight + ind_weight + other_weight
440
+ traffic_attr = int(round((traffic_weight / total_weight) * 100))
441
+ dust_attr = int(round((dust_weight / total_weight) * 100))
442
+ ind_attr = int(round((ind_weight / total_weight) * 100))
443
+ other_attr = 100 - (traffic_attr + dust_attr + ind_attr)
444
+
445
+ source_attribution = {
446
+ "Traffic Emissions": f"{traffic_attr}%",
447
+ "Construction Dust": f"{dust_attr}%",
448
+ "Industrial Stack": f"{ind_attr}%",
449
+ "Secondary / Other": f"{other_attr}%"
450
+ }
451
+
452
+ # Dynamic recommended actions based on attributions & severity
453
+ recommended_actions = ["Deploy Inspection Team to coordinates"]
454
+ if dust_attr > 30:
455
+ recommended_actions.append("Water Sprinkling Required on open dusty roads")
456
+ recommended_actions.append("Fine Construction Contractor for open material storage")
457
+ if traffic_attr > 35:
458
+ recommended_actions.append("Temporary Heavy Truck Diversion active")
459
+ if ind_attr > 25:
460
+ recommended_actions.append("Notify Pollution Control Board for stack inspection")
461
+ if len(recommended_actions) < 3:
462
+ recommended_actions.append("Increase Solid Waste Burning Patrols in residential areas")
463
+
464
+ return land_use, potential_contributors, source_attribution, recommended_actions