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