RescueAI / src /object_detector.py
Nisanth
chore : inital commit
4bab068
Raw
History Blame Contribute Delete
2.41 kB
"""
Thin wrapper around Ultralytics YOLO11.
Why YOLO here at all, when the VLM can already "see" the image?
-> VLMs are known to hallucinate counts ("about 3 people") because they're
generating text, not measuring pixels. YOLO gives us *pixel-grounded*,
confidence-scored counts and boxes. We feed these counts into the VLM
prompt as ground truth context, and use the boxes for drawing on the
annotated image. This is a "detector-grounded VLM" pattern — cheap to
build, and meaningfully reduces hallucination vs a VLM-only pipeline.
"""
from ultralytics import YOLO
from .config import YOLO_MODEL_ID, RELEVANT_CLASSES, YOLO_CONF_THRESHOLD
class DisasterObjectDetector:
def __init__(self, model_id: str = YOLO_MODEL_ID):
self.model = YOLO(model_id)
def detect(self, image_path: str):
"""Run detection, return list of dicts: {class, conf, box=[x1,y1,x2,y2]}"""
results = self.model.predict(
source=image_path,
conf=YOLO_CONF_THRESHOLD,
verbose=False,
)[0]
detections = []
names = results.names
for box in results.boxes:
cls_id = int(box.cls.item())
cls_name = names[cls_id]
if cls_name not in RELEVANT_CLASSES:
continue
conf = float(box.conf.item())
x1, y1, x2, y2 = [float(v) for v in box.xyxy[0].tolist()]
detections.append({
"class": cls_name,
"conf": conf,
"box": [x1, y1, x2, y2],
})
return detections
@staticmethod
def summarize(detections):
"""Turn a list of detections into {'people': 2, 'cars': 1, ...} counts."""
counts = {}
for d in detections:
label = RELEVANT_CLASSES.get(d["class"], d["class"])
counts[label] = counts.get(label, 0) + 1
return counts
@staticmethod
def to_context_string(counts: dict) -> str:
"""Human-readable string injected into the VLM prompt as grounding context."""
if not counts:
return "No standard objects (people/vehicles) were confidently detected by the object detector."
parts = [f"{v} {k}" for k, v in counts.items()]
return "Object detector confidently found: " + ", ".join(parts) + \
". Treat these counts as reliable ground truth; do not contradict them."