【OpenCV-Python】35.OpenCV的人脸检测和识别——示例2(人脸识别训练本地数据)

35.OpenCV的人脸检测和识别——示例2(人脸识别训练本地数据)


文章目录

  • 前言
  • 一、采集人脸样本
  • 二、生成Label
  • 三、训练自己的数据模型
  • 四、进行人脸识别(图片文件)
  • 五、使用视频进行人脸识别
  • 六、OpenCV-Python资源下载
  • 总结


前言

  人脸检测是指在图像中完成人脸定位的过程。人脸识别是在人脸检测的基础上进一步判断人的身份。本示例是对之前有关人脸检测和识别的代码总结。


一、采集人脸样本

  在face文件夹中放入需要进行识别的人脸图片:
在这里插入图片描述
  每个文件夹中放入的照片如下所示:【OpenCV-Python】35.OpenCV的人脸检测和识别——示例2(人脸识别训练本地数据)_第1张图片

import os
import cv2
import imghdr
import numpy as np
from imutils import *

# 人脸检测并保存人脸
def facedetect(image, output):
    # 获取文件名
    name = os.path.basename(image)
    # 读入图片
    image = cv2.imread(image)
    # 变成灰度图
    image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # 级联分类器,检测人脸
    detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
    rects = detector.detectMultiScale(image, scaleFactor=1.1, minNeighbors=3, minSize=(20, 20), flags=cv2.CASCADE_SCALE_IMAGE)
    # 循环每个人脸
    for (x,y,w,h) in rects:
        # 截取人脸,并且都转化为200*200的固定大小
        f = cv2.resize(image[y:y+h, x:x+w], (200,200))
        # 写入指定路径
        cv2.imwrite(os.path.join(output, name), f)

# 检测并截取人脸
def predict_face(path, output):
    # 如果该文件夹不存在则创建文件夹
    if not os.path.exists(output):
        os.makedirs(output)
    # 循环每个人物的文件夹下的图片
    for files in os.listdir(path):
        # 检测是不是文件夹
        if os.path.isdir(os.path.join(path, files)):
            # 定义截取到的人脸的输出路径
            output2 = os.path.join(output, files)
            # 如果该文件夹不存在则创建文件夹
            if not os.path.exists(output2):
                os.makedirs(output2)
            # 人物文件夹的完整路径
            files = os.path.join(path, files)
            # 循环每个人的每张照片
            for file in os.listdir(files):
                # 照片完整路径
                file = os.path.join(files, file)
                # 检测人脸并保存
                facedetect(file, output2)

# 样本路径和采集路径
predict_face('faces', 'predict_faces')

  运行程序后得到predict_faces文件夹,其中包含预测人脸的检测图片,打开后需删除识别错误的图片(红框为识别错误图像):
【OpenCV-Python】35.OpenCV的人脸检测和识别——示例2(人脸识别训练本地数据)_第2张图片


二、生成Label

  程序会根据predict_faces子文件夹中的人数情况看自动生成从0开始的标签。

# 生成label文件
def get_label(path):
    fh = open("label.txt", 'w')
    # 表示人脸label
    label = 0
    for root, dirs, files in os.walk(path):
        # 循环每个文件夹
        for subdir in dirs:
            # 文件夹完整路径
            subdir_path = os.path.join(root,subdir)
            # 循环每个人物文件夹下面每张照片
            for file in os.listdir(subdir_path):
                # 照片完整路径
                filepath = os.path.join(subdir_path, file)
                # 判断文件类型是不是图片类型
                imgType = imghdr.what(filepath)
                if imgType == 'jpeg' or imgType == 'png':
                    # 保存图片路径
                    fh.write(filepath);
                    fh.write(";")
                    # 标签
                    fh.write(str(label))
                    fh.write("\n")
            # 每个人的标签不一样,从0开始计数
            label = label + 1            
    fh.close()
    
# 采集人脸标签的路径
get_label('predict_faces')

  生成的label.txt会根据文件夹中分类的路径生成相应的标签,如下所示:
【OpenCV-Python】35.OpenCV的人脸检测和识别——示例2(人脸识别训练本地数据)_第3张图片


三、训练自己的数据模型

  调用人脸识别器时,程序会根据标签文件对应的读入已知图像和对应的标签进行训练,并在最后保存训练文件。

