Sanjayraju30 commited on
Commit
2bc6272
·
verified ·
1 Parent(s): a72d8ee

Update ocrr_engine.py

Browse files
Files changed (1) hide show
  1. ocrr_engine.py +40 -30
ocrr_engine.py CHANGED
@@ -1,4 +1,4 @@
1
- import pytesseract
2
  import numpy as np
3
  import cv2
4
  import re
@@ -9,8 +9,11 @@ import sys
9
  # Set up logging
10
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[logging.StreamHandler(sys.stdout)])
11
 
 
 
 
12
  def preprocess_image(img):
13
- """Preprocess image for robust OCR, optimized for various weight display formats."""
14
  try:
15
  # Convert PIL to OpenCV format
16
  img = np.array(img)
@@ -23,61 +26,68 @@ def preprocess_image(img):
23
  clahe = cv2.createCLAHE(clipLimit=4.0, tileGridSize=(8, 8))
24
  enhanced = clahe.apply(gray)
25
 
26
- # Apply adaptive thresholding with flexible block size
27
- block_size = max(11, min(31, int(img.shape[0] / 20) * 2 + 1))
28
  thresh = cv2.adaptiveThreshold(
29
- enhanced, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, block_size, 3
30
  )
31
 
32
- # Sharpen to enhance edges
33
- kernel = np.array([[-1, -1, -1],
34
- [-1, 9, -1],
35
- [-1, -1, -1]])
36
- sharpened = cv2.filter2D(thresh, -1, kernel)
37
-
38
- # Denoise for noisy images
39
- denoised = cv2.fastNlMeansDenoising(sharpened, h=10)
40
-
41
- return denoised
42
  except Exception as e:
43
  logging.error(f"Preprocessing failed: {str(e)}")
44
- return gray # Fallback to grayscale
45
 
46
  def extract_weight_from_image(pil_img):
47
- """Extract weight and unit from a digital scale image, supporting various formats."""
48
  try:
49
  # Preprocess image
50
  thresh = preprocess_image(pil_img)
51
 
52
- # Convert to PIL for Tesseract
53
- pil_img = Image.fromarray(cv2.cvtColor(thresh, cv2.COLOR_GRAY2RGB))
54
 
55
- # Try Tesseract with optimized config for numbers and units
56
- config = r'--oem 3 --psm 7 -c tessedit_char_whitelist=0123456789.,kgKg'
57
- text = pytesseract.image_to_string(pil_img, config=config)
58
- logging.info(f"Tesseract raw output: {text}")
59
 
60
- # Clean and validate text
 
61
  text = text.strip().lower()
62
- text = re.sub(r'\s+', '', text) # Remove extra spaces
63
 
64
- # Extract weight and unit
65
- match = re.search(r'(\d*\.?\d+)([kgkg]?)', text)
66
  if match:
67
  weight_str = match.group(1)
68
  unit = match.group(2) if match.group(2) else "g" # Default to grams if no unit
69
  weight_str = weight_str.replace(',', '.') # Handle decimal formats (e.g., 68,0)
70
- if re.fullmatch(r'^\d*\.?\d+$', weight_str):
71
  weight_str = weight_str.lstrip('0') or '0'
72
- confidence = 95.0 if len(weight_str.replace('.', '')) >= 3 else 90.0
73
  try:
74
  weight = float(weight_str)
75
- if 0.001 <= weight <= 5000:
76
  logging.info(f"Detected weight: {weight} {unit}, Confidence: {confidence:.2f}%")
77
  return weight_str, confidence, unit
78
  except ValueError:
79
  logging.warning(f"Invalid weight format: {weight_str}")
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  logging.info("No valid weight detected.")
82
  return "Not detected", 0.0, ""
83
  except Exception as e:
 
1
+ import easyocr
2
  import numpy as np
3
  import cv2
4
  import re
 
9
  # Set up logging
10
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[logging.StreamHandler(sys.stdout)])
11
 
