利用Python做车牌号识别系统

简介: 利用Python做车牌号识别系统

利用Python做车牌号识别系统

今天就继续给大家分享一个实战案例,带大家一起用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)  # 隐藏边框

def retranslateUi(self, MainWindow):

_translate = QtCore.QCoreApplication.translate
MainWindow.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()
  1. 车牌识别

接下来我们需要实现两个核心功能,包括获取车牌ROI区域和车牌自动识别功能。

车牌ROI区域提取:

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

预处理

def pretreatment(self, car_pic):

if type(car_pic) == type(""):
    img = self.__imreadex(car_pic)
else:
    img = car_pic
pic_hight, pic_width = img.shape[:2]

if pic_width > self.MAX_WIDTH:
    resize_rate = self.MAX_WIDTH / pic_width
    img = 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 = img
img = 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_width
    wh_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 = 1
    else:
        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 = point
        if low_point[1] > point[1]:
            low_point = point
        if heigth_point[1] < point[1]:
            heigth_point = point
        if right_point[0] < point[0]:
            right_point = point
    if 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 = 0
    try:
        # 有转换失败的可能,原因来自于上面矫正矩形出错
        card_img_hsv = cv2.cvtColor(card_img, cv2.COLOR_BGR2HSV)
    except:
        print('BGR转HSV失败')
        card_imgs = colors = None
        return card_imgs, colors

    if card_img_hsv is None:
        continue
    row_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 += 1
            elif 35 < H <= 99 and S > 34:  # 图片分辨率调整
                green += 1
            elif 99 < H <= 124 and S > 34:  # 图片分辨率调整
                blue += 1

            if 0 < H < 180 and 0 < S < 255 and 0 < V < 46:
                black += 1
            elif 0 < H < 180 and 0 < S < 43 and 221 < V < 225:
                white += 1
    color = "no"
    # print('黄:{:<6}绿:{:<6}蓝:{:<6}'.format(yellow,green,blue))

    limit1 = limit2 = 0
    if yellow * 2 >= card_img_count:
        color = "yellow"
        limit1 = 11
        limit2 = 34  # 有的图片有色偏偏绿
    elif green * 2 >= card_img_count:
        color = "green"
        limit1 = 35
        limit2 = 99
    elif blue * 2 >= card_img_count:
        color = "blue"
        limit1 = 100
        limit2 = 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:
        continue
    need_accurate = False
    if yl >= yh:
        yl = 0
        yh = row_num
        need_accurate = True
    if xl >= xr:
        xl = 0
        xr = col_num
        need_accurate = True
    card_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:
            continue
        if yl >= yh:
            yl = 0
            yh = row_num
        if xl >= xr:
            xl = 0
            xr = col_num
    card_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区域和车牌颜色了,效果如下:

车牌自动识别:

本篇介绍调用百度AI提供的车牌识别接口 – 百度AI开放平台链接,识别效果非常不错

这里面我们可以创建一个车牌识别的应用,其中的API Key及Secret Key后面我们调用车牌识别检测接口时会用到。

我们可以看到官方提供的帮助文档,介绍了如何调用请求URL数据格式,向API服务地址使用POST发送请求,必须在URL中带上参数access_token,可通过后台的API Key和Secret Key生成。这里面的API Key和Secret Key就是我们上面提到的。

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

那我们如何获取识别的车牌号码呢?API文档可以看到里面有个words_result字典 ,其中的color代表车牌颜色 ,number代表车牌号码 。这样我就可以知道识别的车牌颜色和车牌号了。

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

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_secret
response = requests.get(host)
if response:
    token_info = response.json()
    token_key = token_info['access_token']
return token_key

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_token
headers = {'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 result
else:
    return None

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

  1. 车牌信息显示存储

3.1 车牌信息显示:

def __show(self, result, FileName):

# 显示表格
self.RowLength = self.RowLength + 1
if 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 信息导出存储:

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 == "":  # 未选择
    return
if filetype == 'Excel 工作簿(*.xls)':
    self.__writexls(self.Data, path)
elif filetype == 'CSV (逗号分隔)(*.csv)':
    self.__writecsv(self.Data, path)

效果如下:

导出车牌信息数据如下

至此,整个车牌自动识别系统就完成了~

目录
相关文章
|
8天前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
127 55
|
28天前
|
机器学习/深度学习 数据采集 供应链
使用Python实现智能食品安全追溯系统的深度学习模型
使用Python实现智能食品安全追溯系统的深度学习模型
60 4
|
18天前
|
机器学习/深度学习 人工智能 算法
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
宠物识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了37种常见的猫狗宠物种类数据集【'阿比西尼亚猫(Abyssinian)', '孟加拉猫(Bengal)', '暹罗猫(Birman)', '孟买猫(Bombay)', '英国短毛猫(British Shorthair)', '埃及猫(Egyptian Mau)', '缅因猫(Maine Coon)', '波斯猫(Persian)', '布偶猫(Ragdoll)', '俄罗斯蓝猫(Russian Blue)', '暹罗猫(Siamese)', '斯芬克斯猫(Sphynx)', '美国斗牛犬
104 29
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
|
19天前
|
机器学习/深度学习 算法 前端开发
基于Python深度学习的果蔬识别系统实现
果蔬识别系统,主要开发语言为Python,基于TensorFlow搭建ResNet卷积神经网络算法模型,通过对12种常见的果蔬('土豆', '圣女果', '大白菜', '大葱', '梨', '胡萝卜', '芒果', '苹果', '西红柿', '韭菜', '香蕉', '黄瓜')图像数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django框架搭建Web网页端可视化操作界面,以下为项目实现介绍。
30 4
基于Python深度学习的果蔬识别系统实现
|
1月前
|
弹性计算 数据管理 数据库
从零开始构建员工管理系统:Python与SQLite3的完美结合
本文介绍如何使用Python和Tkinter构建一个图形界面的员工管理系统(EMS)。系统包括数据库设计、核心功能实现和图形用户界面创建。主要功能有查询、添加、删除员工信息及统计员工数量。通过本文,你将学会如何结合SQLite数据库进行数据管理,并使用Tkinter创建友好的用户界面。
61 2
从零开始构建员工管理系统:Python与SQLite3的完美结合
|
1月前
|
Python
Python之音乐专辑管理系统
音乐专辑管理系统是一款用于管理和维护音乐专辑信息的应用程序,支持添加、删除、修改和查询专辑详情(如专辑名、艺术家、发行日期及曲目列表)。系统运行需Python 3.x环境,硬件要求较低,适合个人及小型团队使用。
51 4
|
1月前
|
Python
Python实现摇号系统
本文介绍了如何使用Python构建一个简单的摇号系统,包括用户输入、随机抽取、结果展示和日志记录等功能。通过导入`random`、`datetime`和`logging`模块,实现了从参与者名单中随机抽取中奖者,并记录每次摇号的结果,方便后续查看和审计。完整代码示例提供了从功能实现到主程序调用的全过程。
35 2
|
1月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
79 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
1月前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
89 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
1月前
|
机器学习/深度学习 数据采集 存储
使用Python实现智能农业灌溉系统的深度学习模型
使用Python实现智能农业灌溉系统的深度学习模型
195 6