PixiRus's picture
Update app.py
847202a verified
Raw
History Blame Contribute Delete
5.4 kB
import gradio as gr
from ultralytics import YOLO
from PIL import Image
import tempfile
import os
import shutil
import numpy as np
import easyocr
from collections import defaultdict
import cv2
# Load YOLO model
print("[INFO] Loading Custom YOLO Segmentation model...")
model = YOLO('trained_seg_model/seg_v1.pt')
print("[INFO] Custom YOLO Segmentation model loaded successfully.")
# Load EasyOCR model
print("[INFO] Loading EasyOCR model...")
reader = easyocr.Reader(['fr'])
print("[INFO] EasyOCR model initialized.")
# OCR helper function
def run_easyocr_on_yolo_segments(results, original_img: Image.Image):
print("[INFO] Running EasyOCR on segmented regions...")
original_img_np = np.array(original_img.convert("RGB"))
ocr_dict = defaultdict(list)
class_counts = defaultdict(int)
cropped_images = []
# for result in results:
# if result.masks is None or result.boxes is None:
# continue
for result_index, result in enumerate(results):
print(f"[DEBUG] Processing result index: {result_index}")
if result.masks is None or result.boxes is None:
print("[WARN] Result has no masks or boxes.")
continue
# for seg, class_id in zip(result.masks.xy, result.boxes.cls):
for seg_index, (seg, class_id) in enumerate(zip(result.masks.xy, result.boxes.cls)):
class_name = model.names[int(class_id)]
print(f"[DEBUG] Segment {seg_index}: Class = {class_name}")
poly = np.array(seg, dtype=np.int32)
x, y, w, h = cv2.boundingRect(poly)
crop = original_img_np[y:y+h, x:x+w]
if crop.size == 0:
print(f"[WARN] Empty crop for class: {class_name}")
text = ""
else:
ocr_result = reader.readtext(crop, detail=0)
text = " ".join(ocr_result).strip()
print(f"[DEBUG] OCR result for {class_name}: {text[:60]}...")
# Always use a suffix, starting from 1
class_counts[class_name] += 1
class_key = f"{class_name}_{class_counts[class_name]}"
ocr_dict[class_key] = text
# Convert cropped numpy image to PIL for gallery
cropped_pil = Image.fromarray(crop)
cropped_images.append((class_key, cropped_pil))
print(f"[INFO] OCR completed. Total regions processed: {len(cropped_images)}")
return cropped_images, dict(ocr_dict)
# Main function for Gradio
def segment_and_ocr(img: Image.Image):
print("[INFO] Starting segmentation + OCR pipeline...")
with tempfile.TemporaryDirectory() as tmpdir:
input_path = os.path.join(tmpdir, "input.jpg")
img.save(input_path)
print(f"[INFO] Saved input image to: {input_path}")
print("[INFO] Running YOLO prediction...")
results = model.predict(
source=input_path,
save=True,
save_txt=True,
project=tmpdir,
name="predict",
exist_ok=True
)
print("[INFO] YOLO prediction completed.")
output_img_path = os.path.join(tmpdir, "predict", "input.jpg")
label_txt_path = os.path.join(tmpdir, "predict", "labels", "input.txt")
# segmented_img = Image.open(output_img_path) if os.path.exists(output_img_path) else None
# label_data = open(label_txt_path).read() if os.path.exists(label_txt_path) else "No labels generated."
segmented_img = None
if os.path.exists(output_img_path):
segmented_img = Image.open(output_img_path)
print(f"[INFO] Segmented image found: {output_img_path}")
else:
print("[ERROR] Segmented image not found!")
if os.path.exists(label_txt_path):
with open(label_txt_path) as f:
label_data = f.read()
print(f"[INFO] Label file found with length: {len(label_data)} chars")
else:
label_data = "No labels generated."
print("[WARN] Label file not found.")
print("[INFO] Extracting OCR results from segments...")
cropped_images_with_labels, ocr_dict = run_easyocr_on_yolo_segments(results, img)
# Format gallery for Gradio [(image, label)]
gallery_output = [(image, label) for label, image in cropped_images_with_labels]
print(f"[INFO] Returning {len(gallery_output)} cropped images and {len(ocr_dict)} OCR entries.")
return segmented_img, label_data, gallery_output, ocr_dict
# Sample images for "Examples" section
examples = [
["sample_images/seg_v1.jpg"],
["sample_images/seg_v2.jpg"],
["sample_images/seg_v3.jpg"],
["sample_images/seg_v4.jpg"]
]
# Gradio UI
print("[INFO] Launching Gradio interface...")
gr.Interface(
fn=segment_and_ocr,
inputs=gr.Image(type="pil", label="Upload Image"),
outputs=[
gr.Image(type="pil", label="Segmented Image"),
gr.Textbox(label="YOLO Labels (.txt Output)"),
gr.Gallery(label="Segmented Crops (OCR Regions)"),
gr.JSON(label="OCR Output by Class (with suffix)")
],
examples=examples,
cache_examples=False, # <- this disables automatic execution
title="AI-Powered YOLO Segmentation + OCR with EasyOCR",
description="Upload or choose an image to segment using YOLO and extract text using EasyOCR from each region."
).launch()