GradioHVAC / app.py
shrey14's picture
Update app.py
cb97926 verified
import gradio as gr
from inference_sdk import InferenceHTTPClient
from PIL import Image, ImageDraw, ImageFont
import os
from collections import defaultdict
API_KEY = os.getenv("ROBOFLOW_API_KEY")
CLIENT = InferenceHTTPClient(
api_url="https://detect.roboflow.com",
api_key=API_KEY
)
# Model settings
MODEL_ID = "hvacsym/5"
CONFIDENCE_THRESHOLD = 0.3 # Confidence threshold for filtering predictions
GRID_SIZE = (3, 3) # 4x4 segmentation
def process_image(image_path):
"""Processes an uploaded image and returns the final image with bounding boxes & symbol counts."""
original_image = Image.open(image_path)
width, height = original_image.size
seg_w, seg_h = width // GRID_SIZE[1], height // GRID_SIZE[0]
# Create a copy of the image for bounding boxes
final_image = original_image.copy()
draw_final = ImageDraw.Draw(final_image)
# Load font
try:
font = ImageFont.truetype("arial.ttf", 10)
except:
font = ImageFont.load_default()
# Dictionary for total counts
total_counts = defaultdict(int)
# Process each segment
for row in range(GRID_SIZE[0]):
for col in range(GRID_SIZE[1]):
x1, y1 = col * seg_w, row * seg_h
x2, y2 = (col + 1) * seg_w, (row + 1) * seg_h
segment = original_image.crop((x1, y1, x2, y2))
segment_path = f"segment_{row}_{col}.png"
segment.save(segment_path)
# Run inference
result = CLIENT.infer(segment_path, model_id=MODEL_ID)
filtered_predictions = [
pred for pred in result["predictions"] if pred["confidence"] * 100 >= CONFIDENCE_THRESHOLD
]
# Draw bounding boxes and update counts
for obj in filtered_predictions:
sx, sy, sw, sh = obj["x"], obj["y"], obj["width"], obj["height"]
class_name = obj["class"]
confidence = obj["confidence"]
total_counts[class_name] += 1
# Adjust coordinates for final image
x_min, y_min = x1 + (sx - sw // 2), y1 + (sy - sh // 2)
x_max, y_max = x1 + (sx + sw // 2), y1 + (sy + sh // 2)
# Draw bounding box
draw_final.rectangle([x_min, y_min, x_max, y_max], outline="green", width=2)
# Draw label
text = f"{class_name} {confidence:.2f}"
draw_final.text((x_min + 2, y_min - 10), text, fill="white", font=font)
# Save final image with bounding boxes
final_image_path = "final_detected_image.png"
final_image.save(final_image_path)
return final_image_path, total_counts
def process_uploaded_image(image):
"""Gradio wrapper function that calls `process_image` and formats the output."""
final_image_path, total_counts = process_image(image)
# Convert count dictionary to readable text
count_text = "\n".join([f"{label}: {count}" for label, count in total_counts.items()])
return final_image_path, count_text
# Deploy with Gradio
iface = gr.Interface(
fn=process_uploaded_image,
inputs=gr.Image(type="filepath"), # Gradio input expects a file path
outputs=[gr.Image(type="filepath"), gr.Text()],
title="HVAC Symbol Detector",
description="Upload an HVAC blueprint image. The model will detect symbols and return the final image with bounding boxes along with symbol counts."
)
# Launch the Gradio app
iface.launch()