AutoWeightLogger1 / ocr_engine.py
Sanjayraju30's picture
Update ocr_engine.py
5234a64 verified
raw
history blame
4.96 kB
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