车牌识别算法,支持12种中文车牌类型 基于yolov5的车牌检测 车牌矫正以及 基于CRNN的车牌识别 onnx推理代码

1.单行蓝牌 2.单行黄牌 3.新能源车牌 4.白色警用车牌 5 教练车牌 6 武警车牌 7 双层黄牌 8 双层武警 9 使馆车牌 10 港澳牌车 11 双层农用车牌 12 民航车牌

全部onnx推理代码如下:

github:
https://github.com/we0091234/Chinese_license_plate_detection_recognitionimport onnxruntime
import numpy as np
import cv2
import copy
import os
import argparse
from PIL import Image, ImageDraw, ImageFont
import timeplateName=r"#京沪津渝冀晋蒙辽吉黑苏浙皖闽赣鲁豫鄂湘粤桂琼川贵云藏陕甘青宁新学警港澳挂使领民航深0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
mean_value,std_value=((0.588,0.193))#识别模型均值标准差def decodePlate(preds):        #识别后处理pre=0newPreds=[]for i in range(len(preds)):if preds[i]!=0 and preds[i]!=pre:newPreds.append(preds[i])pre=preds[i]plate=""for i in newPreds:plate+=plateName[int(i)]return plate# return newPredsdef rec_pre_precessing(img,size=(48,168)): #识别前处理img =cv2.resize(img,(168,48))img = img.astype(np.float32)img = (img/255-mean_value)/std_valueimg = img.transpose(2,0,1)img = img.reshape(1,*img.shape)return imgdef get_plate_result(img,session_rec):img =rec_pre_precessing(img)y_onnx = session_rec.run([session_rec.get_outputs()[0].name], {session_rec.get_inputs()[0].name: img})[0]# print(y_onnx[0])plate_no = decodePlate(y_onnx[0])return plate_nodef allFilePath(rootPath,allFIleList):fileList = os.listdir(rootPath)for temp in fileList:if os.path.isfile(os.path.join(rootPath,temp)):allFIleList.append(os.path.join(rootPath,temp))else:allFilePath(os.path.join(rootPath,temp),allFIleList)def get_split_merge(img):  #双层车牌进行分割后识别h,w,c = img.shapeimg_upper = img[0:int(5/12*h),:]img_lower = img[int(1/3*h):,:]img_upper = cv2.resize(img_upper,(img_lower.shape[1],img_lower.shape[0]))new_img = np.hstack((img_upper,img_lower))return new_imgdef order_points(pts):rect = np.zeros((4, 2), dtype = "float32")s = pts.sum(axis = 1)rect[0] = pts[np.argmin(s)]rect[2] = pts[np.argmax(s)]diff = np.diff(pts, axis = 1)rect[1] = pts[np.argmin(diff)]rect[3] = pts[np.argmax(diff)]return rectdef four_point_transform(image, pts):rect = order_points(pts)(tl, tr, br, bl) = rectwidthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))maxWidth = max(int(widthA), int(widthB))heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))maxHeight = max(int(heightA), int(heightB))dst = np.array([[0, 0],[maxWidth - 1, 0],[maxWidth - 1, maxHeight - 1],[0, maxHeight - 1]], dtype = "float32")M = cv2.getPerspectiveTransform(rect, dst)warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))# return the warped imagereturn warpeddef my_letter_box(img,size=(640,640)):h,w,c = img.shaper = min(size[0]/h,size[1]/w)new_h,new_w = int(h*r),int(w*r)top = int((size[0]-new_h)/2)left = int((size[1]-new_w)/2)bottom = size[0]-new_h-topright = size[1]-new_w-leftimg_resize = cv2.resize(img,(new_w,new_h))img = cv2.copyMakeBorder(img_resize,top,bottom,left,right,borderType=cv2.BORDER_CONSTANT,value=(114,114,114))return img,r,left,topdef xywh2xyxy(boxes):xywh =copy.deepcopy(boxes)xywh[:,0]=boxes[:,0]-boxes[:,2]/2xywh[:,1]=boxes[:,1]-boxes[:,3]/2xywh[:,2]=boxes[:,0]+boxes[:,2]/2xywh[:,3]=boxes[:,1]+boxes[:,3]/2return xywhdef my_nms(boxes,iou_thresh):index = np.argsort(boxes[:,4])[::-1]keep = []while index.size >0:i = index[0]keep.append(i)x1=np.maximum(boxes[i,0],boxes[index[1:],0])y1=np.maximum(boxes[i,1],boxes[index[1:],1])x2=np.minimum(boxes[i,2],boxes[index[1:],2])y2=np.minimum(boxes[i,3],boxes[index[1:],3])w = np.maximum(0,x2-x1)h = np.maximum(0,y2-y1)inter_area = w*hunion_area = (boxes[i,2]-boxes[i,0])*(boxes[i,3]-boxes[i,1])+(boxes[index[1:],2]-boxes[index[1:],0])*(boxes[index[1:],3]-boxes[index[1:],1])iou = inter_area/(union_area-inter_area)idx = np.where(iou<=iou_thresh)[0]index = index[idx+1]return keepdef restore_box(boxes,r,left,top):boxes[:,[0,2,5,7,9,11]]-=leftboxes[:,[1,3,6,8,10,12]]-=topboxes[:,[0,2,5,7,9,11]]/=rboxes[:,[1,3,6,8,10,12]]/=rreturn boxesdef detect_pre_precessing(img,img_size):img,r,left,top=my_letter_box(img,img_size)# cv2.imwrite("1.jpg",img)img =img[:,:,::-1].transpose(2,0,1).copy().astype(np.float32)img=img/255img=img.reshape(1,*img.shape)return img,r,left,topdef post_precessing(dets,r,left,top,conf_thresh=0.3,iou_thresh=0.5):#检测后处理choice = dets[:,:,4]>conf_threshdets=dets[choice]dets[:,13:15]*=dets[:,4:5]box = dets[:,:4]boxes = xywh2xyxy(box)score= np.max(dets[:,13:15],axis=-1,keepdims=True)index = np.argmax(dets[:,13:15],axis=-1).reshape(-1,1)output = np.concatenate((boxes,score,dets[:,5:13],index),axis=1) reserve_=my_nms(output,iou_thresh) output=output[reserve_] output = restore_box(output,r,left,top)return outputdef rec_plate(outputs,img0,session_rec):dict_list=[]for output in outputs:result_dict={}rect=output[:4].tolist()land_marks = output[5:13].reshape(4,2)roi_img = four_point_transform(img0,land_marks)label = int(output[-1])if label==1:  #代表是双层车牌roi_img = get_split_merge(roi_img)plate_no = get_plate_result(roi_img,session_rec) #得到车牌识别结果result_dict['rect']=rectresult_dict['landmarks']=land_marks.tolist()result_dict['plate_no']=plate_noresult_dict['roi_height']=roi_img.shape[0]dict_list.append(result_dict)return dict_listdef cv2ImgAddText(img, text, left, top, textColor=(0, 255, 0), textSize=20):if (isinstance(img, np.ndarray)):  #判断是否OpenCV图片类型img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))draw = ImageDraw.Draw(img)fontText = ImageFont.truetype("fonts/platech.ttf", textSize, encoding="utf-8")draw.text((left, top), text, textColor, font=fontText)return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)def draw_result(orgimg,dict_list):result_str =""for result in dict_list:rect_area = result['rect']x,y,w,h = rect_area[0],rect_area[1],rect_area[2]-rect_area[0],rect_area[3]-rect_area[1]padding_w = 0.05*wpadding_h = 0.11*hrect_area[0]=max(0,int(x-padding_w))rect_area[1]=min(orgimg.shape[1],int(y-padding_h))rect_area[2]=max(0,int(rect_area[2]+padding_w))rect_area[3]=min(orgimg.shape[0],int(rect_area[3]+padding_h))height_area = result['roi_height']landmarks=result['landmarks']result = result['plate_no']result_str+=result+" "for i in range(4):  #关键点cv2.circle(orgimg, (int(landmarks[i][0]), int(landmarks[i][1])), 5, clors[i], -1)cv2.rectangle(orgimg,(rect_area[0],rect_area[1]),(rect_area[2],rect_area[3]),(0,0,255),2) #画框if len(result)>=1:orgimg=cv2ImgAddText(orgimg,result,rect_area[0]-height_area,rect_area[1]-height_area-10,(255,0,0),height_area)print(result_str)return orgimgif __name__ == "__main__":begin = time.time()parser = argparse.ArgumentParser()parser.add_argument('--detect_model',type=str, default=r'weights/plate_detect.onnx', help='model.pt path(s)')  #检测模型parser.add_argument('--rec_model', type=str, default='weights/plate_rec.onnx', help='model.pt path(s)')#识别模型parser.add_argument('--image_path', type=str, default='imgs', help='source') parser.add_argument('--img_size', type=int, default=640, help='inference size (pixels)')parser.add_argument('--output', type=str, default='result', help='source') opt = parser.parse_args()file_list = []allFilePath(opt.image_path,file_list)providers =  ['CPUExecutionProvider']clors = [(255,0,0),(0,255,0),(0,0,255),(255,255,0),(0,255,255)]img_size = (opt.img_size,opt.img_size)session_detect = onnxruntime.InferenceSession(opt.detect_model, providers=providers )session_rec = onnxruntime.InferenceSession(opt.rec_model, providers=providers )if not os.path.exists(opt.output):os.mkdir(opt.output)save_path = opt.outputcount = 0for pic_ in file_list:count+=1print(count,pic_,end=" ")img=cv2.imread(pic_)img0 = copy.deepcopy(img)img,r,left,top = detect_pre_precessing(img,img_size) #检测前处理# print(img.shape)y_onnx = session_detect.run([session_detect.get_outputs()[0].name], {session_detect.get_inputs()[0].name: img})[0]outputs = post_precessing(y_onnx,r,left,top) #检测后处理result_list=rec_plate(outputs,img0,session_rec)ori_img = draw_result(img0,result_list)img_name = os.path.basename(pic_)save_img_path = os.path.join(save_path,img_name)cv2.imwrite(save_img_path,ori_img)print(f"总共耗时{time.time()-begin} s")

