前言

今天出门,出小区的时候发现停车杆没有反应,然后我就打电话让人来给我开杆!后来通过和物业人员聊天过程中,原来是车牌识别不了了。好像是坏了!这不是小事吗,我和物业说了一声,晚上我给你弄好!物业小姐姐硬要给我去申请奖金,没办法,拿了奖金就请物业小姐姐吃饭吧!

正文

一起用Python的PyQt5开发一个车牌自动识别系统!

首先一起来看看最终实现的车牌识别系统效果图:

下面,我们就开始介绍如何实现这款自动车牌识别系统。

一、核心功能设计

总体来说,我们首先要进行UI界面构建设计,根据车牌识别系统功能进行画面排版布局;其次我们的这款车牌识别系统的主要功能车辆图片读取识别显示、图片中车牌ROI区域获取、车牌识别结果输出显示。

对于结果输出显示,我们主要包含了读取图片名称、读取录入时间、识别车牌号码、识别车牌颜色、识别车牌所属地。最后我们还可以将车牌识别系统的数据信息导出本地存储。

拆解需求,大致可以整理出核心功能如下:

UI设计排版布局

  • 左侧区域进行识别信息显示,包含图片名称、读取录入时间、识别车牌号码、识别车牌颜色、识别车牌所属地信息
  • 右侧可以分成3个区域,顶部区域包含窗体最小化,最大化,关闭功能;中间区域显示读取车辆图片;底部区域包含车牌显示区域、图片读取、车牌信息存储功能
  • 车牌识别

    • 通过读取图片进行车牌区域提取输出
    • 车牌自动识别结果输出
  • 车牌信息显示存储

    • 根据自动识别结果对车牌各类信息显示
    • 对录入识别的车辆车牌识别信息存储

二、实现步骤

1. UI设计排版布局

根据车牌识别需要的功能,首先进行

UI布局设计

,我们这次还是使用的

pyqt5

。核心设计代码如下:

