Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, UploadFile, File, Query | |
| from fastapi.responses import JSONResponse | |
| import easyocr | |
| import numpy as np | |
| import cv2 | |
| import time | |
| import requests | |
| from io import BytesIO | |
| from PIL import Image | |
| import os | |
| app = FastAPI(title="EasyOCR API") | |
| # Use /tmp for writable storage | |
| tmp_dir = "/tmp/EasyOCR" | |
| model_dir = os.path.join(tmp_dir, "models") | |
| user_net_dir = os.path.join(tmp_dir, "user_network") | |
| os.makedirs(model_dir, exist_ok=True) | |
| os.makedirs(user_net_dir, exist_ok=True) | |
| # Initialize reader with custom directories | |
| reader = easyocr.Reader( | |
| ['en'], | |
| gpu=False, | |
| model_storage_directory=model_dir, | |
| user_network_directory=user_net_dir | |
| ) | |
| def read_image_from_url(url: str): | |
| response = requests.get(url) | |
| response.raise_for_status() | |
| img = np.array(Image.open(BytesIO(response.content)).convert("RGB")) | |
| return img | |
| def preprocess_image(image: np.ndarray) -> np.ndarray: | |
| # Convert to grayscale | |
| gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) | |
| # Denoise slightly | |
| gray = cv2.GaussianBlur(gray, (3, 3), 0) | |
| # Adaptive threshold (makes text sharper) | |
| thresh = cv2.adaptiveThreshold( | |
| gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, | |
| cv2.THRESH_BINARY, 31, 2 | |
| ) | |
| return thresh | |
| async def ocr_url(url: str = Query(None)): | |
| start_time = time.time() | |
| if not url: | |
| return JSONResponse( | |
| status_code=400, | |
| content={"status": False, "error": "Provide ?url= for OCR."} | |
| ) | |
| try: | |
| image = read_image_from_url(url) | |
| # Preprocess for better OCR | |
| processed = preprocess_image(image) | |
| # OCR | |
| result = reader.readtext(processed) | |
| # Format result (only text) | |
| output = [r[1] for r in result] | |
| end_time = time.time() | |
| time_taken = round(end_time - start_time, 3) | |
| return { | |
| "status": True, | |
| "time_taken": time_taken, | |
| "results": output | |
| } | |
| except Exception as e: | |
| return JSONResponse( | |
| status_code=500, | |
| content={"status": False, "error": str(e)} | |
| ) | |
| async def ocr_file(file: UploadFile = File(...)): | |
| start_time = time.time() | |
| try: | |
| image = np.array(Image.open(file.file).convert("RGB")) | |
| # Preprocess for better OCR | |
| processed = preprocess_image(image) | |
| # OCR | |
| result = reader.readtext(processed) | |
| # Format result (only text) | |
| output = [r[1] for r in result] | |
| end_time = time.time() | |
| time_taken = round(end_time - start_time, 3) | |
| return { | |
| "status": True, | |
| "time_taken": time_taken, | |
| "results": output | |
| } | |
| except Exception as e: | |
| return JSONResponse( | |
| status_code=500, | |
| content={"status": False, "error": str(e)} | |
| ) |