I developed an Android application that uses chaquopy to run easyocr and pyzbar modules, during the processing of an input image. The app goal is to be able to extract text and decode barcodes present in the input image. The problem is that the Python script takes about a minute to finish processing the image. The time it takes is essentially due to easyocr processing. How can I speed up the process?
I already run the script in a secondary thread.
Python script:
import pyzbar
from pyzbar.pyzbar import decode
import easyocr
import cv2
import numpy as np
import re
import os
import io
import base64
language = ['fr']
reader = easyocr.Reader(lang_list=language)
def getPrice(base64_image):
YELLOW_MIN = np.array([20, 100, 100], dtype=np.uint8)
YELLOW_MAX = np.array([40, 255, 255], dtype=np.uint8)
# Converte-se o base64 numa imagem cv2.
decoded_image = base64.b64decode(base64_image)
np_image = np.fromstring(decoded_image, np.uint8)
image_cv2 = cv2.imdecode(np_image, cv2.IMREAD_UNCHANGED)
# Conversão da imagem RGB em HSV.
image_cv2_hsv = cv2.cvtColor(image_cv2, cv2.COLOR_BGR2HSV)
# Isolamento da região onde se encontra o preço.
yellow_mask = cv2.inRange(image_cv2_hsv, YELLOW_MIN, YELLOW_MAX)
contours = cv2.findContours(yellow_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
greater_contour = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(greater_contour)
center_x = x + w // 2
center_y = y + h // 2
tamanho_retangulo_central = 0.90
new_x = int(center_x - w * tamanho_retangulo_central / 2)
new_y = int(center_y - h * tamanho_retangulo_central / 2)
new_w = int(w * tamanho_retangulo_central)
new_h = int(h * tamanho_retangulo_central)
roi_cv2 = image_cv2[new_y:new_y + new_h, new_x:new_x + new_w]
# Implementação do OCR.
results = reader.readtext(roi_cv2)
# Pós-processamento da saída do OCR.
flag = True
output = ''
int_part = ''
decimal_part = ''
price = 'None'
for result in results:
text = result[1]
if re.match(r'^\d{1},\d{2}$', text):
flag = False
output = text
break
elif re.match(r'^[^\d]\d{1},\d{2}$', text):
flag = False
output = text
break
elif re.match(r'^\d{2},\d{2}$', text):
flag = False
output = text[1:]
break
elif re.match(r'^[^\d]\d{2},\d{2}$', text):
flag = False
output = text
break
elif re.match(r'^\d{3},\d{2}$', text):
flag = False
output = text[1:]
break
elif re.match(r'^[^\d]\d{1} ,\d{2}$', text):
flag = False
output = text
break
elif re.match(r'^[^\d]\d{2} ,\d{2}$', text):
flag = False
output = text
break
if flag == True:
for result in results:
text = result[1]
if re.match(r'^[^\d]\d{1}$', text):
int_part = text
elif re.match(r'^\d{2}$', text):
decimal_part = text
elif re.match(r'^[^\d]\d{1},$', text):
int_part = text
elif re.match(r'^,\d{2}$', text):
decimal_part = text
elif re.match(r'^[^\d]\d{2},$', text):
int_part = text
elif re.match(r'^[^\d]\d{2}$', text):
int_part = text
elif re.match(r'^\d{3},$', text):
int_part = text[1:]
elif re.match(r'^\d{3}$', text):
int_part = text[1:]
elif re.match(r"^',\d{2}$", text):
decimal_part = text
if int_part != '' and decimal_part != '':
break
output = int_part + decimal_part
digits = re.findall(r'\d', output)
if len(digits) == 3:
price = digits[0] + ',' + digits[1] + digits[2] + ' €'
elif len(digits) == 4:
price = digits[0] + digits[1] + ',' + digits[2] + digits[3] + ' €'
return str(price)
def getProductNum(base64_image):
# Converte-se o base64 numa imagem cv2.
decoded_image = base64.b64decode(base64_image)
np_image = np.fromstring(decoded_image, np.uint8)
image_cv2 = cv2.imdecode(np_image, cv2.IMREAD_UNCHANGED)
# Redimensionamento da imagem.
zoom_percent = 0.2
height, weight, _ = image_cv2.shape
new_height = int(height * zoom_percent)
new_weight = int(weight * zoom_percent)
resized_image = cv2.resize(image_cv2, (new_weight, new_height))
# Implementação do OCR.
results = reader.readtext(resized_image)
# Pós processamento da saída do OCR.
product_num = 'None'
for result in results:
text = result[1]
if re.match(r'^\d{7}$', text):
product_num = text
break
return str(product_num)
def getBarCodeData(base64_image):
# Converte-se o base64 numa imagem cv2.
decoded_image = base64.b64decode(base64_image)
np_image = np.fromstring(decoded_image, np.uint8)
image_cv2 = cv2.imdecode(np_image, cv2.IMREAD_UNCHANGED)
# Binarização da imagem RGB.
image_cv2_gray = cv2.cvtColor(image_cv2, cv2.COLOR_BGR2GRAY)
image_cv2_binary_1 = cv2.adaptiveThreshold(
image_cv2_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 51, 1
)
image_cv2_binary_2 = cv2.adaptiveThreshold(
image_cv2_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 41, 1
)
image_cv2_binary_3 = cv2.adaptiveThreshold(
image_cv2_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 1
)
image_cv2_binary_4 = cv2.adaptiveThreshold(
image_cv2_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 21, 1
)
image_cv2_binary_5 = cv2.adaptiveThreshold(
image_cv2_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 1
)
# Decodificação do código de barras.
barcode_data = 'None'
barcodes = decode(image_cv2, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
elif len(barcodes) == 0:
barcodes = decode(image_cv2_binary_1, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
elif len(barcodes) == 0:
kernel = np.ones((3, 3), np.uint8)
eroded_image = cv2.erode(image_cv2_binary_1, kernel, iterations=1)
dilated_image = cv2.dilate(eroded_image, kernel, iterations=1)
barcodes = decode(dilated_image, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
elif len(barcodes) == 0:
barcodes = decode(image_cv2_binary_2, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
elif len(barcodes) == 0:
kernel = np.ones((3, 3), np.uint8)
eroded_image = cv2.erode(image_cv2_binary_2, kernel, iterations=1)
dilated_image = cv2.dilate(eroded_image, kernel, iterations=1)
barcodes = decode(dilated_image, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
elif len(barcodes) == 0:
barcodes = decode(image_cv2_binary_3, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
elif len(barcodes) == 0:
kernel = np.ones((3, 3), np.uint8)
eroded_image = cv2.erode(image_cv2_binary_3, kernel, iterations=1)
dilated_image = cv2.dilate(eroded_image, kernel, iterations=1)
barcodes = decode(dilated_image, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
elif len(barcodes) == 0:
barcodes = decode(image_cv2_binary_4, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
elif len(barcodes) == 0:
kernel = np.ones((3, 3), np.uint8)
eroded_image = cv2.erode(image_cv2_binary_4, kernel, iterations=1)
dilated_image = cv2.dilate(eroded_image, kernel, iterations=1)
barcodes = decode(dilated_image, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
elif len(barcodes) == 0:
barcodes = decode(image_cv2_binary_5, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
elif len(barcodes) == 0:
kernel = np.ones((3, 3), np.uint8)
eroded_image = cv2.erode(image_cv2_binary_5, kernel, iterations=1)
dilated_image = cv2.dilate(eroded_image, kernel, iterations=1)
barcodes = decode(dilated_image, symbols=[pyzbar.pyzbar.ZBarSymbol.CODE128])
if len(barcodes) != 0:
for barcode in barcodes:
barcode_data = barcode.data.decode('utf-8')
barcode_type = barcode.type
return str(barcode_data)
I recommend using KerasOCR with TensorflowLITE so you can integrate the lightweight format of the model directly in your application no need to launch python scripts with Chaquopy lib, you will notice a remarkable improvement in the performance of the application.