def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(1213, 670)MainWindow.setFixedSize(1213, 670)  # 设置窗体固定大小MainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.scrollArea = QtWidgets.QScrollArea(self.centralwidget)self.scrollArea.setGeometry(QtCore.QRect(690, 40, 511, 460))self.scrollArea.setWidgetResizable(True)self.scrollArea.setObjectName("scrollArea")self.scrollAreaWidgetContents = QtWidgets.QWidget()self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 500, 489))self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")self.label_0 = QtWidgets.QLabel(self.scrollAreaWidgetContents)self.label_0.setGeometry(QtCore.QRect(10, 10, 111, 20))font = QtGui.QFont()font.setPointSize(11)self.label_0.setFont(font)self.label_0.setObjectName("label_0")self.label = QtWidgets.QLabel(self.scrollAreaWidgetContents)self.label.setGeometry(QtCore.QRect(10, 40, 481, 420))self.label.setObjectName("label")self.label.setAlignment(Qt.AlignCenter)self.scrollArea.setWidget(self.scrollAreaWidgetContents)self.scrollArea_2 = QtWidgets.QScrollArea(self.centralwidget)self.scrollArea_2.setGeometry(QtCore.QRect(10, 10, 671, 631))self.scrollArea_2.setWidgetResizable(True)self.scrollArea_2.setObjectName("scrollArea_2")self.scrollAreaWidgetContents_1 = QtWidgets.QWidget()self.scrollAreaWidgetContents_1.setGeometry(QtCore.QRect(0, 0, 669, 629))self.scrollAreaWidgetContents_1.setObjectName("scrollAreaWidgetContents_1")self.label_1 = QtWidgets.QLabel(self.scrollAreaWidgetContents_1)self.label_1.setGeometry(QtCore.QRect(10, 10, 111, 20))font = QtGui.QFont()font.setPointSize(11)self.label_1.setFont(font)self.label_1.setObjectName("label_1")self.tableWidget = QtWidgets.QTableWidget(self.scrollAreaWidgetContents_1)self.tableWidget.setGeometry(QtCore.QRect(10, 40, 651, 581))  # 581))self.tableWidget.setObjectName("tableWidget")self.tableWidget.setColumnCount(5)self.tableWidget.setColumnWidth(0, 140)  # 设置1列的宽度self.tableWidget.setColumnWidth(1, 130)  # 设置2列的宽度self.tableWidget.setColumnWidth(2, 110)  # 设置3列的宽度self.tableWidget.setColumnWidth(3, 90)  # 设置4列的宽度self.tableWidget.setColumnWidth(4, 181)  # 设置5列的宽度self.tableWidget.setHorizontalHeaderLabels(["图片名称", "录入时间", "车牌号码", "车牌类型", "车牌信息"])self.tableWidget.setRowCount(self.RowLength)self.tableWidget.verticalHeader().setVisible(False)  # 隐藏垂直表头)self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)self.tableWidget.raise_()self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_1)self.scrollArea_3 = QtWidgets.QScrollArea(self.centralwidget)self.scrollArea_3.setGeometry(QtCore.QRect(690, 510, 341, 131))self.scrollArea_3.setWidgetResizable(True)self.scrollArea_3.setObjectName("scrollArea_3")self.scrollAreaWidgetContents_3 = QtWidgets.QWidget()self.scrollAreaWidgetContents_3.setGeometry(QtCore.QRect(0, 0, 339, 129))self.scrollAreaWidgetContents_3.setObjectName("scrollAreaWidgetContents_3")self.label_2 = QtWidgets.QLabel(self.scrollAreaWidgetContents_3)self.label_2.setGeometry(QtCore.QRect(10, 10, 111, 20))font = QtGui.QFont()font.setPointSize(11)self.label_2.setFont(font)self.label_2.setObjectName("label_2")self.label_3 = QtWidgets.QLabel(self.scrollAreaWidgetContents_3)self.label_3.setGeometry(QtCore.QRect(10, 40, 321, 81))self.label_3.setObjectName("label_3")self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3)self.scrollArea_4 = QtWidgets.QScrollArea(self.centralwidget)self.scrollArea_4.setGeometry(QtCore.QRect(1040, 510, 161, 131))self.scrollArea_4.setWidgetResizable(True)self.scrollArea_4.setObjectName("scrollArea_4")self.scrollAreaWidgetContents_4 = QtWidgets.QWidget()self.scrollAreaWidgetContents_4.setGeometry(QtCore.QRect(0, 0, 159, 129))self.scrollAreaWidgetContents_4.setObjectName("scrollAreaWidgetContents_4")self.pushButton_2 = QtWidgets.QPushButton(self.scrollAreaWidgetContents_4)self.pushButton_2.setGeometry(QtCore.QRect(20, 50, 121, 31))self.pushButton_2.setObjectName("pushButton_2")self.pushButton = QtWidgets.QPushButton(self.scrollAreaWidgetContents_4)self.pushButton.setGeometry(QtCore.QRect(20, 90, 121, 31))self.pushButton.setObjectName("pushButton")self.label_4 = QtWidgets.QLabel(self.scrollAreaWidgetContents_4)self.label_4.setGeometry(QtCore.QRect(10, 10, 111, 20))font = QtGui.QFont()font.setPointSize(11)self.label_4.setFont(font)self.label_4.setObjectName("label_4")self.scrollArea_4.setWidget(self.scrollAreaWidgetContents_4)MainWindow.setCentralWidget(self.centralwidget)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)self.pushButton.clicked.connect(self.__openimage)  # 设置点击事件self.pushButton.setStyleSheet('''QPushButton{background:#222225;border-radius:5px;}QPushButton:hover{background:#2B2B2B;}''')self.pushButton_2.clicked.connect(self.__writeFiles)  # 设置点击事件self.pushButton_2.setStyleSheet('''QPushButton{background:#222225;border-radius:5px;}QPushButton:hover{background:#2B2B2B;}''')self.retranslateUi(MainWindow)self.close_widget = QtWidgets.QWidget(self.centralwidget)self.close_widget.setGeometry(QtCore.QRect(1130, 0, 90, 50))self.close_widget.setObjectName("close_widget")self.close_layout = QGridLayout()  # 创建左侧部件的网格布局层self.close_widget.setLayout(self.close_layout)  # 设置左侧部件布局为网格self.left_close = QPushButton("")  # 关闭按钮self.left_close.clicked.connect(self.close)self.left_visit = QPushButton("")  # 空白按钮self.left_visit.clicked.connect(MainWindow.big)self.left_mini = QPushButton("")  # 最小化按钮self.left_mini.clicked.connect(MainWindow.mini)self.close_layout.addWidget(self.left_mini, 0, 0, 1, 1)self.close_layout.addWidget(self.left_close, 0, 2, 1, 1)self.close_layout.addWidget(self.left_visit, 0, 1, 1, 1)self.left_close.setFixedSize(15, 15)  # 设置关闭按钮的大小self.left_visit.setFixedSize(15, 15)  # 设置按钮大小self.left_mini.setFixedSize(15, 15)  # 设置最小化按钮大小self.left_close.setStyleSheet('''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}''')self.left_visit.setStyleSheet('''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''')self.left_mini.setStyleSheet('''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''')QtCore.QMetaObject.connectSlotsByName(MainWindow)self.ProjectPath = os.getcwd()  # 获取当前工程文件位置self.scrollAreaWidgetContents.setStyleSheet(sc)self.scrollAreaWidgetContents_3.setStyleSheet(sc)self.scrollAreaWidgetContents_4.setStyleSheet(sc)b =             '''color:white;background:#2B2B2B;'''self.label_0.setStyleSheet(b)self.label_1.setStyleSheet(b)self.label_2.setStyleSheet(b)self.label_3.setStyleSheet(b)MainWindow.setWindowOpacity(0.95)  # 设置窗口透明度MainWindow.setAttribute(Qt.WA_TranslucentBackground)MainWindow.setWindowFlag(Qt.FramelessWindowHint)  # 隐藏边框# author:CSDN-Dragon少年
def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "车牌识别系统"))self.label_0.setText(_translate("MainWindow", "原始图片:"))self.label.setText(_translate("MainWindow", ""))self.label_1.setText(_translate("MainWindow", "识别结果:"))self.label_2.setText(_translate("MainWindow", "车牌区域:"))self.label_3.setText(_translate("MainWindow", ""))self.pushButton.setText(_translate("MainWindow", "打开文件"))self.pushButton_2.setText(_translate("MainWindow", "导出数据"))self.label_4.setText(_translate("MainWindow", "事件:"))self.scrollAreaWidgetContents_1.show()

