0xarchit commited on
Commit
443b1bb
·
1 Parent(s): 0888cf8

minor fixes for detection

Browse files
Backend/agents/priority/agent.py CHANGED
@@ -56,7 +56,7 @@ Priority Scale:
56
  1 = CRITICAL (Public safety, electrical hazards, major hazards)
57
  2 = HIGH (Potholes, road damage, fallen trees)
58
  3 = MEDIUM (Garbage, broken signs, minor structures)
59
- 4 = LOW (Parking violations, minor vandalism)
60
 
61
  Consider safety impact, infrastructure criticality, and community accessibility.
62
 
 
56
  1 = CRITICAL (Public safety, electrical hazards, major hazards)
57
  2 = HIGH (Potholes, road damage, fallen trees)
58
  3 = MEDIUM (Garbage, broken signs, minor structures)
59
+ 4 = LOW (Parking violations)
60
 
61
  Consider safety impact, infrastructure criticality, and community accessibility.
62
 
Backend/agents/vision/agent.py CHANGED
@@ -56,15 +56,36 @@ class VisionAgent(BaseAgent):
56
  async def download_image(self, remote_path: str) -> bytes:
57
  return await download_from_supabase(remote_path)
58
 
59
- async def save_annotated(self, results, original_path: str, subfolder: str) -> str:
60
- im_array = results[0].plot()
61
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  original_name = Path(original_path).stem
63
  annotated_filename = f"annotated_{original_name}.jpg"
64
-
65
- _, buffer = cv2.imencode('.jpg', im_array, [cv2.IMWRITE_JPEG_QUALITY, 90])
66
  image_bytes = buffer.tobytes()
67
-
68
  remote_path = await save_bytes(image_bytes, annotated_filename, subfolder=subfolder)
69
  return remote_path
70
 
@@ -162,8 +183,9 @@ class VisionAgent(BaseAgent):
162
  ) -> tuple[list[DetectionBox], str, Optional[IssueCategory], float, Optional[str]]:
163
  image_data = await self.download_image(image_path)
164
  results, inference_time = await self.run_inference(image_data)
165
- annotated_path = await self.save_annotated(results, image_path, subfolder)
166
  detections = self.extract_detections(results)
 
 
167
 
168
  gemini_category = None
169
  gemini_confidence = 0.0
 
56
  async def download_image(self, remote_path: str) -> bytes:
57
  return await download_from_supabase(remote_path)
58
 
59
+ async def save_annotated(
60
+ self,
61
+ image_data: bytes,
62
+ detections: list[DetectionBox],
63
+ primary_class_id: Optional[int],
64
+ original_path: str,
65
+ subfolder: str,
66
+ ) -> str:
67
+ nparr = np.frombuffer(image_data, np.uint8)
68
+ img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
69
+ if img is None:
70
+ raise ValueError("Invalid image data")
71
+
72
+ if primary_class_id is not None:
73
+ draw_detections = [d for d in detections if d.class_id == primary_class_id]
74
+ else:
75
+ draw_detections = []
76
+
77
+ for d in draw_detections:
78
+ x1, y1, x2, y2 = map(int, d.bbox)
79
+ cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
80
+ label = f"{d.class_name} {d.confidence:.2f}"
81
+ cv2.putText(img, label, (x1, max(y1 - 10, 0)), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 0, 255), 3)
82
+
83
  original_name = Path(original_path).stem
84
  annotated_filename = f"annotated_{original_name}.jpg"
85
+
86
+ _, buffer = cv2.imencode('.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 90])
87
  image_bytes = buffer.tobytes()
88
+
89
  remote_path = await save_bytes(image_bytes, annotated_filename, subfolder=subfolder)
90
  return remote_path
91
 
 
183
  ) -> tuple[list[DetectionBox], str, Optional[IssueCategory], float, Optional[str]]:
184
  image_data = await self.download_image(image_path)
185
  results, inference_time = await self.run_inference(image_data)
 
186
  detections = self.extract_detections(results)
187
+ primary_class_id = max(detections, key=lambda d: d.confidence).class_id if detections else None
188
+ annotated_path = await self.save_annotated(image_data, detections, primary_class_id, image_path, subfolder)
189
 
190
  gemini_category = None
191
  gemini_confidence = 0.0
Backend/core/schemas.py CHANGED
@@ -33,7 +33,6 @@ class IssueCategory(StrEnum):
33
  BROKEN_SIGN = "Broken Road Sign Issues"
34
  FALLEN_TREE = "Fallen Trees"
35
  GARBAGE = "Littering/Garbage on Public Places"
36
- VANDALISM = "Vandalism Issues"
37
  DEAD_ANIMAL = "Dead Animal Pollution"
38
  DAMAGED_CONCRETE = "Damaged Concrete Structures"
39
  DAMAGED_ELECTRIC = "Damaged Electric Wires and Poles"
@@ -46,7 +45,6 @@ CLASS_ID_TO_CATEGORY = {
46
  3: IssueCategory.BROKEN_SIGN,
47
  4: IssueCategory.FALLEN_TREE,
48
  5: IssueCategory.GARBAGE,
49
- 6: IssueCategory.VANDALISM,
50
  7: IssueCategory.DEAD_ANIMAL,
51
  8: IssueCategory.DAMAGED_CONCRETE,
52
  9: IssueCategory.DAMAGED_ELECTRIC,
 
33
  BROKEN_SIGN = "Broken Road Sign Issues"
34
  FALLEN_TREE = "Fallen Trees"
35
  GARBAGE = "Littering/Garbage on Public Places"
 
36
  DEAD_ANIMAL = "Dead Animal Pollution"
37
  DAMAGED_CONCRETE = "Damaged Concrete Structures"
38
  DAMAGED_ELECTRIC = "Damaged Electric Wires and Poles"
 
45
  3: IssueCategory.BROKEN_SIGN,
46
  4: IssueCategory.FALLEN_TREE,
47
  5: IssueCategory.GARBAGE,
 
48
  7: IssueCategory.DEAD_ANIMAL,
49
  8: IssueCategory.DAMAGED_CONCRETE,
50
  9: IssueCategory.DAMAGED_ELECTRIC,
Backend/utils/fuzzy_match.py CHANGED
@@ -26,10 +26,6 @@ CATEGORY_KEYWORDS: dict[str, list[str]] = {
26
  "garbage", "trash", "litter", "waste", "rubbish", "dump", "dirty",
27
  "filth", "debris", "plastic", "pile", "mess", "junk", "disposal"
28
  ],
29
- "Vandalism Issues": [
30
- "vandal", "graffiti", "spray", "paint", "defaced",
31
- "smashed", "destroyed", "torn"
32
- ],
33
  "Dead Animal Pollution": [
34
  "dead", "animal", "carcass", "body", "corpse", "rotting", "smell",
35
  "stink", "dog", "cat", "bird", "cow", "roadkill"
 
26
  "garbage", "trash", "litter", "waste", "rubbish", "dump", "dirty",
27
  "filth", "debris", "plastic", "pile", "mess", "junk", "disposal"
28
  ],
 
 
 
 
29
  "Dead Animal Pollution": [
30
  "dead", "animal", "carcass", "body", "corpse", "rotting", "smell",
31
  "stink", "dog", "cat", "bird", "cow", "roadkill"