Sanjayraju30 commited on
Commit
49bdc4d
·
verified ·
1 Parent(s): d9656e4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +96 -19
app.py CHANGED
@@ -15,7 +15,12 @@ import os
15
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
16
 
17
  # Configure Tesseract path for Hugging Face
18
- pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract'
 
 
 
 
 
19
 
20
  # Salesforce configuration (use environment variables in production)
21
  SF_USERNAME = os.getenv("SF_USERNAME", "your_salesforce_username")
@@ -56,27 +61,93 @@ def resize_image(img, max_size_mb=5):
56
  logging.error(f"Image resizing failed: {str(e)}")
57
  return img, None
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  def extract_weight(img):
60
- """Extract weight from image using Tesseract OCR."""
61
  try:
 
 
 
 
62
  # Convert PIL image to OpenCV format
63
  img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
64
- gray = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
65
- # Preprocess image for better OCR accuracy
66
- _, thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
67
- # Configure Tesseract for 7-segment display (digits only, single line)
68
- config = '--psm 7 digits'
69
- text = pytesseract.image_to_string(thresh, config=config)
70
- # Extract numeric values (digits and decimal point)
71
- weight = ''.join(filter(lambda x: x in '0123456789.', text))
72
- # Validate weight (ensure it’s a valid number)
73
- try:
74
- weight_float = float(weight)
75
- # Simplified confidence: 95% if valid number, else 0%
76
- confidence = 95.0 if weight_float > 0 else 0.0
77
- return weight, confidence
78
- except ValueError:
79
- return "Not detected", 0.0
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  except Exception as e:
81
  logging.error(f"OCR processing failed: {str(e)}")
82
  return "Not detected", 0.0
@@ -84,20 +155,24 @@ def extract_weight(img):
84
  def process_image(img):
85
  """Process uploaded or captured image and extract weight."""
86
  if img is None:
 
87
  return "No image uploaded", None, None, None, gr.update(visible=False), gr.update(visible=False)
88
 
89
  ist_time = datetime.now(pytz.timezone("Asia/Kolkata")).strftime("%d-%m-%Y %I:%M:%S %p")
90
  img, img_bytes = resize_image(img)
91
  if img_bytes is None:
 
92
  return "Image processing failed", ist_time, img, None, gr.update(visible=False), gr.update(visible=False)
93
 
94
  weight, confidence = extract_weight(img)
95
 
96
  if weight == "Not detected" or confidence < 95.0:
 
97
  return f"{weight} (Confidence: {confidence:.2f}%)", ist_time, img, None, gr.update(visible=True), gr.update(visible=False)
98
 
99
  img_buffer = io.BytesIO(img_bytes)
100
  img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
 
101
  return f"{weight} kg (Confidence: {confidence:.2f}%)", ist_time, img, img_base64, gr.update(visible=True), gr.update(visible=True)
102
 
103
  def save_to_salesforce(weight_text, img_base64):
@@ -105,6 +180,7 @@ def save_to_salesforce(weight_text, img_base64):
105
  try:
106
  sf = connect_to_salesforce()
107
  if sf is None:
 
108
  return "Failed to connect to Salesforce"
109
 
110
  weight = float(weight_text.split(" ")[0])
@@ -155,10 +231,11 @@ with gr.Blocks(title="⚖️ Auto Weight Logger") as demo:
155
 
156
  gr.Markdown("""
157
  ### Instructions
158
- - Upload a clear, well-lit image of a digital weight scale display.
159
  - Ensure the image is < 5MB (automatically resized if larger).
160
  - Review the detected weight and click 'Confirm and Save to Salesforce' to log the data.
161
  - Works on desktop and mobile browsers.
 
162
  """)
163
 
164
  if __name__ == "__main__":
 
15
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
16
 
17
  # Configure Tesseract path for Hugging Face
18
+ try:
19
+ pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract'
20
+ pytesseract.get_tesseract_version() # Test Tesseract availability
21
+ logging.info("Tesseract is available")
22
+ except Exception as e:
23
+ logging.error(f"Tesseract not found or misconfigured: {str(e)}")
24
 
25
  # Salesforce configuration (use environment variables in production)
26
  SF_USERNAME = os.getenv("SF_USERNAME", "your_salesforce_username")
 
61
  logging.error(f"Image resizing failed: {str(e)}")
62
  return img, None
63
 
