标题树莓派:人脸识别和口罩检测
依赖
# coding=utf-8
# import the necessary packages
import time
import cv2 as cv
import numpy as np
打开摄像头及加载模型
#打开摄像头
cap = cv.VideoCapture(0)
# 创建检测器
face_recognizer = cv.face.LBPHFaceRecognizer_create()
#低版本的opencv使用下面的语句
#face_recognizer = cv.face.createLBPHFaceRecognizer()
# 加载 人脸识别model
face_recognizer.read('fm_model.xml')
#低版本的opencv使用下面的语句
#face_recognizer.laod('fm_model.xml')
# 加载 人脸检测model
face_cascade=cv.CascadeClassifier('model/haarcascade_frontalface_default.xml')
# 加载 人脸的鼻子检测model
nose_cascade=cv.CascadeClassifier('model/haarcascade_mcs_nose.xml')
如果能opencv的版本>=3.3,可以使用dnn,我是在安装openVINO时装的opencv,可能这样才能使用dnn去加载Intel的模型,dnn模型会比检测器更快,而且可以使用Intel的神经计算棒,极大提高检测速度。
# Load the model
net = cv.dnn.readNet('face-detection-adas-0001.xml', 'face-detection-adas-0001.bin')
# Specify target device
net.setPreferableTarget(cv.dnn.DNN_TARGET_CPU)
交互界面
# create switch for ON/OFF functionality
def nothing(x):
pass
cv.namedWindow('Frame')
switch1 = "face_Recognize"
switch2 = "face_mask"
#创建滑条作为开关
cv.createTrackbar(switch1, 'Frame',0,1,nothing)
cv.createTrackbar(switch2, 'Frame',0,1,nothing)
# 画框
def draw_rectangle(img, rect):
for x,y,w,h in rect:
cv.rectangle(img, (x, y), (x+w, y+h), (128, 128, 0), 2)
# 写文字
def draw_text(img, text, rect):
for x,y,w,h in rect:
cv.putText(img, text, (x, y), cv.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 2)
模型信息
# 用户列表
def user_list():
label = 0人脸检测
while True:
name = face_recognizer.getLabelInfo(label)
if len(name) != 0:
print('label:', label, 'name:', name)
else:
name = input("inoutID:")
face_recognizer.setLabelInfo(label, name)
return label
label += 1
截取人脸图片
def cut_face(image):
#运行人脸检测模型
results=face_cascade.detectMultiScale(gray,1.1,5)
if results != ():
for x,y,w,h in results:
return results,gray[y:y+h, x:x+w]
else:
return [[0, 0, 0, 0]], None
或使用dnn
def detect_face(image):
blob = cv.dnn.blobFromImage(image, size=(672,384), ddepth=cv.CV_8U)
net.setInput(blob)
out = net.forward()
# Draw detected faces on the frame
for detection in out.reshape(-1, 7):
confidence = float(detection[2])
xmin = int(detection[3] * image.shape[1])
ymin = int(detection[4] * image.shape[0])
xmax = int(detection[5] * image.shape[1])
ymax = int(detection[6] * image.shape[0])
if confidence > 0.5:
return [[xmin,ymin,xmax-xmin,ymax-ymin]],image[ymin:ymax, xmin:xmax]
else:
return [[0, 0, 0, 0]], None
口罩检测
# 口罩判别
def Mask_detection(image,rect):
#运行模型
nose = nose_cascade.detectMultiScale(gray,1.3,5)
#判断是否带口罩
if nose!=() and rect[0][0]+rect[0][2] != 0:
return "NO"
elif rect[0][0]+rect[0][2] != 0:
return "YES"
return '**'
人脸识别
人脸识别 预测
def predict(image):
if image is not None:
#预测人脸
results = face_recognizer.predict(image)
print(results[1])
#置信度阈值
if results[1] < 60:
label_text = face_recognizer.getLabelInfo(results[0])
else:
label_text = 'stranger'
return label_text
else:
#print eye
return 'not whole face'
主函数
train_faces = []
train_labels = []
num = -1
#训练每个人的图片数
train_face_num = 15
label_mask = ""
while( cap.isOpened() ):
# USB摄像头工作时,读取一帧图像
start = time.time()
#读取图片
ret, image = cap.read()
#二值化
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
#识别人脸并截取人脸图片
rect,cut_img = cut_face(gray)
#画人脸框
draw_rectangle(image, rect)
#获取滑条开关的值
f = cv.getTrackbarPos(switch1,'Frame')
m = cv.getTrackbarPos(switch2,'Frame')
if f == 1:
# 预测 返回人脸标签
label_text = predict(cut_img)
draw_text(image, label_text, rect)
if m == 1:
# 检测口罩
label_mask = Mask_detection(gray,rect)
draw_text(image, "mask:"+label_mask, [[10,40,10,10]])
key = cv.waitKey(1) & 0xFF
end = time.time()
#显示fps
draw_text(image, "fps:"+str(1//(end-start)), [[10,60,10,10]])
#显示视频
cv.imshow("Frame", image)
#当num=0时训练
if num > -1 and num < train_face_num :
rect,cut_img=cut_face(gray)
if cut_img is not None:
train_faces.append(cut_img)
train_labels.append(train_label)
num=num+1
draw_text(image, "condition:"+str(train_face_num-num), [[10,100,10,10]])
elif num >= train_face_num:
face_recognizer.update(train_faces, np.array(train_labels))
face_recognizer.save('fm_model3.0.xml')
train_faces = []
train_labels = []
num = -1
# if the `q` key was pressed, break from the loop
if key == ord("q"):
break
# 按‘s’键训练
if key == ord("s"):
if num == -1:
train_label = user_list()
num=0
# 释放资源和关闭窗口
cap.release()
cv.destroyAllWindows()
要提前创建好模型
# coding=utf-8
import time
import cv2 as cv
face_recognizer = cv.face.createLBPHFaceRecognizer()
face_recognizer.save('fm_model.xml')
OpenVINO
OpenVINO安装
源码、模型及资料
链接: https://pan.baidu.com/s/1EFxwwNkLfDKrAhcwm2DxKA
提取码: tb28