准备
1)摄像头一个
2)训练好的模型
介绍
到了最激动人心的阶段了,先用opencv检测人脸,使用前面训练好的模式,对摄像头采集到的视频流,进行对每一帧人脸识别
效果
近距离人脸识别
中距离人脸识别
解释:pu:97.31% pu为识别用户的名称(我们使用--用户名的拼音建立文件夹),这里的pu是我的用户名;
97.31%为识别用户的准确率。
源代码:
#python recognize_video.py --detector face_detection_model --embedding-model openface_nn4.small2.v1.t7 --recognizer output/recognizer.pickle --le output/le.pickle
# 导入必要的包
from imutils.video import VideoStream
from imutils.video import FPS
import numpy as np
import argparse
import imutils
import pickle
import time
import cv2
import os
# 构造参数解析器并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-d", "--detector", required=True,
help="path to OpenCV's deep learning face detector")
ap.add_argument("-m", "--embedding-model", required=True,
help="path to OpenCV's deep learning face embedding model")
ap.add_argument("-r", "--recognizer", required=True,
help="path to model trained to recognize faces")
ap.add_argument("-l", "--le", required=True,
help="path to label encoder")
ap.add_argument("-c", "--confidence", type=float, default=0.5,
help="minimum probability to filter weak detections")
args = vars(ap.parse_args())
# 从磁盘加载我们的序列化面部检测器
print("[INFO] loading face detector...")
protoPath = os.path.sep.join([args["detector"], "deploy.prototxt"])
modelPath = os.path.sep.join([args["detector"],
"res10_300x300_ssd_iter_140000.caffemodel"])
detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)
# 从磁盘加载我们的序列化面嵌入模型
print("[INFO] loading face recognizer...")
embedder = cv2.dnn.readNetFromTorch(args["embedding_model"])
# 加载实际的人脸识别模型和标签编码器
recognizer = pickle.loads(open(args["recognizer"], "rb").read())
le = pickle.loads(open(args["le"], "rb").read())
# 初始化视频流,然后让相机传感器预热
print("[INFO] starting video stream...")
#vs = VideoStream(src=0).start()
vs = VideoStream(1).start()
time.sleep(2.0)
# 启动FPS吞吐量估算器
fps = FPS().start()
# 循环来自视频文件流的帧
while True:
# 从线程视频流中抓取帧
frame = vs.read()
#将框架调整为宽度为400像素(同时
#保持宽高比),然后抓取图像
frame = imutils.resize(frame, width=400)#,height=100)
(h, w) = frame.shape[:2]
# 从图像构造一个blob
imageBlob = cv2.dnn.blobFromImage(
cv2.resize(frame, (300, 300)), 1.0, (300, 300),(1.0, 177.0, 123.0), swapRB=False, crop=False)
# 应用OpenCV基于深度学习的人脸检测器进行本地化
# 输入图像中的面
detector.setInput(imageBlob)
detections = detector.forward()
# 循环检测
for i in range(0, detections.shape[2]):
#提取与之相关的置信度(即概率)
#预测
confidence = detections[0, 0, i, 2]
# 过滤弱检测
if confidence > args["confidence"]:
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
# 提取面部区域
face = frame[startY:endY, startX:endX]
(fH, fW) = face.shape[:2]
# 确保面部宽度和高度足够大
if fW < 20 or fH < 20:
continue
#为面部ROI构造一个blob,然后传递blob
#通过我们的面部嵌入模型获得128 - d
#量化面部
faceBlob = cv2.dnn.blobFromImage(face, 1.0 / 255,
(96, 96), (0, 0, 0), swapRB=True, crop=False)
embedder.setInput(faceBlob)
vec = embedder.forward()
#执行分类以识别面部
preds = recognizer.predict_proba(vec)[0]
j = np.argmax(preds)
proba = preds[j]
name = le.classes_[j]
#绘制脸部的边界框
#关联概率
text = "{}: {:.2f}%".format(name, proba * 100)
y = startY - 10 if startY - 10 > 10 else startY + 10
cv2.rectangle(frame, (startX, startY), (endX, endY),
(0, 0, 255), 2)
cv2.putText(frame, text, (startX, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)
# 更新FPS计数器
fps.update()
# 显示输出框架
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
# 如果按下`q`键,则从循环中断开
if key == ord("q"):
break
# 停止计时器并显示FPS信息
fps.stop()
print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
# 做一点清理
cv2.destroyAllWindows()
vs.stop()
代码解释
实际的管道本身几乎与识别图像中的面部相同,只有一些更新,我们将在此过程中进行检查。
开拓 recognize_video 的.py 文件,让我们开始吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# import the necessary packages from imutils.video import VideoStream from imutils.video import FPS import numpy as np import argparse import imutils import pickle import time import cv2 import os
# construct the argument parser and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-d", "--detector", required=True, help="path to OpenCV's deep learning face detector") ap.add_argument("-m", "--embedding-model", required=True, help="path to OpenCV's deep learning face embedding model") ap.add_argument("-r", "--recognizer", required=True, help="path to model trained to recognize faces") ap.add_argument("-l", "--le", required=True, help="path to label encoder") ap.add_argument("-c", "--confidence", type=float, default=0.5, help="minimum probability to filter weak detections") args = vars(ap.parse_args()) |
我们的导入与 上面的步骤#3部分相同 ,除了 我们使用 imutils的第2行和第3 行 imutils.video 模块。我们将使用 VideoStream 从我们的相机和FPS捕获帧 以计算每秒帧数统计数据。
除了我们没有通过命令行将路径传递给静态图像之外,命令行参数也是相同的。相反,我们将获取对我们网络摄像头的引用,然后处理视频。如果需要查看参数,请参阅 步骤3。
我们的三个模型和标签编码器在这里加载:
26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# load our serialized face detector from disk print("[INFO] loading face detector...") protoPath = os.path.sep.join([args["detector"], "deploy.prototxt"]) modelPath = os.path.sep.join([args["detector"], "res10_300x300_ssd_iter_140000.caffemodel"]) detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)
# load our serialized face embedding model from disk print("[INFO] loading face recognizer...") embedder = cv2.dnn.readNetFromTorch(args["embedding_model"])
# load the actual face recognition model along with the label encoder recognizer = pickle.loads(open(args["recognizer"], "rb").read()) le = pickle.loads(open(args["le"], "rb").read()) |
在这里我们加载面部 detector ,面部 embedder 模型,面部 recognizer 模型(线性SVM)和标签编码器。
如果您对三种型号或标签编码器感到困惑,请务必参考 步骤#3。
让我们初始化我们的视频流并开始处理帧:
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# initialize the video stream, then allow the camera sensor to warm up print("[INFO] starting video stream...") vs = VideoStream(src=0).start() time.sleep(2.0)
# start the FPS throughput estimator fps = FPS().start()
# loop over frames from the video file stream while True: # grab the frame from the threaded video stream frame = vs.read()
# resize the frame to have a width of 600 pixels (while # maintaining the aspect ratio), and then grab the image # dimensions frame = imutils.resize(frame, width=600) (h, w) = frame.shape[:2]
# construct a blob from the image imageBlob = cv2.dnn.blobFromImage( cv2.resize(frame, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0), swapRB=False, crop=False)
# apply OpenCV's deep learning-based face detector to localize # faces in the input image detector.setInput(imageBlob) detections = detector.forward() |
我们的 VideoStream 对象已初始化并在第43行启动 。我们等待相机传感器在44号线上预热 。
我们还初始化每秒帧数(第47行)并开始在第50行的帧上循环 。我们 从第52行的网络摄像头 抓取一个 框架。
从这里开始,一切都与第3步相同。我们 调整 帧的大小(L ine 57),然后我们从帧构造一个blob +检测面的位置(第61-68行)。
现在让我们处理检测:
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# loop over the detections for i in range(0, detections.shape[2]): # extract the confidence (i.e., probability) associated with # the prediction confidence = detections[0, 0, i, 2]
# filter out weak detections if confidence > args["confidence"]: # compute the (x, y)-coordinates of the bounding box for # the face box = detections[0, 0, i, 3:7] * np.array([w, h, w, h]) (startX, startY, endX, endY) = box.astype("int")
# extract the face ROI face = frame[startY:endY, startX:endX] (fH, fW) = face.shape[:2]
# ensure the face width and height are sufficiently large if fW < 20 or fH < 20: continue |
正如在上一节中一样,我们开始循环 检测 并滤除弱检测(第71-77行)。然后我们提取 面部 ROI以及确保空间尺寸足够大以用于后续步骤(第84-89行)。
现在是时候进行OpenCV人脸识别了:
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# construct a blob for the face ROI, then pass the blob # through our face embedding model to obtain the 128-d # quantification of the face faceBlob = cv2.dnn.blobFromImage(face, 1.0 / 255, (96, 96), (0, 0, 0), swapRB=True, crop=False) embedder.setInput(faceBlob) vec = embedder.forward()
# perform classification to recognize the face preds = recognizer.predict_proba(vec)[0] j = np.argmax(preds) proba = preds[j] name = le.classes_[j]
# draw the bounding box of the face along with the # associated probability text = "{}: {:.2f}%".format(name, proba * 100) y = startY - 10 if startY - 10 > 10 else startY + 10 cv2.rectangle(frame, (startX, startY), (endX, endY), (0, 0, 255), 2) cv2.putText(frame, text, (startX, y), cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)
# update the FPS counter fps.update() |
在这里,我们:
- 构造 faceBlob (第94和95行)并通过深度学习计算面部嵌入(第96和97行)。
- 在计算概率时识别最可能 的面部名称(第100-103行)。
- 在脸部周围绘制一个边界框和 人名 +概率(第107-112行)。
我们的 fps 计数器在115行更新 。
让我们显示结果并清理:
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# show the output frame cv2.imshow("Frame", frame) key = cv2.waitKey(1) & 0xFF
# if the `q` key was pressed, break from the loop if key == ord("q"): break
# stop the timer and display FPS information fps.stop() print("[INFO] elasped time: {:.2f}".format(fps.elapsed())) print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
# do a bit of cleanup cv2.destroyAllWindows() vs.stop() |
要关闭脚本,我们:
- 显示带注释的 帧 (第118行)并等待按下“q”键,此时我们突破循环(第119-123行)。
- 停止我们的 fps 计数器并在终端中打印统计数据(第126-128行)。
- 通过关闭窗口并释放指针进行清理(第131和132行)。
要在视频流上执行OpenCV人脸识别管道,请打开终端并执行以下命令:
1 2 3 4 5 6 7 8 9 |
$ python recognize_video.py --detector face_detection_model \ --embedding-model openface_nn4.small2.v1.t7 \ --recognizer output/recognizer.pickle \ --le output/le.pickle [INFO] loading face detector... [INFO] loading face recognizer... [INFO] starting video stream... [INFO] elasped time: 12.52 [INFO] approx. FPS: 16.13 |
希望对你有帮助。