Spaces:
Sleeping
Sleeping
File size: 2,927 Bytes
2675ec4 c3ef86d 2675ec4 f038111 c3ef86d 6c08e04 c3ef86d 2675ec4 af5ce57 2675ec4 c3ef86d af5ce57 c3ef86d af5ce57 f038111 c3ef86d af5ce57 6c08e04 2675ec4 af5ce57 2675ec4 af5ce57 c3ef86d af5ce57 | 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 | import gradio as gr
from transformers import TrOCRProcessor, VisionEncoderDecoderModel
from PIL import Image, ImageEnhance, ImageOps
import torch
import re
import easyocr
from io import BytesIO
import numpy as np
# Initialize EasyOCR Reader
reader = easyocr.Reader(['en'])
# Load the pre-trained model and processor for fallback
processor = TrOCRProcessor.from_pretrained('microsoft/trocr-small-printed')
model = VisionEncoderDecoderModel.from_pretrained('microsoft/trocr-small-printed')
model.eval()
def enhance_image(image):
image = ImageEnhance.Contrast(image).enhance(2.0)
image = ImageEnhance.Sharpness(image).enhance(2.0)
image = ImageOps.grayscale(image)
return image
def ocr_with_easyocr(pil_img):
# Convert PIL to bytes for EasyOCR
buf = BytesIO()
pil_img.save(buf, format='PNG')
return reader.readtext(buf.getvalue(), detail=0)
def ocr_with_trocr(pil_img):
pixel_values = processor(images=pil_img.convert("RGB"), return_tensors="pt").pixel_values
with torch.no_grad():
ids = model.generate(pixel_values)
return processor.batch_decode(ids, skip_special_tokens=True)[0]
def extract_meter_reading(image):
try:
pil = Image.fromarray(image)
w, h = pil.size
# Define regions: reading top 40%, serial bottom 40%
top_region = pil.crop((0, 0, w, int(h * 0.4)))
bottom_region = pil.crop((0, int(h * 0.5), w, h))
# Enhance regions
top_enh = enhance_image(top_region)
bot_enh = enhance_image(bottom_region)
# OCR regions
top_texts = ocr_with_easyocr(top_enh) + [ocr_with_trocr(top_enh)]
bot_texts = ocr_with_easyocr(bot_enh) + [ocr_with_trocr(bot_enh)]
top_combined = " ".join(top_texts)
bot_combined = " ".join(bot_texts)
# Extract reading: look for digits near kwh
reading_match = re.search(r"(\d+)\s*(?=kwh|kw h|k w h)", top_combined, re.IGNORECASE)
if not reading_match:
# fallback: any 4-7 digit number
fallback = re.findall(r"\b\d{4,7}\b", top_combined)
reading = fallback[0] if fallback else "Not Found"
else:
reading = reading_match.group(1)
# Extract serial: longest digit sequence in bottom
serials = re.findall(r"\d{6,12}", bot_combined)
serial = max(serials, key=len) if serials else "Not Found"
return f"Serial Number: {serial}\nMeter Reading: {reading}"
except Exception as e:
return f"Error: {str(e)}"
# Gradio app
def main():
iface = gr.Interface(
fn=extract_meter_reading,
inputs=gr.Image(type="numpy", label="Upload or Capture Meter Image"),
outputs="text",
title="Meter Reading and Serial Number Extractor",
description="Upload a meter image; extracts serial number and meter reading using region-based OCR."
)
iface.launch()
if __name__ == '__main__':
main() |