文章目录
一.前言
二.原理阐述
三.源代码
四.代码改进
五.流程概述
一.前言
原开源项目是对于某时段校园门口学生出入的视频,使用YOLOv8目标检测算法以及yolov8l-face模型将目标换算成只检测人脸, 通过该模型中的track技术实现检测出的人脸进行自动跟踪, 通过跟踪到的人脸使用dlib库中的的dlib_face_recognition_resnet_model_v1模型来检测人脸的特征, 根据返回的128个特征值可以存进dataset数据集中进行进一步的训练,已得到更好的匹配效果 同时对于可以检测到特征值的人脸会自行进行判断是否是学校内的学生,如果是学生的话可以通过,呈绿色效果 而未检测到的人脸将呈现红色效果, 正中央记录出能识别出的人脸的数量。
参考博客
Github链接
二.原理阐述
1.人脸检测
人脸检测是通过YOLO(You Only Look Once)模型实现的。YOLO是一种基于深度学习的目标检测算法,能够直接从输入图像中预测目标的位置(边界框)和类别。
原理:
YOLO将输入图像划分为多个格子(grid cells),每个格子负责检测其中心点落在该格子内的目标。
模型输出每个格子中目标的坐标框(坐标、宽高)、置信度(目标存在的概率)和类别信息。
在本代码中,使用了YOLOv8的轻量级版本(yolov8n-face.pt),专门用于人脸检测。
应用:
YOLO模型在每一帧图像上运行,输出人脸的边界框(x1,y1,x2,y2),这些边界框用于定位图像中的人脸区域。
2.特征提取
特征提取是通过dlib的人脸关键点检测器和人脸识别模型来实现的。
原理:
①人脸关键点检测:
使用 dlib.shape_predictor 模型( shape_predictor_68_face_landmarks.dat ),基于人脸检测框,提取人脸的68个关键点(如眼睛、鼻子、嘴巴等位置)。
②人脸特征提取:
使用 dlib.face_recognition_model_v1 模型,基于关键点,提取人脸的128维特征向量。这些特征向量是人脸的唯一标识,用于后续的身份对比。
应用:
对于每一帧中检测到的人脸,提取其特征向量,用于与已知人脸特征进行比对。
3.特征比对
特征比对是通过计算欧氏距离实现的。
原理:
对于检测到的人脸特征向量和已知人脸特征向量,计算它们之间的欧氏距离。
欧氏距离越小,表示两个特征向量越相似。
设置一个阈值(如0.8),如果距离小于阈值,则认为是同一个人;否则认为是陌生人。
应用:
在每一帧中,将检测到的人脸特征与已知人脸特征库逐一比对,确定身份。
4.实时推流
实时推流是通过FFmpeg实现的,将处理后的视频帧推送到RTSP服务器。
原理:
FFmpeg是一个强大的多媒体处理工具,支持音视频的编码、解码、转码和推流。
通过FFmpeg的命令行工具,将处理后的视频帧(原始像素数据)编码为 H.264格式,并推送到RTSP服务器。
RTSP(Real-Time Streaming Protocol)是一种流媒体传输协议,用于实时视频流的传输和控制。
应用:
在代码中,FFmpeg作为子进程运行,通过管道接收每一帧的像素数据,并将其编码后推流到指定的RTSP地址。
三.源代码
源代码实现了一个基于人脸检测与识别的视频处理系统,主要功能包括:实时人脸检测、随机生成姓名、人脸特征提取与保存,以及在视频中实时标注人脸信息。
'''这段代码实现了一个完整的人脸检测与识别系统,结合了 YOLOv8 的高效目标检测能力和 dlib 的人脸关键点检测与特征提取功能。
它能够实时处理视频流,检测人脸并标记随机生成的姓名,同时将识别到的人脸保存到文件夹中'''
import cv2
from ultralytics import YOLO
from faker import Faker
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import os
import dlib
# 人脸关键点检测器
predictor_path = "model/shape_predictor_68_face_landmarks.dat"
# 人脸识别模型、提取特征值
face_rec_model_path = "model/dlib_face_recognition_resnet_model_v1.dat"
# 加载模型
# 人脸检测
detector = dlib.get_frontal_face_detector()
# 关键点检测
sp = dlib.shape_predictor(predictor_path)
# 编码
facerec = dlib.face_recognition_model_v1(face_rec_model_path)
# 实例化YOLO模型并将其移动到设备上
model = YOLO('model/yolov8n-face.pt')
# 创建一个Faker对象用于生成随机姓名sms
faker = Faker(locale='zh_CN')
# 打开视频文件并获取视频参数
video_path =r'D:\01_liuhairui\YOLOv8-Detection-Project-main\media\zhu.mp4'
# video_path = "media/00009.MTS"
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
# 设置输出视频参数
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# out = cv2.VideoWriter('result/Student.mp4', fourcc, fps, size, True)
# 判断人脸照片是否有特征
def judge_character(image):
# 人脸检测
dets = detector(image, 1)
if len(dets) == 1:
# 关键点
shape = sp(image, dets[0])
# 提取特征
# 获取到128位的编码
face_descriptor = facerec.compute_face_descriptor(image, shape)
v = np.array(face_descriptor)
return v
else:
return None
# cv2将标识结果可视化
def box_label(origin, studentId, image, b, label='', txt_color=(255, 255, 255)):
# 得到目标矩形框的左上角和右下角坐标(xx,yy)
p1, p2 = (int(b[0]), int(b[1])), (int(b[2]), int(b[3]))
# 获取可以识别出的人脸的文件夹中的所有文件名
rec_file_names = os.listdir('rec-face')
# 将每个人的人脸单独提取出来
face = origin[int(b[1]):int(b[3]), int(b[0]):int(b[2])]
face2 = cv2.cvtColor(face, cv2.COLOR_BGR2RGB)
result = judge_character(face2)
# 如果识别出来则记录进识别列表
if result is not None and track_id_number not in rec_list:
rec_list.append(track_id_number)
# 如果检测出人脸则使用绿色框框出来
# 因为后续该人脸截取到的图片不一定能提取到人脸特征,所以识别出来后面可能不会显示绿色
# 将识别出来的id记录下来,这样子后续即使识别不出人脸特征也能直接给其框出绿色方框
if result is not None or track_id_number in rec_list:
# 如果文件夹中识别出该人脸则存入进文件夹
if f'{int(studentId)}-{label}.png' not in rec_file_names:
cv