Spaces:
Running
Running
Refactor inference function and add preprocessing
Browse files
app.py
CHANGED
|
@@ -15,37 +15,20 @@ def get_sample_images():
|
|
| 15 |
return [[i] for i in list_]
|
| 16 |
|
| 17 |
|
| 18 |
-
def
|
| 19 |
-
|
| 20 |
-
demo = TFliteDemo(os.path.join(os.path.dirname(__file__), 'model.tflite'))
|
| 21 |
-
# check image is not None
|
| 22 |
-
if image is None:
|
| 23 |
-
return 'None', 'None'
|
| 24 |
-
# load image
|
| 25 |
-
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
| 26 |
-
image = center_fit(image, 128, 64, top_left=True)
|
| 27 |
-
image = np.reshape(image, (1, *image.shape, 1)).astype(np.uint8)
|
| 28 |
-
# inference
|
| 29 |
-
pred = demo.inference(image)
|
| 30 |
-
# decode
|
| 31 |
-
dict = load_dict(os.path.join(os.path.dirname(__file__), 'label.names'))
|
| 32 |
-
res = decode_label(pred, dict)
|
| 33 |
-
# get confidence
|
| 34 |
-
confidence = get_confidence(pred)
|
| 35 |
-
return res, confidence
|
| 36 |
|
| 37 |
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
return self.interpreter.get_tensor(self.output_details[0]['index'])
|
| 49 |
|
| 50 |
|
| 51 |
def center_fit(img, w, h, inter=cv2.INTER_NEAREST, top_left=True):
|
|
@@ -86,31 +69,60 @@ def load_dict(dict_path='label.names'):
|
|
| 86 |
return dict
|
| 87 |
|
| 88 |
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
if idx != blank_idx:
|
| 98 |
-
avg_confidence.append(conf)
|
| 99 |
-
conf = np.mean(avg_confidence) / 255.0
|
| 100 |
-
# keep 4 decimal places
|
| 101 |
-
return "{:.4f}".format(conf)
|
| 102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
|
| 104 |
-
def
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
|
| 115 |
|
| 116 |
if __name__ == '__main__':
|
|
@@ -122,6 +134,8 @@ if __name__ == '__main__':
|
|
| 122 |
</p>
|
| 123 |
</div>
|
| 124 |
'''
|
|
|
|
|
|
|
| 125 |
interface = gr.Interface(
|
| 126 |
fn=inference,
|
| 127 |
inputs="image",
|
|
|
|
| 15 |
return [[i] for i in list_]
|
| 16 |
|
| 17 |
|
| 18 |
+
def cv2_imread(path):
|
| 19 |
+
return cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
|
| 22 |
+
def decode_label(mat, chars) -> str:
|
| 23 |
+
# mat is the output of model
|
| 24 |
+
# get char indices along best path
|
| 25 |
+
best_path_indices = np.argmax(mat[0], axis=-1)
|
| 26 |
+
# collapse best path (using itertools.groupby), map to chars, join char list to string
|
| 27 |
+
best_chars_collapsed = [chars[k] for k, _ in groupby(best_path_indices) if k != len(chars)]
|
| 28 |
+
res = ''.join(best_chars_collapsed)
|
| 29 |
+
# remove space and '_'
|
| 30 |
+
res = res.replace(' ', '').replace('_', '')
|
| 31 |
+
return res
|
|
|
|
| 32 |
|
| 33 |
|
| 34 |
def center_fit(img, w, h, inter=cv2.INTER_NEAREST, top_left=True):
|
|
|
|
| 69 |
return dict
|
| 70 |
|
| 71 |
|
| 72 |
+
class TFliteDemo:
|
| 73 |
+
def __init__(self, model_path, blank=85, conf_mode="mean"):
|
| 74 |
+
self.blank = blank
|
| 75 |
+
self.conf_mode = conf_mode
|
| 76 |
+
self.interpreter = tf.lite.Interpreter(model_path=model_path)
|
| 77 |
+
self.interpreter.allocate_tensors()
|
| 78 |
+
self.input_details = self.interpreter.get_input_details()
|
| 79 |
+
self.output_details = self.interpreter.get_output_details()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
+
def inference(self, x):
|
| 82 |
+
self.interpreter.set_tensor(self.input_details[0]['index'], x)
|
| 83 |
+
self.interpreter.invoke()
|
| 84 |
+
return self.interpreter.get_tensor(self.output_details[0]['index'])
|
| 85 |
|
| 86 |
+
def preprocess(self, img):
|
| 87 |
+
if isinstance(img, str):
|
| 88 |
+
image = cv2_imread(img)
|
| 89 |
+
else:
|
| 90 |
+
image = img
|
| 91 |
+
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
| 92 |
+
image = center_fit(image, 128, 64, top_left=True)
|
| 93 |
+
image = np.reshape(image, (1, *image.shape, 1)).astype(np.uint8)
|
| 94 |
+
return image
|
| 95 |
+
|
| 96 |
+
def get_confidence(self, pred, mode="mean"):
|
| 97 |
+
conf = []
|
| 98 |
+
idxs = np.argmax(pred, axis=-1)
|
| 99 |
+
values = np.max(pred, axis=-1)
|
| 100 |
+
|
| 101 |
+
for idx, c in zip(idxs, values):
|
| 102 |
+
if idx == self.blank: continue
|
| 103 |
+
conf.append(c/255)
|
| 104 |
+
|
| 105 |
+
if mode == "min":
|
| 106 |
+
return np.min(conf)
|
| 107 |
+
|
| 108 |
+
return np.mean(conf)
|
| 109 |
+
|
| 110 |
+
def postprocess(self, pred):
|
| 111 |
+
label = decode_label(pred, load_dict())
|
| 112 |
+
conf = self.get_confidence(pred[0], mode=self.conf_mode)
|
| 113 |
+
# keep 4 decimal places
|
| 114 |
+
conf = float('{:.4f}'.format(conf))
|
| 115 |
+
return label, conf
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def inference(img):
|
| 119 |
+
# preprocess
|
| 120 |
+
img = demo.preprocess(img)
|
| 121 |
+
# inference
|
| 122 |
+
pred = demo.inference(img)
|
| 123 |
+
# postprocess
|
| 124 |
+
label, conf = demo.postprocess(pred)
|
| 125 |
+
return label, conf
|
| 126 |
|
| 127 |
|
| 128 |
if __name__ == '__main__':
|
|
|
|
| 134 |
</p>
|
| 135 |
</div>
|
| 136 |
'''
|
| 137 |
+
# init model
|
| 138 |
+
demo = TFliteDemo(os.path.join(os.path.dirname(__file__), 'model.tflite'))
|
| 139 |
interface = gr.Interface(
|
| 140 |
fn=inference,
|
| 141 |
inputs="image",
|