Spaces:
Running
Running
File size: 3,125 Bytes
975f9c6 fcdea18 975f9c6 fcdea18 975f9c6 fcdea18 975f9c6 fcdea18 975f9c6 8ccdb60 975f9c6 e75e9eb 8ccdb60 e75e9eb 8ccdb60 975f9c6 8ccdb60 975f9c6 8ccdb60 975f9c6 8ccdb60 975f9c6 8ccdb60 975f9c6 8ccdb60 385a153 975f9c6 385a153 975f9c6 385a153 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
import easyocr
import numpy as np
import cv2
import re
reader = easyocr.Reader(['en'], gpu=False)
def enhance_image(img):
# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply sharpening kernel
kernel = np.array([[0, -1, 0], [-1, 5,-1], [0, -1, 0]])
sharp = cv2.filter2D(gray, -1, kernel)
# Contrast Limited Adaptive Histogram Equalization (CLAHE)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
contrast = clahe.apply(sharp)
# Denoising
denoised = cv2.fastNlMeansDenoising(contrast, h=30)
# Adaptive threshold for very dim images
thresh = cv2.adaptiveThreshold(denoised, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
return thresh
def extract_weight_from_image(pil_img):
try:
img = np.array(pil_img)
# Resize if too large or too small
max_dim = 1000
height, width = img.shape[:2]
if max(height, width) > max_dim:
scale = max_dim / max(height, width)
img = cv2.resize(img, None, fx=scale, fy=scale, interpolation=cv2.INTER_AREA)
elif max(height, width) < 400:
scale = 2.5 # Upscale very small images
img = cv2.resize(img, None, fx=scale, fy=scale, interpolation=cv2.INTER_CUBIC)
# Enhance image for OCR
preprocessed = enhance_image(img)
results = reader.readtext(preprocessed)
best_weight = None
best_conf = 0.0
for item in results:
if len(item) != 2 or not isinstance(item[1], tuple):
continue
text, conf = item[1]
cleaned = text.lower().strip()
cleaned = cleaned.replace(",", ".")
cleaned = cleaned.replace("o", "0").replace("O", "0")
cleaned = cleaned.replace("s", "5").replace("S", "5")
cleaned = cleaned.replace("g", "9").replace("G", "6")
cleaned = cleaned.replace("kg", "").replace("kgs", "")
cleaned = re.sub(r"[^\d\.]", "", cleaned)
if re.fullmatch(r"\d{2,4}(\.\d{1,3})?", cleaned):
if conf > best_conf:
best_weight = cleaned
best_conf = conf
if not best_weight:
for item in results:
if len(item) != 2 or not isinstance(item[1], tuple):
continue
text, conf = item[1]
fallback = re.sub(r"[^\d\.]", "", text)
if fallback and fallback.replace(".", "").isdigit():
best_weight = fallback
best_conf = conf
break
if not best_weight:
return "Not detected", 0.0
if "." in best_weight:
int_part, dec_part = best_weight.split(".")
int_part = int_part.lstrip("0") or "0"
best_weight = f"{int_part}.{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
|