RescueAI / src /pipeline.py
Nisanth
chore : inital commit
4bab068
Raw
History Blame Contribute Delete
2.01 kB
"""
TriagePipeline: the single entrypoint the UI (or any batch script / API)
calls. Wires together:
image -> YOLO11 (grounding)
-> Qwen2.5-VL (reasoning, grounded by YOLO context)
-> TriageResult (validated, clamped, defaulted)
-> OpenCV annotated image
Models are loaded once (lazy singletons) so repeated Gradio calls are fast.
"""
import cv2
import numpy as np
from .object_detector import DisasterObjectDetector
from .vlm_engine import DisasterVLM
from .annotator import annotate
from .schema import TriageResult
_detector = None
_vlm = None
def get_detector() -> DisasterObjectDetector:
global _detector
if _detector is None:
_detector = DisasterObjectDetector()
return _detector
def get_vlm() -> DisasterVLM:
global _vlm
if _vlm is None:
_vlm = DisasterVLM()
return _vlm
def run_triage(image_path: str):
"""
Returns:
annotated_image_rgb (np.ndarray, HxWx3, RGB) - for Gradio display
result (TriageResult)
"""
detector = get_detector()
vlm = get_vlm()
# 1. Grounded object detection
detections = detector.detect(image_path)
counts = detector.summarize(detections)
yolo_context = detector.to_context_string(counts)
# 2. VLM scene reasoning, grounded with YOLO context
parsed_json, raw_text = vlm.analyze(image_path, yolo_context=yolo_context)
result = TriageResult.from_dict(parsed_json, yolo_detections=counts, raw_model_output=raw_text)
# If the VLM failed to report people count but YOLO found people, trust YOLO.
if result.people_visible_count == 0 and counts.get("people", 0) > 0:
result.people_visible_count = counts["people"]
# 3. Annotate image (boxes + risk badge)
image_bgr = cv2.imread(image_path)
annotated_bgr = annotate(
image_bgr, detections, result.risk_score, result.risk_level, result.risk_color
)
annotated_rgb = cv2.cvtColor(annotated_bgr, cv2.COLOR_BGR2RGB)
return annotated_rgb, result