计算机竞赛 python 机器视觉 车牌识别 - opencv 深度学习 机器学习

1 前言

🔥 优质竞赛项目系列,今天要分享的是

🚩 基于python 机器视觉 的车牌识别系统

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:3分

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1 课题背景

车牌识别其实是个经典的机器视觉任务了,通过图像处理技术检测、定位、识别车牌上的字符,实现计算机对车牌的智能管理功能。如今在小区停车场、高速公路出入口、监控场所、自动收费站等地都有车牌识别系统的存在,车牌识别的研究也已逐步成熟。尽管该技术随处可见了,但其实在精度和识别速度上还需要进一步提升,自己动手实现一个车牌识别系统有利于学习和理解图像处理的先进技术。

本文详细介绍基于深度学习的中文车牌识别与管理系统,在介绍算法原理的同时,给出Python的实现代码以及PyQt的简单UI界面。在界面中可以选择需要识别的车牌视频、图片文件等。

2 效果演示

首先还是用动图先展示一下效果,系统主要实现的功能是对图片、视频中的车牌进行检测和识别,演示效果如下。

2.1 图片检测识别

在这里插入图片描述

2.2视频检测识别

在这里插入图片描述

3 车牌检测与识别

目前,智能交通系统中集成运用计算机视觉、物联网、人工智能等多种技术成为未来发展方向。其中,车牌识别(License Plate Recognition,
LPR)技术作为一项重要技术,从获取的图像中提取目标车辆的车牌信息,成为完善智能交通管理运行的基础。

由于本文介绍的是中文车牌,所以可以简单了解一下国内汽车拍照的特点:字符数为七个,包括汉字、字母和数字。车牌颜色组合中,其中最常见的组合为普通小型汽车蓝底白字和新能源汽车的渐变绿底黑字。

在这里插入图片描述

总结来说,车牌是一个有特点的图像区域,几种特征可以综合起来确定车牌定位,所以之前就有利用车牌与周围环境的差异的算法。目前常见的车牌定位算法有以下 4
种:基于颜色、纹理、边缘信息的车牌定位算法和基于人工神经网络的车牌定位算法。

如下图所示,常规的步骤包括图像采集、预处理、车牌定位、字符分割、字符识别、输出结果。深度学习技术成熟之后,端到端的网络模型使得这一过程变得简单起来。从思想上来说,基于深度学习的车牌识别实现思路主要包括两个部分:(1)车牌检测定位;(2)车牌字符识别。

在这里插入图片描述

其中,车牌的检测定位本质是一个特定的目标检测任务,即通过算法框选出属于车牌的位置坐标,以便将其与背景区分开来。可以认为检测出的车牌位置才是我们的感兴趣区域。好用的方法如Cascade
LBP,它是一种机器学习的方法,可以利用OpenCV训练级联分类器,依赖CPU进行计算,级联分类器的方法对于常用场景效果比较好,检测速度较快,曾经一度比较流行,但准确率一般。基于深度学习的检测算法有Mobilene-
SSD、YOLO-v5等,利用大批量的标注数据进行训练.

当ROI被检测出来,如何对这一区域中的字符进行识别,这就涉及到采取的处理方式。第一种处理方式,首先利用一系列字符分割的算法将车牌中的字符逐个分开,然后基于深度学习进行字符分类,得到识别结果;第二种,区别于第一种先分割再分类的两步走方式,利用端到端的CTC(
Connectionist Temporal Classification)网络直接进行识别。

这里我们使用网上开源的HyperLPR中文车牌识别框架,首先导入OpenCV和hyperlpr,读取一张车牌图片调用架构中的车牌识别方法获得结果,以下代码来自官方的示例:

    #导入包from hyperlpr import *#导入OpenCV库import cv2#读入图片image = cv2.imread("demo.jpg")#识别结果print(HyperLPR_plate_recognition(image))

以上代码运行结果如下,可以看出该方法识别了车牌的车牌字符、置信度值、车牌位置坐标、图片尺寸等结果。

在这里插入图片描述

这样的结果还不够直观,我们写一个函数将车牌的识别结果标注在图片上,首先导入相关依赖包,其代码如下:

    # 导入包from hyperlpr import *# 导入OpenCV库import cv2 as cvfrom PIL import Image, ImageDraw, ImageFontimport numpy as np

