环境:
python3.5
opencv3.4.1
网络模型:
可以从这个https://www.pyimagesearch.com/2018/02/26/face-detection-with-opencv-and-deep-learning/ 下载,
这是一个人脸检测的10层的ResNet+SSD
原理:
利用训练好的caffe的ResNet-10人脸检测网络来人脸检测;
利用opencv的FaceRicognizer()类来对人脸进行识别;
读取数据:
def loadData(path):
dataSet = []
label = []
person_list = os.listdir(path)
for i, a_person in enumerate(person_list):
dir = os.path.join(path, a_person)
img_list = os.listdir(dir)
for a_img in img_list:
ima = cv2.imread(os.path.join(dir, a_img), 0)
ima = cv2.resize(ima, (IMAGE_SIZE, IMAGE_SIZE))
dataSet.append(ima)
label.append(i)
label = np.asarray(label)
return dataSet, label
其中path为所需识别的所有人的总文件夹,子文件夹为所需识别的个人,子文件内存放某人的几张脸部照片(我这里每人只用了五张)
创建网络模型:
net = cv2.dnn.readNetFromCaffe('./models/deploy.prototxt', './models/res10_ssd.caffemodel')
创建->训练->保存人脸识别模型:
# first train
dataSet, label = loadData(r'./img') # 加载人脸图像, 类别
lbfh = cv2.face.LBPHFaceRecognizer_create() # 创建LBPH人脸分类器
lbfh.train(dataSet, label) # 训练模型
lbfh.save('./my_lbph.xml') # 保存模型
# second read and update
# lbfh = cv2.face.LBPHFaceRecognizer_create() # 下次运行时,无需训练之间创建LBPH,然后read即可
# lbfh.read('./my_lbph.xml') # 重载模型
# dataSet, label = updataSet('./3')
# lbfh.update(dataSet, label) # 还提供了再训练方法
# lbfh.save('./my_lbph.xml')
# lbs = lbfh.getLabels() # 还可以展示所有已训练的图像的各个类别
# print(lbs)
net检测人脸,LBPH识别人脸
cap = cv2.VideoCapture(0) # 创建摄像头
result = None
while 1 :
_, frame = cap.read()
frame = cv2.resize(frame, (300, 300))
(h, w) = frame.shape[:2]
blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 1.0, # 送入网络
(300, 300), (104.0, 177.0, 123.0))
detections = net.forward() # 网络前向预测
# 或者原图的人脸框
for i in range(0, detections.shape[2]):
confidence = detections[0, 0, i, 2]
# filter out weak detections by ensuring the `confidence` is
# greater than the minimum confidence
if confidence < CF: # 置信度阈值
continue
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
testImg = frame[startY:endY, startX:endX] # 将人脸抠出
if testImg.shape[0]*testImg.shape[1] == 0:
continue
#
testImg = cv2.cvtColor(testImg, cv2.COLOR_BGR2GRAY)
testImg = cv2.resize(testImg, (IMAGE_SIZE, IMAGE_SIZE))
# predict face ID
result = lbfh.predict(testImg) # (id, a_float)
text = "{:.2f}%-{}".format(confidence * 100, result)
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)
# 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
总结:
opencv的face recognizer还是很好用的 ,比PCA+KNN好用,而且简单快捷.