基于 Python + OpenCV 进行人脸识别,视频追踪代码全注释

先来普及一下概念, 计算机对人脸是如何识别的呢? 或者说图像是如何识别的。主要是获取单张图片的特征值记录了特征值以后,如果下一张图片来了以后两张图片特征值进行对比,如果相似度很高那么计算机就认定这两个是一类图(当然这是需要算法来实现的)

我写的这个是怎么实现的呢,一组训练集训练要识别的人的图像来进行特征提取保存到模型中,在通过摄像头返回的图像进行处理并最后展现出来

直接上代码:   ---- 抱歉由于不知道插入代码后怎么写文字我就全写这了。代码不算完善,但是识别没问题   使用时修改   train_path 和 fd 的人脸描述.xml文件路径就ok了

训练文件结构描述 :  train_path文件结构  train_path -> LL(老李) -> 所有人脸图片

face.xml 文件下载地址 :  http://note.youdao.com/noteshare?id=a74c5cffa145ff5341560d6c269702cb&sub=6A602009232C468CBE83114E840D679E

# 抱歉由于本人不会用 github 所以大家用有道云下载吧(捂脸笑)

  1 # -*- coding: utf-8 -*-
  2 from __future__ import unicode_literals
  3 # 操作文件
  4 import os
  5 # 科学计算
  6 import numpy as np
  7 # 图像识别
  8 import cv2 as cv
  9 # 数据预处理, 该项目中只使用了标签编码
 10 import sklearn.preprocessing as sp
 11 
 12 
 13 def load_imgs(directory):
 14     '''加载 directory 该文件夹下所有以 .jpg 结尾的图片'''
 15     # 识别 系统环境 自动分配当前系统的路径分隔符并替换
 16     directory = os.path.normpath(directory)
 17     # 判断当前路径是否为存在
 18     if not os.path.isdir(directory):
 19         # 手动抛出异常 biu biu biu
 20         raise IOError("The directory '" + directory + "' doesn't exist!")
 21     # 创建图片集合 用于存储文件夹名和该文件夹下所有的图片
 22     faces = {}
 23     # os.walk(directory) 获取当前文件夹下所有的文件夹以及文件
 24     # curdir: 当前文件夹路径
 25     # subdirs: 当前文件夹下所有文件夹 (列表)
 26     # files: 当前文件夹下所有文件 (列表)
 27     for curdir, subdirs, files in os.walk(directory):
 28         # 首先便利所有的文件 筛选.jpg结尾文件并循环
 29         for jpeg in (file for file in files if file.endswith('.jpg')):
 30                 # 拼接图片路径
 31             path = os.path.join(curdir, jpeg)
 32             # 获取该图片分类名称
 33             label = path.split(os.path.sep)[-2]
 34             # 判断当前key值是否存在图片集合中, 如果为空则创建该键并赋值空列表
 35             # 否则给图片集合中的 key 添加图片路径
 36             if label not in faces:
 37                 faces[label] = []
 38             faces[label].append(path)
 39     # 返回图片集合
 40     return faces
 41 
 42 
 43 def LBPHModel(fd, codec, train_path):
 44     '''
 45     -------------------
 46     参数说明: fd, codec, [model_path]
 47     fd: Haar-like(人脸特征模型对象)
 48     codec: LabelEncoder(标签编码器对象)
 49     model_path: 服用模型路径(功能未实现, 没找到读取的函数...)
 50     -------------------
 51     返回: 训练后的模型对象
 52     '''
 53     # 加载当前文件加下所有.jpg结尾的图片
 54     train_faces = load_imgs(train_path)  # 'traom_imgs'
 55     # 将所有标签放入编码器进行训练
 56     codec.fit(list(train_faces.keys()))
 57     # 创建空的训练集数组x y
 58     train_x, train_y = [], []
 59     # 循环所有训练组
 60     for label, filenames in train_faces.items():
 61         # 循环当前样本组中的图片
 62         for filename in filenames:
 63             # 读取图片
 64             image = cv.imread(filename)
 65             # 将图片转成灰度图
 66             gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
 67             # 获取人脸特征位置
 68             faces = fd.detectMultiScale(
 69                 gray, 1.1, 2, minSize=(100, 100))
 70             # 循环脸部特征数组
 71             for l, t, w, h in faces:
 72                 # 将图片中的脸部特征裁剪下来
 73                 train_x.append(gray[t:t + h, l:l + w])
 74                 # 标签编码结果存储
 75                 train_y.append(codec.transform([label])[0])
 76     train_y = np.array(train_y)
 77     # 创建LBPH人脸检测器
 78     model = cv.face.LBPHFaceRecognizer_create()
 79     # 对训练集进行训练
 80     model.train(train_x, train_y)
 81     return model
 82 
 83 
 84 if __name__ == "__main__":
 85     # 训练集图片存储路径
 86     train_path = 'train_imgs'
 87     # 读取人脸描述文件,  构建人脸检测器
 88     fd = cv.CascadeClassifier('face.xml')
 89     # 创建标签编码器
 90     codec = sp.LabelEncoder()
 91     # 获取model
 92     model = LBPHModel(fd, codec, train_path)
 93     # 打开视频捕捉设备
 94     vc = cv.VideoCapture(0)
 95     while True:
 96         # 读取视频帧
 97         frame = vc.read()[1]
 98         # 反转图片
 99         frame = cv.flip(frame, 1)
100         # print(frame)
101         # 人脸位置检测, 返回数组
102         faces = fd.detectMultiScale(frame, 1.3, 5)
103         # 循环人脸位置数组
104         for l, t, w, h in faces:
105             # 给人脸描边
106             cv.rectangle(frame, (l, t), (l + w, t + h),
107                          (255, 0, 0), 4)
108             # 复制原图片文本
109             gray = frame.copy()
110             # 将图片变化成灰度图
111             gray = cv.cvtColor(gray, cv.COLOR_BGR2GRAY)
112             # 对面部特征进行识别
113             pred_test_y = model.predict(gray[t:t + h, l:l + w])[0]
114             # 将预测后的结果进行标签解码
115             face_name = codec.inverse_transform([pred_test_y])[0]
116             # 给图片添加文本 图片矩阵, 添加文本名称, 设置文本显示位置,
117             # 字体样式, 字体大小, 字体颜色, 字体粗细
118             cv.putText(frame, face_name, (l + 5, t - 15),
119                        cv.FONT_HERSHEY_SIMPLEX, 1,
120                        (255, 255, 255), 3)
121             # 打印名称
122             # print(face_name)
123 
124         # 显示图片
125         cv.imshow('VideoCapture', frame)
126         # 等待按下ESC键退出, 每次等待33毫秒
127         if cv.waitKey(33) == 27:
128             break
129     # 关闭视频捕捉设备
130     vc.release()
131     # 关闭视频窗口
132     cv.destroyAllWindows()
 

猜你喜欢

转载自www.cnblogs.com/laolibk/p/9098853.html