感谢恩培大佬对项目进行了完整的实现,并将代码进行开源,供大家交流学习。
一、项目简介
本项目最终达到的效果为检测屏幕面前的人是否在看电视。如下所示
项目用python实现,调用opencv等库,由以下步骤组成:
1、使用OpenCV读取摄像头视频流;
2、识别面部关键点像素坐标;
3、根据坐标计算脸的朝向,离屏幕的距离;
4、根据朝向、距离判断孩子是否在看电视。
二、代码详解
"""
! author: enpei
! date: 2021-12-23
主要功能:检测孩子是否在看电视,看了多久,距离多远
使用技术点:人脸检测、人脸识别(采集照片、训练、识别)、姿态估计
"""
import cv2,time
from pose_estimator import PoseEstimator
import numpy as np
import dlib
from utils import Utils
import os
from argparse import ArgumentParser
class MonitorBabay:
def __init__(self):
# 人脸检测
self.face_detector = dlib.get_frontal_face_detector()
# 人脸识别模型:pip uninstall opencv-python,pip install opencv-contrib-python
self.face_model = cv2.face.LBPHFaceRecognizer_create()
# 人脸68个关键点
self.landmark_predictor = dlib.shape_predictor("./assets/shape_predictor_68_face_landmarks.dat")
# 站在1.5M远处,左眼最左边距离右眼最右边的像素距离(请使用getEyePixelDist方法校准,然后修改这里的值)
self.eyeBaseDistance = 65
# pose_estimator.show_3d_model()
self.utils = Utils()
# 采集照片用于训练
# 参数
# label_index: label的索引
# save_interval:隔几秒存储照片
# save_num:存储总量
def collectFacesFromCamera(self,label_index,save_interval,save_num):
cap = cv2.VideoCapture(0)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
fpsTime = time.time()
last_save_time = fpsTime
saved_num = 0
while True:
_, frame = cap.read()
frame = cv2.flip(frame,1)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = self.face_detector(gray)
for face in faces:
if saved_num < save_num:
if (time.time() - last_save_time) > save_interval:
self.utils.save_face(face,frame,label_index)
saved_num +=1
last_save_time = time.time()
print('label_index:{index},成功采集第{num}张照片'.format(index = label_index,num = saved_num))
else:
print('照片采集完毕!')
exit()
self.utils.draw_face_box(face,frame,'','',