依赖
paddle2onnx==1.3.1
onnxruntime-gpu==1.14.0
ultralytics==8.3.38
背景
在车牌识别之一:车牌检测(包含全部免费的数据集、源码和模型下载)我们得到了车牌检测模型;
在车牌识别之二:车牌OCR识别(包含全部免费的数据集、源码和模型下载)我们得到了车牌识别模型;
本节中,我们将检测和识别整合起来,并主要使用onnx格式进行推理, windows或没有GPU同样适用
项目地址(含模型)
戳这里获取
PlateRecognition
├── 22_16_5_0_25_24_25.jpg
├── license_models
│ ├── dict.txt
│ ├── license_ocr.onnx
│ ├── y11n-pose_plate_best.onnx
│ └── y11n-pose_plate_best.pt
├── ocr_rec.py
├── plate.jpg
├── plate_rec.py
├── README.md
├── requirements.txt
├── result.jpg
└── test_plate
├── 402d522edcc44c51bd29d4c21588cf9d.jpeg
├── ec4a268fc_r.jpg
├── hcqccip6335913.jpg
├── nimg.ws.126.jpeg
├── u=1570203173,1434495175&fm=253&fmt=auto&app=138&f=JPEG.webp
├── u=2912148279,95351854&fm=253&fmt=auto&app=138&f=JPEG.webp
├── u=3989120446,3136378086&fm=253&fmt=auto&app=138&f=JPEG.webp
└── u=4235953944,2077995208&fm=253&fmt=auto&app=138&f=JPEG.webp
导出检测onnx
yolo export model=runs/pose/train/weights/y11n-pose_plate_best.pt format=onnx
如果支持tensorrt,也可以导出TensorRT格式
yolo export model=runs/pose/train/weights/y11n-pose_plate_best.pt format=TensorRT
导出后,生成y11n-pose_plate_best.onnx或y11n-pose_plate_best.engine
导出OCR识别onnx
python tools/export_model.py -c configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_liecece.yml -o Global.pretrained_model=output/rec_ppocr_licence_v3/best_model/model Global.save_inference_dir=output/rec_ppocr_licence_v3/best_model/
paddle2onnx --model_dir output/rec_ppocr_licence_v3/best_model/ --model_filename inference.pdmodel --params_filename inference.pdiparams --save_file ./license_ocr.onnx --opset_version 11 --enable_onnx_checker True
识别测试
测试图片:
python ./plate_rec.py --image_path ./test_plate/hcqccip6335913.jpg
测试速度:
python ./plate_rec.py --speed_test True
avgtime cost: 8.244389284320489ms [{'text': '粤A63N9S', 'score_text': 0.9457973837852478, 'bbox': [248, 509, 440, 598], 'score_bbox': 0.8173038959503174}]
avgtime cost: 8.244389296076081ms [{'text': '苏A6PQ33', 'score_text': 0.999988853931427, 'bbox': [786, 1026, 1213, 1197], 'score_bbox': 0.8369629383087158}]
avgtime cost: 8.244372001034755ms [{'text': '苏D2B222', 'score_text': 0.9999993443489075, 'bbox': [245, 235, 437, 345], 'score_bbox': 0.8726518154144287}]
单张推理时间仅8ms, 本人的测试环境是ubuntu, RTX 4090 如果使用tensorrt和tritonserver, 应该还有提速空间。
测试源码
import numpy as np
import cv2
from ocr_rec import TextRecognizer, init_args
from PIL import Image, ImageDraw, ImageFont
from ultralytics import YOLO
import warnings
warnings.filterwarnings("ignore")
class PlateRecognizer:
def __init__(self, det_model_path="license_models/y11n-pose_plate_best.onnx"):
self.model_det = YOLO(det_model_path)
parser = init_args().parse_args()
self.model_ocr = TextRecognizer(parser)
def recognize(self, img):
plate_objs=[]
# detect plates
plates = self.model_det(img, verbose=False)
for plate, conf in zip(plates[0].boxes.xyxy, plates[0].boxes.conf):
x1, y1, x2, y2 = plate.cpu()
x1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)
plate_img = img[y1:y2, x1:x2]
# recognize text
try:
rec_res, _ = self.model_ocr([plate_img])
except Exception as E:
print(E)
exit()
if len(rec_res[0])>0:
obj = {}
obj['text'] = rec_res[0][0]
obj['score_text'] = rec_res[0][1]
obj['bbox'] = [x1, y1, x2, y2]
obj['score_bbox'] = conf.cpu().numpy().item()
plate_objs.append(obj)
return plate_objs
def DrawPlateNum(img, palte_num, x1, y1):
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_pil = Image.fromarray(img_rgb)
draw = ImageDraw.Draw(img_pil)
font = ImageFont.truetype("simsun.ttc", 40)
draw.text((x1, y1), palte_num, font=font, fill=(255, 255, 0))
img_bgr = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
return img_bgr
def demo():
parser = init_args().parse_args()
img = cv2.imread(parser.image_path)
if img is None:
print("Error: no image found")
return
plate_rec = PlateRecognizer()
plate_objs = plate_rec.recognize(img)
print(plate_objs)
for bbox in plate_objs:
x1, y1, x2, y2 = bbox['bbox']
cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 2)
img = DrawPlateNum(img, bbox['text'], x1, y1)
# cv2.imshow("result", img)
# cv2.waitKey(0)
cv2.imwrite("result.jpg", img)
# 计算平均识别时间
def test_ocr_speed():
plate_rec = PlateRecognizer()
imgs = [cv2.imread("test_plate/ec4a268fc_r.jpg"),
cv2.imread("test_plate/hcqccip6335913.jpg"),
cv2.imread("test_plate/u=1570203173,1434495175&fm=253&fmt=auto&app=138&f=JPEG.webp"),
]
#warm up
plate_objs = plate_rec.recognize(imgs[0])
time_start = cv2.getTickCount()
cal_count = 0
while True:
plate_objs = plate_rec.recognize(imgs[cal_count%len(imgs)])
cal_count += 1
time_pause = cv2.getTickCount()
time_cost = (time_pause - time_start)*1000 / cv2.getTickFrequency()
print(f"avgtime cost: {time_cost/(cal_count)}ms {plate_objs}")
if __name__ == "__main__":
parser = init_args().parse_args()
if parser.speed_test:
test_ocr_speed()
else:
demo()
关联
车牌识别之一:车牌检测(包含全部免费的数据集、源码和模型下载)
车牌识别之二:车牌OCR识别(包含全部免费的数据集、源码和模型下载)