毕业设计:2023-2024年计算机专业毕业设计选题汇总(建议收藏)

毕业设计:2023-2024年最新最全计算机专业毕设选题推荐汇总

🍅感兴趣的可以先收藏起来,点赞、关注不迷路,大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助同学们顺利毕业 。🍅

1、项目介绍

技术栈:
Python语言、OpenCV、HyperLPR中文车牌识别框架、pyqt5

2、项目界面

(1)上传图片进行车牌识别

python车牌识别系统 深度学习 车牌实时检测 OpenCV 毕业设计(源码) ✅-LMLPHP

(2)上传视频进行车牌识别

python车牌识别系统 深度学习 车牌实时检测 OpenCV 毕业设计(源码) ✅-LMLPHP

(3)连接摄像头进行车牌识别

python车牌识别系统 深度学习 车牌实时检测 OpenCV 毕业设计(源码) ✅-LMLPHP

(4)车牌识别记录管理

python车牌识别系统 深度学习 车牌实时检测 OpenCV 毕业设计(源码) ✅-LMLPHP

3、项目说明

车牌识别系统是一种利用计算机视觉和深度学习技术来自动识别和提取车辆上的车牌信息的系统。它通常由以下几个主要组成部分构成:

图像采集:系统需要获取车辆图像或视频流。这可以通过摄像头、监控摄像机或其他图像采集设备实现。

图像预处理:对采集到的图像进行预处理,包括图像去噪、增强、调整尺寸等操作,以便提高后续识别算法的效果。

车牌定位:使用图像处理技术,如边缘检测、颜色过滤等方法,对图像中的车牌位置进行定位和标定。OpenCV是一个广泛应用于图像处理和计算机视觉的开源库,提供了丰富的函数和工具来实现这些功能。

字符分割:将车牌图像中的字符分割成单个字符。这是一个关键的步骤,通常使用基于图像处理和机器学习的方法来确定字符的边界。

字符识别:使用深度学习算法和训练好的模型对分割出的字符进行识别。HyperLPR是一个开源的中文车牌识别框架,它基于深度学习技术,能够快速准确地识别车牌上的字符。

结果输出:将识别出的车牌信息输出到用户界面、数据库或其他系统中,以便进一步处理和应用。PyQt5是一个基于Python的GUI开发框架,可以用于创建用户界面,实现与用户的交互和结果展示。

python车牌识别系统 深度学习 车牌实时检测 OpenCV 毕业设计(源码) ✅-LMLPHP

综上所述,车牌识别系统利用Python编程语言、OpenCV图像处理库、HyperLPR中文车牌识别框架以及PyQt5图形界面开发框架等技术,能够实现车牌图像的自动识别和字符提取功能,并将结果展示给用户。

4、核心代码

import os
import warnings
from os import getcwd
import numpy as np
import cv2
from PIL import Image, ImageDraw, ImageFont

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QFileDialog, QTableWidgetItem
from hyperlpr import HyperLPR_plate_recognition
from PlateRecognition_UI import Ui_MainWindow