新建一个函数drawRectBox,将图像数据、识别结果、字体等参数传入,函数内部利用OpenCV和PIL库添加标注框和识别结果的字符,其代码如下:

    def drawRectBox(image, rect, addText, fontC):cv.rectangle(image, (int(round(rect[0])), int(round(rect[1]))),(int(round(rect[2]) + 8), int(round(rect[3]) + 8)),(0, 0, 255), 2)cv.rectangle(image, (int(rect[0] - 1), int(rect[1]) - 16), (int(rect[0] + 75), int(rect[1])), (0, 0, 255), -1, cv.LINE_AA)img = Image.fromarray(image)draw = ImageDraw.Draw(img)draw.text((int(rect[0] + 1), int(rect[1] - 16)), addText, (255, 255, 255), font=fontC)imagex = np.array(img)return imagex

我们首先读取图片文件,利用前面的HyperLPR_plate_recognition方法识别出车牌结果,调用以上函数获得带标注框的图片,利用OpenCV的imshow方法显示结果图片,其代码如下:

    image = cv.imread('test3.jpeg')  # 读取选择的图片res_all = HyperLPR_plate_recognition(image)fontC = ImageFont.truetype("./platech.ttf", 14, 0)res, confi, axes = res_all[0]image = drawRectBox(image, axes, res, fontC)cv.imshow('Stream', image)c = cv.waitKey(0) & 0xff

此时运行以上代码可以得到如下结果:

在这里插入图片描述

同理,识别视频中的车牌也可以做类似的操作,不过我们需要先对视频文件进行逐帧读取,然后采用以上的方式在图片中标识出车牌并显示。

这部分代码如下:

    
capture = cv.VideoCapture("./车牌检测.mp4")  # 读取视频文件
fontC = ImageFont.truetype("./platech.ttf", 14, 0)  # 字体,用于标注图片
​    i = 1
while (True):ref, frame = capture.read()if ref:i = i + 1if i % 5 == 0:i = 0res_all = HyperLPR_plate_recognition(frame)  # 识别车牌if len(res_all) > 0:res, confi, axes = res_all[0]  # 获取结果frame = drawRectBox(frame, axes, res, fontC)cv.imshow("num", frame)  # 显示画面if cv.waitKey(1) & 0xFF == ord('q'):break  # 退出else:break

以上代码每5帧识别一次视频中的车牌,将车牌的结果标注在画面中进行实时显示,运行结果的截图如下所示:
在这里插入图片描述

车牌的识别部分代码演示完毕,对此我们完成了图片和视频的识别,然而这些还是简单的脚本呈现。为了方便更换图片、视频以及管理车牌,还需要设计文件选择功能以及系统的UI界面。这部分代码如下:

    class Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(800, 600)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.openimage = QtWidgets.QPushButton(self.centralwidget)self.openimage.setGeometry(QtCore.QRect(20, 40, 91, 51))self.openimage.setObjectName("openimage")self.showlabel = QtWidgets.QLabel(self.centralwidget)self.showlabel.setGeometry(QtCore.QRect(110, 10, 471, 441))self.showlabel.setObjectName("showlabel")self.LPRdetect = QtWidgets.QPushButton(self.centralwidget)self.LPRdetect.setGeometry(QtCore.QRect(20, 150, 81, 51))self.LPRdetect.setObjectName("LPRdetect")self.LPR_Rec = QtWidgets.QPushButton(self.centralwidget)self.LPR_Rec.setGeometry(QtCore.QRect(20, 292, 75, 31))self.LPR_Rec.setObjectName("LPR_Rec")self.lineEdit_result = QtWidgets.QLineEdit(self.centralwidget)self.lineEdit_result.setGeometry(QtCore.QRect(20, 400, 101, 41))self.lineEdit_result.setObjectName("lineEdit_result")self.openvideo = QtWidgets.QPushButton(self.centralwidget)self.openvideo.setGeometry(QtCore.QRect(20, 360, 75, 23))self.openvideo.setObjectName("openvideo")MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))self.openimage.setText(_translate("MainWindow", "打开图片"))self.showlabel.setText(_translate("MainWindow", "TextLabel"))self.LPRdetect.setText(_translate("MainWindow", "车牌检测"))self.LPR_Rec.setText(_translate("MainWindow", "车牌识别"))self.openvideo.setText(_translate("MainWindow", "PushButton"))

4 HyperLPR库

4.1 简介

HyperLPR是一个使用深度学习针对对中文车牌识别的实现,与较为流行的开源的EasyPR相比,它的检测速度和鲁棒性和多场景的适应性都要好于目前开源的EasyPR,HyperLPR可以识别多种中文车牌包括白牌,新能源车牌,使馆车牌,教练车牌,武警车牌等。

