File size: 7,030 Bytes
9ee6029
47ae1d3
6896c3d
 
47ae1d3
 
886d0ac
bf09d82
dcf1926
b5adec5
 
 
 
 
 
 
 
 
 
 
dcf1926
b5adec5
 
dcf1926
 
 
b5adec5
dcf1926
 
b5adec5
dcf1926
47ae1d3
b5adec5
 
 
 
 
 
 
 
 
 
655f2f4
47ae1d3
b5adec5
 
 
 
 
 
 
 
47ae1d3
80f71bc
b5adec5
 
 
 
 
 
 
 
 
 
 
 
 
 
47ae1d3
6896c3d
b5adec5
 
 
 
 
 
 
6896c3d
80f71bc
b5adec5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47ae1d3
2844ae3
b5adec5
 
 
 
6896c3d
 
dcf1926
 
 
 
 
 
 
 
 
 
 
 
b5adec5
 
 
dcf1926
 
 
 
 
 
 
 
 
 
b5adec5
dcf1926
b5adec5
dcf1926
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b5adec5
80f71bc
b5adec5
80f71bc
 
 
b5adec5
80f71bc
dcf1926
47ae1d3
 
 
b5adec5
2844ae3
b5adec5
47ae1d3
9ee6029
47ae1d3
886d0ac
47ae1d3
 
 
dcf1926
 
9ee6029
 
b5adec5
dcf1926
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
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)