64
+ def preprocess_image(img_cv):
65
+ """Preprocess image for OCR: enhance contrast, reduce noise, and apply adaptive thresholding."""
66
+ try:
67
+ # Convert to grayscale
68
+ gray = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
69
+ # Enhance contrast
70
+ clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
71
+ contrast = clahe.apply(gray)
72
+ # Reduce noise with Gaussian blur
73
+ blurred = cv2.GaussianBlur(contrast, (5, 5), 0)
74
+ # Apply adaptive thresholding
75
+ thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
76
+ # Sharpen the image
77
+ kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
78
+ sharpened = cv2.filter2D(thresh, -1, kernel)
79
+ return sharpened
80
+ except Exception as e:
81
+ logging.error(f"Image preprocessing failed: {str(e)}")
82
+ return gray
83
+
84
+ def detect_roi(img_cv):
85
+ """Detect the region of interest (ROI) containing the weight display."""
86
+ try:
87
+ # Convert to grayscale for edge detection
88
+ gray = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
89
+ # Apply edge detection
90
+ edges = cv2.Canny(gray, 50, 150)
91
+ # Find contours
92
+ contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
93
+ if not contours:
94
+ logging.warning("No contours detected for ROI")
95
+ return img_cv # Return full image if no contours found
96
+
97
+ # Find the largest contour (assuming it’s the display)
98
+ largest_contour = max(contours, key=cv2.contourArea)
99
+ x, y, w, h = cv2.boundingRect(largest_contour)
100
+ # Add padding
101
+ padding = 10
102
+ x = max(0, x - padding)
103
+ y = max(0, y - padding)
104
+ w = min(img_cv.shape[1] - x, w + 2 * padding)
105
+ h = min(img_cv.shape[0] - y, h + 2 * padding)
106
+ roi = img_cv[y:y+h, x:x+w]
107
+ logging.info(f"ROI detected at ({x}, {y}, {w}, {h})")
108
+ return roi
109
+ except Exception as e:
110
+ logging.error(f"ROI detection failed: {str(e)}")
111
+ return img_cv
112
+
113
  def extract_weight(img):
114
+ """Extract weight from image using Tesseract OCR with multiple PSM modes."""
115
  try:
116
+ if img is None:
117
+ logging.error("No image provided for OCR")
118
+ return "Not detected", 0.0
119
+
120
  # Convert PIL image to OpenCV format
121
  img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
122
+ # Detect ROI
123
+ roi_img = detect_roi(img_cv)
124
+ # Preprocess the ROI
125
+ processed_img = preprocess_image(roi_img)
126
+
127
+ # Try multiple PSM modes for better detection
128
+ psm_modes = [
129
+ ('--psm 7 digits', 'Single line, digits only'),
130
+ ('--psm 6 digits', 'Single block, digits only'),
131
+ ('--psm 10 digits', 'Single character, digits only'),
132
+ ('--psm 8 digits', 'Single word, digits only')
133
+ ]
134
+
135
+ for config, desc in psm_modes:
136
+ text = pytesseract.image_to_string(processed_img, config=config)
137
+ logging.info(f"OCR attempt with {desc}: Raw text = '{text}'")
138
+ weight = ''.join(filter(lambda x: x in '0123456789.', text.strip()))
139
+ try:
140
+ weight_float = float(weight)
141
+ if weight_float >= 0: # Allow zero weights
142
+ confidence = 95.0 # Simplified confidence for valid numbers
143
+ logging.info(f"Weight detected: {weight} (Confidence: {confidence:.2f}%)")
144
+ return weight, confidence
145
+ except ValueError:
146
+ logging.warning(f"Invalid number format: {weight}")
147
+ continue
148
+
149
+ logging.error("All OCR attempts failed to detect a valid weight")
150
+ return "Not detected", 0.0
151
  except Exception as e:
152
  logging.error(f"OCR processing failed: {str(e)}")
153
  return "Not detected", 0.0
 
155
  def process_image(img):
156
  """Process uploaded or captured image and extract weight."""
157
  if img is None:
158
+ logging.error("No image provided")
159
  return "No image uploaded", None, None, None, gr.update(visible=False), gr.update(visible=False)
160
 
161
  ist_time = datetime.now(pytz.timezone("Asia/Kolkata")).strftime("%d-%m-%Y %I:%M:%S %p")
162
  img, img_bytes = resize_image(img)
163
  if img_bytes is None:
164
+ logging.error("Image resizing failed")
165
  return "Image processing failed", ist_time, img, None, gr.update(visible=False), gr.update(visible=False)
166
 
167
  weight, confidence = extract_weight(img)
168
 
169
  if weight == "Not detected" or confidence < 95.0:
170
+ logging.warning(f"Weight detection failed: {weight} (Confidence: {confidence:.2f}%)")
171
  return f"{weight} (Confidence: {confidence:.2f}%)", ist_time, img, None, gr.update(visible=True), gr.update(visible=False)
172
 
173
  img_buffer = io.BytesIO(img_bytes)
174
  img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
175
+ logging.info(f"Weight detected successfully: {weight} kg")
176
  return f"{weight} kg (Confidence: {confidence:.2f}%)", ist_time, img, img_base64, gr.update(visible=True), gr.update(visible=True)
177
 
178
  def save_to_salesforce(weight_text, img_base64):
 
180
  try:
181
  sf = connect_to_salesforce()
182
  if sf is None:
183
+ logging.error("Salesforce connection failed")
184
  return "Failed to connect to Salesforce"
185
 
186
  weight = float(weight_text.split(" ")[0])
 
231
 
232
  gr.Markdown("""
233
  ### Instructions
234
+ - Upload a clear, well-lit image of a digital weight scale display (7-segment font preferred).
235
  - Ensure the image is < 5MB (automatically resized if larger).
236
  - Review the detected weight and click 'Confirm and Save to Salesforce' to log the data.
237
  - Works on desktop and mobile browsers.
238
+ - If weight detection fails, check the image for glare, low contrast, or non-numeric characters and try again.
239
  """)
240
 
241
  if __name__ == "__main__":