import cv2 as cv
import numpy as np
images =['jjy.jpg','lye.jpg']
faces_list =[]
labels =[]
label =1for f in images:# 读取图片并转成灰度图像
img = cv.imread(f,0)# 加载级联检测器,人脸特征分类器
face_classifier = cv.CascadeClassifier('haarcascade_frontalface_alt2.xml')# 提取人脸信息
faces = face_classifier.detectMultiScale(img)
x, y, w, h = faces[0]# 将提取出的人脸放入列表
faces_list.append(img[y:y + h, x:x + w])# 将标签放入列表
labels.append(label)
label +=1# 加载识别器
recognizer = cv.face.LBPHFaceRecognizer_create()# 训练数据
recognizer.train(faces_list, np.array(labels))
recognizer.write('train.yml')
4. 人脸识别
import cv2 as cv
# 读取图片
img = cv.imread('jjy.jpg')# 调整图像比例
img = cv.resize(img,None, fx=0.5, fy=0.5)# 转成灰度图像
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# 加载级联检测器,人脸特征分类器
face_classifier = cv.CascadeClassifier('haarcascade_frontalface_alt2.xml')# 提取人脸信息
faces = face_classifier.detectMultiScale(gray)# 加载识别器
recognizer = cv.face.LBPHFaceRecognizer_create()# 读取训练数据
recognizer.read('train.yml')for x, y, w, h in faces:# 识别图中人脸,返回标签和置信度
img_id, confidence = recognizer.predict(gray[y:y + h, x:x + w])if confidence >100:
name ='unknown'else:
name ='jjy'if img_id ==1else'lye'
cv.putText(img=img, org=(x, y), text=name, fontFace=cv.FONT_HERSHEY_SIMPLEX, fontScale=0.75, color=(0,255,0),
thickness=2)
cv.circle(img=img, center=(x + w //2, y + h //2), radius=h //2, color=(0,0,255), thickness=2)# 展示人脸
cv.imshow('face', img)# 按'q'键退出whileTrue:if cv.waitKey(1)==ord('q'):break# 关闭窗口
cv.destroyAllWindows()
3. 完整代码
1. 人脸录入
import os
import cv2 as cv
IMG_SAVE_PATH ='../data/'defmain():# 打开摄像头
cap = cv.VideoCapture(0)ifnot cap.isOpened():print('摄像头连接失败')# 输入姓名
name =input('请输入需要录入的名字:')print("姓名输入完成,按's'键保存图片,按'q'键退出")# 循环读取每一帧画面whileTrue:
ret, frame = cap.read()ifnot ret:print('读帧失败')break# 提取的人脸信息和灰度图像
faces, gray = img_extract_faces(frame)# 框出人脸for x, y, w, h in faces:
cv.rectangle(img=frame, pt1=(x, y), pt2=(x + w, y + h), color=(255,0,0), thickness=2)# 展示人脸
cv.imshow('face', frame)
k = cv.waitKey(1)# 按 's' 键保存人脸if k ==ord('s'):
save_face(faces, frame, name)# 按 'q' 键退出elif k ==ord('q'):break# 关闭摄像头和窗口
cap.release()
cv.destroyAllWindows()# 返回提取的人脸信息和灰度图像defimg_extract_faces(img):
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
face_classifier = cv.CascadeClassifier('haarcascade_frontalface_alt2.xml')
faces = face_classifier.detectMultiScale(gray)return faces, gray
# 保存提取到的人脸信息和姓名defsave_face(faces, img, name):iflen(faces)==0:print('没有检测到人脸,请调整')returniflen(faces)>1:print('检测到多个人脸,请调整')return
x, y, w, h = faces[0]
cv.imwrite(get_img_name(name), img[y:y + h, x:x + w])print('录入成功,按 q 键退出')# 返回保存路径 + name_number + '.' + name + '.jpg'defget_img_name(name):# 读取保存路径下所有的目录,格式:name_number + '.' + name + '.jpg'
name_map ={f.split('.')[1]:int(f.split('.')[0])for f in os.listdir(IMG_SAVE_PATH)}ifnot name_map:
name_number =1elif name in name_map:
name_number = name_map[name]else:
name_number =max(name_map.values())+1return IMG_SAVE_PATH +str(name_number)+'.'+ name +'.jpg'if __name__ =='__main__':
main()
2. 训练数据
import cv2 as cv
import os
import numpy as np
IMG_SAVE_PATH ='../data/'# 读取所有图片路径
image_paths =[os.path.join(IMG_SAVE_PATH, f)for f in os.listdir(IMG_SAVE_PATH)]# 读取所有图片并转成灰度图像
faces_list =[cv.imread(image_path,0)for image_path in image_paths]# 读取所有标签
labels =[int(f.split('.')[0])for f in os.listdir(IMG_SAVE_PATH)]# 加载识别器
recognizer = cv.face.LBPHFaceRecognizer_create()# 训练数据,放入人脸信息列表和标签数组
recognizer.train(faces_list, np.array(labels))# 保存数据
recognizer.write('train.yml')
3. 人脸识别
import os
import cv2 as cv
IMG_SAVE_PATH ='../data/'
recognizer = cv.face.LBPHFaceRecognizer_create()
recognizer.read('train.yml')
cap = cv.VideoCapture(0)ifnot cap.isOpened():print('摄像头连接失败')
name_map ={int(f.split('.')[0]): f.split('.')[1]for f in os.listdir(IMG_SAVE_PATH)}whileTrue:
ret, frame = cap.read()ifnot ret:print('读帧失败')break
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
face_classifier = cv.CascadeClassifier('haarcascade_frontalface_alt2.xml')
faces = face_classifier.detectMultiScale(gray)for x, y, w, h in faces:
img_id, confidence = recognizer.predict(gray[y:y + h, x:x + w])if confidence >85:
name ='unknown'else:
name = name_map[img_id]
cv.putText(frame, name,(x, y), fontFace=cv.FONT_HERSHEY_SIMPLEX, fontScale=0.75, color=(0,255,0),
thickness=2)
cv.circle(frame,(x + w //2, y + h //2), w //2, color=(255,0,0), thickness=2)
cv.imshow('face', frame)if cv.waitKey(1)==ord('q'):break
cap.release()
cv.destroyAllWindows()