# faceRecognize_opencv **Repository Path**: ZhijianCao_admin/face-recognize_opencv ## Basic Information - **Project Name**: faceRecognize_opencv - **Description**: 使用opencv自带的分类器实现人脸检测与识别 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-01-28 - **Last Updated**: 2024-02-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 环境配置 安装`opencv-python`和`opencv-contrib-python` ## 项目流程 * 人脸数据录入 * 人脸库数据训练 * 对检测到的人脸进行识别并输出 ## 重要方法 ### 检测人脸 ```python def detectFace(img): ''' 人脸检测 :param img: :return: 检测到的人脸的 bbox(x,y,w,h) ''' gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) face_detector = cv2.CascadeClassifier(recognierPath) facesLocations = face_detector.detectMultiScale(img) return facesLocations ``` ### 检测一张主要人脸 ```python def detectOneFace(img): ''' 从图像中检测一张人脸 :param img: :return: ''' res = detectFace(img) maxArea=-1 maxAreaIndex=-1 if len(res)>1: for index,( x,y,w,h) in enumerate(res): area=w*h if area>maxArea: maxArea=area maxAreaIndex=index return [res[0]] return res ``` ### 绘制BBox ```python def drawBox(facesLocations, img, names=[]): ''' 绘制人脸框 :param facesLocations: 人脸bbox :param img: 原始图像 :param names: 每个bbox对应的人脸的label :return:null ''' for index, (x, y, w, h) in enumerate(facesLocations): cv2.rectangle(img, (x, y), (x + w, y + h), color=(0, 0, 255)) # FONT_HERSHEY_PLAIN # FONT_HERSHEY_SIMPLEX if len(names) > 0: font = cv2.FONT_HERSHEY_SIMPLEX textSize = cv2.getTextSize(names[index], font, 1, 2) cv2.rectangle(img, (x, y - textSize[0][1] - textSize[1] - 1), (x + textSize[0][0], y), (0, 0, 255), -1) cv2.putText(img, names[index], (x, y - textSize[1]), font, 1, (255, 255, 255), 2) ``` ## 人脸数据录入 * 使用opencv打开摄像头 * 输入即将录入人脸对应的标签(姓名) * 对读取到的图像进行人脸检测,检测到的人脸绘制BBox并输出 * 用户按下`s`会将当前人脸数据保存到人脸库目录下 * 重复操作录入,按下`q`键退出 * 继续录入下一个人脸数据,输入`q`退出 代码示例 ```python import cv2 import faceUtil import time import os faceSavePath = './facelib/' def faceInput(): capture = cv2.VideoCapture(0) while True: name = input('请输入姓名或者‘q’退出:') if (name.strip() == 'q'): break cv2.namedWindow(name, cv2.WINDOW_NORMAL) while True: flag, img = capture.read() if flag: face = faceUtil.detectOneFace(img) imgWithBox = img.copy() faceUtil.drawBox(face, imgWithBox) cv2.imshow(name, imgWithBox) key = cv2.waitKey(2) if key == ord('s'): if len(face) == 0: continue (x, y, w, h) = face[0] fileName = name + '-' + time.strftime('%Y%m%d%H%M%S', time.localtime()) + '.jpg' cv2.imwrite(os.path.join(faceSavePath, fileName), img[y:y + h, x:x + w]) if key == ord('q'): cv2.destroyWindow(name) break if __name__ == '__main__': faceInput() ``` ## 人脸库数据训练 * 把人脸数据和对应的标签(需要转化成整数)进行训练 * 并将结果保存到文件中,需要保存训练数据和标签对应的id数据 代码 ```python import cv2 as cv import os import numpy as np # 人脸数据目录 facesPath = './facelib' # 模型目录 modelFileDir='./model/' #训练结果文件名 modelFileName='face' names2id = {} facesSample = [] ids=[] for index, file in enumerate(os.listdir(facesPath)): img = cv.imread(os.path.join(facesPath, file),0) facesSample.append(img) infos = file.split('-') name=infos[0] id=names2id.get(name,None) if id==None: id = len(names2id) names2id[name]=id ids.append(id) print(names2id, ids) recognizer = cv.face.LBPHFaceRecognizer_create() recognizer.train(facesSample, np.array(ids)) recognizer.write(os.path.join(modelFileDir,modelFileName)+'.model') id2name=dict([val, key] for key, val in names2id.items()) print(id2name) np.save(os.path.join(modelFileDir,modelFileName),id2name) ``` ## 人脸检测并识别 ```python import cv2 as cv2 import faceUtil import numpy as np import os modelFileDir='./model/' modelFileName='face' if __name__ == '__main__': capture = cv2.VideoCapture(0) cv2.namedWindow('0', cv2.WINDOW_NORMAL) labels=np.load(os.path.join(modelFileDir,modelFileName)+'.npy',allow_pickle=True).item() print(labels) recognizer = cv2.face.LBPHFaceRecognizer_create(); recognizer.read(os.path.join(modelFileDir, modelFileName) + '.model') while True: flag, img = capture.read() if flag: img = cv2.flip(img, 1) gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) faces = faceUtil.detectFace(img) names=[] for x, y, w, h in faces: # confidence值越大,检测结果越不可靠 predict_face_id, confidence = recognizer.predict(gray[y:y+h,x:x+w]) print('检测到'+labels.get(predict_face_id)+",置信评分:"+str(confidence)) if confidence<80: names.append(labels.get(predict_face_id)) else: names.append('unknow') faceUtil.drawBox(faces, img, names) cv2.imshow('0', img) if cv2.waitKey(1) == ord('q'): # 如果点了退出键 break; ``` ## 更多 [项目仓库](https://gitee.com/ZhijianCao_admin/face-recognize_opencv)