基于Python+Keras+OpenCV实现实时人脸活体检测

磐创AI
关注

def isBlinking(history, maxFrames):    """ @history: A string containing the history of eyes status          where a '1' means that the eyes were closed and '0' open.        @maxFrames: The maximal number of successive frames where an eye is closed """    for i in range(maxFrames):        pattern = '1' + '0'*(i+1) + '1'        if pattern in history:            return True    return False3.活体的人脸识别我们几乎拥有了建立“真实”人脸识别算法的所有要素,我们只需要一种实时检测人脸和眼睛的方法。我使用openCV预先训练的Haar级联分类器来完成这些任务。有关Haar cascade人脸和眼睛检测的更多信息,我强烈建议你阅读openCV的这篇强大的文章。https://docs.opencv.org/3.4.3/d7/d8b/tutorial_py_face_detection.htmldef detect_and_display(model, video_capture, face_detector, open_eyes_detector, left_eye_detector, right_eye_detector, data, eyes_detected):        frame = video_capture.read()        # 调整框架大小        frame = cv2.resize(frame, (0, 0), fx=0.6, fy=0.6)

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)        rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

# 检测人脸        faces = face_detector.detectMultiScale(            gray,            scaleFactor=1.2,            minNeighbors=5,            minSize=(50, 50),            flags=cv2.CASCADE_SCALE_IMAGE        )

# 对于每个检测到的脸        for (x,y,w,h) in faces:            # 将人脸编码为128维嵌入向量            encoding = face_recognition.face_encodings(rgb, [(y, x+w, y+h, x)])[0]

# 将向量与所有已知的人脸编码进行比较            matches = face_recognition.compare_faces(data["encodings"], encoding)

# 目前我们不知道该人的名字            name = "Unknown"

# 如果至少有一次匹配:            if True in matches:                matchedIdxs = [i for (i, b) in enumerate(matches) if b]                counts = {}                for i in matchedIdxs:                    name = data["names"][i]                    counts[name] = counts.get(name, 0) + 1

# 匹配次数最多的已知编码对应于检测到的人脸名称                name = max(counts, key=counts.get)

face = frame[y:y+h,x:x+w]            gray_face = gray[y:y+h,x:x+w]

eyes = []

# 眼睛检测            # 首先检查眼睛是否睁开(考虑到眼镜)            open_eyes_glasses = open_eyes_detector.detectMultiScale(gray_face,scaleFactor=1.1,minNeighbors=5,minSize=(30, 30),flags = cv2.CASCADE_SCALE_IMAGE            )  # 如果open_eyes_glasses检测到眼睛,则眼睛睁开 if len(open_eyes_glasses) == 2: eyes_detected[name]+='1' for (ex,ey,ew,eh) in open_eyes_glasses:                    cv2.rectangle(face,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)

# 否则尝试使用left和right_eye_detector检测眼睛    # 以检测到睁开和闭合的眼睛  else:  # 将脸分成左右两边    left_face = frame[y:y+h, x+int(w/2):x+w]     left_face_gray = gray[y:y+h, x+int(w/2):x+w]

right_face = frame[y:y+h, x:x+int(w/2)]                right_face_gray = gray[y:y+h, x:x+int(w/2)]

# 检测左眼                left_eye = left_eye_detector.detectMultiScale(                    left_face_gray,                    scaleFactor=1.1,                    minNeighbors=5,                    minSize=(30, 30),                    flags = cv2.CASCADE_SCALE_IMAGE                )

# 检测右眼                right_eye = right_eye_detector.detectMultiScale(                    right_face_gray,                    scaleFactor=1.1,                    minNeighbors=5,                    minSize=(30, 30),                    flags = cv2.CASCADE_SCALE_IMAGE                )

eye_status = '1' # we suppose the eyes are open

# 检查每只眼睛是否闭合。                # 如果有人闭着眼睛,我们得出结论是闭着眼睛                for (ex,ey,ew,eh) in right_eye:                    color = (0,255,0)                    pred = predict(right_face[ey:ey+eh,ex:ex+ew],model)                    if pred == 'closed':                        eye_status='0'                        color = (0,0,255)                    cv2.rectangle(right_face,(ex,ey),(ex+ew,ey+eh),color,2)                for (ex,ey,ew,eh) in left_eye:                    color = (0,255,0)                    pred = predict(left_face[ey:ey+eh,ex:ex+ew],model)                    if pred == 'closed':                        eye_status='0'                        color = (0,0,255)                    cv2.rectangle(left_face,(ex,ey),(ex+ew,ey+eh),color,2)                eyes_detected[name] += eye_status

# 每次,我们都会检查该人是否眨眼            # 如果是,我们显示其名字            if isBlinking(eyes_detected[name],3):                cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

# 显示名字                y = y - 15 if y - 15 > 15 else y + 15                cv2.putText(frame, name, (x, y), cv2.FONT_HERSHEY_SIMPLEX,0.75, (0, 255, 0), 2)

return frame上面的功能是用于检测和识别真实人脸的代码,它接受以下参数:model:我们的睁眼/闭眼分类器video_capture:流视频face_detector:Haar级联的人脸分类器。我使用了haarcascade_frontalface_alt.xmlopen_eyes_detector:Haar级联睁眼分类器。我使用了haarcascade_eye_tree_eyeglasses.xmlleft_eye_detector:Haar级联的左眼分类器。我使用了haarcascade_lefteye_2splits.xml,它可以检测睁眼或闭眼。right_eye_detector:Haar级联的右眼分类器。我使用了haarcascade_righteye_2splits.xml,它可以检测睁眼或闭眼。data:已知编码和已知名称的字典eyes_detected:包含每个名称的眼睛状态历史记录的字典。在第2-4行,我们从网络摄像头流中获取一个帧,然后调整其大小以加快计算速度。在第10行,我们从帧中检测人脸,然后在第21行,我们将其编码为128-d矢量。在第23-38行,我们将这个向量与已知的人脸编码进行比较,并通过计算匹配的次数来确定此人的姓名,选择匹配次数最多的一个。从第45行开始,我们试着探测眼睛进入人脸框。首先,我们尝试用睁眼检测器来检测睁眼,如果探测器探测成功,则在第54行,将“1”添加到眼睛状态历史记录中,这意味着眼睛是睁开的,因为睁开的眼睛探测器无法检测到闭着的眼睛;否则,如果第一个分类器失败(可能是因为眼睛是闭着的,或者仅仅是因为它不能识别眼睛),则使用左眼和右眼检测器,人脸被分为左右两侧,以便对各个探测器进行分类。从第92行开始,提取眼睛部分,训练后的模型预测眼睛是否闭合,如果检测到一只眼睛闭着,则两眼都将被预测为闭着,并将“0”添加到眼睛状态历史记录中;否则就可以断定眼睛是睁开的。最后,在第110行,is blinking()函数用于检测眨眼,如果该人眨眼,则显示姓名。整个代码都可以在我的github帐户上找到。

声明: 本文由入驻OFweek维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。
侵权投诉

下载OFweek,一手掌握高科技全行业资讯

还不是OFweek会员,马上注册
打开app,查看更多精彩资讯 >
  • 长按识别二维码
  • 进入OFweek阅读全文
长按图片进行保存