12
+ # Initialize EasyOCR reader (once at module level for efficiency)
13
+ reader = easyocr.Reader(['en'], gpu=False) # GPU=False for CPU-only environments like Hugging Face Spaces
14
+
15
  def preprocess_image(img):
16
+ """Preprocess image for robust OCR with EasyOCR, optimized for weight displays."""
17
  try:
18
  # Convert PIL to OpenCV format
19
  img = np.array(img)
 
26
  clahe = cv2.createCLAHE(clipLimit=4.0, tileGridSize=(8, 8))
27
  enhanced = clahe.apply(gray)
28
 
29
+ # Apply adaptive thresholding
30
+ block_size = max(11, min(31, int(img.shape[0] / 15) * 2 + 1))
31
  thresh = cv2.adaptiveThreshold(
32
+ enhanced, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, block_size, 2
33
  )
34
 
35
+ return thresh # EasyOCR handles further processing
 
 
 
 
 
 
 
 
 
36
  except Exception as e:
37
  logging.error(f"Preprocessing failed: {str(e)}")
38
+ return gray
39
 
40
  def extract_weight_from_image(pil_img):
41
+ """Extract weight and unit from a digital scale image using EasyOCR."""
42
  try:
43
  # Preprocess image
44
  thresh = preprocess_image(pil_img)
45
 
46
+ # Convert to numpy array for EasyOCR
47
+ img_np = np.array(thresh)
48
 
49
+ # Use EasyOCR to detect text
50
+ results = reader.readtext(img_np, detail=1, paragraph=False)
51
+ logging.info(f"EasyOCR raw output: {results}")
 
52
 
53
+ # Extract weight and unit from detected text
54
+ text = " ".join([result[1] for result in results]) # Combine all detected text
55
  text = text.strip().lower()
56
+ text = re.sub(r'\s+', ' ', text) # Normalize spaces
57
 
58
+ # Extract weight and unit, prioritizing common formats
59
+ match = re.search(r'(-?\d*\.?\d+)([kgkg]?)', text)
60
  if match:
61
  weight_str = match.group(1)
62
  unit = match.group(2) if match.group(2) else "g" # Default to grams if no unit
63
  weight_str = weight_str.replace(',', '.') # Handle decimal formats (e.g., 68,0)
64
+ if re.fullmatch(r'^-?\d*\.?\d+$', weight_str):
65
  weight_str = weight_str.lstrip('0') or '0'
66
+ confidence = min([result[2] for result in results if result[1]] or [0.0]) * 100 # Convert EasyOCR confidence (0-1) to percentage
67
  try:
68
  weight = float(weight_str)
69
+ if -5000 <= weight <= 5000:
70
  logging.info(f"Detected weight: {weight} {unit}, Confidence: {confidence:.2f}%")
71
  return weight_str, confidence, unit
72
  except ValueError:
73
  logging.warning(f"Invalid weight format: {weight_str}")
74
 
75
+ # Fallback to detect numbers without units if no match
76
+ match_no_unit = re.search(r'(-?\d*\.?\d+)', text)
77
+ if match_no_unit and not match:
78
+ weight_str = match_no_unit.group(1)
79
+ weight_str = weight_str.replace(',', '.')
80
+ if re.fullmatch(r'^-?\d*\.?\d+$', weight_str):
81
+ weight_str = weight_str.lstrip('0') or '0'
82
+ confidence = min([result[2] for result in results if result[1]] or [0.0]) * 100
83
+ try:
84
+ weight = float(weight_str)
85
+ if -5000 <= weight <= 5000:
86
+ logging.info(f"Detected weight (no unit): {weight} g, Confidence: {confidence:.2f}%")
87
+ return weight_str, confidence, "g"
88
+ except ValueError:
89
+ logging.warning(f"Invalid weight format: {weight_str}")
90
+
91
  logging.info("No valid weight detected.")
92
  return "Not detected", 0.0, ""
93
  except Exception as e: