jerewy's picture
Upload 79 files
a58d271 verified
from ultralytics import YOLO
from groq import Groq
from .config import MODEL_PATH, MODEL_IMAGE_SIZE, GROQ_API_KEY
import cv2
import json
import logging
import time
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Load model once
logger.info(f"Loading model from {MODEL_PATH}")
try:
model = YOLO(MODEL_PATH)
except Exception as e:
logger.error(f"Failed to load model: {e}")
raise
def run_inference(image_path, output_path):
"""
Runs YOLO inference on the image.
Saves the annotated image to output_path.
Returns a dictionary with detections and metadata.
"""
start_time = time.time()
# Run inference
results = model(image_path, imgsz=MODEL_IMAGE_SIZE, conf=0.4)
end_time = time.time()
processing_time_ms = (end_time - start_time) * 1000
result = results[0]
# Save annotated image
annotated_frame = result.plot()
cv2.imwrite(str(output_path), annotated_frame)
# Severity Mapping Logic
SEVERITY_MAP = {
"scratch": "Low",
"dent": "Medium",
"crack": "High",
"lamp_broken": "High",
"tire_flat": "High",
"glass_shatter": "Critical"
}
# Extract detections for LLM and UI
detections = []
for box in result.boxes:
cls_id = int(box.cls[0])
class_name = result.names[cls_id]
confidence = float(box.conf[0])
# Simple location logic based on box center
x_center = box.xywh[0][0]
img_width = result.orig_shape[1]
if x_center < img_width / 3:
location = "Left Side"
elif x_center > 2 * img_width / 3:
location = "Right Side"
else:
location = "Center"
# Determine Severity
severity = SEVERITY_MAP.get(class_name, "Medium")
# Boost severity if confidence is very high for critical items
if severity == "Critical" and confidence > 0.8:
severity = "CRITICAL (Safety Risk)"
detections.append({
"class": class_name,
"confidence": confidence,
"location": location,
"severity": severity
})
return {
"detections": detections,
"processing_time": round(processing_time_ms, 2),
"count": len(detections),
"model_info": f"YOLO11s ({MODEL_IMAGE_SIZE})"
}
def generate_insurance_report(detection_data, make, model_name, year):
"""
Generates a structured JSON report using Groq API based on detections.
"""
if not GROQ_API_KEY:
return {"error": "Groq API Key not configured"}
client = Groq(api_key=GROQ_API_KEY)
vehicle_info = f"{year} {make} {model_name}"
detections = detection_data.get("detections", [])
det_str = json.dumps(detections, indent=2)
# Fallback if no detections
if not detections:
return {
"summary": f"No specific damage patterns were detected by the automated system on the {vehicle_info}.",
"severity_level": "Low",
"severity_reasoning": "No visible dents, scratches, or tears identified by AI.",
"repair_urgency": "None",
"urgency_details": "Vehicle appears to be in good condition based on visual inspection.",
"cost_range": "$0",
"cost_details": "No repairs needed.",
"recommended_action": "Routine maintenance.",
"immediate_actions": ["Verify visual inspection manually.", "Wash vehicle to ensure no hidden marks."],
"secondary_actions": ["Keep regular service schedule."]
}
prompt = f"""
Act as a Senior Automotive Claims Adjuster and Technical Appraiser.
Analyze the following vehicle damage detection data provided by an automated computer vision system.
Vehicle: {vehicle_info}
Detected Damages: {det_str}
Generate a formal, industry-standard damage assessment report in valid JSON format ONLY.
Use professional terminology (e.g., 'refinish', 'R&I', 'structural integrity') and maintain an objective tone.
The JSON must have these exact keys:
{{
"summary": "A formal executive summary of the visual inspection findings.",
"severity_level": "Low, Medium, High, or Total Loss",
"severity_reasoning": "Technical justification for the severity classification.",
"repair_urgency": "Routine, Urgent, or Safety Critical",
"urgency_details": "Explanation focusing on safety and drivability.",
"cost_range": "Estimated repair cost range (e.g., '$800 - $1,500 USD').",
"cost_details": "Breakdown of cost drivers (e.g., 'Includes body labor, paint supplies, and parts').",
"estimated_labor_hours": "Estimated labor time (e.g., '12-16 hours').",
"likely_parts_needed": ["List of parts likely requiring repair or replacement"],
"recommended_action": "Primary technical recommendation (e.g., 'Tear-down and blueprinting').",
"immediate_actions": ["Action 1", "Action 2"],
"secondary_actions": ["Action 1", "Action 2"]
}}
"""
try:
chat_completion = client.chat.completions.create(
messages=[
{
"role": "user",
"content": prompt,
}
],
model="llama-3.3-70b-versatile",
response_format={"type": "json_object"} # Enforce JSON mode
)
return json.loads(chat_completion.choices[0].message.content)
except Exception as e:
logger.error(f"Groq API error: {e}")
return {
"summary": "Error generating detailed report.",
"severity_level": "Unknown",
"severity_reasoning": str(e),
"repair_urgency": "Unknown",
"urgency_details": "Contact support.",
"cost_range": "Unknown",
"cost_details": "Unknown",
"estimated_labor_hours": "Unknown",
"likely_parts_needed": [],
"recommended_action": "Manual Inspection",
"immediate_actions": ["Contact support"],
"secondary_actions": []
}