使用opencv-python实现一个简易人脸检测和识别系统

本文介绍了一套完整的人脸检测与识别系统实现过程,包括环境配置、人脸数据录入、人脸库数据训练及最终的人脸识别应用。通过具体的代码示例展示了如何使用OpenCV进行人脸检测与识别。

环境配置

安装opencv-pythonopencv-contrib-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

检测一张主要人脸

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

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退出

代码示例

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数据

代码

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)

人脸检测并识别

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;

更多

项目仓库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_console_

您的关注与鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值