Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import torch | |
| from ultralytics import YOLO | |
| from PIL import Image | |
| import numpy as np | |
| import easyocr | |
| import cv2 | |
| # Load YOLOv8 Model (Nano for speed) | |
| model = YOLO('yolov8n.pt') | |
| # Load EasyOCR (English) | |
| # This will download the OCR models on first run | |
| reader = easyocr.Reader(['en'], gpu=torch.cuda.is_available()) | |
| def detect_and_read(image, threshold): | |
| # 1. YOLO Detection | |
| results = model.predict(source=image, conf=threshold) | |
| # 2. EasyOCR Full Page Read | |
| # Convert PIL to numpy for EasyOCR | |
| img_np = np.array(image) | |
| ocr_results = reader.readtext(img_np) | |
| detections = [] | |
| # Process YOLO boxes (UI Components) | |
| for r in results: | |
| for box in r.boxes: | |
| b = box.xyxy[0].cpu().numpy() | |
| c = box.cls.cpu().item() | |
| label = model.names[int(c)] | |
| # Box coords [xmin, ymin, xmax, ymax] | |
| xmin, ymin, xmax, ymax = b | |
| # Link OCR text to this specific YOLO box | |
| box_text = "" | |
| for (ocr_box, text, prob) in ocr_results: | |
| # Calculate OCR center | |
| ox = (ocr_box[0][0] + ocr_box[2][0]) / 2 | |
| oy = (ocr_box[0][1] + ocr_box[2][1]) / 2 | |
| # If text is inside the UI box | |
| if xmin <= ox <= xmax and ymin <= oy <= ymax: | |
| box_text += text + " " | |
| # Normalize coordinates for RapnssZ | |
| norm_box = [ | |
| float(ymin / image.height), # ymin | |
| float(xmin / image.width), # xmin | |
| float(ymax / image.height), # ymax | |
| float(xmax / image.width) # xmax | |
| ] | |
| detections.append({ | |
| "box": norm_box, | |
| "label": label, | |
| "text": box_text.strip(), | |
| "score": float(box.conf.cpu().item()) | |
| }) | |
| # 3. Handle Floating Text (OCR text not inside a YOLO box) | |
| for (ocr_box, text, prob) in ocr_results: | |
| already_matched = False | |
| for d in detections: | |
| if text in d["text"]: | |
| already_matched = True | |
| break | |
| if not already_matched: | |
| # Add as a 'text' element | |
| # EasyOCR box format: [[x,y], [x,y], [x,y], [x,y]] | |
| norm_box = [ | |
| float(ocr_box[0][1] / image.height), | |
| float(ocr_box[0][0] / image.width), | |
| float(ocr_box[2][1] / image.height), | |
| float(ocr_box[2][0] / image.width) | |
| ] | |
| detections.append({ | |
| "box": norm_box, | |
| "label": "text", | |
| "text": text, | |
| "score": float(prob) | |
| }) | |
| return detections | |
| # Gradio Interface | |
| iface = gr.Interface( | |
| fn=detect_and_read, | |
| inputs=[ | |
| gr.Image(type="pil", label="Screen Capture"), | |
| gr.Slider(0, 1, value=0.2, label="Radar Sensitivity (Threshold)") | |
| ], | |
| outputs=gr.JSON(label="OCR-Radar Analysis"), | |
| title="RapnssZ OCR-Radar // Mega v4.5", | |
| description="Zero-latency UI mapping using YOLOv8 and EasyOCR." | |
| ) | |
| iface.launch() | |