4.2 特点

  • 基于端到端sequence模型,无需进行字符分割,识别速度更快。
  • 速度快 720p ,单核 Intel 2.2G CPU (macbook Pro 2015)平均识别时间<=90ms
  • 识别率高,仅仅针对车牌ROI在EasyPR数据集上,0-error达到 95.2%, 1-error识别率达到 97.4% (指在定位成功后的车牌识别率)
  • 轻量总代码量不超1k行。
  • 带有Android实现,其Android Demo可解决一些在一些普通业务场景(如执法记录仪)下的车牌识别任务。
  • 支持多种车牌的识别,详情见如下

4.3 HyperLPR的检测流程

  • 使用opencv的HAAR Cascade检测车牌大致位置
  • Extend检测到的大致位置的矩形区域
  • 使用类似于MSER的方式的多级二值化和RANSAC拟合车牌的上下边界
  • 使用CNN Regression回归车牌左右边界
  • 使用基于纹理场的算法进行车牌校正倾斜
  • 使用CNN滑动窗切割字符
  • 使用CNN识别字符

4.4 安装


​ pip install hyperlpr

4.5 Python 依赖

  • Keras (>2.0.0)

  • Theano(>0.9) or Tensorflow(>1.1.x)

  • Numpy (>1.10)

  • Scipy (0.19.1)

  • OpenCV(>3.0)

  • Scikit-image (0.13.0)

  • PIL

  • 使用CNN识别字符

5 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/90327.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【量化课程】02_4.数理统计的基本概念

2.4_数理统计的基本概念 数理统计思维导图 更多详细内容见notebook 1.基本概念 总体&#xff1a;研究对象的全体&#xff0c;它是一个随机变量&#xff0c;用 X X X表示。 个体&#xff1a;组成总体的每个基本元素。 简单随机样本&#xff1a;来自总体 X X X的 n n n个相互…

梯度下降介绍

什么是梯度 梯度是微积分中一个很重要的概念&#xff0c;在单变量的函数中&#xff0c;梯度其实就是函数的微分&#xff0c;代表着函数在某个给定点的切线的斜率&#xff1b;在多变量函数中&#xff0c;梯度是一个向量&#xff0c;向量有方向&#xff0c;梯度的方向就指出了函…

809协议nodejs编写笔记(还在更新)

一、总体流程 数据首先通过receiver接受层接收&#xff0c;去掉标识头和标识尾&#xff1b;再进入depacker解包层进行解包&#xff0c;把标识头分解出来并解析&#xff1b;之后发给handler处理层根据不同的消息id选择使用不同的业务逻辑&#xff1b;如果有应答&#xff0c;则通…

陪诊小程序开发|陪诊陪护小程序让看病不再难

陪诊小程序通过与医疗机构的合作&#xff0c;整合了医疗资源&#xff0c;让用户能够更加方便地获得专业医疗服务。用户不再需要面对繁琐的挂号排队&#xff0c;只需通过小程序预约服务&#xff0c;便能够享受到合适的医疗资源。这使得用户的就医过程变得简单高效&#xff0c;并…

CSS中的position属性有哪些值,并分别描述它们的作用。

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ static⭐ relative⭐ absolute⭐ fixed⭐ sticky⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那…

Tomcat多实例部署及nginx+tomcat的负载均衡和动静分离

Tomcat多实例部署 安装 jdk、tomcat&#xff08;流程可看之前博客&#xff09; 配置 tomcat 环境变量 [rootlocalhost ~]# vim /etc/profile.d/tomcat.sh#tomcat1 export CATALINA_HOME1/usr/local/tomcat/tomcat1 export CATALINA_BASE1/usr/local/tomcat/tomcat1 export T…

pdf怎么转换成jpg图片?这几个转换方法了解一下

pdf怎么转换成jpg图片&#xff1f;转换PDF文件为JPG图片格式在现代工作中是非常常见的需求&#xff0c;比如将PDF文件中的图表、表格或者图片转换为JPG格式后使用在PPT演示、网页设计等场景中。 【迅捷PDF转换器】是一款非常实用的工具&#xff0c;可以将PDF文件转换成多种不同…

HTML详解连载(5)

HTML详解连载&#xff08;5&#xff09; 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽行高&#xff1a;设置多行文本的间距属性名属性值行高的测量方法 行高-垂直居中技巧 字体族属性名属性值示例扩展 font 复合属性使用场景复合属性示例注意 文本缩进属性…

YOLO v8目标跟踪详细解读(二)

