import cv2 import numpy as np import logging from typing import List, Dict, Any # Configure logging logging.basicConfig( filename="app.log", level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" ) def overlay_boxes(frame: np.ndarray, detected_items: List[Dict[str, Any]]) -> np.ndarray: """ Overlay bounding boxes and labels on the frame for detected items. Args: frame: Input frame in BGR format. detected_items: List of detected items with coordinates and labels. Returns: np.ndarray: Frame with overlaid bounding boxes and labels. """ if not isinstance(frame, np.ndarray) or frame.size == 0: logging.error("Invalid input frame provided to overlay_service.") return frame if not isinstance(detected_items, list): logging.error("Detected items must be a list.") return frame try: for item in detected_items: if "box" not in item or "type" not in item or "severity" not in item: logging.warning(f"Skipping item without box, type, or severity: {item}") continue x_min, y_min, x_max, y_max = map(int, item["box"]) severity = item["severity"] if item["type"] == "crack": color = (0, 0, 255) if severity == "Severe" else (0, 255, 255) if severity == "Moderate" else (0, 255, 0) if severity == "Minor" else (255, 165, 0) label = f"Crack: {severity}" else: # Hole color = (255, 0, 0) if severity == "Severe" else (255, 255, 0) if severity == "Moderate" else (0, 128, 0) label = f"Hole: {severity}" cv2.rectangle(frame, (x_min, y_min), (x_max, y_max), color, 2) cv2.putText(frame, label, (x_min, y_min - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) logging.info(f"Overlaid {len(detected_items)} items on frame.") return frame except Exception as e: logging.error(f"Error overlaying boxes: {str(e)}") return frame