python3 3. 通过opencv库进行人脸识别 学习笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mcyJacky/article/details/84933096

前言

     计算机视觉系列之学习笔记主要是本人进行学习人工智能(计算机视觉方向)的代码整理。本系列所有代码是用python3编写,在平台Anaconda中运行实现,在使用代码时,默认你已经安装相关的python库,这方面不做多余的说明。本系列所涉及的所有代码和资料可在我的github或者码云上下载到,gitbub地址:https://github.com/mcyJacky/DeepLearning-CV,如有问题,欢迎指出~。

一、人脸识别项目简介

     该项目主要通过opencv库来进行人脸识别:我项目中进行识别的人脸分别是麦迪、姚明和邓超,即首先从网上下载3个人脸的照片各若干张(我下载了每人20张左右)放在各自的文件夹中,如图1.1所示:

图1.1 样本图片的位置

     利用opencv库进行人脸识别的步骤包括:

  • 人脸采集:对样本图片进行人脸采集
  • 生产标签文件:生产对应样本图片的标签文件
  • 训练模型数据:对样本图片进行训练,产生相应的xml文件
  • 人脸识别:利用训练好的数据文件和级联分类器进行人脸识别

二、人脸识别项目实战

2.1 构建简单的读取图片的模块

     先构建一个通用模块,用来读取并显示图片,模块命名为imutils
     使用到python的相关库包括:计算机视觉库cv2、绘图库matplotlib.

import cv2
import matplotlib.pyplot as plt

# 显示图片
def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()

# 读取图片    
def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    return image

2.2 人脸样本采集

import os #用于文件处理
import imghdr #用于图片类型判断
from imutils import *

'''
function: 对样本图片进行人脸采集
params:
    image 样本图片
    outPut 采集人脸的输出路径
'''
def faceDetect(image, outPut):
    #图片名称
    name = os.path.basename(image)
    #读取图片
    image = imread(image)
    #转换为灰度
    image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    #用级联分类器进行人脸识别并保存图片
    detector = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
    rects = detector.detectMultiScale(image, scaleFactor = 1.1, minNeighbors = 3, minSize = (10,10), flags = cv2.CASCADE_SCALE_IMAGE)
    for (x,y,w,h) in rects:
        face_image = cv2.resize(image[y:y+h, x:x+w], (200,200))
        cv2.imwrite(os.path.join(outPut, name), face_image)

'''
function: 对样本图片进行人脸采集
params:
    path 样本图片保存的根目录
    outPut 采集人脸的输出路径
'''
def predict_face(path, outPut):
    #输出图片路径不存在,则创建文件夹
    if not os.path.exists(outPut):
        os.makedirs(outPut)
    
    for file in os.listdir(path):
        #检测是否为存放图片的文件夹
        if os.path.isdir(os.path.join(path, file)):
            outPut2 = os.path.join(outPut, file)
            #创建存放图片的子文件夹
            if not os.path.exists(outPut2):
                os.makedirs(outPut2)
                
            file_path = os.path.join(path, file)
            for image_path in os.listdir(file_path):
                image = os.path.join(file_path, image_path)
                faceDetect(image, outPut2)
#进行人脸采集
predict_face('train_faces', 'predict_faces')

     通过上述方法,可以将样本图片进行灰度人脸的采集并保存在文件夹predict_faces中。

2.3 生产标签文件

'''
function: 生产标签文件label.txt
params:
    path 采集后人脸的文件路径
'''
def make_label(path):
    with open('label.txt', 'w') as fh:
        #表示人脸的标签
        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):
                    image_path = os.path.join(subDir_path, file)
                    #判断图片类型
                    imgType = imghdr.what(image_path)
                    if imgType == 'jpeg' or imgType == 'png':
                        fh.write(image_path)
                        fh.write(':')
                        fh.write(str(label))
                        fh.write('\n')
                label += 1
             
 #进行标签文件的生成               
make_label('predict_faces')

     通过上述方法,可以使采集后的人脸图片对应的标签txt文件。

2.4 训练模型数据

images = []
labels = []
#打开对应的标签文件
with open('label.txt') as fh:
    for line in fh:
        arrLine = line.split(':')
        image = cv2.imread(arrLine[0], 0)
        images.append(image)
        labels.append(int(arrLine[1]))

#定义人脸识别模型
model = cv2.face.EigenFaceRecognizer_create()
#进行模型训练
model.train(np.array(images), np.array(labels))
#保存训练模型数据
model.save('predict_face_deng_tm_yao.xml')

     通过上述方法,通过训练图片和对应的标签,产生相应的训练模型数据,保存于xml文件中。

2.5 人脸识别

#分类名称
name = ['Deng', 'T-MAC', 'Yao']
#载入训练后后的模型
model = cv2.face.EigenFaceRecognizer_create()
model.read('predict_face_deng_tm_yao.xml')

for file in os.listdir('test'):
    image = os.path.join('test', file)
    imgType = imghdr.what(image)
    if imgType == 'jpeg' or imgType == 'png':
        image = imread(image)
        gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
        detector = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
        rects = detector.detectMultiScale(gray, scaleFactor = 1.1, minNeighbors = 3, minSize = (10,10), flags = cv2.CASCADE_SCALE_IMAGE)
        for (x,y,w,h) in rects:
            cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)
            face = cv2.resize(gray[y:y+h,x:x+w], (200,200))
            params = model.predict(face)
            #params[0] 表示相应的标签, 写入训练标签
            cv2.putText(image, name[params[0]], (x,y-10), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,0), 2)
        show(image)

     部分显示结果如图2.5所示:

图2.1 人脸识别结果

总结

     我们可以利用计算机视觉库OpenCV3进行简单的人脸识别,但是错误率较高(可以自己去验证)。不过这更加吸引了我对后续深度学习的兴趣。

【参考】:
     1. 城市数据团课程《AI工程师》计算机视觉方向
     2. 《OpenCV3编程入门》 毛星云
     3. 《OpenCV3计算机视觉:Python语言实现》 JoeMinichino


转载声明:
版权声明:非商用自由转载-保持署名-注明出处
署名 :mcyJacky
文章出处:https://blog.csdn.net/mcyJacky

猜你喜欢

转载自blog.csdn.net/mcyJacky/article/details/84933096