YOLO数据处理 界面程序
本案例 使用 YOLO
模型 结合 Python Qt
,开发图形界面的 监测程序。
需要先安装 PySide6 和 Yolo 库 ultralytics
注意
目前 ultralytics库 兼容 YOLOv8
以及后续模型。
如果你使用 早期版本YOLO(比如YOLOv5)训练的模型,请修改相应的 库的导入和检测代码。
您需要高效学习,找工作? 点击咨询 报名实战班
点击查看学员就业情况
物品检测
下面示例代码实现了 摄像头实时视频流 的 YOLO 物品检测。
如果还需要 包含 视频文件实时检测
功能的代码, 请将这个YOLO+Qt视频分享到朋友圈(点击打开),截屏发微给 byhy44
from PySide6 import QtWidgets, QtCore, QtGui
import cv2, os, time
from threading import Thread
# 不然每次YOLO处理都会输出调试信息
os.environ['YOLO_VERBOSE'] = 'False'
from ultralytics import YOLO
class MWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
# 设置界面
self.setupUI()
self.camBtn.clicked.connect(self.startCamera)
self.stopBtn.clicked.connect(self.stop)
# 定义定时器,用于控制显示视频的帧率
self.timer_camera = QtCore.QTimer()
# 定时到了,回调 self.show_camera
self.timer_camera.timeout.connect(self.show_camera)
# 加载 YOLO nano 模型,第一次比较耗时,要20秒左右
self.model = YOLO('yolov8n.pt')
# 要处理的视频帧图片队列,目前就放1帧图片
self.frameToAnalyze = []
# 启动处理视频帧独立线程
Thread(target=self.frameAnalyzeThreadFunc,daemon=True).start()
def setupUI(self):
self.resize(1200, 800)
self.setWindowTitle('白月黑羽 YOLO-Qt 演示')
# central Widget
centralWidget = QtWidgets.QWidget(self)
self.setCentralWidget(centralWidget)
# central Widget 里面的 主 layout
mainLayout = QtWidgets.QVBoxLayout(centralWidget)
# 界面的上半部分 : 图形展示部分
topLayout = QtWidgets.QHBoxLayout()
self.label_ori_video = QtWidgets.QLabel(self)
self.label_treated = QtWidgets.QLabel(self)
self.label_ori_video.setMinimumSize(520,400)
self.label_treated.setMinimumSize(520,400)
self.label_ori_video.setStyleSheet('border:1px solid #D7E2F9;')
self.label_treated.setStyleSheet('border:1px solid #D7E2F9;')
topLayout.addWidget(self.label_ori_video)
topLayout.addWidget(self.label_treated)
mainLayout.addLayout(topLayout)
# 界面下半部分: 输出框 和 按钮
groupBox = QtWidgets.QGroupBox(self)
bottomLayout = QtWidgets.QHBoxLayout(groupBox)
self.textLog = QtWidgets.QTextBrowser()
bottomLayout.addWidget(self.textLog)
mainLayout.addWidget(groupBox)
btnLayout = QtWidgets.QVBoxLayout()
self.videoBtn = QtWidgets.QPushButton('🎞️视频文件')
self.camBtn = QtWidgets.QPushButton('📹摄像头')
self.stopBtn = QtWidgets.QPushButton('🛑停止')
btnLayout.addWidget(self.videoBtn)
btnLayout.addWidget(self.camBtn)
btnLayout.addWidget(self.stopBtn)
bottomLayout.addLayout(btnLayout)
def startCamera(self):
# 参考 https://docs.opencv.org/3.4/dd/d43/tutorial_py_video_display.html
# 在 windows上指定使用 cv2.CAP_DSHOW 会让打开摄像头快很多,
# 在 Linux/Mac上 指定 V4L, FFMPEG 或者 GSTREAMER
self.cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
if not self.cap.isOpened():
print("1号摄像头不能打开")
return()
if self.timer_camera.isActive() == False: # 若定时器未启动
self.timer_camera.start(50)
def show_camera(self):
ret, frame = self.cap.read() # 从视频流中读取
if not ret:
return
# 把读到的16:10帧的大小重新设置
frame = cv2.resize(frame, (520, 400))
# 视频色彩转换回RGB,OpenCV images as BGR
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
qImage = QtGui.QImage(frame.data, frame.shape[1], frame.shape[0],
QtGui.QImage.Format_RGB888) # 变成QImage形式
# 往显示视频的Label里 显示QImage
self.label_ori_video.setPixmap(QtGui.QPixmap.fromImage(qImage))
# 如果当前没有处理任务
if not self.frameToAnalyze:
self.frameToAnalyze.append(frame)
def frameAnalyzeThreadFunc(self):
while True:
if not self.frameToAnalyze:
time.sleep(0.01)
continue
frame = self.frameToAnalyze.pop(0)
results = self.model(frame)[0]
img = results.plot(line_width=1)
qImage = QtGui.QImage(img.data, img.shape[1], img.shape[0],
QtGui.QImage.Format_RGB888) # 变成QImage形式
self.label_treated.setPixmap(QtGui.QPixmap.fromImage(qImage)) # 往显示Label里 显示QImage
time.sleep(0.5)
def stop(self):
self.timer_camera.stop() # 关闭定时器
self.cap.release() # 释放视频流
self.label_ori_video.clear() # 清空视频显示区域
self.label_treated.clear() # 清空视频显示区域
app = QtWidgets.QApplication()
window = MWindow()
window.show()
app.exec()
物品检测(hyqt)
使用 hyqt
库,可以使界面开发更加 简洁,代码如下
对应的代码需要安装 hyqt 库
执行 pip install hyqt
安装
from hyqt import *
app = QApplication()
import cv2, os, time
from threading import Thread
# 不然每次YOLO处理都会输出调试信息
os.environ['YOLO_VERBOSE'] = 'False'
from ultralytics import YOLO
class VideoHandler:
def __init__(self):
super().__init__()
# 定义定时器,用于控制显示视频的帧率
self.timer_camera = QtCore.QTimer()
# 定时到了,回调 self.show_camera
self.timer_camera.timeout.connect(self.show_camera)
# 加载 YOLO nano 模型,第一次比较耗时,要20秒左右
self.model = YOLO('yolov11n.pt')
# 要处理的视频帧图片队列,目前就放1帧图片
self.frameToAnalyze = []
# 启动处理视频帧独立线程
Thread(target=self.frameAnalyzeThreadFunc,daemon=True).start()
def startCamera(self):
# 参考 https://docs.opencv.org/3.4/dd/d43/tutorial_py_video_display.html
# 在 windows上指定使用 cv2.CAP_DSHOW 会让打开摄像头快很多,
# 在 Linux/Mac上 指定 V4L, FFMPEG 或者 GSTREAMER
self.cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
if not self.cap.isOpened():
print("1号摄像头不能打开")
return()
if self.timer_camera.isActive() == False: # 若定时器未启动
self.timer_camera.start(50)
def show_camera(self):
ret, frame = self.cap.read() # 从视频流中读取
if not ret:
return
# 把读到的16:10帧的大小重新设置
frame = cv2.resize(frame, (520, 400))
# 视频色彩转换回RGB,OpenCV images as BGR
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
qImage = QtGui.QImage(frame.data, frame.shape[1], frame.shape[0],
QtGui.QImage.Format_RGB888) # 变成QImage形式
# 往显示视频的Label里 显示QImage
label_ori_video.setPixmap(QtGui.QPixmap.fromImage(qImage))
# 如果当前没有处理任务
if not self.frameToAnalyze:
self.frameToAnalyze.append(frame)
def frameAnalyzeThreadFunc(self):
while True:
if not self.frameToAnalyze:
time.sleep(0.01)
continue
frame = self.frameToAnalyze.pop(0)
results = self.model(frame)[0]
img = results.plot(line_width=1)
qImage = QtGui.QImage(img.data, img.shape[1], img.shape[0],
QtGui.QImage.Format_RGB888) # 变成QImage形式
label_treated.setPixmap(QtGui.QPixmap.fromImage(qImage)) # 往显示Label里 显示QImage
time.sleep(0.5)
def stop(self):
self.timer_camera.stop() # 关闭定时器
self.cap.release() # 释放视频流
label_ori_video.clear() # 清空视频显示区域
label_treated.clear() # 清空视频显示区域
vh = VideoHandler()
win = Column(
# 上半部分
Row(
label_ori_video := Label(minWidth=520, minHeight=400, border='1px solid lightgreen',
hExpanding=True,vExpanding=True),
label_treated := Label(minWidth=520, minHeight=400, border='1px solid lightgreen',
hExpanding=True,vExpanding=True),
),
# 下半部分
Row(
TextArea(hExpanding=True,vExpanding=True,minHeight=300),
Column(
s__(width=100),
Button('🎞️视频文件'),
camBtn := Button('📹摄像头', onClick=vh.startCamera),
stopBtn := Button('🛑停止', onClick=vh.stop),
)
)
)
win.show()
app.exec()
交通监控
本例 使用 Github 上 bahakizil 的 YOLOv12n交通监控调优模型 结合图形界面监测交通情况。
不能直接访问的Github链接的朋友,可以点击这里,网盘下载模型和示例视频文件
视频讲解对应的代码 需要安装 hyqt
, pyqtgraph
库 和 yolo
库
最后 图表功能
的讲解和代码,点击这里,只需要3元即可观看学习
如果 只需要 包含 图表功能
的代码, 请将 这个 YOLO交通监测 视频分享到朋友圈(点击打开),截屏发微给 byhy44
参考代码如下
from hyqt import *
import pyqtgraph as pg
from threading import Thread
from PySide6.QtCore import Signal,QObject
import cv2 as cv
import os,time
# 不然每次YOLO处理都会输出调试信息
os.environ['YOLO_VERBOSE'] = 'False'
from ultralytics import YOLO
app = QApplication()
# 自定义信号源对象类型,一定要继承自 QObject
class SignalMgr(QObject):
imgGen = Signal(QtGui.QPixmap)
sm = SignalMgr()
class VideoHandler:
def __init__(self):
# 定义定时器,用于控制显示视频文件的帧率
self.timer_videoFile = QtCore.QTimer()
# 定时到了,回调 self.show_videoFile
self.timer_videoFile.timeout.connect(self.play_video_file)
# cv2.VideoCapture 实例
self.cap = None
# 加载 YOLO 模型,第一次比较耗时,要20秒左右
self.model = YOLO("best.pt")
self.frameToPredict = None
sm.imgGen.connect(self.showImgGen)
# 启动Yolo处理视频帧独立线程
thread = Thread(target=self.theadFunc_framePredict, daemon=True)
thread.start()
def openVideoFile(self):
videoPath, _ = QFileDialog.getOpenFileName(
win, # 父窗口对象
"选择视频文件", # 标题
".", # 起始目录
"图片类型 (*.mp4 *.avi)" # 选择类型过滤项,过滤内容在括号中
)
if not videoPath:
return
self.cap = cv.VideoCapture(videoPath)
if not self.cap.isOpened():
print('打开视频文件失败')
return
self.timer_videoFile.start(30)
def play_video_file(self):
ret, frame = self.cap.read()
# if frame is read correctly ret is True
if not ret:
print('视频播放结束,重新开始')
self.cap.set(cv.CAP_PROP_POS_FRAMES, 0)
ret, frame = self.cap.read()
# 视频色彩转换回RGB,OpenCV images as BGR
frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
qImage = QtGui.QImage(frame.data, frame.shape[1], frame.shape[0],
QtGui.QImage.Format_RGB888) # 变成QImage形式
# 往显示视频的Label里 显示QImage
label_ori_video.setPixmap(QtGui.QPixmap.fromImage(qImage))
# 如果当前后台Yolo线程没有处理任务
if self.frameToPredict is None:
self.frameToPredict = frame
def theadFunc_framePredict(self):
while True:
if self.frameToPredict is None:
time.sleep(0.01)
continue
# YOLO 推理图片
result = self.model.predict(self.frameToPredict)[0]
img = result.plot(line_width=1)
qImage = QtGui.QImage(img.data, img.shape[1], img.shape[0],
QtGui.QImage.Format_RGB888) # 变成QImage形式
sm.imgGen.emit(QtGui.QPixmap.fromImage(qImage))
time.sleep(2)
self.frameToPredict = None
def showImgGen(self, img):
label_gen_video.setPixmap(img)
def stop(self):
self.frameToPredict = None
self.timer_videoFile.stop()
if self.cap:
self.cap.release()
label_ori_video.clear()
label_gen_video.clear()
vh = VideoHandler()
win = Column(
s__(windowTitle="白月黑羽 YOLO-Qt 演示" ,size=(1000,800)),
# 上半部分
Row(s__(paddings=0, ),
label_ori_video := Label(border="1px solid lightblue", minWidth=520, minHeight=400),
label_gen_video := Label(border="1px solid lightblue", minWidth=520, minHeight=400),
),
# 下半部分
Row(s__( border="1px solid lightblue" ),
pw := pg.PlotWidget(),
TextBrowser(hExpanding=True,vExpanding=True),
Column(s__(hExpanding=False),
Button('🎞️视频文件', onClick=vh.openVideoFile),
Button('📹摄像头', ),
Button('🛑停止', onClick=vh.stop ),
)
),
)
pw.showGrid(x=True, y=True)
pw.setBackground('w')
win.show()
app.exec()