UI实现效果如下:

2. 车牌识别

接下来我们需要实现两个核心功能,包括获取

车牌ROI区域

车牌自动识别

功能。

车牌ROI区域提取:

根据读取的车辆图片,预处理进行车牌ROI区域提取,主要通过Opencv的图像处理相关知识点来完成。主要包括对图像去噪、二值化、边缘轮廓提取、矩形区域矫正、蓝绿黄车牌颜色定位识别。核心代码如下:

# author:CSDN-Dragon少年
# 预处理
def pretreatment(self, car_pic):if type(car_pic) == type(""):img = self.__imreadex(car_pic)else:img = car_picpic_hight, pic_width = img.shape[:2]if pic_width > self.MAX_WIDTH:resize_rate = self.MAX_WIDTH / pic_widthimg = cv2.resize(img, (self.MAX_WIDTH, int(pic_hight * resize_rate)),interpolation=cv2.INTER_AREA)  # 图片分辨率调整blur = self.cfg["blur"]# 高斯去噪if blur > 0:img = cv2.GaussianBlur(img, (blur, blur), 0)oldimg = imgimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)kernel = np.ones((20, 20), np.uint8)img_opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)  # 开运算img_opening = cv2.addWeighted(img, 1, img_opening, -1, 0);  # 与上一次开运算结果融合# cv2.imshow('img_opening', img_opening)# 找到图像边缘ret, img_thresh = cv2.threshold(img_opening, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)  # 二值化img_edge = cv2.Canny(img_thresh, 100, 200)# cv2.imshow('img_edge', img_edge)# 使用开运算和闭运算让图像边缘成为一个整体kernel = np.ones((self.cfg["morphologyr"], self.cfg["morphologyc"]), np.uint8)img_edge1 = cv2.morphologyEx(img_edge, cv2.MORPH_CLOSE, kernel)  # 闭运算img_edge2 = cv2.morphologyEx(img_edge1, cv2.MORPH_OPEN, kernel)  # 开运算# cv2.imshow('img_edge2', img_edge2)# cv2.imwrite('./edge2.png', img_edge2)# 查找图像边缘整体形成的矩形区域,可能有很多,车牌就在其中一个矩形区域中image, contours, hierarchy = cv2.findContours(img_edge2, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)contours = [cnt for cnt in contours if cv2.contourArea(cnt) > self.Min_Area]# 逐个排除不是车牌的矩形区域car_contours = []for cnt in contours:# 框选 生成最小外接矩形 返回值(中心(x,y), (宽,高), 旋转角度)rect = cv2.minAreaRect(cnt)# print('宽高:',rect[1])area_width, area_height = rect[1]# 选择宽大于高的区域if area_width < area_height:area_width, area_height = area_height, area_widthwh_ratio = area_width / area_height# print('宽高比:',wh_ratio)# 要求矩形区域长宽比在2到5.5之间,2到5.5是车牌的长宽比,其余的矩形排除if wh_ratio > 2 and wh_ratio < 5.5:car_contours.append(rect)box = cv2.boxPoints(rect)box = np.int0(box)# 矩形区域可能是倾斜的矩形,需要矫正,以便使用颜色定位card_imgs = []for rect in car_contours:if rect[2] > -1 and rect[2] < 1:  # 创造角度,使得左、高、右、低拿到正确的值angle = 1else:angle = rect[2]rect = (rect[0], (rect[1][0] + 5, rect[1][1] + 5), angle)  # 扩大范围,避免车牌边缘被排除box = cv2.boxPoints(rect)heigth_point = right_point = [0, 0]left_point = low_point = [pic_width, pic_hight]for point in box:if left_point[0] > point[0]:left_point = pointif low_point[1] > point[1]:low_point = pointif heigth_point[1] < point[1]:heigth_point = pointif right_point[0] < point[0]:right_point = pointif left_point[1] <= right_point[1]:  # 正角度new_right_point = [right_point[0], heigth_point[1]]pts2 = np.float32([left_point, heigth_point, new_right_point])  # 字符只是高度需要改变pts1 = np.float32([left_point, heigth_point, right_point])M = cv2.getAffineTransform(pts1, pts2)dst = cv2.warpAffine(oldimg, M, (pic_width, pic_hight))self.__point_limit(new_right_point)self.__point_limit(heigth_point)self.__point_limit(left_point)card_img = dst[int(left_point[1]):int(heigth_point[1]), int(left_point[0]):int(new_right_point[0])]card_imgs.append(card_img)elif left_point[1] > right_point[1]:  # 负角度new_left_point = [left_point[0], heigth_point[1]]pts2 = np.float32([new_left_point, heigth_point, right_point])  # 字符只是高度需要改变pts1 = np.float32([left_point, heigth_point, right_point])M = cv2.getAffineTransform(pts1, pts2)dst = cv2.warpAffine(oldimg, M, (pic_width, pic_hight))self.__point_limit(right_point)self.__point_limit(heigth_point)self.__point_limit(new_left_point)card_img = dst[int(right_point[1]):int(heigth_point[1]), int(new_left_point[0]):int(right_point[0])]card_imgs.append(card_img)#使用颜色定位,排除不是车牌的矩形,目前只识别蓝、绿、黄车牌colors = []for card_index, card_img in enumerate(card_imgs):green = yellow = blue = black = white = 0try:# 有转换失败的可能,原因来自于上面矫正矩形出错card_img_hsv = cv2.cvtColor(card_img, cv2.COLOR_BGR2HSV)except:print('BGR转HSV失败')card_imgs = colors = Nonereturn card_imgs, colorsif card_img_hsv is None:continuerow_num, col_num = card_img_hsv.shape[:2]card_img_count = row_num * col_num# 确定车牌颜色for i in range(row_num):for j in range(col_num):H = card_img_hsv.item(i, j, 0)S = card_img_hsv.item(i, j, 1)V = card_img_hsv.item(i, j, 2)if 11 < H <= 34 and S > 34:  # 图片分辨率调整yellow += 1elif 35 < H <= 99 and S > 34:  # 图片分辨率调整green += 1elif 99 < H <= 124 and S > 34:  # 图片分辨率调整blue += 1if 0 < H < 180 and 0 < S < 255 and 0 < V < 46:black += 1elif 0 < H < 180 and 0 < S < 43 and 221 < V < 225:white += 1color = "no"# print('黄:{:<6}绿:{:<6}蓝:{:<6}'.format(yellow,green,blue))limit1 = limit2 = 0if yellow * 2 >= card_img_count:color = "yellow"limit1 = 11limit2 = 34  # 有的图片有色偏偏绿elif green * 2 >= card_img_count:color = "green"limit1 = 35limit2 = 99elif blue * 2 >= card_img_count:color = "blue"limit1 = 100limit2 = 124  # 有的图片有色偏偏紫elif black + white >= card_img_count * 0.7:color = "bw"# print(color)colors.append(color)# print(blue, green, yellow, black, white, card_img_count)if limit1 == 0:continue# 根据车牌颜色再定位,缩小边缘非车牌边界xl, xr, yh, yl = self.accurate_place(card_img_hsv, limit1, limit2, color)if yl == yh and xl == xr:continueneed_accurate = Falseif yl >= yh:yl = 0yh = row_numneed_accurate = Trueif xl >= xr:xl = 0xr = col_numneed_accurate = Truecard_imgs[card_index] = card_img[yl:yh, xl:xr] \if color != "green" or yl < (yh - yl) // 4 else card_img[yl - (yh - yl) // 4:yh, xl:xr]if need_accurate:  # 可能x或y方向未缩小,需要再试一次card_img = card_imgs[card_index]card_img_hsv = cv2.cvtColor(card_img, cv2.COLOR_BGR2HSV)xl, xr, yh, yl = self.accurate_place(card_img_hsv, limit1, limit2, color)if yl == yh and xl == xr:continueif yl >= yh:yl = 0yh = row_numif xl >= xr:xl = 0xr = col_numcard_imgs[card_index] = card_img[yl:yh, xl:xr] \if color != "green" or yl < (yh - yl) // 4 else card_img[yl - (yh - yl) // 4:yh, xl:xr]# cv2.imshow("result", card_imgs[0])# cv2.imwrite('1.jpg', card_imgs[0])# print('颜色识别结果:' + colors[0])return card_imgs, colors

