neerajkalyank's picture
Update app.py
dcf1926 verified
import gradio as gr
from PIL import Image, ImageEnhance, ImageOps
import cv2
import numpy as np
from datetime import datetime
import pytz
import re
import easyocr
import pytesseract
import logging
# Set up logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
# Initialize OCR engines
try:
reader = easyocr.Reader(['en'])
logging.info("EasyOCR initialized successfully")
except Exception as e:
logging.error(f"Failed to initialize EasyOCR: {str(e)}")
reader = None
try:
# Verify Tesseract is installed
pytesseract.pytesseract.tesseract_cmd = r'/usr/bin/tesseract' # Adjust path if needed
logging.info("Tesseract initialized successfully")
except Exception as e:
logging.error(f"Failed to initialize Tesseract: {str(e)}")
pytesseract = None
# Image enhancement functions
def enhance_image(image):
try:
image = image.convert("L")
image = ImageEnhance.Contrast(image).enhance(3.0)
image = ImageEnhance.Sharpness(image).enhance(2.0)
image = image.resize((image.width * 3, image.height * 3), Image.Resampling.LANCZOS)
image = image.convert("RGB")
return image
except Exception as e:
logging.error(f"Error in enhance_image: {str(e)}")
return image
def apply_clahe(image):
try:
gray = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2GRAY)
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
cl1 = clahe.apply(gray)
return Image.fromarray(cv2.cvtColor(cl1, cv2.COLOR_GRAY2RGB))
except Exception as e:
logging.error(f"Error in apply_clahe: {str(e)}")
return image
def preprocess_7segment(img):
try:
np_img = np.array(img.convert("L"))
blurred = cv2.GaussianBlur(np_img, (3, 3), 0)
thresh = cv2.adaptiveThreshold(
blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 15, 3
)
kernel = np.ones((2, 2), np.uint8)
thresh = cv2.dilate(thresh, kernel, iterations=1)
scaled = cv2.resize(thresh, None, fx=3.0, fy=3.0, interpolation=cv2.INTER_LINEAR)
return Image.fromarray(cv2.cvtColor(scaled, cv2.COLOR_GRAY2RGB))
except Exception as e:
logging.error(f"Error in preprocess_7segment: {str(e)}")
return img
def denoise_image(image):
try:
np_img = np.array(image)
denoised = cv2.fastNlMeansDenoisingColored(np_img, h=10, hColor=10, templateWindowSize=7, searchWindowSize=21)
return Image.fromarray(denoised)
except Exception as e:
logging.error(f"Error in denoise_image: {str(e)}")
return image
def recognize_7segment(image):
try:
gray = np.array(image.convert("L"))
_, binary = cv2.threshold(gray, 128, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=lambda x: cv2.boundingRect(x)[0])
digits = []
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
if w < 10 or h < 10:
continue
roi = binary[y:y+h, x:x+w]
segment_count = np.sum(roi == 255) / (w * h)
if segment_count > 0.5:
digits.append("8")
elif segment_count > 0.3:
digits.append("7")
else:
digits.append("1")
text = "".join(digits)
if len(contours) > len(digits):
text = text[:2] + "." + text[2:]
return text
except Exception as e:
logging.error(f"Error in recognize_7segment: {str(e)}")
return ""
def detect_weight(image):
try:
if image is None:
logging.error("No image provided")
return "Error: No image provided", None
best_confidence = 0.0
best_text = ""
weight = None
# Apply preprocessing variants
variants = [
enhance_image(image),
apply_clahe(image),
preprocess_7segment(image),
denoise_image(image)
]
# EasyOCR processing
if reader:
for variant in variants:
try:
img_np = np.array(variant)
result = reader.readtext(img_np)
for detection in result:
text = detection[1]
confidence = detection[2]
logging.info(f"Detected Text (EasyOCR): {text}, Confidence: {confidence}")
match = re.search(r"(\d{1,4}(?:\.\d{1,2})?)", text)
if match and confidence > best_confidence:
weight = match.group(1)
best_confidence = confidence
best_text = text
except Exception as e:
logging.error(f"Error in EasyOCR processing: {str(e)}")
# Tesseract fallback if EasyOCR fails or is unavailable
if not weight and pytesseract:
for variant in variants:
try:
img_np = np.array(variant)
text = pytesseract.image_to_string(img_np, config='--psm 6 digits')
logging.info(f"Detected Text (Tesseract): {text}")
match = re.search(r"(\d{1,4}(?:\.\d{1,2})?)", text)
if match:
weight = match.group(1)
best_text = text
except Exception as e:
logging.error(f"Error in Tesseract processing: {str(e)}")
# Manual 7-segment recognition fallback
if not weight:
logging.info("OCR failed, trying manual 7-segment recognition...")
variant = preprocess_7segment(image)
manual_text = recognize_7segment(variant)
logging.info(f"Manual 7-segment recognition result: {manual_text}")
match = re.search(r"(\d{1,4}(?:\.\d{1,2})?)", manual_text)
if match:
weight = match.group(1)
best_text = manual_text
weight = weight if weight else "Not detected"
ist = pytz.timezone('Asia/Kolkata')
current_time = datetime.now(ist).strftime("%Y-%m-%d %H:%M:%S")
return f"Weight: {weight} kg\nCaptured At: {current_time} (IST)", image
except Exception as e:
logging.error(f"Error in detect_weight: {str(e)}")
return f"Error: {str(e)}", image
# Gradio UI
interface = gr.Interface(
fn=detect_weight,
inputs=gr.Image(type="pil", label="Upload or Capture Image"),
outputs=[gr.Textbox(label="Weight Info"), gr.Image(label="Snapshot")],
title="⚖️ Auto Weight Detector (EasyOCR + Tesseract + 7-Segment Fallback)",
description="OCR pipeline using EasyOCR and Tesseract with 7-segment display optimization."
)
if __name__ == "__main__":
interface.launch(server_port=8080)