Mr-HASSAN
Add Arabic character mapping for proper letter display
b239850
import cv2
import numpy as np
from ultralytics import YOLO
import torch
from typing import Dict, List, Any
import os
import gc
# Arabic letter mapping from English class names to Arabic characters
ARABIC_MAP = {
"aleff": "ุง",
"bb": "ุจ",
"ta": "ุช",
"thaa": "ุซ",
"jeem": "ุฌ",
"haa": "ุญ",
"khaa": "ุฎ",
"dal": "ุฏ",
"thal": "ุฐ",
"ra": "ุฑ",
"zay": "ุฒ",
"seen": "ุณ",
"sheen": "ุด",
"saad": "ุต",
"dhad": "ุถ",
"taa": "ุท",
"dha": "ุธ",
"ain": "ุน",
"ghain": "ุบ",
"fa": "ู",
"gaaf": "ู‚",
"kaaf": "ูƒ",
"laam": "ู„",
"la": "ู„ุง",
"meem": "ู…",
"nun": "ู†",
"ha": "ู‡",
"waw": "ูˆ",
"ya": "ูŠ",
"yaa": "ูŠ",
"toot": "ุฉ",
"al": "ุงู„"
}
class ArabicSignDetector:
def __init__(self, model_path: str = None):
print("๐Ÿ”„ Initializing ArabicSignDetector...")
# Check GPU status
print(f"๐ŸŽฎ CUDA available: {torch.cuda.is_available()}")
if torch.cuda.is_available():
print(f"๐ŸŽฏ GPU device: {torch.cuda.get_device_name(0)}")
torch.cuda.empty_cache()
else:
print("โšก Running on CPU")
if model_path is None:
possible_paths = ['best.pt', '/tmp/best.pt', 'utils/best.pt', './best.pt', '/app/best.pt']
found_path = None
for path in possible_paths:
if os.path.exists(path):
found_path = path
print(f"โœ… Found model at: {path}")
break
if found_path:
model_path = found_path
else:
print("โŒ No best.pt found!")
self.model = None
return
try:
print(f"๐Ÿ”„ Loading YOLO model from: {model_path}")
# Optimized YOLO loading for ZeroGPU
self.model = YOLO(model_path)
# Set to eval mode and optimize
if hasattr(self.model, 'model'):
self.model.model.eval()
# Lower confidence threshold for better real-time detection
self.confidence_threshold = 0.15
# Clear memory after loading
gc.collect()
if torch.cuda.is_available():
torch.cuda.empty_cache()
print(f"โœ… YOLO model loaded successfully!")
if hasattr(self.model, 'names') and self.model.names:
print(f"๐Ÿ“Š Number of classes: {len(self.model.names)}")
print(f"๐ŸŽฏ Confidence threshold: {self.confidence_threshold}")
except Exception as e:
print(f"โŒ YOLO loading failed: {e}")
try:
print("๐Ÿ”„ Trying alternative YOLO loading...")
checkpoint = torch.load(model_path, map_location='cpu', weights_only=False)
self.model = YOLO(model_path)
print("โœ… YOLO model loaded with alternative method!")
except Exception as e2:
print(f"โŒ All loading methods failed: {e2}")
self.model = None
def detect_letters(self, image: np.ndarray) -> Dict[str, Any]:
"""Detect Arabic letters and form text - optimized for ZeroGPU"""
if self.model is None:
print("โŒ YOLO model is not loaded")
return {
'success': False,
'error': 'YOLO model not loaded',
'arabic_text': '',
'letters': [],
'total_detections': 0
}
try:
# Use GPU if available, with optimizations
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# Optimized inference settings for ZeroGPU
with torch.inference_mode(): # Use inference_mode for better performance
results = self.model(
image,
conf=self.confidence_threshold,
device=device,
verbose=False, # Reduce output
half=torch.cuda.is_available() # Use FP16 on GPU
)
detected_letters = []
confidences = []
for result in results:
if hasattr(result, 'boxes') and result.boxes is not None:
boxes = result.boxes
for i in range(len(boxes.cls)):
class_id = int(boxes.cls[i])
confidence = float(boxes.conf[i])
letter_english = self.model.names.get(class_id, "")
if confidence > self.confidence_threshold:
# Convert English class name to Arabic character
letter_arabic = ARABIC_MAP.get(letter_english.lower(), letter_english)
detected_letters.append(letter_arabic)
confidences.append(confidence)
# Clear GPU memory after inference
if torch.cuda.is_available():
torch.cuda.empty_cache()
if detected_letters:
arabic_text = "".join(detected_letters)
print(f"๐Ÿ“ Detected: '{arabic_text}' ({len(detected_letters)} letters)")
return {
'success': True,
'arabic_text': arabic_text,
'letters': detected_letters,
'confidences': confidences,
'total_detections': len(detected_letters)
}
else:
return {
'success': False,
'error': 'No Arabic sign letters detected',
'arabic_text': '',
'letters': [],
'total_detections': 0
}
except Exception as e:
print(f"โŒ Detection error: {e}")
# Clean up on error
if torch.cuda.is_available():
torch.cuda.empty_cache()
return {
'success': False,
'error': str(e),
'arabic_text': '',
'letters': [],
'total_detections': 0
}