车牌识别包括两个步骤:
1.车牌检测 这里我们用比较成熟的yolov5算法,改进了yolov5,加上了关键点检测,用于检测车牌的四个角点,通过角点进行透视变换,得到矫正后的车牌图像
2.车牌识别,这里采用OCR常用的CRNN算法,主要是CNN+RNN+CTCloss进行训练,准确率还是比较高的

仅仅依赖onnxruntime的基于yolov5的车牌识别项目,需要onnx模型的 加qq群获取:871797331

ONNX 推理yolov5车牌关键点检测 crnn 车牌识别相关推荐

  1. 【CV秋季划】人脸关键点检测,人脸识别视频更新

    本次给大家带来的是有三AI-CV秋季划-人脸算法组的视频,包括人脸关键点检测,人脸识别两期的内容,如果你还不知道有三AI-CV秋季划-人脸算法组是什么,可以看下面的视频和图文. 点击边框调出视频工具条 ...

  2. 机器视觉 手部关键点检测(手部识别)安卓应用App(Hand Tracking)基于mediapipe。

    目录 前言 一.下载APP! 二.安装后使用结果: 三.总结 前言 安卓系统手机实现对手部关键点的识别. 一.下载APP! csdn下载:Hand Tracking 百度网盘下载:链接:https:/ ...

  3. 人脸数据库大全(包括人脸识别、关键点检测、表情识别,人脸姿态等等)

    搞计算机视觉的人,对人脸技术并不陌生.在做实验的时候需要各种数据集进行训练,却往往苦于找不到合适的数据集,这篇文章将给大家带来一点福音. 目前为止最全的是人脸数据库总结: The Color FERE ...

  4. 猫脸关键点检测大赛:三种方法,轻松实现猫脸识别!

    导语:挑战猫脸,就差你了! 今天这个比赛,得从一个做程序猿的铲屎官开始说起...... 话说,有一天「铲屎猿」早起之后,发现猫主子竟然没了身影:他找啊找啊,找了好久,可仍然到处都没找到猫主子.这时,客 ...

  5. caffe 人脸关键点检测_人脸检测关键点新增至81个,比Dlib更精准、更贴边

    人脸关键点检测是人脸识别和分析领域中的关键一步,它是诸如自动人脸识别.表情分析.三维人脸重建及三维动画等其它人脸相关问题的前提和突破口. 虽然人脸的结构是确定的,由眉毛.眼睛.鼻子和嘴等部位组成,近似 ...

  6. 人脸关键点检测综述(含论文、数据集、方法等)

    人脸关键点 人脸关键点检测是人脸识别和分析领域中的关键一步,它是诸如自动人脸识别.表情分析.三维人脸重建及三维动画等其它人脸相关问题的前提和突破口.近些年来,深度学习(http://www.rainc ...

  7. 基于人脸关键点检测的驾驶员睡意检测系统

    摘要 驾驶员注意力不集中或者分心是道路交通事故的主要原因. 为了减少道路交通事故,设计开发驾驶员疲劳检测系统至关重要. 本研究利用人脸关键点检测方法提出了驾驶员睡意检测系统,目的是使驾驶更安全. 一. ...

  8. paddle2.0高层API实现人脸关键点检测(人脸关键点检测综述_自定义网络_paddleHub_趣味ps)

    paddle2.0高层API实现人脸关键点检测(人脸关键点检测综述_自定义网络_paddleHub_趣味ps) 本文包含了: - 人脸关键点检测综述 - 人脸关键点检测数据集介绍以及数据处理实现 - ...

  9. 【目标检测】英雄联盟能用YOLOv5实时目标检测了 支持onnx推理

    目录 一.项目介绍 二.项目结构 三.准备数据 1.数据标注 2.数据转换格式 四.执行训练 1.anchors文件 2.标签文件 3.预训练模型 4.训练数据 5.修改配置 6.执行训练 五.执行预 ...

  10. Yolov5+图像分割+百度AI接口——车牌实时检测识别系统

    Hallo,各位小伙伴大家好呀!这两天一直在肝项目,都是关于计算机视觉方面的,所以这两天一直也没有更新(真的不是我懒)!在这个过程中我对Yolov5有了更深刻的理解,在原有的Yolov5框架上增加了图 ...

最新文章

  1. Python Qt GUI设计:QPainter、QPen、QBrush和QPixmap窗口绘图类(基础篇—17)
  2. 在Unity3D中连接WCF服务端
  3. 3D图形学的线性代数的通俗解释。
  4. python pdf报告_Python实现html转换为pdf报告(生成pdf报告)功能示例
  5. PAT甲级1107 Social Clusters (30 分):[C++题解]并查集,爱好、人数
  6. Nginx深入详解之过滤模块
  7. php正则过滤html标签_空格_换行符的代码,PHP 正则过滤 html 标签、空格、换行符的代码 (文章格式化)...
  8. 清除浮动-父级添加overflow(HTML、CSS)
  9. flash制作文字笔顺_教你如何给GIF动态图片加上文字
  10. 如何选择深度学习框架 TensorFlow/Torch/Mxnet/Theano
  11. 【Sort】QuickSort
  12. matlab数字调制蒙特卡洛仿真,AWGN信道下数字通信系统的蒙特卡洛仿真(基于matlab)...
  13. 愿你出走半生,归来仍是少年——2017年半年总结(下)
  14. 【文献学习】《Reference-free detection of isolated SNPs》
  15. esxi - with nvidia geforce 10 titan xp card
  16. 老羊摘编自《罗辑思维跨年演讲》——分享3——阿里和腾讯
  17. linux字符串加引号,请问 命令行中写路径,加引号和不加有什么区别?
  18. [嵌入式开发模块]JY61姿态角度传感器 驱动模块
  19. python 小说cms系统_「博文小说网」Python爬虫爬取小说网站 - seo实验室
  20. 从2020全球前十的数字货币交易所甄别风险

热门文章

  1. 苹果电脑如何设置屏保时间?
  2. Windows7 的激活命令小结
  3. 手机号码归属地查询工具的正确使用方法
  4. Editplus从下载到使用
  5. CSS美化超链接样式
  6. android--手机桌面添加网址链接图标(解决方式)
  7. 沙巴克服务器占用,传奇私服服务端里最完整的攻沙传送教程,直接飞皇宫和影之道方法...
  8. sublime text3 炫酷主题
  9. HSQLDB:一款基于 Java 的嵌入式关系型数据库
  10. java计算机毕业设计招聘信息系统源代码+系统+数据库+lw文档