至此我们就可以输出车牌ROI区域和车牌颜色了,效果如下:

车牌自动识别:

车牌识别博主自己写了一个基于Opencv和SVM的识别系统,由于代码篇幅较长,本篇不进行展示(

感兴趣的可以私信博主获取源码

)。

这里面我们可以创建一个车牌识别的应用,其中的

API Key及Secret Key

后面我们调用车牌识别检测接口时会用到。

我们可以看到官方提供的帮助文档,介绍了如何

调用请求URL数据格式,向API服务地址使用POST发送请求

,必须在URL中带上参数

access_token

,可通过后台的API Key和Secret Key生成。这里面的API Key和Secret Key就是我们上面提到的。

接下来我们看看调用车牌识别接口代码示例。

那我们如何获取识别的车牌号码呢?API文档可以看到里面有个

words_result字典

,其中的

color代表车牌颜色

number代表车牌号码

。这样我就可以知道识别的车牌颜色和车牌号了。

车牌识别的接口调用流程基本已经清楚了,下面就可以进行代码实现了。

# author:CSDN-Dragon少年
def get_token(self):host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=' + self.client_id + '&client_secret=' + self.client_secretresponse = requests.get(host)if response:token_info = response.json()token_key = token_info['access_token']return token_key# author:CSDN-Dragon少年
def get_license_plate(self, car_pic):result = {}card_imgs, colors = self.pretreatment(car_pic)request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate"# 二进制方式打开图片文件f = open(car_pic, 'rb')img = base64.b64encode(f.read())params = {"image": img}access_token = self.get_token()request_url = request_url + "?access_token=" + access_tokenheaders = {'content-type': 'application/x-www-form-urlencoded'}response = requests.post(request_url, data=params, headers=headers)if response:print(response.json())license_result = response.json()['words_result']['number']card_color = response.json()['words_result']['color']if license_result != []:result['InputTime'] = time.strftime("%Y-%m-%d %H:%M:%S")result['Type'] = self.cardtype[card_color]result['Picture'] = card_imgs[0]result['Number'] = ''.join(license_result[:2]) + '·' + ''.join(license_result[2:])try:result['From'] = ''.join(self.Prefecture[license_result[0]][license_result[1]])except:result['From'] = '未知'return resultelse:return None

