import easyocr import numpy as np import cv2 import re reader = easyocr.Reader(['en'], gpu=False) def enhance_image(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (5, 5), 0) _, thresh = cv2.threshold(blur, 120, 255, cv2.THRESH_BINARY_INV) # Find contours to crop region with max text contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) height, width = gray.shape digit_region = gray # default if contours: largest = max(contours, key=cv2.contourArea) x, y, w, h = cv2.boundingRect(largest) pad = 10 x = max(x - pad, 0) y = max(y - pad, 0) w = min(w + 2 * pad, width - x) h = min(h + 2 * pad, height - y) digit_region = gray[y:y+h, x:x+w] # Resize and sharpen digit_region = cv2.resize(digit_region, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC) kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]]) digit_region = cv2.filter2D(digit_region, -1, kernel) return digit_region def extract_weight_from_image(pil_img): try: img = np.array(pil_img) img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) processed = enhance_image(img) results = reader.readtext(processed) best_weight = None best_conf = 0.0 for (_, text, conf) in results: text = text.lower().strip() text = text.replace(",", ".").replace("o", "0").replace("s", "5") text = text.replace("kgs", "").replace("kg", "") text = re.sub(r"[^\d\.]", "", text) if len(text) >= 2 and re.fullmatch(r"\d{1,4}(\.\d{1,3})?", text): if conf > best_conf: best_weight = text best_conf = conf if not best_weight: return "Not detected", 0.0 if "." in best_weight: int_part, dec_part = best_weight.split(".") best_weight = f"{int_part.lstrip('0') or '0'}.{dec_part}" else: best_weight = best_weight.lstrip("0") or "0" return best_weight, round(best_conf * 100, 2) except Exception as e: return f"Error: {str(e)}", 0.0