KR_LPR / app.py
noahzhy's picture
Update TFliteDemo constructor parameters and model.tflite file
931f551
raw
history blame
4.56 kB
import os, glob
from itertools import groupby
import cv2
import numpy as np
import gradio as gr
import tensorflow as tf
def get_sample_images():
list_ = glob.glob(os.path.join(os.path.dirname(__file__), 'samples/*.jpg'))
# sort by name
list_.sort(key=lambda x: int(x.split('/')[-1].split('.')[0]))
return [[i] for i in list_]
def cv2_imread(path):
return cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
def decode_label(mat, chars) -> str:
# mat is the output of model
# get char indices along best path
best_path_indices = np.argmax(mat[0], axis=-1)
# collapse best path (using itertools.groupby), map to chars, join char list to string
best_chars_collapsed = [chars[k] for k, _ in groupby(best_path_indices) if k != len(chars)]
res = ''.join(best_chars_collapsed)
# remove space and '_'
res = res.replace(' ', '').replace('_', '')
return res
def center_fit(img, w, h, inter=cv2.INTER_NEAREST, top_left=True):
# get img shape
img_h, img_w = img.shape[:2]
# get ratio
ratio = min(w / img_w, h / img_h)
if len(img.shape) == 3:
inter = cv2.INTER_AREA
# resize img
img = cv2.resize(img, (int(img_w * ratio), int(img_h * ratio)), interpolation=inter)
# get new img shape
img_h, img_w = img.shape[:2]
# get start point
start_w = (w - img_w) // 2
start_h = (h - img_h) // 2
if top_left:
start_w = 0
start_h = 0
if len(img.shape) == 2:
# create new img
new_img = np.zeros((h, w), dtype=np.uint8)
new_img[start_h:start_h+img_h, start_w:start_w+img_w] = img
else:
new_img = np.zeros((h, w, 3), dtype=np.uint8)
new_img[start_h:start_h+img_h, start_w:start_w+img_w, :] = img
return new_img
def load_dict(dict_path='label.names'):
with open(dict_path, 'r', encoding='utf-8') as f:
_dict = f.read().splitlines()
_dict = {i: _dict[i] for i in range(len(_dict))}
return _dict
class TFliteDemo:
def __init__(self, model_path, blank=0, conf_mode="min"):
self.blank = blank
self.conf_mode = conf_mode
self.interpreter = tf.lite.Interpreter(model_path=model_path)
self.interpreter.allocate_tensors()
self.inputs = self.interpreter.get_input_details()
self.outputs = self.interpreter.get_output_details()
def inference(self, x):
self.interpreter.set_tensor(self.inputs[0]['index'], x)
self.interpreter.invoke()
return self.interpreter.get_tensor(self.outputs[0]['index'])
def preprocess(self, img):
if isinstance(img, str):
image = cv2_imread(img)
else:
# check none
if img is None:
raise ValueError('img is None')
image = img.copy()
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = center_fit(image, 192, 96, top_left=True)
image = np.reshape(image, (1, *image.shape, 1)).astype(np.float32) / 255.0
return image
def get_confidence(self, pred, mode="mean"):
_argmax = np.argmax(pred, axis=-1)
_idx = _argmax != pred.shape[-1] - 1
conf = pred[_idx, _argmax[_idx]]
conf = np.exp(conf)
return np.min(conf) if mode == "min" else np.mean(conf)
def postprocess(self, pred):
label = decode_label(pred, load_dict())
conf = self.get_confidence(pred[0], mode=self.conf_mode)
# keep 4 decimal places
conf = float('{:.4f}'.format(conf))
return label, conf
def inference(img):
img = demo.preprocess(img)
pred = demo.inference(img)
return demo.postprocess(pred)
if __name__ == '__main__':
_TITLE = '''South Korean License Plate Recognition'''
_DESCRIPTION = '''
<div>
<p style="text-align: center; font-size: 1.3em">This is a demo of South Korean License Plate Recognition.
<a style="display:inline-block; margin-left: .5em" href='https://github.com/noahzhy/KR_LPR_TF/'><img src='https://img.shields.io/github/stars/noahzhy/KR_LPR_TF?style=social' /></a>
</p>
</div>
'''
# init model
demo = TFliteDemo(os.path.join(os.path.dirname(__file__), 'model.tflite'))
interface = gr.Interface(
fn=inference,
inputs="image",
outputs=[
gr.Textbox(label="Plate Number", type="text"),
gr.Textbox(label="Confidence", type="text"),
],
title=_TITLE,
description=_DESCRIPTION,
examples=get_sample_images(),
)
interface.launch()