上一篇&#xff0c;结合代码&#xff0c;我们详细的介绍了YOLOV8目标跟踪的Pipeline。大家应该对跟踪的流程有了大致的了解&#xff0c;下面我们将对跟踪中出现的卡尔曼滤波进行解读。 1.卡尔曼滤波器介绍 卡尔曼滤波&#xff08;kalman Filtering&#xff09;是一种利用线性…

Python学习 -- 常用函数与实例详解

在Python编程中&#xff0c;数据转换是一项关键任务&#xff0c;它允许我们在不同数据类型之间自由流动&#xff0c;从而提高代码的灵活性和效率。本篇博客将深入探讨常用的数据转换函数&#xff0c;并通过实际案例为你展示如何巧妙地在不同数据类型之间转换。 数据类型转换函…

分布式监控平台——Zabbix

市场上常用的监控软件&#xff1a; 传统运维&#xff1a;zabbix、 Nagios 一、zabbix概述 作为一个运维&#xff0c;需要会使用监控系统查看服务器状态以及网站流量指标&#xff0c;利用监控系统的数据去了解上线发布的结果&#xff0c;和网站的健康状态。 利用一个优秀的监…

【数学建模】--因子分析模型

因子分析有斯皮尔曼在1904年首次提出&#xff0c;其在某种程度上可以被看成时主成分分析的推广和扩展。 因子分析法通过研究变量间的相关稀疏矩阵&#xff0c;把这些变量间错综复杂的关系归结成少数几个综合因子&#xff0c;由于归结出的因子个数少于原始变量的个数&#xff0c…

【第三讲-三维空间刚体运动】

旋转矩阵 点、向量、坐标系 坐标系分为左左手系和右手系 下面讨论有关向量的运算&#xff1a; 内积 外积&#xff1a; 外积的结果是一个向量&#xff0c;方向垂直于这两个向量&#xff0c;大小为

sift-1M数据集的读取及ES插入数据

sift是检查ann近邻召回率的标准数据集,ann可以选择faiss,milvus等库或者方法;sift数据分为query和base,以及label(groundtruth)数据。本文采用sift-1M进行解读,且看如下: 1、sift-1m数据集 官方链接地址:Evaluation of Approximate nearest neighbors: large datase…

brew+nginx配置静态文件服务器

背景 一下子闲下来了&#xff0c;了解的我的人都知道我闲不下来。于是&#xff0c;我在思考COS之后&#xff0c;决定自己整一个本地的OSS&#xff0c;实现静态文件的访问。那么&#xff0c;首屈一指的就是我很熟的nginx。也算是个小复习吧&#xff0c;复习一下nginx代理静态文…

通过网关访问微服务,一次正常,一次不正常 (nacos配置的永久实例却未启动导致)

微服务直接访问没问题&#xff0c;通过网关访问&#xff0c;就一次正常访问&#xff0c;一次401错误&#xff0c;交替正常和出错 负载均衡试了 路由配置检查了 最后发现nacos下竟然有2个order服务实例&#xff0c;我明明只开启了一个呀 原来之前的8080端口微服务还残留&…

spring按条件注入@Condition及springboot对其的扩展

概述 spring的ioc极大的方便了日常开发&#xff0c;但随着业务的迭代。配置的一些参数在某些情况下需要按条件注入。 比如原先定义的db公共模块下&#xff0c;相关的配置和工具类只是基于mysql的。但是后续有模块需要使用mongo/es等其他数据库&#xff0c;又想继续使用db公共…

基于ipad协议的gewe框架进行微信群组管理(二)

友情链接 geweapi.com 点击访问即可。 获取群组详情 小提示&#xff1a; 该接口可以一次查询20个群组查询出来的信息是不带公告的 请求URL&#xff1a; http://域名地址/api/group/detail 请求方式&#xff1a; POST 请求头&#xff1a; Content-Type&#xff1a;applica…

HTTP和HTTPS协议

目录 一、HTTP和HTTPS区别&#x1f33b; 二、有了https还有使用http场景吗&#x1f34a; 三、https协议的工作原理&#x1f4a5; 四、https协议的优点和缺点&#x1f35e; 一、HTTP和HTTPS区别&#x1f33b; HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和HTT…

Android AOSP源码编译——AOSP整编(二)

切换到源码目录下执行下面命令 1、初始化环境 . build/envsetup.sh //清除缓存 make clobber2、选择编译目标 lunchAOSP 预制了很多 Product。这里为了简单我们先不用真机&#xff0c;而是选择模拟器的方式&#xff0c;对于 x86_64 模拟器&#xff0c;我们选择的是 aosp_x86…