geethareddy commited on
Commit
1ff656a
·
verified ·
1 Parent(s): d0186bc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -27
app.py CHANGED
@@ -9,31 +9,35 @@ import pytz
9
  import numpy as np
10
  import logging
11
 
12
- # Set up logging for better debugging
13
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
14
 
15
  # Configure Tesseract path (ensure it's correctly set to your Tesseract installation)
16
  try:
17
- pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract' # Adjust this to your tesseract path
18
- pytesseract.get_tesseract_version() # Test Tesseract availability
19
- logging.info("Tesseract is available")
20
  except Exception as e:
21
  logging.error(f"Tesseract not found or misconfigured: {str(e)}")
22
 
23
- # Image Preprocessing to improve OCR accuracy
24
  def preprocess_image(img_cv):
25
- """Preprocess image for OCR: enhance contrast, reduce noise, and apply adaptive thresholding."""
26
  try:
27
- # Convert to grayscale
28
  gray = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
29
- # Enhance contrast using CLAHE (Contrast Limited Adaptive Histogram Equalization)
 
30
  clahe = cv2.createCLAHE(clipLimit=5.0, tileGridSize=(8, 8))
31
  contrast = clahe.apply(gray)
32
- # Reduce noise with Gaussian blur
 
33
  blurred = cv2.GaussianBlur(contrast, (5, 5), 0)
34
- # Apply adaptive thresholding for better binary image representation
 
35
  thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
36
- # Sharpen the image to enhance details
 
37
  sharpened = cv2.filter2D(thresh, -1, np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]]))
38
  return sharpened
39
  except Exception as e:
@@ -42,35 +46,36 @@ def preprocess_image(img_cv):
42
 
43
  # Function to extract weight from the image using Tesseract OCR
44
  def extract_weight(img):
45
- """Extract weight from image using Tesseract OCR."""
46
  try:
47
  if img is None:
48
  logging.error("No image provided for OCR")
49
  return "Not detected", 0.0, None
50
 
51
- # Convert PIL image to OpenCV format for processing
52
  img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
53
- # Preprocess the image (contrast, noise reduction, etc.)
 
54
  processed_img = preprocess_image(img_cv)
55
 
56
- # OCR configuration to focus on digits and decimals
57
  custom_config = r'--oem 3 --psm 6 -c tessedit_char_whitelist=0123456789.'
58
 
59
  # Run OCR on the processed image
60
  text = pytesseract.image_to_string(processed_img, config=custom_config)
61
  logging.info(f"OCR result: '{text}'")
62
 
63
- # Extract valid weight (only digits and decimals)
64
  weight = ''.join(filter(lambda x: x in '0123456789.', text.strip()))
65
  if weight:
66
  try:
67
  weight_float = float(weight)
68
- if weight_float >= 0: # Ensure valid weight value
69
- confidence = 95.0 # High confidence if weight is valid
70
  logging.info(f"Weight detected: {weight} (Confidence: {confidence:.2f}%)")
71
  return weight, confidence, processed_img
72
  except ValueError:
73
- logging.warning(f"Invalid number format: {weight}")
74
 
75
  logging.error("OCR failed to detect a valid weight")
76
  return "Not detected", 0.0, None
@@ -78,25 +83,25 @@ def extract_weight(img):
78
  logging.error(f"OCR processing failed: {str(e)}")
79
  return "Not detected", 0.0, None
80
 
81
- # Main function to process the image and return results
82
  def process_image(img):
83
- """Process uploaded or captured image and extract weight."""
84
  if img is None:
85
- logging.error("No image provided")
86
  return "No image uploaded", None, gr.update(visible=False), gr.update(visible=False)
87
 
88
  # Get the current time in IST format
89
  ist_time = datetime.now(pytz.timezone("Asia/Kolkata")).strftime("%d-%m-%Y %I:%M:%S %p")
90
 
91
- # Extract weight and confidence from the image
92
  weight, confidence, processed_img = extract_weight(img)
93
 
94
- # If no weight detected, display the failure message
95
  if weight == "Not detected" or confidence < 95.0:
96
  logging.warning(f"Weight detection failed: {weight} (Confidence: {confidence:.2f}%)")
97
  return f"{weight} (Confidence: {confidence:.2f}%)", ist_time, gr.update(visible=True), gr.update(visible=False)
98
 
99
- # Convert processed image to base64 for displaying it as a snapshot
100
  pil_image = Image.fromarray(processed_img)
101
  buffered = io.BytesIO()
102
  pil_image.save(buffered, format="PNG")
@@ -104,7 +109,7 @@ def process_image(img):
104
 
105
  return f"{weight} kg (Confidence: {confidence:.2f}%)", ist_time, img_base64, gr.update(visible=True)
106
 
107
- # Gradio Interface for user input and displaying results
108
  with gr.Blocks(title="⚖️ Auto Weight Logger") as demo:
109
  gr.Markdown("## ⚖️ Auto Weight Logger")
110
  gr.Markdown("📷 Upload or capture an image of a digital weight scale (max 5MB).")
@@ -126,7 +131,7 @@ with gr.Blocks(title="⚖️ Auto Weight Logger") as demo:
126
 
127
  gr.Markdown("""
128
  ### Instructions
129
- - Upload a clear, well-lit image of a digital weight scale display (7-segment font preferred).
130
  - Ensure the image is < 5MB (automatically resized if larger).
131
  - Review the detected weight and try again if it's incorrect.
132
  """)
 
