import numpy as np import re import cv2 from PIL import Image import easyocr import os # ✅ Initialize OCR reader only once reader = easyocr.Reader(['en'], gpu=False) def preprocess_image(image): """ Preprocess the image to improve OCR detection. Converts to grayscale and applies adaptive threshold. """ gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # Apply adaptive threshold to isolate digits better thresh = cv2.adaptiveThreshold( gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 11, 10 ) return thresh def extract_weight_from_image(pil_image): try: # ✅ Step 1: Convert to OpenCV format image = np.array(pil_image.convert("RGB")) # ✅ Step 2: Preprocess image processed = preprocess_image(image) # ✅ Step 3: Optional - Save debug image debug_path = "debug_processed_image.png" Image.fromarray(processed).save(debug_path) print(f"[DEBUG] Saved preprocessed image to {debug_path}") # ✅ Step 4: Run EasyOCR result = reader.readtext(processed) print("🔍 OCR Results:") for r in result: print(f" • Text: '{r[1]}' | Confidence: {r[2]*100:.2f}%") # ✅ Step 5: Look for a decimal number like 53.25 weight = None confidence = 0.0 for detection in result: text = detection[1].replace(",", ".") # Handle comma decimal (if any) conf = detection[2] # Look for numbers like 53.25 or 100 match = re.search(r"\b\d{1,3}(\.\d{1,2})?\b", text) if match: weight = match.group() confidence = conf break if weight: return weight, round(confidence * 100, 2) else: return "No weight detected", 0.0 except Exception as e: print(f"❌ OCR Error: {e}") return f"Error: {str(e)}", 0.0