目录
前言
使用dlib库进行疲劳检测通常涉及人脸特征点检测和分析眼部特征(如眨眼率、眼睛开合程度等)。通过观察这些特征,可以推测一个人是否处于疲劳状态。
一、完整代码
import numpy as np
import dlib
import cv2
from sklearn.metrics.pairwise import euclidean_distances
from PIL import Image, ImageDraw, ImageFont
def eye_aspect_ration(eye): # 计算眼睛纵横比
x = eye[1]
y = eye[1].reshape(1, 2)
A = euclidean_distances(eye[1].reshape(1, 2), eye[5].reshape(1, 2))
# euclidean_distances 函数的输入要求是两个二维数组 计算两点之间的欧氏距离
B = euclidean_distances(eye[2].reshape(1, 2), eye[4].reshape(1, 2))
C = euclidean_distances(eye[0].reshape(1, 2), eye[3].reshape(1, 2))
return ((A + B) / 2.0) / C
def drawEye(eye):
eyeHull = cv2.convexHull(eye)
cv2.drawContours(frame, [eyeHull], -1, (0, 0, 255), -1)
def cv2AddChineseText(img, text, position, textColor=(255, 0, 0), textSize=30):
# 向图片中添加中文
if (isinstance(img, np.ndarray)): # 判断图片是否是opencv的图片类型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # 实现array到image的转换
draw = ImageDraw.Draw(img) # 在img图片上创建一个绘图的对象
# 字体的格式
fontStyle = ImageFont.truetype('simsun.ttc', textSize, encoding='utf-8')
draw.text(position, text, textColor, font=fontStyle) # 绘制文本
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR) # 转换回opencv格式
detector = dlib.get_frontal_face_detector() # 人脸检测器
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') # 关键点检测器
counter = 0 # 记录闭眼帧数
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
faces = detector(frame, 0)
for face in faces:
shape = predictor(frame, face) # 检测关键点
shape = np.array([[p.x, p.y] for p in shape.parts()]) # 获取关键点坐标
rightEye = shape[36:42]
leftEye = shape[42:48]
rightEAR = eye_aspect_ration(rightEye)
leftEAR = eye_aspect_ration(leftEye)
ear = (leftEAR + rightEAR) / 2.0 # 平均值
if ear < 0.3:
counter += 1
if counter >= 50: # 闭眼时长大于50帧判断为疲劳
frame = cv2AddChineseText(frame, "!!!疲劳危险!!!", (250, 250))
else:
counter = 0
drawEye(leftEye)
drawEye(rightEye)
info = f"EAR:{ear[0][0]:.2f}" # 二维数组访问元素 ear[0,0]
frame = cv2AddChineseText(frame, info, (0, 30))
cv2.imshow('Frame', frame)
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()
cap.release()
二、代码步骤解析
1.计算眼睛纵横比
获取眼睛关键点的坐标,计算眼睛的纵横比
def eye_aspect_ration(eye): # 计算眼睛纵横比
x = eye[1]
y = eye[1].reshape(1, 2)
A = euclidean_distances(eye[1].reshape(1, 2), eye[5].reshape(1, 2))
# euclidean_distances 函数的输入要求是两个二维数组 计算两点之间的欧氏距离
B = euclidean_distances(eye[2].reshape(1, 2), eye[4].reshape(1, 2))
C = euclidean_distances(eye[0].reshape(1, 2), eye[3].reshape(1, 2))
return ((A + B) / 2.0) / C
2.向图片中添加中文
开源代码,网上搜索即可
def cv2AddChineseText(img, text, position, textColor=(255, 0, 0), textSize=30):
# 向图片中添加中文
if (isinstance(img, np.ndarray)): # 判断图片是否是opencv的图片类型
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) # 实现array到image的转换
draw = ImageDraw.Draw(img) # 在img图片上创建一个绘图的对象
# 字体的格式
fontStyle = ImageFont.truetype('simsun.ttc', textSize, encoding='utf-8')
draw.text(position, text, textColor, font=fontStyle) # 绘制文本
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR) # 转换回opencv格式
3.绘制凸包
def drawEye(eye):
eyeHull = cv2.convexHull(eye)
cv2.drawContours(frame, [eyeHull], -1, (0, 0, 255), -1)
4.打开摄像头读取每一帧画面进行处理
- 创建人脸检测器和关键点检测器
- 获取每一帧的左右眼纵横比的平均值
- 若小于0.3就判断为闭眼
- 闭眼帧数大于50帧时判断为疲劳
- 在屏幕中央显示疲劳危险
detector = dlib.get_frontal_face_detector() # 人脸检测器
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') # 关键点检测器
counter = 0 # 记录闭眼帧数
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
faces = detector(frame, 0)
for face in faces:
shape = predictor(frame, face) # 检测关键点
shape = np.array([[p.x, p.y] for p in shape.parts()]) # 获取关键点坐标
rightEye = shape[36:42]
leftEye = shape[42:48]
rightEAR = eye_aspect_ration(rightEye)
leftEAR = eye_aspect_ration(leftEye)
ear = (leftEAR + rightEAR) / 2.0 # 平均值
if ear < 0.3:
counter += 1
if counter >= 50: # 闭眼时长大于50帧判断为疲劳
frame = cv2AddChineseText(frame, "!!!疲劳危险!!!", (250, 250))
else:
counter = 0
drawEye(leftEye)
drawEye(rightEye)
info = f"EAR:{ear[0][0]:.2f}" # 二维数组访问元素 ear[0,0]
frame = cv2AddChineseText(frame, info, (0, 30))
cv2.imshow('Frame', frame)
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()
cap.release()
标签:eye,img,疲劳,检测,frame,cv2,shape,reshape,Dlib
From: https://blog.csdn.net/weixin_65047977/article/details/143098370