Spaces:
Running
Running
File size: 4,242 Bytes
975f9c6 5234a64 0bb13f0 5234a64 975f9c6 fcdea18 5234a64 fcdea18 5234a64 fcdea18 5234a64 fcdea18 5234a64 fcdea18 5234a64 fcdea18 975f9c6 5234a64 975f9c6 2154cf1 975f9c6 5234a64 8ccdb60 975f9c6 5234a64 0bb13f0 2154cf1 8ccdb60 2154cf1 5234a64 2154cf1 5234a64 0bb13f0 2154cf1 975f9c6 0bb13f0 5234a64 2154cf1 8ccdb60 975f9c6 8ccdb60 5234a64 385a153 975f9c6 2154cf1 975f9c6 5234a64 975f9c6 385a153 975f9c6 5234a64 |
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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
import easyocr
import numpy as np
import cv2
import re
import logging
# Set up logging for debugging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Initialize EasyOCR
easyocr_reader = easyocr.Reader(['en'], gpu=False)
def estimate_blur(img):
"""Estimate image blur using Laplacian variance"""
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
return cv2.Laplacian(gray, cv2.CV_64F).var()
def enhance_image(img):
try:
# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Bilateral filter for noise reduction while preserving edges
denoised = cv2.bilateralFilter(gray, d=9, sigmaColor=75, sigmaSpace=75)
# CLAHE for contrast enhancement
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
contrast = clahe.apply(denoised)
# Adaptive thresholding for uneven lighting
thresh = cv2.adaptiveThreshold(contrast, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2)
# Morphological operations to enhance text
kernel = np.ones((3, 3), np.uint8)
morphed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1)
# Sharpen image
sharpen_kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
sharpened = cv2.filter2D(morphed, -1, sharpen_kernel)
# Dynamic resizing
h, w = sharpened.shape
target_size = 800 # Target max dimension for OCR
scale_factor = min(target_size / max(h, w), 2.0) if max(h, w) < 300 else min(target_size / max(h, w), 1.0)
if scale_factor != 1.0:
sharpened = cv2.resize(sharpened, None, fx=scale_factor, fy=scale_factor,
interpolation=cv2.INTER_CUBIC if scale_factor > 1 else cv2.INTER_AREA)
return sharpened
except Exception as e:
logging.error(f"Image enhancement failed: {str(e)}")
return img # Return original image as fallback
def extract_weight_from_image(pil_img):
try:
img = np.array(pil_img)
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
# Estimate blur to adjust confidence threshold
blur_score = estimate_blur(img)
conf_threshold = 0.3 if blur_score < 100 else 0.5 # Lower threshold for blurry images
# Preprocess image
processed = enhance_image(img)
# Initialize results
best_weight = None
best_conf = 0.0
# EasyOCR detection
results = easyocr_reader.readtext(processed, detail=1, paragraph=False)
if not results: # Fallback to original image if no results
results = easyocr_reader.readtext(img, detail=1, paragraph=False)
for (bbox, text, conf) in results:
original_text = text
text = text.lower().strip()
# Fix common OCR errors
text = text.replace(",", ".").replace(";", ".")
text = text.replace("o", "0").replace("O", "0")
text = text.replace("s", "5").replace("S", "5")
text = text.replace("g", "9").replace("G", "6")
text = text.replace("l", "1").replace("I", "1")
text = text.replace("b", "8").replace("B", "8")
text = text.replace("kgs", "").replace("kg", "").replace("k", "")
text = re.sub(r"[^\d\.]", "", text)
# Regex for weight (0.0 to 9999.999)
if re.fullmatch(r"\d{1,4}(\.\d{0,3})?", text):
if conf > best_conf and conf > conf_threshold:
best_weight = text
best_conf = conf
if not best_weight:
logging.info("No valid weight detected")
return "Not detected", 0.0
# Format output
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.rstrip('0')}"
else:
best_weight = best_weight.lstrip("0") or "0"
return best_weight, round(best_conf * 100, 2)
except Exception as e:
logging.error(f"Weight extraction failed: {str(e)}")
return "Not detected", 0.0 |