优秀的编程知识分享平台

网站首页 > 技术文章 正文

使用OpenCv和Dlib进行打哈欠检测(opencv haar 训练)

nanyue 2024-09-11 05:20:19 技术文章 6 ℃

OpenCV: OpenCV是一个用于计算机视觉的库函数,最初是用c++编写的。

Dlib: Dlib是一个Python库,包含了数据挖掘、数据结构、机器学习、图像处理等工具。

打哈欠检测与应用

打哈欠检测就是使用OpenCV和Dlib来检测打哈欠(由于疲劳或无聊而张大嘴巴深吸气)。可广泛应用于自驾车、驾驶员疲劳检测、驾驶员睡意检测、驾驶员意识检测等领域。

安装OpenCv和Dlib库

OpenCv的安装如下:

pip install opencv-python

Dlib的安装如下:

pip install cmake
pip install dlib

导入Opencv,Dlib和Numpy库

import cv2
import dlib
import numpy as np

设置dat文件

PREDICTOR_PATH = "shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(PREDICTOR_PATH)
#cascade_path='haarcascade_frontalface_default.xml
#cascade = cv2.CascadeClassifier(cascade_path)
detector = dlib.get_frontal_face_detector()

我们将.dat文件放置到工作目录中,它是一个可以识别面部特征并提供信息的模型。Dlib将从文件中提取所有信息,使用opencv查找不同的特征。

定义函数获取landmarks并使用颜色对其进行注释

def geting_landmarks(im):
    rects = detector(im, 1)
    if len(rects) > 1:
        return "error"
    if len(rects) == 0:
         return "error",
    return np.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])    
    
def annotate_landmarks(im, landmarks):
    im = im.copy()
    for idx, point in enumerate(landmarks):
        pos = (point[0, 0], point[0, 1])
        cv2.putText(im, str(idx), pos,
                    fontFace=cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,
                    fontScale=0.4,
                    color=(1, 2, 255))
        cv2.circle(im, pos, 3, color=(0, 2, 2))
        return im

形状预测器(dat文件)用于从图像中提取信息,例如眼角,鼻子周围的区域等。图像被转换为??矩阵,并且annotate_landmarks()函数标记这些特征/信息,其他函数使用这些特征/信息来提取各种像上嘴唇,上嘴等

提取有关各种特征的关键信息,以检测打哈欠

def top_lip(landmarks):
    top_lip_pts = []
    for i in range(50,53):
        top_lip_pts.append(landmarks[i])
    for i in range(61,64):
        top_lip_pts.append(landmarks[i])
    top_lip_all_pts = np.squeeze(np.asarray(top_lip_pts))
    top_lip_mean = np.mean(top_lip_pts, axis=0)
    return int(top_lip_mean[:,1])

def bottom_lip(landmarks):
    bottom_lip_pts = []
    for i in range(65,68):
        bottom_lip_pts.append(landmarks[i])
    for i in range(56,59):
        bottom_lip_pts.append(landmarks[i])
    bottom_lip_all_pts = np.squeeze(np.asarray(bottom_lip_pts))
    bottom_lip_mean = np.mean(bottom_lip_pts, axis=0)
    return int(bottom_lip_mean[:,1])

def mouth_open(image):
    landmarks = geting_landmarks(image)
    
    if landmarks == "error":
        return image, 0
    
    image_with_landmarks = annotate_landmarks(image, landmarks)
    top_lip_center = top_lip(landmarks)
    bottom_lip_center = bottom_lip(landmarks)
    lip_distance = abs(top_lip_center - bottom_lip_center)
    return image_with_landmarks, lip_distance

当yawn_status为True时,打开摄像头并定义打哈欠标准,然后相应地分配操作。Python实现如下:

cap = cv2.VideoCapture(0)
yawns = 0
yawn_status = False 
while True:
    ret, frame = cap.read()   
    image_landmarks, lip_distance = mouth_open(frame)
    
    prev_yawn_status = yawn_status  
    
    if lip_distance > 25:
        yawn_status = True 
        
        cv2.putText(frame, "Employee is Yawning", (50,450), 
                    cv2.FONT_HERSHEY_COMPLEX, 1,(0,0,255),2)
        
        from pygame import mixer
        mixer.init()
        mixer.music.load('Yawn.mp3')
        mixer.music.play()

        output_text = " Yawn Count: " + str(yawns + 1)

        cv2.putText(frame, output_text, (50,50),
                    cv2.FONT_HERSHEY_COMPLEX, 1,(0,255,127),2)
        
    else:
        yawn_status = False 
         
    if prev_yawn_status == True and yawn_status == False:
        yawns += 1

    cv2.imshow('Live Landmarks', image_landmarks )
    cv2.imshow('Yawn Detection', frame )
    
    if cv2.waitKey(1) == 13:
        break
        
cap.release()
cv2.destroyAllWindows() 

如果lip_distance大于25,则(yawn_status)被定义为打呵欠。在这种情况下,屏幕上会出现“Employee is Yawning”的文字,然后我们播放mp3文件。如果Yawn_status为true,则“Yawn Count”将继续显示该对象打哈欠的次数。

实时显示Landmark如下所示


Tags:

最近发表
标签列表