1+ #主函数
12import sys
23import os
34from glob import glob
1011import myframe
1112
1213# 定义变量
13- # 眼睛长宽比
14- # 闪烁阈值
15- EYE_AR_THRESH = 0.15
16- EYE_AR_CONSEC_FRAMES = 2
17- # 打哈欠长宽比
18- # 闪烁阈值
19- MAR_THRESH = 0.65
20- MOUTH_AR_CONSEC_FRAMES = 3
21- # 初始化帧计数器和眨眼总数
22- COUNTER = 0
23- TOTAL = 0
24- # 初始化帧计数器和打哈欠总数
25- mCOUNTER = 0
26- mTOTAL = 0
27- # 行为帧数变量
28- ActionCOUNTER = 0
29- # 周期变量
30- Roll = 0
31- Rolleye = 0
32- Rollmouth = 0
14+
15+ # 眼睛闭合判断
16+ EYE_AR_THRESH = 0.15 # 眼睛长宽比
17+ EYE_AR_CONSEC_FRAMES = 2 # 闪烁阈值
18+
19+ #嘴巴开合判断
20+ MAR_THRESH = 0.65 # 打哈欠长宽比
21+ MOUTH_AR_CONSEC_FRAMES = 3 # 闪烁阈值
22+
23+ # 定义检测变量,并初始化
24+ COUNTER = 0 #眨眼帧计数器
25+ TOTAL = 0 #眨眼总数
26+ mCOUNTER = 0 #打哈欠帧计数器
27+ mTOTAL = 0 #打哈欠总数
28+ ActionCOUNTER = 0 #分心行为计数器器
29+
30+ # 疲劳判断变量
31+ # Perclos模型
32+ # perclos = (Rolleye/Roll) + (Rollmouth/Roll)*0.2
33+ Roll = 0 #整个循环内的帧技术
34+ Rolleye = 0 #循环内闭眼帧数
35+ Rollmouth = 0 #循环内打哈欠数
3336
3437class MainWindow (QMainWindow , Ui_MainWindow ):
3538 def __init__ (self ):
@@ -40,6 +43,7 @@ def __init__(self):
4043
4144 def window_init (self ):
4245 # 设置控件属性
46+ # 设置label的初始值
4347 self .label .setText ("请打开摄像头" )
4448 self .label_2 .setText ("疲劳检测:" )
4549 self .label_3 .setText ("眨眼次数:0" )
@@ -56,10 +60,6 @@ def window_init(self):
5660 self .actionOpen_camera .triggered .connect (CamConfig_init )
5761 # 自适应窗口缩放
5862 self .label .setScaledContents (True )
59- # def printf(self, mes):
60- # self.textBrowser.append(mes) # 在指定的区域显示提示信息
61- # self.cursot = self.textBrowser.textCursor()
62- # self.textBrowser.moveCursor(self.cursot.End)
6363
6464# 定义摄像头类
6565class CamConfig :
@@ -76,22 +76,34 @@ def __init__(self):
7676 self .v_timer .start (20 )
7777 # 连接定时器周期溢出的槽函数,用于显示一帧视频
7878 self .v_timer .timeout .connect (self .show_pic )
79+ # 在前端UI输出提示信息
7980 Ui_MainWindow .printf (window ,"载入成功,开始运行程序" )
8081 Ui_MainWindow .printf (window ,"" )
8182 Ui_MainWindow .printf (window ,"开始执行疲劳检测..." )
8283 window .statusbar .showMessage ("正在使用摄像头..." )
8384 def show_pic (self ):
8485 # 全局变量
86+ # 在函数中引入定义的全局变量
8587 global EYE_AR_THRESH ,EYE_AR_CONSEC_FRAMES ,MAR_THRESH ,MOUTH_AR_CONSEC_FRAMES ,COUNTER ,TOTAL ,mCOUNTER ,mTOTAL ,ActionCOUNTER ,Roll ,Rolleye ,Rollmouth
86- # 读取一帧
88+
89+ # 读取摄像头的一帧画面
8790 success , frame = self .cap .read ()
8891 if success :
89- # Mat格式图像转Qt中图像的方法
90- #检测
91- ret ,frame = myframe .frametest (frame )
92+ # 检测
93+ # 将摄像头读到的frame传入检测函数myframe.frametest()
94+ ret ,frame = myframe .frametest (frame )
9295 lab ,eye ,mouth = ret
93- #行为判断
96+ # ret和frame,为函数返回
97+ # ret为检测结果,ret的格式为[lab,eye,mouth],lab为yolo的识别结果包含'phone' 'smoke' 'drink',eye为眼睛的开合程度(长宽比),mouth为嘴巴的开合程度
98+ # frame为标注了识别结果的帧画面,画上了标识框
99+
100+ # 分心行为判断
101+ # 分心行为检测以15帧为一个循环
94102 ActionCOUNTER += 1
103+
104+ # 如果检测到分心行为
105+ # 将信息返回到前端ui,使用红色字体来体现
106+ # 并加ActionCOUNTER减1,以延长循环时间
95107 for i in lab :
96108 if (i == "phone" ):
97109 window .label_6 .setText ("<font color=red>正在用手机</font>" )
@@ -104,44 +116,62 @@ def show_pic(self):
104116 if ActionCOUNTER > 0 :
105117 ActionCOUNTER -= 1
106118 elif (i == "drink" ):
107- window .label_7 .setText ("<font color=red>正在用喝水</font>" )
119+ window .label_8 .setText ("<font color=red>正在用喝水</font>" )
108120 window .label_9 .setText ("<font color=red>请不要分心</font>" )
109121 if ActionCOUNTER > 0 :
110122 ActionCOUNTER -= 1
111- #疲劳判断
112- if eye < EYE_AR_THRESH : # 眼睛长宽比:0.2
123+
124+ # 如果超过15帧未检测到分心行为,将label修改为平时状态
125+ if ActionCOUNTER == 15 :
126+ window .label_6 .setText ("手机" )
127+ window .label_7 .setText ("抽烟" )
128+ window .label_8 .setText ("喝水" )
129+ window .label_9 .setText ("" )
130+ ActionCOUNTER = 0
131+
132+ # 疲劳判断
133+ # 眨眼判断
134+ if eye < EYE_AR_THRESH :
135+ # 如果眼睛开合程度小于设定好的阈值
136+ # 则两个和眼睛相关的计数器加1
113137 COUNTER += 1
114138 Rolleye += 1
115139 else :
116- # 如果连续3次都小于阈值 ,则表示进行了一次眨眼活动
117- if COUNTER >= EYE_AR_CONSEC_FRAMES : # 阈值:3
140+ # 如果连续2次都小于阈值 ,则表示进行了一次眨眼活动
141+ if COUNTER >= EYE_AR_CONSEC_FRAMES :
118142 TOTAL += 1
119143 window .label_3 .setText ("眨眼次数:" + str (TOTAL ))
120144 # 重置眼帧计数器
121145 COUNTER = 0
122- if mouth > MAR_THRESH : # 张嘴阈值0.5
146+
147+ # 哈欠判断,同上
148+ if mouth > MAR_THRESH :
123149 mCOUNTER += 1
124150 Rollmouth += 1
125151 else :
126152 # 如果连续3次都小于阈值,则表示打了一次哈欠
127- if mCOUNTER >= MOUTH_AR_CONSEC_FRAMES : # 阈值:3
153+ if mCOUNTER >= MOUTH_AR_CONSEC_FRAMES :
128154 mTOTAL += 1
129155 window .label_4 .setText ("哈欠次数:" + str (mTOTAL ))
130156 # 重置嘴帧计数器
131157 mCOUNTER = 0
132- if ActionCOUNTER == 15 :
133- window .label_6 .setText ("手机" )
134- window .label_7 .setText ("抽烟" )
135- window .label_8 .setText ("喝水" )
136- window .label_9 .setText ("" )
137- ActionCOUNTER = 0
158+
159+ # 将画面显示在前端UI上
138160 show = cv2 .cvtColor (frame , cv2 .COLOR_BGR2RGB )
139161 showImage = QImage (show .data , show .shape [1 ], show .shape [0 ], QImage .Format_RGB888 )
140162 window .label .setPixmap (QPixmap .fromImage (showImage ))
163+
164+ # 疲劳模型
165+ # 疲劳模型以150帧为一个循环
166+ # 每一帧Roll加1
141167 Roll += 1
168+ # 当检测满150帧时,计算模型得分
142169 if Roll == 150 :
170+ # 计算Perclos模型得分
143171 perclos = (Rolleye / Roll ) + (Rollmouth / Roll )* 0.2
172+ # 在前端UI输出perclos值
144173 Ui_MainWindow .printf (window ,"过去150帧中,Perclos得分为" + str (round (perclos ,3 )))
174+ # 当过去的150帧中,Perclos模型得分超过0.38时,判断为疲劳状态
145175 if perclos > 0.38 :
146176 Ui_MainWindow .printf (window ,"当前处于疲劳状态" )
147177 window .label_10 .setText ("<font color=red>疲劳!!!</font>" )
@@ -150,11 +180,15 @@ def show_pic(self):
150180 Ui_MainWindow .printf (window ,"当前处于清醒状态" )
151181 window .label_10 .setText ("清醒" )
152182 Ui_MainWindow .printf (window ,"" )
153- #归零
183+
184+ # 归零
185+ # 将三个计数器归零
186+ # 重新开始新一轮的检测
154187 Roll = 0
155188 Rolleye = 0
156189 Rollmouth = 0
157190 Ui_MainWindow .printf (window ,"重新开始执行疲劳检测..." )
191+
158192def CamConfig_init ():
159193 window .f_type = CamConfig ()
160194
0 commit comments