畢業(yè)設(shè)計(jì):2023-2024年計(jì)算機(jī)專業(yè)畢業(yè)設(shè)計(jì)選題匯總(建議收藏)
畢業(yè)設(shè)計(jì):2023-2024年最新最全計(jì)算機(jī)專業(yè)畢設(shè)選題推薦匯總
??感興趣的可以先收藏起來(lái),點(diǎn)贊、關(guān)注不迷路,大家在畢設(shè)選題,項(xiàng)目以及論文編寫(xiě)等相關(guān)問(wèn)題都可以給我留言咨詢,希望幫助同學(xué)們順利畢業(yè)?。??
1、項(xiàng)目介紹
技術(shù)棧:
Python3.8 YOLOv8 深度學(xué)習(xí) LPRNet算法 pytorch
項(xiàng)目介紹:
基于YOLOv8+LPRNet進(jìn)行車牌檢測(cè)及識(shí)別,包括對(duì)車輛的車牌區(qū)域精確定位,利用校正探測(cè)器對(duì)定位的車牌進(jìn)行邊框校正處理,使用增強(qiáng)神經(jīng)網(wǎng)絡(luò)模型對(duì)車牌區(qū)域進(jìn)行超分辨率技術(shù)處理和光學(xué)字符識(shí)別。經(jīng)過(guò)多次試驗(yàn)測(cè)試,可以對(duì)視頻中的車輛車牌實(shí)時(shí)識(shí)別以及圖片中的車輛車牌進(jìn)行準(zhǔn)確定位和識(shí)別,識(shí)別速度快,準(zhǔn)確率高,比那些傳統(tǒng)車牌識(shí)別方法效果好很多。
LPRNet由輕量級(jí)的卷積神經(jīng)網(wǎng)絡(luò)組成,所以它可以采用端到端的方法來(lái)進(jìn)行訓(xùn)練。據(jù)我們所知,LPRNet是第一個(gè)沒(méi)有采用RNNs的實(shí)時(shí)車牌識(shí)別系統(tǒng)。因此,LPRNet算法可以為L(zhǎng)PR創(chuàng)建嵌入式部署的解決方案,即便是在具有較高挑戰(zhàn)性的中文車牌識(shí)別上。
2、項(xiàng)目界面
(1)上傳圖片進(jìn)行車牌識(shí)別
(2)上傳圖片進(jìn)行車牌識(shí)別2
(3)多車牌號(hào)碼進(jìn)行車牌識(shí)別
(4)上傳視頻進(jìn)行車牌識(shí)別實(shí)時(shí)檢測(cè)
(5)連接攝像頭進(jìn)行車牌識(shí)別
(6)連接攝像頭進(jìn)行車牌識(shí)別2
(7)車牌識(shí)別檢測(cè)
3、項(xiàng)目說(shuō)明
項(xiàng)目介紹:
基于YOLOv8+LPRNet進(jìn)行車牌檢測(cè)及識(shí)別,包括對(duì)車輛的車牌區(qū)域精確定位,利用校正探測(cè)器對(duì)定位的車牌進(jìn)行邊框校正處理,使用增強(qiáng)神經(jīng)網(wǎng)絡(luò)模型對(duì)車牌區(qū)域進(jìn)行超分辨率技術(shù)處理和光學(xué)字符識(shí)別。經(jīng)過(guò)多次試驗(yàn)測(cè)試,可以對(duì)視頻中的車輛車牌實(shí)時(shí)識(shí)別以及圖片中的車輛車牌進(jìn)行準(zhǔn)確定位和識(shí)別,識(shí)別速度快,準(zhǔn)確率高,比那些傳統(tǒng)車牌識(shí)別方法效果好很多。
LPRNet由輕量級(jí)的卷積神經(jīng)網(wǎng)絡(luò)組成,所以它可以采用端到端的方法來(lái)進(jìn)行訓(xùn)練。據(jù)我們所知,LPRNet是第一個(gè)沒(méi)有采用RNNs的實(shí)時(shí)車牌識(shí)別系統(tǒng)。因此,LPRNet算法可以為L(zhǎng)PR創(chuàng)建嵌入式部署的解決方案,即便是在具有較高挑戰(zhàn)性的中文車牌識(shí)別上。
4、核心代碼
from ultralytics.yolo.engine.predictor import BasePredictor
from ultralytics.yolo.engine.results import Results
from ultralytics.yolo.utils import DEFAULT_CFG, LOGGER, SETTINGS, callbacks, ops
from ultralytics.yolo.utils.plotting import Annotator, colors, save_one_box
from ultralytics.yolo.utils.torch_utils import smart_inference_mode
from ultralytics.yolo.utils.files import increment_path
from ultralytics.yolo.utils.checks import check_imshow
from ultralytics.yolo.cfg import get_cfg
from PySide6.QtWidgets import QApplication, QMainWindow, QFileDialog, QMenu
from PySide6.QtGui import QImage, QPixmap, QColor
from PySide6.QtCore import QTimer, QThread, Signal, QObject, QPoint, Qt
from ui.CustomMessageBox import MessageBox
from ui.home import Ui_MainWindow
from UIFunctions import *
from collections import defaultdict
from pathlib import Path
from utils.capnums import Camera
from utils.rtsp_win import Window
import numpy as np
import time
import json
import torch
import sys
import cv2
import os
from yoloPre import YoloPredictor
class MainWindow(QMainWindow, Ui_MainWindow):
# 這是一個(gè) PySide6 的信號(hào)(Signal)對(duì)象,
# 用于在應(yīng)用程序中傳遞消息。在這個(gè)場(chǎng)景中,它被用于在主窗口和 YOLO 實(shí)例之間傳遞消息。
main2yolo_begin_sgl = Signal() # The main window sends an execution signal to the yolo instance
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
# basic interface 【UI初始化!】
self.setupUi(self)
self.setAttribute(Qt.WA_TranslucentBackground) # rounded transparent
self.setWindowFlags(Qt.FramelessWindowHint) # Set window flag: hide window borders
UIFuncitons.uiDefinitions(self)
# Show module shadows
UIFuncitons.shadow_style(self, self.Class_QF, QColor(162,129,247))
UIFuncitons.shadow_style(self, self.Target_QF, QColor(251, 157, 139))
UIFuncitons.shadow_style(self, self.Fps_QF, QColor(170, 128, 213))
UIFuncitons.shadow_style(self, self.Model_QF, QColor(64, 186, 193))
# read model folder 加載模型
self.pt_list = os.listdir('./models')
self.pt_list = [file for file in self.pt_list if file.endswith('.pt')]
self.pt_list.sort(key=lambda x: os.path.getsize('./models/' + x)) # sort by file size
self.model_box.clear()
self.model_box.addItems(self.pt_list)
self.Qtimer_ModelBox = QTimer(self) # Timer: Monitor model file changes every 2 seconds
self.Qtimer_ModelBox.timeout.connect(self.ModelBoxRefre)
self.Qtimer_ModelBox.start(2000)
# Yolo-v8 thread 初始化
self.yolo_predict = YoloPredictor() # Create a Yolo instance
self.select_model = self.model_box.currentText() # default model
self.yolo_predict.new_model_name = "./models/%s" % self.select_model
self.yolo_thread = QThread() # Create yolo thread
# 將 Yolo 類中的信號(hào)綁定到主線程的槽函數(shù)上
self.yolo_predict.yolo2main_pre_img.connect(lambda x: self.show_image(x, self.pre_video))
self.yolo_predict.yolo2main_res_img.connect(lambda x: self.show_image(x, self.res_video))
self.yolo_predict.yolo2main_status_msg.connect(lambda x: self.show_status(x))
self.yolo_predict.yolo2main_fps.connect(lambda x: self.fps_label.setText(x))
# self.yolo_predict.yolo2main_labels.connect(self.show_labels)
self.yolo_predict.yolo2main_class_num.connect(lambda x:self.Class_num.setText(str(x)))
self.yolo_predict.yolo2main_target_num.connect(lambda x:self.Target_num.setText(str(x)))
self.yolo_predict.yolo2main_progress.connect(lambda x: self.progress_bar.setValue(x))
# 將主線程的信號(hào)綁定到 Yolo 類的槽函數(shù)上,并啟動(dòng) Yolo 線程
self.main2yolo_begin_sgl.connect(self.yolo_predict.run)
self.yolo_predict.moveToThread(self.yolo_thread)
# Model parameters
self.model_box.currentTextChanged.connect(self.change_model)
self.iou_spinbox.valueChanged.connect(lambda x:self.change_val(x, 'iou_spinbox')) # iou box
self.iou_slider.valueChanged.connect(lambda x:self.change_val(x, 'iou_slider')) # iou scroll bar
self.conf_spinbox.valueChanged.connect(lambda x:self.change_val(x, 'conf_spinbox')) # conf box
self.conf_slider.valueChanged.connect(lambda x:self.change_val(x, 'conf_slider')) # conf scroll bar
self.speed_spinbox.valueChanged.connect(lambda x:self.change_val(x, 'speed_spinbox'))# speed box
self.speed_slider.valueChanged.connect(lambda x:self.change_val(x, 'speed_slider')) # speed scroll bar
# Prompt window initialization
self.Class_num.setText('--')
self.Target_num.setText('--')
self.fps_label.setText('--')
self.Model_name.setText(self.select_model)
# Select detection source
self.src_file_button.clicked.connect(self.open_src_file) # select local file
self.src_cam_button.clicked.connect(self.chose_cam) #chose_camera
# self.src_rtsp_button.clicked.connect(self.show_status("The function has not yet been implemented."))#chose_rtsp
# start testing button
self.run_button.clicked.connect(self.run_or_continue) # pause/start
self.stop_button.clicked.connect(self.stop) # termination
# Other function buttons
self.save_res_button.toggled.connect(self.is_save_res) # save image option
self.save_txt_button.toggled.connect(self.is_save_txt) # Save label option
self.ToggleBotton.clicked.connect(lambda: UIFuncitons.toggleMenu(self, True)) # left navigation button
self.settings_button.clicked.connect(lambda: UIFuncitons.settingBox(self, True)) # top right settings button
# initialization
self.load_config()
# The main window displays the original image and detection results
@staticmethod
def show_image(img_src, label):
try:
ih, iw, _ = img_src.shape # 獲取原始圖像的高度和寬度
w = label.geometry().width() # 獲取 QLabel 組件的當(dāng)前寬度
h = label.geometry().height() # 獲取 QLabel 組件的當(dāng)前高度
# 根據(jù)原始圖像和 QLabel 組件的大小,等比例縮放原始圖像
if iw / w > ih / h: # 如果原始圖像的寬度比高度大,按照寬度比例縮放
scal = w / iw
nw = w
nh = int(scal * ih)
img_src_ = cv2.resize(img_src, (nw, nh))
else: # 如果原始圖像的高度比寬度大,按照高度比例縮放
scal = h / ih
nw = int(scal * iw)
nh = h
img_src_ = cv2.resize(img_src, (nw, nh))
# 將 OpenCV 圖像轉(zhuǎn)換為 QImage 對(duì)象,并將其顯示在 QLabel 組件中
frame = cv2.cvtColor(img_src_, cv2.COLOR_BGR2RGB) # 將圖像的顏色空間從 BGR 轉(zhuǎn)換為 RGB
img = QImage(frame.data, frame.shape[1], frame.shape[0], frame.shape[2] * frame.shape[1],
QImage.Format_RGB888) # 創(chuàng)建 QImage 對(duì)象
label.setPixmap(QPixmap.fromImage(img)) # 將 QImage 對(duì)象轉(zhuǎn)換為 QPixmap 對(duì)象,并將其顯示在 QLabel 組件中
except Exception as e:
print(repr(e))
# Control start/pause
def run_or_continue(self):
if self.yolo_predict.source == '':
print('Please select a video source')
self.show_status('Please select a video source before starting detection...')
self.run_button.setChecked(False)
else:
self.yolo_predict.stop_dtc = False
print('start')
if self.run_button.isChecked():
self.run_button.setChecked(True) # start button
self.save_txt_button.setEnabled(False) # It is forbidden to check and save after starting the detection
self.save_res_button.setEnabled(False)
self.show_status('Detecting...')
self.yolo_predict.continue_dtc = True # Control whether Yolo is paused
if not self.yolo_thread.isRunning():
self.yolo_thread.start()
self.main2yolo_begin_sgl.emit()
else:
self.yolo_predict.continue_dtc = False
self.show_status("Pause...")
self.run_button.setChecked(False) # start button
# bottom status bar information
def show_status(self, msg):
self.status_bar.setText(msg)
print(msg)
if msg == 'Detection completed' or msg == '檢測(cè)完成':
self.save_res_button.setEnabled(True)
self.save_txt_button.setEnabled(True)
self.run_button.setChecked(False)
self.progress_bar.setValue(0)
if self.yolo_thread.isRunning():
self.yolo_thread.quit() # end process
elif msg == 'Detection terminated!' or msg == '檢測(cè)終止':
self.save_res_button.setEnabled(True)
self.save_txt_button.setEnabled(True)
self.run_button.setChecked(False)
self.progress_bar.setValue(0)
if self.yolo_thread.isRunning():
self.yolo_thread.quit() # end process
self.pre_video.clear() # clear image display
self.res_video.clear()
self.Class_num.setText('--')
self.Target_num.setText('--')
self.fps_label.setText('--')
# select local file
def open_src_file(self):
print('local file')
config_file = 'config/fold.json'
config = json.load(open(config_file, 'r', encoding='utf-8'))
open_fold = config['open_fold']
if not os.path.exists(open_fold):
open_fold = os.getcwd()
name, _ = QFileDialog.getOpenFileName(self, 'Video/image', open_fold, "Pic File(*.mp4 *.mkv *.avi *.flv *.jpg *.png)")
if name:
self.yolo_predict.source = name
self.show_status('Load File:{}'.format(os.path.basename(name)))
config['open_fold'] = os.path.dirname(name)
config_json = json.dumps(config, ensure_ascii=False, indent=2)
with open(config_file, 'w', encoding='utf-8') as f:
f.write(config_json)
self.stop()
# Select camera source---- have one bug
def chose_cam(self):
try:
print('open camera')
# self.stop()
# MessageBox(
# self.close_button, title='Note', text='loading camera...', time=2000, auto=True).exec()
# get the number of local cameras
# _, cams = Camera().get_cam_num()
# self.viewer = CameraViewer() # 創(chuàng)建新的 CameraViewer 類的對(duì)象
# self.viewer.show() # 顯示 CameraViewer 類的 GUI 界面
self.yolo_predict.camera_run()
except Exception as e:
print(e)
self.show_status('%s' % e)
# select network source
def chose_rtsp(self):
self.rtsp_window = Window()
config_file = 'config/ip.json'
if not os.path.exists(config_file):
ip = "rtsp://admin:admin888@192.168.1.2:555"
new_config = {"ip": ip}
new_json = json.dumps(new_config, ensure_ascii=False, indent=2)
with open(config_file, 'w', encoding='utf-8') as f:
f.write(new_json)
else:
config = json.load(open(config_file, 'r', encoding='utf-8'))
ip = config['ip']
self.rtsp_window.rtspEdit.setText(ip)
self.rtsp_window.show()
self.rtsp_window.rtspButton.clicked.connect(lambda: self.load_rtsp(self.rtsp_window.rtspEdit.text()))
# load network sources
def load_rtsp(self, ip):
try:
self.stop()
MessageBox(
self.close_button, title='提示', text='加載 rtsp...', time=1000, auto=True).exec()
self.yolo_predict.source = ip
new_config = {"ip": ip}
new_json = json.dumps(new_config, ensure_ascii=False, indent=2)
with open('config/ip.json', 'w', encoding='utf-8') as f:
f.write(new_json)
self.show_status('Loading rtsp:{}'.format(ip))
self.rtsp_window.close()
except Exception as e:
self.show_status('%s' % e)
# Save test result button--picture/video
def is_save_res(self):
if self.save_res_button.checkState() == Qt.CheckState.Unchecked:
self.show_status('NOTE: Run image results are not saved.')
self.yolo_predict.save_res = False
elif self.save_res_button.checkState() == Qt.CheckState.Checked:
self.show_status('NOTE: Run image results will be saved.')
self.yolo_predict.save_res = True
if __name__ == "__main__":
app = QApplication(sys.argv)
Home = MainWindow()
Home.show()
sys.exit(app.exec())
5、源碼獲取
??由于篇幅限制,獲取完整文章或源碼、代做項(xiàng)目的,查看我的【用戶名】、【專欄名稱】、【頂部選題鏈接】就可以找到我啦??文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-833076.html
感興趣的可以先收藏起來(lái),點(diǎn)贊、關(guān)注不迷路,下方查看????獲取聯(lián)系方式????文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-833076.html
到了這里,關(guān)于畢業(yè)設(shè)計(jì):YOLOv8車牌識(shí)別系統(tǒng) 深度學(xué)習(xí) LPRNet算法 pytorch 大數(shù)據(jù) (源碼)?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!