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
|
| 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(
|
| 60 |
-
|
| 61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
original_name = Path(original_path).stem
|
| 63 |
annotated_filename = f"annotated_{original_name}.jpg"
|
| 64 |
-
|
| 65 |
-
_, buffer = cv2.imencode('.jpg',
|
| 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"
|