File size: 4,454 Bytes
15f17fb 043bbad 7369767 043bbad 7369767 043bbad 15f17fb 043bbad 15f17fb 043bbad 15f17fb 043bbad 7369767 043bbad 15f17fb 043bbad 15f17fb 043bbad 15f17fb 043bbad 15f17fb 043bbad 15f17fb 043bbad 15f17fb 043bbad 15f17fb 043bbad 15f17fb 043bbad 7369767 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
import hashlib
from types import SimpleNamespace
import gradio as gr
from PIL import Image
from ultralytics import YOLO
from ultralytics.utils.plotting import save_one_box
import easyocr
import zxingcpp
import numpy as np
from utils import custom_plot
model = YOLO("YOLOV8s_Barcode_Detection.pt")
reader = easyocr.Reader(['en'])
key_hash = "6734e0268423441620ada6c66bf76c255500139962741833ab33185274b8a010"
hash = lambda x: hashlib.sha256(x.encode()).hexdigest()
def process_image(input_img, activation_key, progress=gr.Progress()):
if input_img is None:
return None, "請上傳圖片後再進行辨識。"
if hash(activation_key) != key_hash:
return None, "金鑰錯誤,請確認後再試一次。"
# Perform object detection on an image
result = model(input_img, imgsz=(1280))[0]
crops = []
for d in result.boxes:
crops.append(save_one_box(
d.xyxy,
result.orig_img.copy(),
save=False,
))
texts = []
for pr, crop in enumerate(crops):
progress((pr+1) / len(crops), desc="辨識中")
img = Image.fromarray(crop)
res = zxingcpp.read_barcodes(img)
if not res:
# rotate and retry
for i in range(1, 8):
res = zxingcpp.read_barcodes(img.rotate(i, resample=2))
if res:
break
res = zxingcpp.read_barcodes(img.rotate(-i, resample=2))
if res:
break
if not res:
# resort to ocr the bottom-left no.
full_res = reader.readtext(crop, allowlist='-0123456789')
res = sorted(
[r for r in full_res if (
r[0][3][0] < (img.width/4) and r[0][3][1] > (img.height/3) and
r[0][0][0] < (img.width/4) and r[0][0][1] > (img.height/2)
)],
key=lambda x: x[2], reverse=True,
)
if res:
pred_text = res[0][1]
# sanity check if the no. is not divided into multiple box
cur_box = res[0]
# if len(cur_box[1]) < 13:
other_boxes = [r for r in full_res if r[1] != cur_box[1]]
thrs = np.linalg.norm(img.size) / 25
while other_boxes:
upper = np.linalg.norm(cur_box[0][1] - np.array([b[0][0] for b in other_boxes]), axis=1)
lower = np.linalg.norm(cur_box[0][2] - np.array([b[0][3] for b in other_boxes]), axis=1)
is_same = (upper < thrs) & (lower < thrs)
rank = sorted(
[(i, dist, s) for (i, dist), s in zip(enumerate(lower + upper), is_same) if s],
key=lambda x: x[1]
)
if rank:
cur_box = other_boxes[rank[0][0]]
other_boxes = [r for r in other_boxes if r[1] != cur_box[1]]
pred_text += cur_box[1]
else:
break
# HACK
if len(pred_text) != 15:
res = []
res = [SimpleNamespace(text=pred_text)] if res else []
texts.append(res[0].text if res else None)
output_text = '\n'.join([t for t in texts if isinstance(t, str)])
results_img = custom_plot(
result, font_size=40, pil=True,
barcode_texts=texts,
)
return results_img, output_text
# Defining the Gradio Interface
with gr.Blocks() as demo:
gr.Markdown("# Barcode")
gr.Markdown("請用下方 example 圖片測試條碼辨識功能,或上傳您自己的圖片。")
with gr.Row():
with gr.Column():
input_view = gr.Image(type="pil", label="輸入圖片")
activation_key = gr.Textbox(label="金鑰")
btn = gr.Button("辨識", variant="primary")
gr.Examples(examples=[["example1.jpeg", ""], ["example2.jpeg", ""]], inputs=input_view)
with gr.Column():
output_view = gr.Image(type="pil", label="辨識結果")
with gr.Column():
text_output = gr.Textbox(label="條碼內容")
# Wire up the button
btn.click(
fn=process_image,
inputs=[input_view, activation_key],
outputs=[output_view, text_output]
)
if __name__ == "__main__":
demo.launch()
|