muhammadAman25's picture
Upload 4 files
ea90d24 verified
import gradio as gr
import cv2
import PIL.Image
import numpy as np
from ultralytics import YOLO
import pandas as pd
# --- Model Loading ---
MODEL_PATH = "best.pt"
try:
model = YOLO(MODEL_PATH)
print(f"Model loaded successfully from {MODEL_PATH}")
except Exception as e:
print(f"Error loading model: {e}")
model = None
def predict(image, conf_threshold, iou_threshold):
"""
Runs YOLO inference on the input image.
Args:
image: Input image (numpy array or PIL Image).
conf_threshold: Confidence threshold for detection.
iou_threshold: IoU threshold for NMS.
Returns:
Annotated image (numpy array), Class counts (dict/str), Detailed Data (DataFrame)
"""
if model is None:
return None, "Model not loaded.", None
try:
# Run inference
results = model.predict(image, conf=conf_threshold, iou=iou_threshold)
result = results[0]
# Plot results
res_plotted = result.plot()
res_image = res_plotted[..., ::-1] # Convert BGR to RGB if needed, specifically for Gradio image output which usually expects RGB
# Count classes
class_counts = {}
box_data = []
for box in result.boxes:
cls = int(box.cls[0])
cls_name = model.names[cls]
class_counts[cls_name] = class_counts.get(cls_name, 0) + 1
box_data.append({
"Class": cls_name,
"Confidence": float(box.conf[0]),
"Coordinates": [round(x, 1) for x in box.xyxy[0].tolist()]
})
# Format class counts for display
counts_summary = pd.DataFrame(list(class_counts.items()), columns=['Class', 'Count'])
# Detailed data
df = pd.DataFrame(box_data)
return res_image, counts_summary, df
except Exception as e:
return None, f"Error: {e}", None
# --- Gradio UI ---
def create_interface():
with gr.Blocks() as demo:
gr.Markdown(
"""
# CAt and DOG Detection Pro
Upload an image to detect Cat and Dog.
"""
)
with gr.Row():
with gr.Column():
input_image = gr.Image(label="Original Image", type="numpy")
conf_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.25, step=0.05, label="Confidence Threshold")
iou_slider = gr.Slider(minimum=0.0, maximum=1.0, value=0.45, step=0.05, label="IoU Threshold")
run_btn = gr.Button("πŸ” Run Detection", variant="primary")
with gr.Column():
output_image = gr.Image(label="Detected Output")
gr.Markdown("### πŸ“Š Detection Statistics")
output_counts = gr.Dataframe(label="Class Counts")
output_details = gr.Dataframe(label="Detailed Detection Data")
run_btn.click(
fn=predict,
inputs=[input_image, conf_slider, iou_slider],
outputs=[output_image, output_counts, output_details]
)
gr.Markdown("---")
gr.Markdown("Model: standard YOLOv8n (Custom Trained) | Classes: Head, Helmet, Person")
return demo
if __name__ == "__main__":
demo = create_interface()
# Fix: Pass theme to launch() as per Gradio 6.0 warning (though usually it's passed to Blocks, the warning said otherwise? Let's re-read carefully)
# Warning: "The parameters have been moved from the Blocks constructor to the launch() method in Gradio 6.0: theme."
# Wait, usually theme is in Blocks. Gradio 6.0 is very new or future? The installed version is 6.2.0?
# Let me check the Pip output: "Requirement already satisfied: gradio in ... (6.2.0)"
# Okay, so for 6.2.0, theme might indeed be in launch() or it's a specific change.
# Actually, standard Gradio usually has theme in Blocks. But if the warning says so, I'll move it.
# However, passing theme to launch() might not work if the object hasn't been built with it?
# No, launch() handles the serving. Theme is a UI property.
# I'll try passing it to launch(), but launch() args are usually server config.
# Actually, Blocks(theme=...) is the standard way. Maybe the warning is about something else or I misread?
# "UserWarning: The parameters have been moved from the Blocks constructor to the launch() method in Gradio 6.0: theme."
# That seems quite explicit.
# Let's try `demo.launch(theme=gr.themes.Soft())`? No, launch takes `auth`, `server_name` etc.
# Wait, maybe `gr.Interface(theme=...)` moved? But I'm using `Blocks`.
# Let's try following the warning.
demo.launch(theme=gr.themes.Soft()) # This relies on launch accepting theme?
# If launch doesn't accept theme, this will fail.
# Let's verify if I can check doc. But I can't browse.
# I'll stick to the warning.
# But wait, `theme` object needs to be constructed.
# Let's try:
# demo = create_interface() -> returns Blocks object
# demo.launch()
# The replacement content below removes it from Blocks() and adds it to launch().