Spaces:
Running
Running
File size: 4,961 Bytes
975f9c6 5234a64 975f9c6 fcdea18 5234a64 fcdea18 5234a64 fcdea18 5234a64 fcdea18 5234a64 fcdea18 5234a64 fcdea18 975f9c6 5234a64 975f9c6 2154cf1 975f9c6 5234a64 8ccdb60 975f9c6 5234a64 2154cf1 8ccdb60 2154cf1 5234a64 2154cf1 5234a64 2154cf1 975f9c6 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 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
import easyocr
import numpy as np
import cv2
import re
import logging
from mmocr.utils.ocr import MMOCR
# Set up logging for debugging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Initialize OCR engines
easyocr_reader = easyocr.Reader(['en'], gpu=False)
try:
mmocr_reader = MMOCR(det='DB_r18', recog='CRNN')
except:
mmocr_reader = None
logging.warning("MMOCR initialization failed, falling back to EasyOCR only")
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
easyocr_results = easyocr_reader.readtext(processed, detail=1, paragraph=False)
if not easyocr_results: # Fallback to original image if no results
easyocr_results = easyocr_reader.readtext(img, detail=1, paragraph=False)
# MMOCR detection (if available)
mmocr_results = []
if mmocr_reader:
try:
mmocr_result = mmocr_reader.readtext(processed)
mmocr_results = [(bbox, text, score) for bbox, text, score in mmocr_result]
except:
logging.warning("MMOCR processing failed, using EasyOCR results only")
# Combine results
all_results = easyocr_results + mmocr_results
for (bbox, text, conf) in all_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("k9", "").replace("k", "")
text = re.sub(r"[^\d\.]", "", text)
# Stricter 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 |