这样我们就可以拿到车牌颜色和车牌号码了,效果如下:

3. 车牌信息显示存储

3.1 车牌信息显示:

# author:CSDN-Dragon少年
def __show(self, result, FileName):# 显示表格self.RowLength = self.RowLength + 1if self.RowLength > 18:self.tableWidget.setColumnWidth(5, 157)self.tableWidget.setRowCount(self.RowLength)self.tableWidget.setItem(self.RowLength - 1, 0, QTableWidgetItem(FileName))self.tableWidget.setItem(self.RowLength - 1, 1, QTableWidgetItem(result['InputTime']))self.tableWidget.setItem(self.RowLength - 1, 2, QTableWidgetItem(result['Number']))self.tableWidget.setItem(self.RowLength - 1, 3, QTableWidgetItem(result['Type']))if result['Type'] == '蓝色牌照':self.tableWidget.item(self.RowLength - 1, 3).setBackground(QBrush(QColor(3, 128, 255)))elif result['Type'] == '绿色牌照':self.tableWidget.item(self.RowLength - 1, 3).setBackground(QBrush(QColor(98, 198, 148)))elif result['Type'] == '黄色牌照':self.tableWidget.item(self.RowLength - 1, 3).setBackground(QBrush(QColor(242, 202, 9)))self.tableWidget.setItem(self.RowLength - 1, 4, QTableWidgetItem(result['From']))self.tableWidget.item(self.RowLength - 1, 4).setBackground(QBrush(QColor(255, 255, 255)))# 显示识别到的车牌位置size = (int(self.label_3.width()), int(self.label_3.height()))shrink = cv2.resize(result['Picture'], size, interpolation=cv2.INTER_AREA)shrink = cv2.cvtColor(shrink, cv2.COLOR_BGR2RGB)self.QtImg = QtGui.QImage(shrink[:], shrink.shape[1], shrink.shape[0], shrink.shape[1] * 3,QtGui.QImage.Format_RGB888)self.label_3.setPixmap(QtGui.QPixmap.fromImage(self.QtImg))

