通过简单代码实现PyQt5调用YOLO v1算法
首先通过PyQt设计窗口界面:
基础功能:打开相机、关闭相机、启用检测、拍照、清理窗口、保存图像、保存录像、停止录像、选择保存路径等
设置初始化参数:
# 初始化参数
def __init__(self): # 构造函数
super().__init__() # 调用基类的构造函数进行初始化
self.setupUi(self) # 调用setupUi方法,根据Ui_MainWindow设计设置界面
self.label_ShowCam.setScaledContents(True) # 设置窗口自适应
self.label_ShowPhoto.setScaledContents(True) # 设置窗口自适应
self.timer_camera = QtCore.QTimer() # 定义定时器,控制视频帧率
self.cap = cv2.VideoCapture() # 初始化视频流
self.CAM_NUM = 0 # 设置相机索引
self.model = YOLO("yolo11l.pt")
Timer = QtCore.QTimer(self)
Timer.timeout.connect(self.showtime)
Timer.start()
self.Stop_Record = False
self.action()
开启相机:
# 开启相机
def OpenCamera_button(self):
if not self.timer_camera.isActive(): # 判断定时器是否启动
flag = self.cap.open(self.CAM_NUM) # 打开摄像头
if not flag:
self.label_ShowCam.setText("相机连接失败")
else:
self.timer_camera.start(40) # 设置定时器30ms,每过40ms读取一帧
self.label_ShowCam.setText("相机正在打开...")
def OpenCamera_Thread(self):
flag, img = self.cap.read() # 读取视频流
frame = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 色彩转换RGB
flip_img = cv2.flip(frame, 1) # 画面镜像翻转
if self.checkBox_AIdetect.isChecked():
result_img = self.model.predict(flip_img, conf=0.5, device="0") # 导入模型检测
return result_img
return flip_img
显示结果:
# 显示相机实时画面
def show_camera(self):
re_img = self.OpenCamera_Thread()
if self.checkBox_AIdetect.isChecked():
detect_img = re_img[0].plot() # 输出检测结果图片(含外框)
else:
detect_img = re_img # 输出检测结果图片(含外框)
# 视频图像格式转换为QImage
img01 = QImage(detect_img.tobytes(), detect_img.shape[1], detect_img.shape[0], QImage.Format_RGB888)
pixmap = QPixmap.fromImage(img01)
self.label_ShowCam.setPixmap(pixmap) # 在label上显示QImage
关闭相机:
# 关闭相机
def CloseCam(self):
if self.timer_camera.isActive():
self.timer_camera.stop() # 关闭定时器
self.cap.release() # 释放视频流
self.label_ShowCam.setText("相机已关闭")
完整代码
import sys # 导入系统模块,用于访问命令行参数和系统相关功能
import cv2
from PyQt5 import QtCore, QtWidgets # 导入PyQt5的主要模块
from PyQt5.QtGui import * # 导入QtGui模块的所有内容,用于图形功能
from PyQt5.QtWidgets import QMainWindow, QMessageBox # 导入QtWidgets模块中的一些特定类
from ultralytics import YOLO
import time
import os
from threading import Thread
"""以下是唯一需要更改的地方——> from 你ui文件的文件名 Ui_MainWindow"""
from CamDetectShow import Ui_MainWindow # 导入UI类,这个类包含了你的主窗口设计
'''
QFileDialog可以帮助用户选择文件路径
QMainWindow则是创建具有菜单、工具栏和状态栏的主窗口的起点。
QMessageBox可以用于向用户显示提示或警告信息
'''
class PyQtMainEntry(QMainWindow, Ui_MainWindow): # 定义一个继承自QMainWindow和Ui_MainWindow的类
# 初始化参数
def __init__(self): # 构造函数
super().__init__() # 调用基类的构造函数进行初始化
self.setupUi(self) # 调用setupUi方法,根据Ui_MainWindow设计设置界面
self.label_ShowCam.setScaledContents(True) # 设置窗口自适应
self.label_ShowPhoto.setScaledContents(True) # 设置窗口自适应
self.timer_camera = QtCore.QTimer() # 定义定时器,控制视频帧率
self.cap = cv2.VideoCapture() # 初始化视频流
self.CAM_NUM = 0 # 设置相机索引
self.model = YOLO("yolo11l.pt")
Timer = QtCore.QTimer(self)
Timer.timeout.connect(self.showtime)
Timer.start()
self.Stop_Record = False
self.action()
# 激活按钮
def action(self):
self.pushButton_OpenCam.clicked.connect(self.OpenCamera_button) # 设置开启相机
self.timer_camera.timeout.connect(self.show_camera) # 开启相机
self.pushButton_CloseCam.clicked.connect(self.CloseCam) # 关闭相机
self.pushButton_TakePhoto.clicked.connect(self.TakePhoto) # 拍照
self.pushButton_SaveImg.clicked.connect(self.Save_Img) # 保存图片
self.pushButton_SaveVideo.clicked.connect(self.open_SaveVideo_thread1) # 保存视频
self.pushButton_SelectFile.clicked.connect(self.Select_File) # 选择文件夹
self.pushButton_StopSaveVideo.clicked.connect(self.Stop_Record_button)
self.checkBox_AIdetect.setChecked(False)
def showtime(self):
self.label_Time.setText(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
# 开启相机
def OpenCamera_button(self):
if not self.timer_camera.isActive(): # 判断定时器是否启动
flag = self.cap.open(self.CAM_NUM) # 打开摄像头
if not flag:
self.label_ShowCam.setText("相机连接失败")
else:
self.timer_camera.start(40) # 设置定时器30ms,每过40ms读取一帧
self.label_ShowCam.setText("相机正在打开...")
def OpenCamera_Thread(self):
flag, img = self.cap.read() # 读取视频流
frame = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 色彩转换RGB
flip_img = cv2.flip(frame, 1) # 画面镜像翻转
if self.checkBox_AIdetect.isChecked():
result_img = self.model.predict(flip_img, conf=0.5, device="0") # 导入模型检测
return result_img
return flip_img
# 显示相机实时画面
def show_camera(self):
re_img = self.OpenCamera_Thread()
if self.checkBox_AIdetect.isChecked():
detect_img = re_img[0].plot() # 输出检测结果图片(含外框)
else:
detect_img = re_img # 输出检测结果图片(含外框)
# 视频图像格式转换为QImage
img01 = QImage(detect_img.tobytes(), detect_img.shape[1], detect_img.shape[0], QImage.Format_RGB888)
pixmap = QPixmap.fromImage(img01)
self.label_ShowCam.setPixmap(pixmap) # 在label上显示QImage
# 关闭相机
def CloseCam(self):
if self.timer_camera.isActive():
self.timer_camera.stop() # 关闭定时器
self.cap.release() # 释放视频流
self.label_ShowCam.setText("相机已关闭")
# 拍照
def TakePhoto(self):
if self.cap.isOpened(): # 读取单帧
result_img = self.OpenCamera_Thread() # 输出检测结果图片(含外框)
if not self.checkBox_AIdetect.isChecked():
detect_img = result_img
else:
detect_img = result_img[0].plot()
# 视频图像格式转换为QImage
img = QImage(detect_img.tobytes(), detect_img.shape[1], detect_img.shape[0], QImage.Format_RGB888)
pixmap = QPixmap.fromImage(img)
self.label_ShowPhoto.setPixmap(pixmap) # 在label上显示QImage
else:
self.label_ShowPhoto.setText("相机打开失败")
def Select_File(self):
p = QtWidgets.QFileDialog.getExistingDirectory(self, "选择文件", "/") # 获取文件夹地址
self.lineEdit_SavePath.setText(p) # 显示文件地址
def Save_Img(self):
FilesPath = self.lineEdit_SavePath.text() # 获取文件夹地址
if len(FilesPath) == 0:
QMessageBox.information(self, "消息对话框", "请先选择文件保存地址!", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
else:
if os.path.isdir(FilesPath):
local_time = time.strftime('%Y-%m-%d-%H-%M-%S')
# 满足文件名唯一性且符合文件名定义规范
new_name = str(local_time) + ".png"
try:
save_pix = self.label_ShowPhoto.pixmap()
save_pix.save(os.path.join(FilesPath, new_name))
except Exception as e:
QMessageBox.warning(self, "警告对话框", "请先选择拍照!", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
else:
QMessageBox.information(self, "消息对话框", "所选文件夹不存在!", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
def Create_Save_Video(self):
FilesPath = self.lineEdit_SavePath.text() # 获取文件夹地址
frame_width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = int(self.cap.get(cv2.CAP_PROP_FPS))
if len(FilesPath) == 0:
QMessageBox.information(self, "消息对话框", "请先选择文件保存地址!", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
elif os.path.isdir(FilesPath):
local_time = time.strftime('%Y_%m_%d')
# 满足文件名唯一性且符合文件名定义规范
new_name = "Record_" + str(local_time) + ".avi"
# initialize the FourCC and a video writer object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
writer = cv2.VideoWriter(os.path.join(FilesPath, new_name), fourcc, fps, (frame_width, frame_height))
return writer
else:
QMessageBox.information(self, "消息对话框", "所选文件夹不存在!", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
def SaveVideo_Thread(self):
while True:
result_img = self.OpenCamera_Thread()
if self.checkBox_AIdetect.isChecked():
detect_img = result_img[0].plot() # 输出检测结果图片(含外框)
else:
detect_img = result_img # 输出检测结果图片(含外框)
rgb_img = cv2.cvtColor(detect_img, cv2.COLOR_BGR2RGB)
save_wr = self.Create_Save_Video()
save_wr.write(rgb_img)
Stop_Record = self.Stop_Record_button()
if Stop_Record:
save_wr.release()
break
def Stop_Record_button(self):
self.Stop_Record = True
return self.Stop_Record
def open_SaveVideo_thread1(self):
T1 = Thread(target=self.SaveVideo_Thread, args=())
T1.start()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv) # 创建应用程序实例
window = PyQtMainEntry() # 创建主窗口实例
window.show() # 显示主窗口
sys.exit(app.exec_()) # 进入事件循环,并确保在退出时清理