9
  import numpy as np
10
  import logging
11
 
12
+ # Set up logging for debugging and better visibility
13
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
14
 
15
  # Configure Tesseract path (ensure it's correctly set to your Tesseract installation)
16
  try:
17
+ pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract' # Change path if necessary
18
+ pytesseract.get_tesseract_version() # Confirm Tesseract is properly set
19
+ logging.info("Tesseract is configured properly.")
20
  except Exception as e:
21
  logging.error(f"Tesseract not found or misconfigured: {str(e)}")
22
 
23
+ # Image Preprocessing to clean up the image for better OCR
24
  def preprocess_image(img_cv):
25
+ """Preprocess the image to enhance clarity for OCR."""
26
  try:
27
+ # Convert image to grayscale for easier processing
28
  gray = cv2.cvtColor(img_cv, cv2.COLOR_BGR2GRAY)
29
+
30
+ # Enhance the image contrast using CLAHE (Contrast Limited Adaptive Histogram Equalization)
31
  clahe = cv2.createCLAHE(clipLimit=5.0, tileGridSize=(8, 8))
32
  contrast = clahe.apply(gray)
33
+
34
+ # Apply Gaussian Blur to reduce noise
35
  blurred = cv2.GaussianBlur(contrast, (5, 5), 0)
36
+
37
+ # Apply adaptive thresholding for better image clarity
38
  thresh = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
39
+
40
+ # Sharpen the image to emphasize digits
41
  sharpened = cv2.filter2D(thresh, -1, np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]]))
42
  return sharpened
43
  except Exception as e:
 
46
 
47
  # Function to extract weight from the image using Tesseract OCR
48
  def extract_weight(img):
49
+ """Extract weight using Tesseract OCR, focusing on numeric digits."""
50
  try:
51
  if img is None:
52
  logging.error("No image provided for OCR")
53
  return "Not detected", 0.0, None
54
 
55
+ # Convert the PIL image to OpenCV format for processing
56
  img_cv = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
57
+
58
+ # Preprocess the image for better OCR results
59
  processed_img = preprocess_image(img_cv)
60
 
61
+ # Tesseract configuration focusing on digits and decimals
62
  custom_config = r'--oem 3 --psm 6 -c tessedit_char_whitelist=0123456789.'
63
 
64
  # Run OCR on the processed image
65
  text = pytesseract.image_to_string(processed_img, config=custom_config)
66
  logging.info(f"OCR result: '{text}'")
67
 
68
+ # Extract only the numeric part (weight)
69
  weight = ''.join(filter(lambda x: x in '0123456789.', text.strip()))
70
  if weight:
71
  try:
72
  weight_float = float(weight)
73
+ if weight_float >= 0: # Ensure it's a valid weight
74
+ confidence = 95.0 # Set high confidence for valid weight
75
  logging.info(f"Weight detected: {weight} (Confidence: {confidence:.2f}%)")
76
  return weight, confidence, processed_img
77
  except ValueError:
78
+ logging.warning(f"Invalid weight format: {weight}")
79
 
80
  logging.error("OCR failed to detect a valid weight")
81
  return "Not detected", 0.0, None
 
83
  logging.error(f"OCR processing failed: {str(e)}")
84
  return "Not detected", 0.0, None
85
 
86
+ # Main function to process the uploaded image and display results
87
  def process_image(img):
88
+ """Process the uploaded image, extract weight, and display results."""
89
  if img is None:
90
+ logging.error("No image uploaded")
91
  return "No image uploaded", None, gr.update(visible=False), gr.update(visible=False)
92
 
93
  # Get the current time in IST format
94
  ist_time = datetime.now(pytz.timezone("Asia/Kolkata")).strftime("%d-%m-%Y %I:%M:%S %p")
95
 
96
+ # Extract weight and confidence
97
  weight, confidence, processed_img = extract_weight(img)
98
 
99
+ # If weight detection failed, display an appropriate message
100
  if weight == "Not detected" or confidence < 95.0:
101
  logging.warning(f"Weight detection failed: {weight} (Confidence: {confidence:.2f}%)")
102
  return f"{weight} (Confidence: {confidence:.2f}%)", ist_time, gr.update(visible=True), gr.update(visible=False)
103
 
104
+ # Convert processed image to base64 format for displaying in Gradio
105
  pil_image = Image.fromarray(processed_img)
106
  buffered = io.BytesIO()
107
  pil_image.save(buffered, format="PNG")
 
109
 
110
  return f"{weight} kg (Confidence: {confidence:.2f}%)", ist_time, img_base64, gr.update(visible=True)
111
 
112
+ # Gradio interface setup
113
  with gr.Blocks(title="⚖️ Auto Weight Logger") as demo:
114
  gr.Markdown("## ⚖️ Auto Weight Logger")
115
  gr.Markdown("📷 Upload or capture an image of a digital weight scale (max 5MB).")
 
131
 
132
  gr.Markdown("""
133
  ### Instructions
134
+ - Upload a clear, well-lit image of a digital weight scale display (preferably a seven-segment font).
135
  - Ensure the image is < 5MB (automatically resized if larger).
136
  - Review the detected weight and try again if it's incorrect.
137
  """)