geethareddy's picture
Update app.py
71f6c9d verified
raw
history blame
5.61 kB
import gradio as gr
import cv2
import pytesseract
from PIL import Image
import io
import base64
from datetime import datetime
import pytz
import numpy as np
import logging
# Set up logging for better debugging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Ensure Tesseract is correctly set up
try:
pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract' # Make sure to set the correct path
pytesseract.get_tesseract_version() # Confirm Tesseract is installed
logging.info("Tesseract is configured properly.")
except Exception as e:
logging.error(f"Tesseract not found or misconfigured: {str(e)}")
# Image Preprocessing to enhance OCR accuracy
def preprocess_image(img_cv):
"""Preprocess the image for better OCR accuracy."""
try:
# Convert to grayscale
gray = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
# Enhance contrast with CLAHE
clahe = cv2.createCLAHE(clipLimit=5.0, tileGridSize=(8, 8))
contrast = clahe.apply(gray)
# Apply Gaussian blur to reduce noise
blurred = cv2.GaussianBlur(contrast, (5, 5), 0)
# Apply adaptive thresholding
thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
# Sharpen the image to emphasize edges
sharpened = cv2.filter2D(thresh, -1, np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]]))
return sharpened
except Exception as e:
logging.error(f"Image preprocessing failed: {str(e)}")
return img_cv
# Function to extract weight using Tesseract OCR
def extract_weight(img):
"""Extract weight using Tesseract OCR, focused on digits and decimals."""
try:
if img is None:
logging.error("No image provided for OCR")
return "Not detected", 0.0, None
# Convert PIL image to OpenCV format
img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
# Preprocess the image
processed_img = preprocess_image(img_cv)
# Tesseract configuration to focus on digits and decimal points
custom_config = r'--oem 3 --psm 6 -c tessedit_char_whitelist=0123456789.'
# Run OCR
text = pytesseract.image_to_string(processed_img, config=custom_config)
logging.info(f"OCR result: '{text}'")
# Extract the valid weight (numbers and decimal points)
weight = ''.join(filter(lambda x: x in '0123456789.', text.strip()))
if weight:
try:
weight_float = float(weight)
if weight_float >= 0: # Ensure it's a valid weight
confidence = 95.0 # High confidence for valid weight
logging.info(f"Weight detected: {weight} (Confidence: {confidence:.2f}%)")
return weight, confidence, processed_img
except ValueError:
logging.warning(f"Invalid weight format: {weight}")
logging.error("OCR failed to detect a valid weight")
return "Not detected", 0.0, None
except Exception as e:
logging.error(f"OCR processing failed: {str(e)}")
return "Not detected", 0.0, None
# Main function to process the image and display results
def process_image(img):
"""Process the uploaded image and show results."""
if img is None:
logging.error("No image uploaded")
return "No image uploaded", None, gr.update(visible=False), gr.update(visible=False)
# Get the current timestamp in IST format
ist_time = datetime.now(pytz.timezone("Asia/Kolkata")).strftime("%d-%m-%Y %I:%M:%S %p")
# Extract weight and confidence
weight, confidence, processed_img = extract_weight(img)
# If weight detection fails, show the error message
if weight == "Not detected" or confidence < 95.0:
logging.warning(f"Weight detection failed: {weight} (Confidence: {confidence:.2f}%)")
return f"{weight} (Confidence: {confidence:.2f}%)", ist_time, gr.update(visible=True), gr.update(visible=False)
# Convert processed image to base64 for Gradio to display
pil_image = Image.fromarray(processed_img)
buffered = io.BytesIO()
pil_image.save(buffered, format="PNG")
img_base64 = base64.b64encode(buffered.getvalue()).decode()
return f"{weight} kg (Confidence: {confidence:.2f}%)", ist_time, img_base64, gr.update(visible=True)
# Gradio Interface setup for Hugging Face
with gr.Blocks(title="โš–๏ธ Auto Weight Logger") as demo:
gr.Markdown("## โš–๏ธ Auto Weight Logger")
gr.Markdown("๐Ÿ“ท Upload or capture an image of a digital weight scale (max 5MB).")
with gr.Row():
image_input = gr.Image(type="pil", label="Upload / Capture Image", sources=["upload", "webcam"])
output_weight = gr.Textbox(label="โš–๏ธ Detected Weight (in kg)")
with gr.Row():
timestamp = gr.Textbox(label="๐Ÿ•’ Captured At (IST)")
snapshot = gr.Image(label="๐Ÿ“ธ Snapshot Image", type="pil")
submit = gr.Button("๐Ÿ” Detect Weight")
submit.click(
fn=process_image,
inputs=image_input,
outputs=[output_weight, timestamp, snapshot]
)
gr.Markdown("""
### Instructions
- Upload a clear, well-lit image of a digital weight scale display (preferably a seven-segment font).
- Ensure the image is < 5MB (automatically resized if larger).
- Review the detected weight and try again if it's incorrect.
""")
if __name__ == "__main__":
demo.launch()