效果如下:

3.2 信息导出存储:

# author:CSDN-Dragon少年
def __writexls(self, DATA, path):wb = xlwt.Workbook();ws = wb.add_sheet('Data');# DATA.insert(0, ['文件名称','录入时间', '车牌号码', '车牌类型', '车牌信息'])for i, Data in enumerate(DATA):for j, data in enumerate(Data):ws.write(i, j, data)wb.save(path)QMessageBox.information(None, "成功", "数据已保存!", QMessageBox.Yes)
def __writecsv(self, DATA, path):f = open(path, 'w')# DATA.insert(0, ['文件名称','录入时间', '车牌号码', '车牌类型', '车牌信息'])for data in DATA:f.write((',').join(data) + '\n')f.close()QMessageBox.information(None, "成功", "数据已保存!", QMessageBox.Yes)def __writeFiles(self):path, filetype = QFileDialog.getSaveFileName(None, "另存为", self.ProjectPath,"Excel 工作簿(*.xls);;CSV (逗号分隔)(*.csv)")if path == "":  # 未选择returnif filetype == 'Excel 工作簿(*.xls)':self.__writexls(self.Data, path)elif filetype == 'CSV (逗号分隔)(*.csv)':self.__writecsv(self.Data, path)

效果如下:

导出车牌信息数据如下:

至此,整个车牌自动识别系统就完成了~今天我们就到这里,明天继续努力!

​​

⑥项目源码案例分享有

如果你用得到的话可以直接拿走,在我的QQ技术交流群里群号:948351247(纯技术交流和资源共享,广告勿入)以自助拿走

点击这里 领取