# 保存图片数据
images = []
# 保存标签
labels = []
# 打开文件
fh = open("label.txt")
# 循环每一行
for line in fh:
    # 以;切分字符串
    arr = line.split(";")
    # 第0部分为图片路径,读取文件
    img = cv2.imread(arr[0],0)
    # 保存图片数据
    images.append(img)
    # 保存对应的标签数据
    labels.append(int(arr[1]))
    
# model = cv2.face.EigenFaceRecognizer_create()
# model = cv2.face.FisherFaceRecognizer_create()
model = cv2.face.LBPHFaceRecognizer_create()

# 训练模型
model.train(np.array(images), np.array(labels))
# 保存模型
model.save("predict_face_NBAstar.xml")

  生成的标签文件和保存的模型:
在这里插入图片描述


四、进行人脸识别(图片文件)

  提前准备好需要进行预测的未知人脸图像,并放入test文件夹。
【OpenCV-Python】35.OpenCV的人脸检测和识别——示例2(人脸识别训练本地数据)_第4张图片
  检测人脸后,通过model.predict()方法进行识别。

# 定义人物名字
name= ['KobeBryant','LeBronJames','TracyMcGrady']

# 载入训练好的模型
model.read('predict_face_NBAstar.xml')

i=0
# 读入测试图片来做测试
for file in os.listdir('test'):
    file = os.path.join('test', file)
    # 判断文件类型
    imgType = imghdr.what(file)
    if imgType == 'jpeg' or imgType == 'png'or 'jpg':
        # 读入图片
        image = cv2.imread(file)
        # 变为灰度图
        gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
        # 级联分类器
        detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
        rects = detector.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3, minSize=(20, 20), flags=cv2.CASCADE_SCALE_IMAGE)
        # 循环每个人脸
        for (x,y,w,h) in rects:
            # 画矩形框
            cv2.rectangle(image, (x,y), (x+w,y+h), (255,255,255), 2)
            # 人脸识别
            face = cv2.resize(gray[y:y+h,x:x+w], (200,200))
            # 预测人物
            params = model.predict(face)
            # 写上人物名字
            cv2.putText(image,name[params[0]],(x,y-5),cv2.FONT_HERSHEY_PLAIN,1,(255,255,255),1)
        i += 1
        cv2.imshow("test"+str(i),image)
        
cv2.waitKey(0)
cv2.destroyAllWindows()

  识别结果如下:
【OpenCV-Python】35.OpenCV的人脸检测和识别——示例2(人脸识别训练本地数据)_第5张图片


五、使用视频进行人脸识别

  可以利用图片文件生成的模型,利用摄像头进行识别。

import cv2

capture = cv2.VideoCapture(0)     

frame_width = capture.get(cv2.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv2.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv2.CAP_PROP_FPS)

if capture.isOpened() is False:  
    print('CAMERA ERROR !')
    exit(0)
model = cv2.face.LBPHFFaceRecognizer_create()

name= ['Kobe Bryant','LeBron James','Tracy McGrady']

model.read('predict_face_NBAstar.xml')  

detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")   

while capture.isOpened():
    
    ret, frame = capture.read()   
    if ret is True:              
        
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)     
        
        rects = detector.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3, minSize=(20, 20), flags=cv2.CASCADE_SCALE_IMAGE)
        
        for (x,y,w,h) in rects:

            cv2.rectangle(frame, (x,y), (x+w,y+h), (255,255,255), 2)

            face = cv2.resize(gray[y:y+h,x:x+w], (200,200))

            params = model.predict(face)

            cv2.putText(frame,name[params[0]],(x,y-5),cv2.FONT_HERSHEY_PLAIN,1,(255,255,255),1)
 
        cv2.imshow('FACE', frame)  
        
        k = cv2.waitKey(100)
        if k == ord('q'):
            break
    else:
        break

capture.release()
cv2.destroyAllWindows()

  识别结果如下:
【OpenCV-Python】35.OpenCV的人脸检测和识别——示例2(人脸识别训练本地数据)_第6张图片


六、OpenCV-Python资源下载

OpenCV-Python测试用图片、中文官方文档、opencv-4.5.4源码


总结

  以上内容介绍了OpenCV-Python的人脸检测和识别的代码示例总结,有关Python、数据科学、人工智能等文章后续会不定期发布,请大家多多关注,一键三连哟(●’◡’●)。

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