OpenCV+Python+Dlib面部标定、眨眼和疲劳检测代码
时间: 2023-09-03 16:13:20 浏览: 142
以下是OpenCV、Python和Dlib实现面部标定、眨眼和疲劳检测的代码:
首先,需要安装OpenCV、Python和Dlib库。在Python中,可以使用pip安装这些库:
```
pip install opencv-python
pip install dlib
```
接下来,导入必要的库:
```python
import cv2
import dlib
import numpy as np
from scipy.spatial import distance as dist
```
然后,定义一些常量和函数:
```python
EYE_AR_THRESH = 0.25 # 眼睛长宽比阈值
EYE_AR_CONSEC_FRAMES = 3 # 连续帧数
YAWN_THRESH = 20 # 打哈欠阈值
ALARM_SOUND_PATH = "alarm.wav" # 警报声音文件路径
def eye_aspect_ratio(eye):
# 计算眼睛长宽比
A = dist.euclidean(eye[1], eye[5])
B = dist.euclidean(eye[2], eye[4])
C = dist.euclidean(eye[0], eye[3])
ear = (A + B) / (2.0 * C)
return ear
def mouth_aspect_ratio(mouth):
# 计算嘴巴长宽比
A = dist.euclidean(mouth[14], mouth[18])
B = dist.euclidean(mouth[12], mouth[16])
C = dist.euclidean(mouth[0], mouth[6])
mar = (A + B) / (2.0 * C)
return mar
def play_alarm_sound(path):
# 播放警报声音
import os
os.system("aplay " + path + " &")
```
现在,让我们加载Dlib的人脸检测器和68个面部标定点模型:
```python
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
```
最后,我们可以开始处理视频流或摄像头输入:
```python
cap = cv2.VideoCapture(0) # 摄像头输入
ear_history = [] # 眼睛长宽比历史记录
mar_history = [] # 嘴巴长宽比历史记录
alarm_on = False # 是否播放警报声音
while True:
ret, frame = cap.read()
if not ret:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
rects = detector(gray, 0)
for rect in rects:
# 检测人脸并标定面部
shape = predictor(gray, rect)
shape = np.array([(p.x, p.y) for p in shape.parts()])
# 计算眼睛长宽比和嘴巴长宽比
left_eye = shape[36:42]
right_eye = shape[42:48]
mouth = shape[48:68]
ear = (eye_aspect_ratio(left_eye) + eye_aspect_ratio(right_eye)) / 2.0
mar = mouth_aspect_ratio(mouth)
# 在视频中显示眼睛和嘴巴区域
cv2.drawContours(frame, [cv2.convexHull(left_eye)], -1, (0, 255, 0), 1)
cv2.drawContours(frame, [cv2.convexHull(right_eye)], -1, (0, 255, 0), 1)
cv2.drawContours(frame, [cv2.convexHull(mouth)], -1, (0, 255, 0), 1)
# 更新眼睛长宽比历史记录
ear_history.append(ear)
if len(ear_history) > EYE_AR_CONSEC_FRAMES:
ear_history.pop(0)
# 更新嘴巴长宽比历史记录
mar_history.append(mar)
if len(mar_history) > EYE_AR_CONSEC_FRAMES:
mar_history.pop(0)
# 判断是否眨眼和打哈欠
ear_avg = np.mean(ear_history)
mar_avg = np.mean(mar_history)
if ear_avg < EYE_AR_THRESH and mar_avg > YAWN_THRESH:
# 开始播放警报声音
if not alarm_on:
alarm_on = True
play_alarm_sound(ALARM_SOUND_PATH)
else:
# 停止播放警报声音
alarm_on = False
cv2.imshow("Frame", frame)
key = cv2.waitKey(1)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
```
这段代码中,我们使用OpenCV从摄像头或视频流中读取帧。然后,我们将每个帧转换为灰度图像,并使用Dlib检测人脸和面部标定点。
接下来,我们计算眼睛长宽比和嘴巴长宽比,并绘制出眼睛和嘴巴的轮廓。然后,我们更新眼睛长宽比和嘴巴长宽比历史记录,并检查是否有连续的帧满足眨眼和打哈欠的条件。如果是,我们播放警报声音。
最后,我们在视频中显示帧,并等待按下ESC键退出程序。
希望这个例子可以帮助你开始使用OpenCV、Python和Dlib实现面部标定、眨眼和疲劳检测。
阅读全文