我给小区物业写了个车牌自动识别系统,非常实用。物业给你免费停车一年!相关推荐

  1. 广元停车场系统推荐_广元车牌自动识别停车系统设计方案,车牌自动识别系统停车场哪家有名...

    广元车牌自动识别停车系统设计方案 成都臻致三才科技有限公司自2014年成立以来"云"车牌识别系统.IC卡车辆管理系统.远距读卡系统.视频车位引导系统.人行通道闸.智能道闸.特种防恐 ...

  2. 基于‘匹配’技术的车牌自动识别系统

    随着智能停车场系统的兴起,车牌识别技术又着实火了一把.我也来了兴趣,大致浏览了下当前的现状,发现目前流行的车牌识别技术是基于神经网络的(这方面可参见Mastering OpenCV with Prac ...

  3. 基于MATLAB的机动车车牌自动识别系统

    随着智慧交通的发展,对机动车监管的需要,车牌识别技术成为现代智慧交通系统中不可或缺的一部分,在日常生活中应用十分 广泛.本文章研究分析了该技术实现各个部分所使用的相关算法,选取了识别准确率高并且效率较 ...

  4. 在线制作车牌效果图_厦门车牌识别系统生产厂家直销

    在智能化飞速发展的今天,人们也越来越追求智能化和自动化,为了满足不同的用户需求,车牌识别系统生产厂家应对多个环境来设计制作,智能车牌识别系统也在不断的升级.创新.车牌自动识别系统也有各种的应用.下面厦 ...

  5. 汽车车牌自动识别技术

    车牌自动识别技术 车牌的自动识别技术是计算机视觉.图像处理与模式识别技术在智能交通领域应用的重要研究课题之一,是实现交通管理智能化的重要环节,主要包括车牌捕捉.车牌定位.字符车牌分割和车牌字符OCR识 ...

  6. python车牌识别系统抬杆_车牌识别系统识别到道闸不抬杆是什么问题?

    原标题:车牌识别系统识别到道闸不抬杆是什么问题? 在日常日生活中,我们在进入商场或许居住区的时候,总是因为一些原因,车牌不能自动识别成功进入.有些时分为什么他人能进入,自己就进不了,有时分是挺疑问的. ...

  7. matlab车牌识别的外文文献翻译,汽车车牌识别系统(带外文翻译).doc

    汽车车牌识别系统 车牌定位子系统的设计与实现 摘 要 汽车识别系统是近几年发展起来的计算机视觉和模式识别技术在智能交通领域应用的重要研究课题之一.在车牌自动识别系统中,首先要将车牌从所获取的图像中分割 ...

  8. 车牌识别存储云服务器,车牌识别系统大显神威,实现智慧交通的“最强利器”。...

    随着人们生活水平提高,私家车的数量逐年增加,截至2017年底全国机动车保有量已达3.10亿辆.交通压力越来越严峻,智能化交通管理已成为交通发展的大方向.其中车牌识别系统的大力发展可以说是解决拥堵问题, ...

  9. 基于Matlab车牌自动识别

    灰度变换 灰度图是指将黑色和白色以对数的关系分为256阶的图像.灰度化处理就是将彩色图片通过处理转化为灰度图的过程.彩色图像一般由三个独立色组成,R.G.B三个分量分别显示出红.绿.蓝.灰度化处理就是 ...

最新文章

  1. sklearn.naive_bayes
  2. Cooperative Content Distribution and Traffic Engineering
  3. jQuery的淡入和淡出简单介绍
  4. K-means的缺点(优化不仅仅是最小化误差)
  5. app接口开发(php)
  6. html文件下的flag,推荐一个SAM文件中flag含义解释工具
  7. [WPF]xml序列化以及反序列化数据
  8. 如何 给给软件开发 添加 代理_敏捷开发是如何被跑偏的
  9. O(1), O(n), O(logn), O(nlogn) 的区别(转自ted 常)
  10. linux查看log软件
  11. 关于SqlServer导入access数据库,十进制字段的精度过小的问题
  12. leetcode/力扣 贪心算法总结,代码随想录PDF下载
  13. 计算机环境变量怎么恢复默认,环境变量怎么还原
  14. android前置拍照镜像代码,从Android的前置摄像头拍摄的镜像翻转视频
  15. HTML- 表单(简单易懂)
  16. c#Winform自定义控件-目录
  17. strcmp函数实现及分析
  18. 购房指南—买房经验总结
  19. 【嵌入式Linux驱动开发】二十一、Linux内核自带的KEY驱动探索
  20. 三. SpringBoot原理

热门文章

  1. 六、最短路径——迪杰斯特拉(Dijkstra)算法
  2. 【cise】基于vscode+docker在mac本机搭建linux持续集成系统和开发环境
  3. 半导体二极管门电路以及CMOS反相器
  4. :android 2.3,安卓网:Android系统版本分析2.3版本领先
  5. 【例说】Verilog HDL 编译器指令,你见过几个?
  6. 计算机英语(31-60)
  7. PYNQ下的DMA传输实现及速度测试
  8. 手机网站制作:PC网站怎么转成手机网站
  9. ai智能外呼系统营销服务一体化中的必备工具
  10. ENVI教程:InSAR技术,相位解缠