0%

YOLO数据处理界面程序

点击这里,观看项目说明视频讲解

本案例 使用 YOLOv8 结合 Python Qt ,开发一个图形界面的 AI实时物品监测程序。

注意

如果你使用其它版本YOLO(比如YOLOv5)训练的模型,请修改相应的导入和检测代码。

您需要高效学习,找工作? 点击咨询 报名实战班

点击查看学员就业情况

示例代码

下面示例代码实现了摄像头实时视频流的YOLO检测。

如果还需要 包含 视频文件实时检测 的功能代码, 请将这个YOLO+Qt视频分享到朋友圈(点击打开),截屏发微给 byhy44

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<span></span><code><span id="__span-0-1"><span>from</span> <span>PySide6</span> <span>import</span> <span>QtWidgets</span><span>,</span> <span>QtCore</span><span>,</span> <span>QtGui</span>
</span><span id="__span-0-2"><span>import</span> <span>cv2</span><span>,</span> <span>os</span><span>,</span> <span>time</span>
</span><span id="__span-0-3"><span>from</span> <span>threading</span> <span>import</span> <span>Thread</span>
</span><span id="__span-0-4">
</span><span id="__span-0-5"><span># 不然每次YOLO处理都会输出调试信息</span>
</span><span id="__span-0-6"><span>os</span><span>.</span><span>environ</span><span>[</span><span>'YOLO_VERBOSE'</span><span>]</span> <span>=</span> <span>'False'</span>
</span><span id="__span-0-7"><span>from</span> <span>ultralytics</span> <span>import</span> <span>YOLO</span>
</span><span id="__span-0-8">
</span><span id="__span-0-9"><span>class</span> <span>MWindow</span><span>(</span><span>QtWidgets</span><span>.</span><span>QMainWindow</span><span>):</span>
</span><span id="__span-0-10">
</span><span id="__span-0-11"> <span>def</span> <span>__init__</span><span>(</span><span>self</span><span>):</span>
</span><span id="__span-0-12">
</span><span id="__span-0-13"> <span>super</span><span>()</span><span>.</span><span>__init__</span><span>()</span>
</span><span id="__span-0-14">
</span><span id="__span-0-15"> <span># 设置界面</span>
</span><span id="__span-0-16"> <span>self</span><span>.</span><span>setupUI</span><span>()</span>
</span><span id="__span-0-17">
</span><span id="__span-0-18"> <span>self</span><span>.</span><span>camBtn</span><span>.</span><span>clicked</span><span>.</span><span>connect</span><span>(</span><span>self</span><span>.</span><span>startCamera</span><span>)</span>
</span><span id="__span-0-19"> <span>self</span><span>.</span><span>stopBtn</span><span>.</span><span>clicked</span><span>.</span><span>connect</span><span>(</span><span>self</span><span>.</span><span>stop</span><span>)</span>
</span><span id="__span-0-20">
</span><span id="__span-0-21"> <span># 定义定时器,用于控制显示视频的帧率</span>
</span><span id="__span-0-22"> <span>self</span><span>.</span><span>timer_camera</span> <span>=</span> <span>QtCore</span><span>.</span><span>QTimer</span><span>()</span>
</span><span id="__span-0-23"> <span># 定时到了,回调 self.show_camera</span>
</span><span id="__span-0-24"> <span>self</span><span>.</span><span>timer_camera</span><span>.</span><span>timeout</span><span>.</span><span>connect</span><span>(</span><span>self</span><span>.</span><span>show_camera</span><span>)</span>
</span><span id="__span-0-25">
</span><span id="__span-0-26"> <span># 加载 YOLO nano 模型,第一次比较耗时,要20秒左右</span>
</span><span id="__span-0-27"> <span>self</span><span>.</span><span>model</span> <span>=</span> <span>YOLO</span><span>(</span><span>'yolov8n.pt'</span><span>)</span>
</span><span id="__span-0-28">
</span><span id="__span-0-29"> <span># 要处理的视频帧图片队列,目前就放1帧图片</span>
</span><span id="__span-0-30"> <span>self</span><span>.</span><span>frameToAnalyze</span> <span>=</span> <span>[]</span>
</span><span id="__span-0-31">
</span><span id="__span-0-32"> <span># 启动处理视频帧独立线程</span>
</span><span id="__span-0-33"> <span>Thread</span><span>(</span><span>target</span><span>=</span><span>self</span><span>.</span><span>frameAnalyzeThreadFunc</span><span>,</span><span>daemon</span><span>=</span><span>True</span><span>)</span><span>.</span><span>start</span><span>()</span>
</span><span id="__span-0-34">
</span><span id="__span-0-35"> <span>def</span> <span>setupUI</span><span>(</span><span>self</span><span>):</span>
</span><span id="__span-0-36">
</span><span id="__span-0-37"> <span>self</span><span>.</span><span>resize</span><span>(</span><span>1200</span><span>,</span> <span>800</span><span>)</span>
</span><span id="__span-0-38">
</span><span id="__span-0-39"> <span>self</span><span>.</span><span>setWindowTitle</span><span>(</span><span>'白月黑羽 YOLO-Qt 演示'</span><span>)</span>
</span><span id="__span-0-40">
</span><span id="__span-0-41"> <span># central Widget</span>
</span><span id="__span-0-42"> <span>centralWidget</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QWidget</span><span>(</span><span>self</span><span>)</span>
</span><span id="__span-0-43"> <span>self</span><span>.</span><span>setCentralWidget</span><span>(</span><span>centralWidget</span><span>)</span>
</span><span id="__span-0-44">
</span><span id="__span-0-45"> <span># central Widget 里面的 主 layout</span>
</span><span id="__span-0-46"> <span>mainLayout</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QVBoxLayout</span><span>(</span><span>centralWidget</span><span>)</span>
</span><span id="__span-0-47">
</span><span id="__span-0-48"> <span># 界面的上半部分 : 图形展示部分</span>
</span><span id="__span-0-49"> <span>topLayout</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QHBoxLayout</span><span>()</span>
</span><span id="__span-0-50"> <span>self</span><span>.</span><span>label_ori_video</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QLabel</span><span>(</span><span>self</span><span>)</span>
</span><span id="__span-0-51"> <span>self</span><span>.</span><span>label_treated</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QLabel</span><span>(</span><span>self</span><span>)</span>
</span><span id="__span-0-52"> <span>self</span><span>.</span><span>label_ori_video</span><span>.</span><span>setMinimumSize</span><span>(</span><span>520</span><span>,</span><span>400</span><span>)</span>
</span><span id="__span-0-53"> <span>self</span><span>.</span><span>label_treated</span><span>.</span><span>setMinimumSize</span><span>(</span><span>520</span><span>,</span><span>400</span><span>)</span>
</span><span id="__span-0-54"> <span>self</span><span>.</span><span>label_ori_video</span><span>.</span><span>setStyleSheet</span><span>(</span><span>'border:1px solid #D7E2F9;'</span><span>)</span>
</span><span id="__span-0-55"> <span>self</span><span>.</span><span>label_treated</span><span>.</span><span>setStyleSheet</span><span>(</span><span>'border:1px solid #D7E2F9;'</span><span>)</span>
</span><span id="__span-0-56">
</span><span id="__span-0-57"> <span>topLayout</span><span>.</span><span>addWidget</span><span>(</span><span>self</span><span>.</span><span>label_ori_video</span><span>)</span>
</span><span id="__span-0-58"> <span>topLayout</span><span>.</span><span>addWidget</span><span>(</span><span>self</span><span>.</span><span>label_treated</span><span>)</span>
</span><span id="__span-0-59">
</span><span id="__span-0-60"> <span>mainLayout</span><span>.</span><span>addLayout</span><span>(</span><span>topLayout</span><span>)</span>
</span><span id="__span-0-61">
</span><span id="__span-0-62"> <span># 界面下半部分: 输出框 和 按钮</span>
</span><span id="__span-0-63"> <span>groupBox</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QGroupBox</span><span>(</span><span>self</span><span>)</span>
</span><span id="__span-0-64">
</span><span id="__span-0-65"> <span>bottomLayout</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QHBoxLayout</span><span>(</span><span>groupBox</span><span>)</span>
</span><span id="__span-0-66"> <span>self</span><span>.</span><span>textLog</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QTextBrowser</span><span>()</span>
</span><span id="__span-0-67"> <span>bottomLayout</span><span>.</span><span>addWidget</span><span>(</span><span>self</span><span>.</span><span>textLog</span><span>)</span>
</span><span id="__span-0-68">
</span><span id="__span-0-69"> <span>mainLayout</span><span>.</span><span>addWidget</span><span>(</span><span>groupBox</span><span>)</span>
</span><span id="__span-0-70">
</span><span id="__span-0-71"> <span>btnLayout</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QVBoxLayout</span><span>()</span>
</span><span id="__span-0-72"> <span>self</span><span>.</span><span>videoBtn</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QPushButton</span><span>(</span><span>'🎞️视频文件'</span><span>)</span>
</span><span id="__span-0-73"> <span>self</span><span>.</span><span>camBtn</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QPushButton</span><span>(</span><span>'📹摄像头'</span><span>)</span>
</span><span id="__span-0-74"> <span>self</span><span>.</span><span>stopBtn</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QPushButton</span><span>(</span><span>'🛑停止'</span><span>)</span>
</span><span id="__span-0-75"> <span>btnLayout</span><span>.</span><span>addWidget</span><span>(</span><span>self</span><span>.</span><span>videoBtn</span><span>)</span>
</span><span id="__span-0-76"> <span>btnLayout</span><span>.</span><span>addWidget</span><span>(</span><span>self</span><span>.</span><span>camBtn</span><span>)</span>
</span><span id="__span-0-77"> <span>btnLayout</span><span>.</span><span>addWidget</span><span>(</span><span>self</span><span>.</span><span>stopBtn</span><span>)</span>
</span><span id="__span-0-78"> <span>bottomLayout</span><span>.</span><span>addLayout</span><span>(</span><span>btnLayout</span><span>)</span>
</span><span id="__span-0-79">
</span><span id="__span-0-80">
</span><span id="__span-0-81"> <span>def</span> <span>startCamera</span><span>(</span><span>self</span><span>):</span>
</span><span id="__span-0-82">
</span><span id="__span-0-83"> <span># 参考 https://docs.opencv.org/3.4/dd/d43/tutorial_py_video_display.html</span>
</span><span id="__span-0-84">
</span><span id="__span-0-85"> <span># 在 windows上指定使用 cv2.CAP_DSHOW 会让打开摄像头快很多, </span>
</span><span id="__span-0-86"> <span># 在 Linux/Mac上 指定 V4L, FFMPEG 或者 GSTREAMER</span>
</span><span id="__span-0-87"> <span>self</span><span>.</span><span>cap</span> <span>=</span> <span>cv2</span><span>.</span><span>VideoCapture</span><span>(</span><span>0</span><span>,</span> <span>cv2</span><span>.</span><span>CAP_DSHOW</span><span>)</span>
</span><span id="__span-0-88"> <span>if</span> <span>not</span> <span>self</span><span>.</span><span>cap</span><span>.</span><span>isOpened</span><span>():</span>
</span><span id="__span-0-89"> <span>print</span><span>(</span><span>"1号摄像头不能打开"</span><span>)</span>
</span><span id="__span-0-90"> <span>return</span><span>()</span>
</span><span id="__span-0-91">
</span><span id="__span-0-92"> <span>if</span> <span>self</span><span>.</span><span>timer_camera</span><span>.</span><span>isActive</span><span>()</span> <span>==</span> <span>False</span><span>:</span> <span># 若定时器未启动</span>
</span><span id="__span-0-93"> <span>self</span><span>.</span><span>timer_camera</span><span>.</span><span>start</span><span>(</span><span>50</span><span>)</span>
</span><span id="__span-0-94">
</span><span id="__span-0-95">
</span><span id="__span-0-96"> <span>def</span> <span>show_camera</span><span>(</span><span>self</span><span>):</span>
</span><span id="__span-0-97">
</span><span id="__span-0-98"> <span>ret</span><span>,</span> <span>frame</span> <span>=</span> <span>self</span><span>.</span><span>cap</span><span>.</span><span>read</span><span>()</span> <span># 从视频流中读取</span>
</span><span id="__span-0-99"> <span>if</span> <span>not</span> <span>ret</span><span>:</span>
</span><span id="__span-0-100"> <span>return</span>
</span><span id="__span-0-101">
</span><span id="__span-0-102"> <span># 把读到的16:10帧的大小重新设置 </span>
</span><span id="__span-0-103"> <span>frame</span> <span>=</span> <span>cv2</span><span>.</span><span>resize</span><span>(</span><span>frame</span><span>,</span> <span>(</span><span>520</span><span>,</span> <span>400</span><span>))</span>
</span><span id="__span-0-104"> <span># 视频色彩转换回RGB,OpenCV images as BGR</span>
</span><span id="__span-0-105"> <span>frame</span> <span>=</span> <span>cv2</span><span>.</span><span>cvtColor</span><span>(</span><span>frame</span><span>,</span> <span>cv2</span><span>.</span><span>COLOR_BGR2RGB</span><span>)</span>
</span><span id="__span-0-106"> <span>qImage</span> <span>=</span> <span>QtGui</span><span>.</span><span>QImage</span><span>(</span><span>frame</span><span>.</span><span>data</span><span>,</span> <span>frame</span><span>.</span><span>shape</span><span>[</span><span>1</span><span>],</span> <span>frame</span><span>.</span><span>shape</span><span>[</span><span>0</span><span>],</span>
</span><span id="__span-0-107"> <span>QtGui</span><span>.</span><span>QImage</span><span>.</span><span>Format_RGB888</span><span>)</span> <span># 变成QImage形式</span>
</span><span id="__span-0-108"> <span># 往显示视频的Label里 显示QImage</span>
</span><span id="__span-0-109"> <span>self</span><span>.</span><span>label_ori_video</span><span>.</span><span>setPixmap</span><span>(</span><span>QtGui</span><span>.</span><span>QPixmap</span><span>.</span><span>fromImage</span><span>(</span><span>qImage</span><span>))</span>
</span><span id="__span-0-110">
</span><span id="__span-0-111"> <span># 如果当前没有处理任务</span>
</span><span id="__span-0-112"> <span>if</span> <span>not</span> <span>self</span><span>.</span><span>frameToAnalyze</span><span>:</span>
</span><span id="__span-0-113"> <span>self</span><span>.</span><span>frameToAnalyze</span><span>.</span><span>append</span><span>(</span><span>frame</span><span>)</span>
</span><span id="__span-0-114">
</span><span id="__span-0-115"> <span>def</span> <span>frameAnalyzeThreadFunc</span><span>(</span><span>self</span><span>):</span>
</span><span id="__span-0-116">
</span><span id="__span-0-117"> <span>while</span> <span>True</span><span>:</span>
</span><span id="__span-0-118"> <span>if</span> <span>not</span> <span>self</span><span>.</span><span>frameToAnalyze</span><span>:</span>
</span><span id="__span-0-119"> <span>time</span><span>.</span><span>sleep</span><span>(</span><span>0.01</span><span>)</span>
</span><span id="__span-0-120"> <span>continue</span>
</span><span id="__span-0-121">
</span><span id="__span-0-122"> <span>frame</span> <span>=</span> <span>self</span><span>.</span><span>frameToAnalyze</span><span>.</span><span>pop</span><span>(</span><span>0</span><span>)</span>
</span><span id="__span-0-123">
</span><span id="__span-0-124"> <span>results</span> <span>=</span> <span>self</span><span>.</span><span>model</span><span>(</span><span>frame</span><span>)[</span><span>0</span><span>]</span>
</span><span id="__span-0-125">
</span><span id="__span-0-126"> <span>img</span> <span>=</span> <span>results</span><span>.</span><span>plot</span><span>(</span><span>line_width</span><span>=</span><span>1</span><span>)</span>
</span><span id="__span-0-127">
</span><span id="__span-0-128"> <span>qImage</span> <span>=</span> <span>QtGui</span><span>.</span><span>QImage</span><span>(</span><span>img</span><span>.</span><span>data</span><span>,</span> <span>img</span><span>.</span><span>shape</span><span>[</span><span>1</span><span>],</span> <span>img</span><span>.</span><span>shape</span><span>[</span><span>0</span><span>],</span>
</span><span id="__span-0-129"> <span>QtGui</span><span>.</span><span>QImage</span><span>.</span><span>Format_RGB888</span><span>)</span> <span># 变成QImage形式</span>
</span><span id="__span-0-130">
</span><span id="__span-0-131"> <span>self</span><span>.</span><span>label_treated</span><span>.</span><span>setPixmap</span><span>(</span><span>QtGui</span><span>.</span><span>QPixmap</span><span>.</span><span>fromImage</span><span>(</span><span>qImage</span><span>))</span> <span># 往显示Label里 显示QImage</span>
</span><span id="__span-0-132">
</span><span id="__span-0-133"> <span>time</span><span>.</span><span>sleep</span><span>(</span><span>0.5</span><span>)</span>
</span><span id="__span-0-134">
</span><span id="__span-0-135"> <span>def</span> <span>stop</span><span>(</span><span>self</span><span>):</span>
</span><span id="__span-0-136"> <span>self</span><span>.</span><span>timer_camera</span><span>.</span><span>stop</span><span>()</span> <span># 关闭定时器</span>
</span><span id="__span-0-137"> <span>self</span><span>.</span><span>cap</span><span>.</span><span>release</span><span>()</span> <span># 释放视频流</span>
</span><span id="__span-0-138"> <span>self</span><span>.</span><span>label_ori_video</span><span>.</span><span>clear</span><span>()</span> <span># 清空视频显示区域 </span>
</span><span id="__span-0-139"> <span>self</span><span>.</span><span>label_treated</span><span>.</span><span>clear</span><span>()</span> <span># 清空视频显示区域</span>
</span><span id="__span-0-140">
</span><span id="__span-0-141">
</span><span id="__span-0-142"><span>app</span> <span>=</span> <span>QtWidgets</span><span>.</span><span>QApplication</span><span>()</span>
</span><span id="__span-0-143"><span>window</span> <span>=</span> <span>MWindow</span><span>()</span>
</span><span id="__span-0-144"><span>window</span><span>.</span><span>show</span><span>()</span>
</span><span id="__span-0-145"><span>app</span><span>.</span><span>exec</span><span>()</span>
</span></code>