class Plate_MainWindow(Ui_MainWindow):
    def __init__(self, MainWindow):
        self.count = 0  # 表格行数,用于记录识别车牌条目
        self.res_set = []  # 用于车牌历史结果记录的列表

        self.cap_video = None  # 视频流对象

        self.path = getcwd()
        self.video_path = getcwd()
        self.fontC = ImageFont.truetype("./Font/platech.ttf", 14, 0)

        self.timer_camera = QtCore.QTimer()  # 定时器
        self.timer_video = QtCore.QTimer()  # 视频定时器
        self.flag_timer = ""  # 用于标记正在进行的功能项(视频/摄像)

        self.CAM_NUM = 0  # 摄像头标号
        self.cap = cv2.VideoCapture(self.CAM_NUM)  # 屏幕画面对象
        self.cap_video = None  # 视频流对象
        # self.model = pr.LPR("./HyperLPR_CarNum/model/cascade_lbp.xml", "./HyperLPR_CarNum/model/model12.h5",
        #                     "./HyperLPR_CarNum/model/ocr_plate_all_gru.h5")

        self.current_image = None  # 保存的画面
        self.setupUi(MainWindow)  # 界面生成
        self.retranslateUi(MainWindow)  # 界面控件
        # 设置表格形式
        self.tableWidget.setColumnWidth(0, 80)
        self.tableWidget.setColumnWidth(1, 200)
        self.tableWidget.setColumnWidth(2, 150)
        self.tableWidget.setColumnWidth(3, 200)
        self.tableWidget.setColumnWidth(4, 120)
        # self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.slot_init()  # 槽函数设置

    def slot_init(self):
        self.toolButton_file.clicked.connect(self.choose_file)
        self.toolButton_runing.clicked.connect(self.run_rec)
        self.toolButton_camera.clicked.connect(self.button_open_camera_click)
        self.tableWidget.cellPressed.connect(self.table_review)
        self.toolButton_video.clicked.connect(self.button_open_video_click)
        self.timer_video.timeout.connect(self.show_video)
        self.timer_camera.timeout.connect(self.show_camera)
        self.toolButton_model.clicked.connect(self.choose_folder)

    def table_review(self, row, col):
        try:
            if col == 0:  # 点击第一列时
                this_path = self.tableWidget.item(row, 1)  # 表格中的文件路径
                res = self.tableWidget.item(row, 2)  # 表格中记录的识别结果
                axes = self.tableWidget.item(row, 3)  # 表格中记录的坐标

                if (this_path is not None) & (res is not None) & (axes is not None):
                    this_path = this_path.text()
                    if os.path.exists(this_path):
                        res = res.text()
                        axes = axes.text()

                        image = self.cv_imread(this_path)  # 读取选择的图片
                        image = cv2.resize(image, (500, 500))  # 设定图像尺寸为显示界面大小

                        axes = [int(i) for i in axes.split(",")]
                        confi = float(self.tableWidget.item(row, 4).text())

                        image = self.drawRectBox(image, axes, res)
                        # 在Qt界面中显示检测完成画面
                        show = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
                        showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)
                        self.label_display.setPixmap(QtGui.QPixmap.fromImage(showImage))
                        self.label_display.setScaledContents(True)

                        # 在界面标签中显示结果
                        self.label_score_result.setText(str(round(confi * 100, 2)) + "%")
                        self.label_score_x1.setText(str(int(axes[0])))
                        self.label_score_y1.setText(str(int(axes[1])))
                        self.label_score_x2.setText(str(int(axes[2])))
                        self.label_score_y2.setText(str(int(axes[3])))
                        self.label_plate_result.setText(str(res))
                        QtWidgets.QApplication.processEvents()
        except:
            self.label_display.setText('重现车牌记录时出错,请检查表格内容!')
            self.label_display.setStyleSheet("border-image: url(:/newPrefix/images_test/ini-image.png);")

    def choose_file(self):
        self.flag_timer = ""

        # 选择图片或视频文件后执行此槽函数
        self.timer_camera.stop()
        self.timer_video.stop()
        if self.cap:
            self.cap.release()
        if self.cap_video:
            self.cap_video.release()  # 释放视频画面帧

        # 清除UI上的label显示
        self.label_plate_result.setText("省X00000")
        self.label_score_result.setText("0")
        self.label_score_x1.setText("0")
        self.label_score_x2.setText("0")
        self.label_score_y1.setText("0")
        self.label_score_y2.setText("0")

  
    def show_camera(self):
        # 定时器槽函数,每隔一段时间执行
        flag, image = self.cap.read()  # 获取画面
        if flag:
            # image = cv2.flip(image, 1)  # 左右翻转
            self.current_image = image.copy()

            res_all = HyperLPR_plate_recognition(image)
            if len(res_all) > 0:
                res, confi, axes = res_all[0]
                # axes[2] = axes[0] + axes[2]
                # axes[3] = axes[1] + axes[3]

                image = self.drawRectBox(image, axes, res)

                # 在界面标签中显示结果
                self.label_score_result.setText(str(round(confi * 100, 2)) + "%")
                self.label_score_x1.setText(str(int(axes[0])))
                self.label_score_y1.setText(str(int(axes[1])))
                self.label_score_x2.setText(str(int(axes[2])))
                self.label_score_y2.setText(str(int(axes[3])))
                self.label_plate_result.setText(str(res))
                QtWidgets.QApplication.processEvents()

                # 将结果记录至列表中
                if res not in self.res_set:
                    self.res_set.append(res)
                    self.change_table(str(self.count), res, axes, confi)

            else:
                # 清除UI上的label显示
                self.label_plate_result.setText("省X00000")
                self.label_score_result.setText("0")
                self.label_score_x1.setText("0")
                self.label_score_x2.setText("0")
                self.label_score_y1.setText("0")
                self.label_score_y2.setText("0")

            # 在Qt界面中显示检测完成画面
            show = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)
            self.label_display.setPixmap(QtGui.QPixmap.fromImage(showImage))
            self.label_display.setScaledContents(True)

    def button_open_video_click(self):
        self.count = 0
        self.res_set = []
        self.tableWidget.clearContents()
        if self.timer_camera.isActive():
            self.timer_camera.stop()
        if self.cap:
            self.cap.release()
        if self.cap_video:
            self.cap_video.release()  # 释放视频画面帧
        self.label_display.clear()
        self.label_display.setStyleSheet("border-image: url(:/newPrefix/images_test/ini-image.png);")

        self.flag_timer = ""
        if not self.timer_video.isActive():  # 检查定时状态
            # 弹出文件选择框选择视频文件
            fileName_choose, filetype = QFileDialog.getOpenFileName(self.centralwidget, "选取视频文件",
                                                                    self.video_path,  # 起始路径
                                                                    "视频(*.mp4;*.avi)")  # 文件类型
            self.video_path = fileName_choose
            if fileName_choose != '':
                self.flag_timer = "video"
                self.textEdit_video.setText(fileName_choose + '文件已选中')
                self.textEdit_video.setStyleSheet("background-color: transparent;\n"
                                                  "border-color: rgb(0, 170, 255);\n"
                                                  "color: rgb(0, 170, 255);\n"
                                                  "font: regular 12pt \"华为仿宋\";")
                # self.label_display.setText('正在启动识别系统...\n\nleading')
                QtWidgets.QApplication.processEvents()

                try:  # 初始化视频流
                    self.cap_video = cv2.VideoCapture(fileName_choose)
                except:
                    print("[INFO] could not determine # of frames in video")
            else:
                self.textEdit_video.setText('视频文件未选中')
      
            # self.label_display.setText('正在启动识别系统...\n\nleading')
            QtWidgets.QApplication.processEvents()

            # 清除UI上的label显示
            self.label_plate_result.setText("省X00000")
            self.label_score_result.setText("0")
            self.label_score_x1.setText("0")
            self.label_score_x2.setText("0")
            self.label_score_y1.setText("0")
            self.label_score_y2.setText("0")

        else:
            # 定时器已开启,界面回复初始状态
            self.flag_timer = ""
            self.timer_video.stop()
            if self.cap:
                self.cap.release()
            self.label_display.clear()
            self.textEdit_file.setText('图片文件未选中')
            self.textEdit_file.setStyleSheet("background-color: transparent;\n"
                                             "border-color: rgb(0, 170, 255);\n"
                                             "color: rgb(0, 170, 255);\n"
                                             "font: regular 12pt \"华为仿宋\";")
            self.textEdit_camera.setText('实时摄像已关闭')
            self.textEdit_camera.setStyleSheet("background-color: transparent;\n"
                                               "border-color: rgb(0, 170, 255);\n"
                                               "color: rgb(0, 170, 255);\n"
                                               "font: regular 12pt \"华为仿宋\";")
            self.textEdit_video.setText('实时视频已关闭')
            self.textEdit_video.setStyleSheet("background-color: transparent;\n"
                                              "border-color: rgb(0, 170, 255);\n"
                                              "color: rgb(0, 170, 255);\n"
                                              "font: regular 12pt \"华为仿宋\";")
            self.label_display.setStyleSheet("border-image: url(:/newPrefix/images_test/ini-image.png);")
            # 清除UI上的label显示
            self.label_plate_result.setText("省X00000")
            self.label_score_result.setText("0")
            self.label_score_x1.setText("0")
            self.label_score_x2.setText("0")
            self.label_score_y1.setText("0")
            self.label_score_y2.setText("0")

    def show_video(self):
        # 定时器槽函数,每隔一段时间执行
        flag, image = self.cap_video.read()  # 获取画面
        if flag:
            # 使用模型预测
            image = cv2.resize(image, (500, 500))  # 设定图像尺寸为显示界面大小

            res_all = HyperLPR_plate_recognition(image)
            if len(res_all) > 0:
                res, confi, axes = res_all[0]
                # axes[2] = axes[0] + axes[2]
                # axes[3] = axes[1] + axes[3]

                image = self.drawRectBox(image, axes, res)

                # 在界面标签中显示结果
                self.label_score_result.setText(str(round(confi * 100, 2)) + "%")
                self.label_score_x1.setText(str(int(axes[0])))
                self.label_score_y1.setText(str(int(axes[1])))
                self.label_score_x2.setText(str(int(axes[2])))
                self.label_score_y2.setText(str(int(axes[3])))
                self.label_plate_result.setText(str(res))
                QtWidgets.QApplication.processEvents()

                # 将结果记录至列表中
                if res not in self.res_set:
                    self.res_set.append(res)
                    self.change_table(str(self.count), res, axes, confi)

            else:
                # 清除UI上的label显示
                self.label_plate_result.setText("省X00000")
                self.label_score_result.setText("0")
                self.label_score_x1.setText("0")
                self.label_score_x2.setText("0")
                self.label_score_y1.setText("0")
                self.label_score_y2.setText("0")

            # 在Qt界面中显示检测完成画面
            show = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
            showImage = QtGui.QImage(show.data, show.shape[1], show.shape[0], QtGui.QImage.Format_RGB888)
            self.label_display.setPixmap(QtGui.QPixmap.fromImage(showImage))
            self.label_display.setScaledContents(True)

    def run_rec(self):

        if self.flag_timer == "image":
            self.do_choose_file()

        elif self.flag_timer == "video":
            if not self.timer_video.isActive():
                # self.count = 0
                # self.tableWidget.clearContents()
                # 打开定时器
                self.timer_video.start(30)
            else:
                self.timer_video.stop()

        elif self.flag_timer == "folder":
            self.count = 0
            self.tableWidget.clearContents()
            QtWidgets.QApplication.processEvents()
            self.do_choose_folder()

        elif self.flag_timer == "camera":
            if not self.timer_camera.isActive():
                self.count = 0
                self.tableWidget.clearContents()
                QtWidgets.QApplication.processEvents()
                self.timer_camera.start(30)
            else:
                self.timer_camera.stop()
                self.flag_timer = ""
                if self.cap:
                    self.cap.release()
                self.textEdit_camera.setText("实时摄像已关闭")
                self.textEdit_camera.setStyleSheet("background-color: transparent;\n"
                                                   "border-color: rgb(0, 170, 255);\n"
                                                   "color: rgb(0, 170, 255);\n"
                                                   "font: regular 12pt \"华为仿宋\";")
                QtWidgets.QApplication.processEvents()

        else:
            self.textEdit_model.setText('选择图片文件夹')
            self.textEdit_model.setStyleSheet("background-color: transparent;\n"
                                              "border-color: rgb(0, 170, 255);\n"
                                              "color: rgb(0, 170, 255);\n"
                                              "font: regular 12pt \"华为仿宋\";")
            self.textEdit_file.setText('图片文件未选中')
            self.textEdit_file.setStyleSheet("background-color: transparent;\n"
                                             "border-color: rgb(0, 170, 255);\n"
                                             "color: rgb(0, 170, 255);\n"
                                             "font: regular 12pt \"华为仿宋\";")
            self.textEdit_camera.setText("实时摄像已关闭")
            self.textEdit_camera.setStyleSheet("background-color: transparent;\n"
                                               "border-color: rgb(0, 170, 255);\n"
                                               "color: rgb(0, 170, 255);\n"
                                               "font: regular 12pt \"华为仿宋\";")
            # self.textEdit_model
            self.textEdit_video.setText('实时视频已关闭')
            self.textEdit_video.setStyleSheet("background-color: transparent;\n"
                                              "border-color: rgb(0, 170, 255);\n"
                                              "color: rgb(0, 170, 255);\n"
                                              "font: regular 12pt \"华为仿宋\";")
            self.label_display.clear()
            self.label_display.setStyleSheet("border-image: url(:/newPrefix/images_test/ini-image.png);")
            self.count = 0
            self.tableWidget.clearContents()
            # 清除UI上的label显示
            self.label_plate_result.setText("省X00000")
            self.label_score_result.setText("0")
            self.label_score_x1.setText("0")
            self.label_score_x2.setText("0")
            self.label_score_y1.setText("0")
            self.label_score_y2.setText("0")

    def drawRectBox(self, image, rect, addText):
        cv2.rectangle(image, (int(round(rect[0])), int(round(rect[1]))),
                      (int(round(rect[2]) + 8), int(round(rect[3]) + 8)),
                      (0, 0, 255), 2)
        cv2.rectangle(image, (int(rect[0] - 1), int(rect[1]) - 16), (int(rect[0] + 75), int(rect[1])), (0, 0, 255), -1,
                      cv2.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=self.fontC)
        imagex = np.array(img)
        return imagex

    def cv_imread(self, filePath):
        # 读取图片
        # cv_img = cv2.imread(filePath)
        cv_img = cv2.imdecode(np.fromfile(filePath, dtype=np.uint8), -1)
        # imdecode读取的是rgb,如果后续需要opencv处理的话,需要转换成bgr,转换后图片颜色会变化
        # cv_img = cv2.cvtColor(cv_img,cv2.COLOR_RGB2BGR)
        if len(cv_img.shape) > 2:
            if cv_img.shape[2] > 3:
                cv_img = cv_img[:, :, :3]
        return cv_img



5、源码获取方式

02-03 21:33