我开发了一个 Android 应用程序,在处理输入图像期间使用 chaquopy 运行 easyocr 和 pyzbar 模块。该应用程序的目标是能够提取文本并解码输入图像中存在的条形码。 问题是 Python 脚本大约需要一分钟才能完成图像处理。所花费的时间本质上是由于easyocr处理造成的。我怎样才能加快这个过程?
我已经在辅助线程中运行脚本。
Python脚本:
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)
我建议将 KerasOCR 与 TensorflowLITE 结合使用,这样您就可以将模型的轻量级格式直接集成到您的应用程序中,无需使用 Chaquopy lib 启动 python 脚本,您会注意到应用程序性能的显着提高。