python + opencv实现人脸识别项目总结

1、提出问题

通过python+opencv实现对摄像头输入的图像实时人脸识别,或者对输入的图片进行人脸识别

2、解决思路

本项目主要有两个模块:数据训练和人脸识别

1.1 数据训练

数据训练模块的思路如下:

(1)定义getImageAndLabels()用来返回训练图像的脸部数据和图像文件名中的顺序数据:

faces和ids

(2)创建、加载识别器recognizer

(3)对faces和np.array(ids)进行训练:recognizer.train(faces, np.array(ids))

(4)训练好的数据存储在trainer.yml下,便于人脸识别模块调用

1.2 人脸识别

人脸识别模块的思路如下:

(1)加载数据训练模块的训练数据

(2)加载opencv提供的人脸分类器

(3)定义face_detect_demo()方法获取需要识别的图片上的人脸并在脸部绘制方框,把方框内部的人脸数据与trainer.yml中的数据对比,返回trainer.yml文件中相似图片数据的idconfidence

(4)定义name()方法获取训练图片的人名,以便于对识别出的图片中的人脸做标记

(5)将摄像头捕捉的图像抽帧传入face_detect_demo()实时识别并在图片上显示结果

3、代码

3.1 数据训练模块代码

import os
import cv2 as cv
import numpy as np
from PIL import Image

def getImageAndLabels(path):
    #储存人脸信息
    facesSamples = []
    #储存序号数据
    ids = []
    #储存姓名信息
    names = []
    #储存图片信息
    imagePaths = []
    # 得到文件名中的人名

    # listdir列出文件夹下的文件
    for file in os.listdir(path):

        if file.endswith('jpg'):
                    # 路径拼接,imagePath是图片的绝对路径
                    imagePath = os.path.join(path, file)
                    # 将图片路径添加到列表中
                    imagePaths.append(imagePath)





    #加载分类器
    face_detector = cv.CascadeClassifier('D:/Software/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')

    #id从0开始
    id = 1
    #遍历imagePaths中存储的绝对路径对应的图片
    for imagePath in imagePaths:
        #打开图片,灰度化PIL有九种不同模式,其中1为黑白,L为灰度
        PIL_img = Image.open(imagePath).convert('L')
        #将图像转换成数组,以黑白深浅
        img_numpy = np.array(PIL_img,'uint8')
        #获取图片人脸特征
        faces = face_detector.detectMultiScale(image=img_numpy,scaleFactor=1.01,minNeighbors=5,minSize=(180,180),maxSize=(300,300))
        # 得到图片绝对路径列表中的人名,存储在names列表

        name = (os.path.split(imagePath)[1].split('-')[1]).split('.')[0]



        #预防无面容照片
        for x,y,w,h in faces:
            names.append(name)
            ids.append(id)
            facesSamples.append(img_numpy[y:y+h,x:x+w])
            #打印脸部特征和id
            print('id:',id)
            print('name:',name)
            print('fs',img_numpy[y:y+h,x:x+w])
            # id自增1
            id += 1

    print(ids)
    print(names)
    return facesSamples,ids
if __name__ == '__main__':
    #图片的路径
    path = 'D:/SoftwareCache/PyCharmCache/Project_Face/trainer/faces'
    #获取图像数组和id标签数组和姓名
    faces,ids = getImageAndLabels(path)
    #加载识别器
    recognizer = cv.face.LBPHFaceRecognizer_create()
    #训练
    recognizer.train(faces, np.array(ids))

    print(ids)
    #保存文件
    recognizer.write('./trainer.yml')

3.2 人脸识别模块代码

import cv2 as cv
import os
import numpy as np
from PIL import Image
import urllib
import urllib.request

#加载训练数据集文件
recognizer = cv.face.LBPHFaceRecognizer_create()
#加载数据
recognizer.read('./trainer.yml')
#名字
names = []
#警报全局变量
warningtime = 0

face_detector = cv.CascadeClassifier('D:/Software/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml')

#准备识别的图像
def face_detect_demo(img):
    gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)#转换为灰度
    #加载官方人脸识别器
    face_detector = cv.CascadeClassifier('D:/Software/opencv/opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml')
    #在gray图上找出人脸
    face = face_detector.detectMultiScale(gray,1.01,5,cv.CASCADE_SCALE_IMAGE,(180,180),(300,300))

    for x,y,w,h in face:
        #在img上面绘制脸部方框
        cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=1)
        #img上绘制脸部圆圈
        cv.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(0,255,0),thickness=1)
        #人脸识别

        ids,confidence = recognizer.predict(gray[y:y+h,x:x+w])
        print(ids)
        print('confidence:',confidence)
        print('name:',names[ids-1])


        if confidence > 120:
            #gloal声明一个全局变量
            global warningtime
            warningtime += 1

            if warningtime > 100:
                #不是存储在数据库中的人脸,图片上打印:unknown
        #
        #
                cv.putText(img,'unknown',(x,y+15),cv.FONT_HERSHEY_SIMPLEX,0.75,(0,255,0),1)

        else:
            cv.putText(img,str(names[ids-1]),(x,y+15),cv.FONT_HERSHEY_SIMPLEX,0.75,(0,255,0),1)

    cv.imshow('result',img)
def name():
    imagePaths = []
    path = './faces'

    for file in os.listdir(path):

        if file.endswith('jpg'):
            # 路径拼接,imagePath是图片的绝对路径
            imagePath = os.path.join(path, file)
            # 将图片路径添加到列表中
            imagePaths.append(imagePath)
    #得到图片文件名中的名字
    for imagePath in imagePaths:
        # 打开图片,灰度化PIL有九种不同模式,其中1为黑白,L为灰度
        PIL_img = Image.open(imagePath).convert('L')
        # 将图像转换成数组,以黑白深浅
        img_numpy = np.array(PIL_img, 'uint8')
        # 获取图片人脸特征
        faces = face_detector.detectMultiScale(image=img_numpy, scaleFactor=1.01, minNeighbors=5, minSize=(180, 180),
                                               maxSize=(300, 300))
        # 得到图片绝对路径列表中的人名,存储在names列表

        name = (os.path.split(imagePath)[1].split('-')[1]).split('.')[0]

        # 预防无面容照片
        for x, y, w, h in faces:
            names.append(name)

            # 打印脸部特征和id
            print('id:', id)
            print('name:', name)
            print('fs', img_numpy[y:y + h, x:x + w])
    print(names)
cap = cv.VideoCapture(0)
name()




# #以图片做实验
# #D:\SoftwareCache\PyCharmCache\Project_Face\trainer\FERET_80_80\FERET_80_80-人脸数据库\FERET-001-Lesley
#
# frame = cv.imread('./face8.jpg')
# face_detect_demo(frame)
#
# while True:
#     if ord('q') == cv.waitKey(0):
#         break
#
# cv.destroyAllWindows()


#以摄像头捕捉图像做实验
while True:
    flag,frame = cap.read()
    if not flag:
        break
    face_detect_demo(frame)

    if ord(' ') == cv.waitKey(10):
        break

cv.destroyAllWindows()
cap.release()


4、结果如下

python + opencv实现人脸识别项目总结_第1张图片

 5、声明

此篇博客为笔者学习B站python+opencv人脸识别项目后自己的一点总结,侵权请联系笔者删除。

B站视频链接:一天搞定人脸识别项目!学不会up直接下跪!(python+opencv)_哔哩哔哩_bilibiliicon-default.png?t=L9C2https://www.bilibili.com/video/BV1Lq4y1Z7dm?spm_id_from=333.999.0.0

你可能感兴趣的:(opencv,python,计算机视觉)