车牌识别在高速公路中有着广泛的应用,比如我们常见的电子收费(ETC)系统和交通违章车辆的检测,除此之外像小区或地下车库门禁也会用到,基本上凡是需要对车辆进行身份检测的地方都会用到。
简介
车牌识别系统(Vehicle License Plate Recognition)是计算机视频图像识别技术在车辆牌照识别中的一种应用,通常一个车牌识别系统主要包括以下这四个部分:
- 车辆图像获取
- 车牌定位
- 车牌字符分割
- 车牌字符识别
实现方式
我们这里不做太复杂的车辆动态识别,只演示从图像中识别车牌信息,车牌识别功能的实现方式大致分为两种,一种是自己编写代码实现,另一种是借助第三方 API 接口实现。
自己实现
如果我们想要通过 Python 自己手动编码实现车牌识别功能,可以借助一些 Python 库,比如:OpenCV、TensorFlow 等,这种方式因为每一个功能点都需要我们自己编码实现,所有会相对复杂一些,另一方面如果我们想要保证识别的准确性,可能需要做大量的实验,也就是说会花费更多的时间。
第三方接口
现在已经有一些第三方平台实现好了车牌识别的功能,并且他们对外提供了 API 接口,我们只需要调用他们提供的接口即可,这种方式实现就相对简单了一些,并且通常接口提供方对外提供的接口功能的准确性也是基本可以保证的,原因很简单,如果接口功能太差的话,一是自己打脸,还有就是基本不会有什么人使用,也就失去了接口对外提供的价值了,另外第三方接口可能会收取一定费用,因此,如果现实中我们具体实现的话要综合考虑。
具体实现
综合上面的情况,我们这里采用第三方接口的方式来实现车牌识别的功能,接口提供方我们选择百度云提供的接口,百度云接口提供了免费额度,简单来说就是每天可以免费使用多少次,如果超过了这个次数就需要交钱什么的了,文档地址为:https://cloud.baidu.com/doc/OCR/index.html
,下面来看一下具体实现过程。
环境配置
SDK:百度云 SDK 对多种语言提供了支持,比如:Python、Java、C++、IOS、Android 等,这里我们安装 Python 版的 SDK,安装很简单,使用 pip install baidu-aip
命令即可,SDK 支持 Python 的版本为:2.7+ 与 3.x,SDK 目录结构如下:
├── README.md ├── aip // SDK 目录 │ ├── __init__.py // 导出类 │ ├── base.py // aip 基类 │ ├── http.py // http 请求 │ └── ocr.py //OCR └── setup.py // setuptools 安装
PyQt5 :由于要用到GUI人机交互界面,这里用PyQt5 ,PyQt5 是Digia的一套Qt5应用框架与python的结合,同时支持2.x和3.x。本教程使用的是3.x。Qt库由Riverbank Computing开发,是最强大的GUI库之一 。可用pip install PyQt5 进行安装
python:这里用的是python 3.7
另外关于百度SDK的申请,可以自行申请,也可用下面实例中的。
SDK 安装好后,我们接着需要创建应用了,这里需要一个百度账号或百度云账号,如果没有的话自己注册一个即可,登录及注册地址为:https://login.bce.baidu.com/?redirect=http%3A%2F%2Fcloud.baidu.com%2Fcampaign%2Fcampus-2018%2Findex.html
,登录之后,我们将鼠标移动到登录头像位置,接着在弹出菜单中单击用户中心,如下图所示:
如果是首次进入的话,勾选一下相应信息,如下图所示:
信息勾选完了之后,点击保存按钮。
接着将鼠标移动到左侧栏中 >
符号位置,再依次选择人工智能和文字识别,如下图所示:
点击之后会进入到下图中:
我们点击创建应用,进入下图中:
这里我们只需要填一下应用名称和下面的应用描述即可,填写完毕之后点击立即创建。
创建完后,我们再返回应用列表,如下图所示:
这里我们需要用到三个值:AppID、API Key 和 Secret Key。
具体实现
应用创建完了,我们就可以调用接口实现车牌识别功能了。
import sys from aip import AipOcr from PyQt5.QtWidgets import (QDialog, QApplication, QLabel, QPushButton, QFileDialog, QMessageBox, QPlainTextEdit, QHBoxLayout, QVBoxLayout) from PyQt5.QtGui import QIcon, QFont from PyQt5 import QtGui APP_ID = \'23612066\' API_KEY = \'Hcm1sLlGlHtyWZsPoDNGKVrt\' SECRET_KEY = \'xGue8I7ZDm8uOPCYb2FKamj8vweI2fUV\' client = AipOcr(APP_ID, API_KEY, SECRET_KEY) options = { \'multi_detect\': \'true\', } class PlateRecognize(QDialog): def __init__(self): super(PlateRecognize, self).__init__()#初始化图形界面 self.text = "" self.filePath = "" self.numbers = [] self.initUI() def initUI(self): self.resize(500, 500) self.setWindowTitle("车牌识别")#界面标题 # self.setWindowIcon(QIcon(\'C:/Users/Administrator/Desktop/icon1.ico\'))#图标 self.plabel = QLabel(self)#创建一个label标签 self.plabel.setFixedSize(400, 300)#标签大小 self.obtn = QPushButton(self)#创建‘打开本地图片’按钮 self.obtn.setText("打开本地图片")#名称 self.obtn.setFont(QFont("苏新诗柳楷繁", 15))#字体,字号 self.obtn.clicked.connect(self.openimage)#单击事件 self.obtn.setFixedSize(180, 40)#大小 self.sbtn = QPushButton(self)#创建‘开始识别’按钮 self.sbtn.setText("开 始 识 别") self.sbtn.setFont(QFont("苏新诗柳楷繁", 15)) self.sbtn.clicked.connect(self.recognize) self.sbtn.setFixedSize(180, 40) #盒子布局(boxlayouts)非常的直截了当。使用它作为最上层的布局,创建布局 #非常简单——它的构造器需要任何参数——并且使用望名知义的方法addWidget来添加widget。 self.v1box = QVBoxLayout() self.v1box.addWidget(self.obtn) self.v1box.addWidget(self.sbtn) # QHBoxLayout也可以被同样使用,尽管它不常作为最上层的布局。 # 它常常被作为子布局。为一个布局中添加另一个布局,使用该布局容器的addLayout方法 self.h1box = QHBoxLayout() self.h1box.addWidget(self.plabel) self.h1box.addLayout(self.v1box) self.tlabel = QLabel(self) self.tlabel.setText("识\n别\n结\n果") self.tlabel.setFont(QFont("苏新诗柳楷繁", 15)) self.tlabel.resize(200, 50) self.tedit = QPlainTextEdit(self) self.tedit.setFont(QFont("宋体", 10)) self.tedit.setFixedSize(500, 100) #盒子布局有另一个更重要并且常用的方法:addStretch。一个常见的布局有很多的控件, # 他们之间具有灵活的空间。为了完成这个目的,在盒子的开始添加widgets,然后添加一个设置大于0的空闲空间, # layout.addStretch(1),然后再添加剩下的widgets。 self.h2box = QHBoxLayout() self.h2box.addStretch(1) self.h2box.addWidget(self.tlabel) self.h2box.addStretch(1) self.h2box.addWidget(self.tedit) self.h2box.addStretch(1) self.vbox = QVBoxLayout() self.vbox.addLayout(self.h1box) self.vbox.addStretch(1) self.vbox.addLayout(self.h2box) self.setLayout(self.vbox) def openimage(self):#创建‘打开本地图片’命令按钮单击事件 self.filePath, imgType = QFileDialog.getOpenFileName(self, "打开本地图片", "", "*.jpg;;*.png;;All Files(*)") self.jpg = QtGui.QPixmap(self.filePath).scaled(self.plabel.width(), self.plabel.height()) self.plabel.setPixmap(self.jpg) def recognize(self):#创建‘开始识别’命令按钮单击事件 if (self.filePath == ""): print(QMessageBox.warning(self, "警告", "请插入图片", QMessageBox.Yes, QMessageBox.Yes)) return result = client.licensePlate(self.get_file_content(self.filePath), options) print(result) plate = \'\' color=\'\' for a in result[\'words_result\']: plate += a[\'number\'] + \'\n\' color += a[\'color\']+\'\n\' self.text = "车牌号码:" + plate +"车牌颜色:" + color print(QMessageBox.information(self, "提醒", "成功识别!" +"\n"+ self.text, QMessageBox.Yes, QMessageBox.Yes)) self.tedit.setPlainText(self.text) def get_file_content(self, filePath): with open(filePath, \'rb\') as fp: return fp.read() if __name__ == \'__main__\': # 这是必须要创建的一个对象。每个GUI程序都必须有且只有一个QApplication的实例。如果没有这个实例的话, # 我们写的QT是没法执行的,所以我们写QT代码的时候一定不要忘了创建这个对象。 创建这个对象时需要传递一个list参数 app = QApplication(sys.argv)#sys.argv其实可以看作是一个列表(list) platerecognizeWindow = PlateRecognize()#对类进行实例化 platerecognizeWindow.show()#调用本身的show方法 platerecognizeWindow.exec_() sys.exit(app.exec_())
这里图标注释掉了,如果需要使用的话找到自己.ico 文件的路径修改
总的来说通过接口方式实现车牌识别功能是比较简单的,以如下图为例:
这里是把图标注释掉的结果:
另外图标没有注释的结果:
是不是对于有些许强迫症的人们看着舒服一些呢(偷乐ing)
总结
本文我们先对车牌识别进行了一些介绍,之后利用百度云接口实现了GUI人机交互界面下的车牌识别。通过本文我们可以对车牌识别的相关概念和具体实现有一些了解。