geethareddy's picture
Update app.py
f9a0fa7 verified
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 visibility
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Configure Tesseract path (ensure it’s correctly set to your Tesseract installation)
try:
pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract' # Adjust path if necessary
pytesseract.get_tesseract_version() # Test Tesseract installation
logging.info("Tesseract is properly configured.")
except Exception as e:
logging.error(f"Tesseract not found or misconfigured: {str(e)}")
# Improved Image Preprocessing function for OCR
def preprocess_image(img_cv):
"""Enhance the image to improve OCR performance."""
try:
# Convert to grayscale
gray = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
# Increase contrast using histogram equalization
contrast = cv2.equalizeHist(gray)
# Apply Gaussian blur to reduce noise
blurred = cv2.GaussianBlur(contrast, (5, 5), 0)
# Apply adaptive thresholding to binarize the image
thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
# Sharpening the image to bring out more details
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 from image using OCR
def extract_weight(img):
"""Extract weight using Tesseract OCR, focusing on digits and decimals."""
try:
if img is None:
logging.error("No image provided for OCR")
return "Not detected", 0.0, None
# Convert the PIL image to OpenCV format
img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
# Preprocess the image for better OCR results
processed_img = preprocess_image(img_cv)
# Configure Tesseract to detect only digits and decimals
custom_config = r'--oem 3 --psm 6 -c tessedit_char_whitelist=0123456789.'
# Use Tesseract OCR to extract text
text = pytesseract.image_to_string(processed_img, config=custom_config)
logging.info(f"OCR result: '{text}'")
# Extract the weight (numbers and decimal)
weight = ''.join(filter(lambda x: x in '0123456789.', text.strip()))
if weight:
try:
weight_float = float(weight)
if weight_float >= 0:
confidence = 95.0 # Assume high confidence if we detect a 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 uploaded image and display results
def process_image(img):
"""Process the uploaded image, extract weight, and return results."""
if img is None:
logging.error("No image uploaded")
return "No image uploaded", None, gr.update(visible=False), gr.update(visible=False)
# Get timestamp for IST (Indian Standard Time)
ist_time = datetime.now(pytz.timezone("Asia/Kolkata")).strftime("%d-%m-%Y %I:%M:%S %p")
# Call the function to extract weight and confidence
weight, confidence, processed_img = extract_weight(img)
# If OCR fails to detect weight
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 the processed image to base64 format for displaying
pil_image = Image.fromarray(processed_img)
buffered = io.BytesIO()
pil_image.save(buffered, format="PNG")
img_base64 = base64.b64encode(buffered.getvalue()).decode()
# Return the detected weight, timestamp, and base64 image for Gradio
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()