ocr / ocr.py
Rhama Damarwijaya
Create ocr.py
a3de355 verified
import pytesseract
from PIL import Image
import cv2
import numpy as np
import re
import os
import glob
import io
class OcrPriceExtractor:
def __init__(self, lang='eng'):
self.lang = lang
self.custom_config = r'--oem 3 --psm 6'
def extract_price(self, text):
pattern = r'Rp\s*\d+(?:[.,]\d+)*'
prices = re.findall(pattern, text)
return prices
def crop_image(self, image):
height = image.shape[0]
crop_top = int(height * 0.2) # 20% from top
crop_bottom = int(height * 0.2) # 20% from bottom
# Crop the image
cropped = image[crop_top:height-crop_bottom, :]
# cv2.imshow("cropped", cropped)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
return cropped
def extract_text_from_bytes(self, image_bytes):
try:
# Convert bytes to numpy array
nparr = np.frombuffer(image_bytes, np.uint8)
image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
if image is None:
raise Exception("Could not decode image bytes")
cropped_image = self.crop_image(image)
pil_image = Image.fromarray(cropped_image)
# Extract text using pytesseract
text = pytesseract.image_to_string(pil_image, config=self.custom_config, lang=self.lang)
text = text.strip()
# Extract prices from the text
prices = self.extract_price(text)
return text, prices
except Exception as e:
print(f"Error during OCR: {str(e)}")
return None, None
def extract_text_from_bytesio(self, bytes_io):
try:
# Convert BytesIO to bytes
image_bytes = bytes_io.getvalue()
return self.extract_text_from_bytes(image_bytes)
except Exception as e:
print(f"Error during OCR from BytesIO: {str(e)}")
return None, None
def extract_text(self, image_input):
try:
if isinstance(image_input, io.BytesIO):
return self.extract_text_from_bytesio(image_input)
elif isinstance(image_input, bytes):
return self.extract_text_from_bytes(image_input)
image = cv2.imread(image_input)
if image is None:
raise Exception("Could not read image")
cropped_image = self.crop_image(image)
pil_image = Image.fromarray(cropped_image)
text = pytesseract.image_to_string(pil_image, config=self.custom_config, lang=self.lang)
text = text.strip()
prices = self.extract_price(text)
return text, prices
except Exception as e:
print(f"Error during OCR: {str(e)}")
return None, None
def test_all_images(self, directory="."):
image_extensions = ('*.jpg', '*.jpeg', '*.png', '*.bmp')
image_files = []
for ext in image_extensions:
image_files.extend(glob.glob(os.path.join(directory, ext)))
if not image_files:
print("No image files found in directory!\n")
return
for image_path in image_files:
print(f"\nProcessing: {image_path}")
print("-" * 50)
text, prices = self.extract_text(image_path)
self._print_results(text, prices)
with open(image_path, 'rb') as f:
bytes_io = io.BytesIO(f.read())
text, prices = self.extract_text(bytes_io)
self._print_results(text, prices)
print("-" * 50)
def _print_results(self, text, prices):
if text:
if prices:
print("\nTest Passed. Found Prices:")
for price in prices:
print(price)
else:
print("\nNo prices found in this image.")
else:
print("No text was extracted or an error occurred.")
if __name__ == "__main__":
import sys
ocr = OcrPriceExtractor()
if len(sys.argv) > 1 and sys.argv[1] == "--all":
ocr.test_all_images()
else:
image_path = "3.jpg"
with open(image_path, 'rb') as f:
bytes_io = io.BytesIO(f.read())
text, prices = ocr.extract_text(bytes_io)
if text:
print("\nFound Prices:")
for price in prices:
print(price)
else:
print("No text was extracted or an error occurred.")