Sign-language / app.py
Mr-HASSAN's picture
Update app.py
1530884 verified
import gradio as gr
import cv2
from ultralytics import YOLO
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import arabic_reshaper
from bidi.algorithm import get_display
import os
import requests
# 1. Load Model
model = YOLO("best.pt")
# 2. Arabic letter mapping
arabic_letters = {
"ain": "ع", "al": "لا", "aleff": "ا", "bb": "ب", "dal": "د", "dha": "ذ",
"dhad": "ض", "fa": "ف", "gaaf": "ق", "ghain": "غ", "ha": "ه", "haa": "ح",
"jeem": "ج", "kaaf": "ك", "khaa": "خ", "la": "ل", "laam": "ل", "meem": "م",
"nun": "ن", "ra": "ر", "saad": "ص", "seen": "س", "sheen": "ش", "ta": "ط",
"taa": "ت", "thaa": "ث", "thal": "ظ", "toot": "ط", "waw": "و", "ya": "ي",
"yaa": "ي", "zay": "ز"
}
# --- BULLETPROOF FONT DOWNLOAD ---
FONT_PATH = "Amiri-Regular.ttf"
if not os.path.exists(FONT_PATH):
print("📥 Downloading Arabic font...")
try:
res = requests.get("https://github.com/google/fonts/raw/main/ofl/amiri/Amiri-Regular.ttf")
with open(FONT_PATH, "wb") as f:
f.write(res.content)
print("✅ Font ready!")
except:
FONT_PATH = None
def predict_live(img):
if img is None: return None
# Speed optimization
results = model(img, conf=0.3, imgsz=320, verbose=False)
pil_img = Image.fromarray(img)
draw = ImageDraw.Draw(pil_img)
# Load font
try:
font = ImageFont.truetype(FONT_PATH, 60) if FONT_PATH else ImageFont.load_default()
except:
font = ImageFont.load_default()
for r in results:
for box in r.boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0])
cls_name = model.names[int(box.cls[0])]
# Arabic Transformation
raw_text = arabic_letters.get(cls_name, cls_name)
reshaped_text = arabic_reshaper.reshape(raw_text)
bidi_text = get_display(reshaped_text)
# Draw
draw.rectangle([x1, y1, x2, y2], outline=(0, 255, 0), width=5)
draw.text((x1, y1 - 75), bidi_text, font=font, fill=(0, 255, 0))
return np.array(pil_img)
demo = gr.Interface(
fn=predict_live,
inputs=gr.Image(sources=["webcam"], streaming=True),
outputs=gr.Image(label="Translator"),
live=True
)
if __name__ == "__main__":
demo.launch()