Python基于Opencv来快速实现人脸识别过程详解(完整版)


Posted in Python onJuly 11, 2019

前言

随着人工智能的日益火热,计算机视觉领域发展迅速,尤其在人脸识别或物体检测方向更为广泛,今天就为大家带来最基础的人脸识别基础,从一个个函数开始走进这个奥妙的世界。

首先看一下本实验需要的数据集,为了简便我们只进行两个人的识别,选取了beyond乐队的主唱黄家驹和贝斯手黄家强,这哥俩长得有几分神似,这也是对人脸识别的一个考验:

Python基于Opencv来快速实现人脸识别过程详解(完整版)

两个文件夹,一个为训练数据集,一个为测试数据集,训练数据集中有两个文件夹0和1,之前看一些资料有说这里要遵循“slabel”命名规则,但后面处理起来比较麻烦,因为目前opencv接受的人脸识别标签为整数,那我们就直接用整数命名吧:

Python基于Opencv来快速实现人脸识别过程详解(完整版)

为了方便,我们每个人用20张照片来训练,0代表黄家驹,1代表黄家强:

Python基于Opencv来快速实现人脸识别过程详解(完整版)

开始啦:

1.检测人脸

这应该是最基本的,给我们一张图片,我们要先检测出人脸的区域,然后才能
进行操作,opencv已经内置了很多分类检测器,我们这次用haar:

def detect_face(img):
 #将测试图像转换为灰度图像,因为opencv人脸检测器需要灰度图像
 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 #加载OpenCV人脸检测分类器Haar
 face_cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
 #检测多尺度图像,返回值是一张脸部区域信息的列表(x,y,宽,高)
 faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
 # 如果未检测到面部,则返回原始图像
 if (len(faces) == 0):
 return None, None
 #目前假设只有一张脸,xy为左上角坐标,wh为矩形的宽高
 (x, y, w, h) = faces[0]
 #返回图像的正面部分
 return gray[y:y + w, x:x + h], faces[0]

2.有了数据集和检测人脸的功能后,我们就可以进行预训练了

最后返回所有训练图片的人脸检测信息和标签:

# 该函数将读取所有的训练图像,从每个图像检测人脸并将返回两个相同大小的列表,分别为脸部信息和标签
def prepare_training_data(data_folder_path):
 # 获取数据文件夹中的目录(每个主题的一个目录)
 dirs = os.listdir(data_folder_path)
 # 两个列表分别保存所有的脸部和标签
 faces = []
 labels = []
 # 浏览每个目录并访问其中的图像
 for dir_name in dirs:
 # dir_name(str类型)即标签
 label = int(dir_name)
 # 建立包含当前主题主题图像的目录路径
 subject_dir_path = data_folder_path + "/" + dir_name
 # 获取给定主题目录内的图像名称
 subject_images_names = os.listdir(subject_dir_path)
 # 浏览每张图片并检测脸部,然后将脸部信息添加到脸部列表faces[]
 for image_name in subject_images_names:
 # 建立图像路径
 image_path = subject_dir_path + "/" + image_name
 # 读取图像
 image = cv2.imread(image_path)
 # 显示图像0.1s
 cv2.imshow("Training on image...", image)
 cv2.waitKey(100)
 # 检测脸部
 face, rect = detect_face(image)
 # 我们忽略未检测到的脸部
 if face is not None:
 #将脸添加到脸部列表并添加相应的标签
 faces.append(face)
 labels.append(label)
 cv2.waitKey(1)
 cv2.destroyAllWindows()
 #最终返回值为人脸和标签列表
 return faces, labels

3.有了脸部信息和对应标签后,我们就可以使用opencv自带的识别器来进行训练了

#调用prepare_training_data()函数
faces, labels = prepare_training_data("training_data")
#创建LBPH识别器并开始训练,当然也可以选择Eigen或者Fisher识别器
face_recognizer = cv2.face.LBPHFaceRecognizer_create()
face_recognizer.train(faces, np.array(labels))

4.训练完毕后就可以进行预测了

在这之前我们可以设定一下预测的格式,包括用矩形框框出人脸并标出其名字,当然最后别忘了建立标签与真实姓名直接的映射表:

#根据给定的(x,y)坐标和宽度高度在图像上绘制矩形
def draw_rectangle(img, rect):
 (x, y, w, h) = rect
 cv2.rectangle(img, (x, y), (x + w, y + h), (128, 128, 0), 2)
# 根据给定的(x,y)坐标标识出人名
def draw_text(img, text, x, y):
 cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)
#建立标签与人名的映射列表(标签只能为整数)
subjects = ["jiaju", "jiaqiang"]

5.现在就可以定义我们的预测函数了:

# 此函数识别传递的图像中的人物并在检测到的脸部周围绘制一个矩形及其名称
def predict(test_img):
 #生成图像的副本,这样就能保留原始图像
 img = test_img.copy()
 #检测人脸
 face, rect = detect_face(img)
 #预测人脸
 label = face_recognizer.predict(face)
 # 获取由人脸识别器返回的相应标签的名称
 label_text = subjects[label[0]]
 # 在检测到的脸部周围画一个矩形
 draw_rectangle(img, rect)
 # 标出预测的名字
 draw_text(img, label_text, rect[0], rect[1] - 5)
 #返回预测的图像
 return img

6.最后使用我们test_data中的图片进行预测并显示最终效果:

#加载测试图像
test_img1 = cv2.imread("test_data/test1.jpg")
test_img2 = cv2.imread("test_data/test2.jpg")
#执行预测
predicted_img1 = predict(test_img1)
predicted_img2 = predict(test_img2)
#显示两个图像
cv2.imshow(subjects[0], predicted_img1)
cv2.imshow(subjects[1], predicted_img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

来看看识别的结果:

Python基于Opencv来快速实现人脸识别过程详解(完整版)

这就是人脸识别最基本的流程,后续还会进一步的研究,下一篇我们将讨论本次实验的一些细节和注意事项,算是对本篇的一次挖掘和总结吧。

最后附上完整代码:

# # -*- coding:utf-8 -*-
import cv2
import os
import numpy as np
# 检测人脸
def detect_face(img):
 #将测试图像转换为灰度图像,因为opencv人脸检测器需要灰度图像
 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 #加载OpenCV人脸检测分类器Haar
 face_cascade = cv2.CascadeClassifier('./haarcascade_frontalface_default.xml')
 #检测多尺度图像,返回值是一张脸部区域信息的列表(x,y,宽,高)
 faces = face_cascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5)
 # 如果未检测到面部,则返回原始图像
 if (len(faces) == 0):
 return None, None
 #目前假设只有一张脸,xy为左上角坐标,wh为矩形的宽高
 (x, y, w, h) = faces[0]
 #返回图像的正面部分
 return gray[y:y + w, x:x + h], faces[0]
# 该函数将读取所有的训练图像,从每个图像检测人脸并将返回两个相同大小的列表,分别为脸部信息和标签
def prepare_training_data(data_folder_path):
 # 获取数据文件夹中的目录(每个主题的一个目录)
 dirs = os.listdir(data_folder_path)
 # 两个列表分别保存所有的脸部和标签
 faces = []
 labels = []
 # 浏览每个目录并访问其中的图像
 for dir_name in dirs:
 # dir_name(str类型)即标签
 label = int(dir_name)
 # 建立包含当前主题主题图像的目录路径
 subject_dir_path = data_folder_path + "/" + dir_name
 # 获取给定主题目录内的图像名称
 subject_images_names = os.listdir(subject_dir_path)
 # 浏览每张图片并检测脸部,然后将脸部信息添加到脸部列表faces[]
 for image_name in subject_images_names:
 # 建立图像路径
 image_path = subject_dir_path + "/" + image_name
 # 读取图像
 image = cv2.imread(image_path)
 # 显示图像0.1s
 cv2.imshow("Training on image...", image)
 cv2.waitKey(100)
 # 检测脸部
 face, rect = detect_face(image)
 # 我们忽略未检测到的脸部
 if face is not None:
 #将脸添加到脸部列表并添加相应的标签
 faces.append(face)
 labels.append(label)
 cv2.waitKey(1)
 cv2.destroyAllWindows()
 #最终返回值为人脸和标签列表
 return faces, labels
#调用prepare_training_data()函数
faces, labels = prepare_training_data("training_data")
#创建LBPH识别器并开始训练,当然也可以选择Eigen或者Fisher识别器
face_recognizer = cv2.face.LBPHFaceRecognizer_create()
face_recognizer.train(faces, np.array(labels))
#根据给定的(x,y)坐标和宽度高度在图像上绘制矩形
def draw_rectangle(img, rect):
 (x, y, w, h) = rect
 cv2.rectangle(img, (x, y), (x + w, y + h), (128, 128, 0), 2)
# 根据给定的(x,y)坐标标识出人名
def draw_text(img, text, x, y):
 cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)
#建立标签与人名的映射列表(标签只能为整数)
subjects = ["jiaju", "jiaqiang"]
# 此函数识别传递的图像中的人物并在检测到的脸部周围绘制一个矩形及其名称
def predict(test_img):
 #生成图像的副本,这样就能保留原始图像
 img = test_img.copy()
 #检测人脸
 face, rect = detect_face(img)
 #预测人脸
 label = face_recognizer.predict(face)
 # 获取由人脸识别器返回的相应标签的名称
 label_text = subjects[label[0]]
 # 在检测到的脸部周围画一个矩形
 draw_rectangle(img, rect)
 # 标出预测的名字
 draw_text(img, label_text, rect[0], rect[1] - 5)
 #返回预测的图像
 return img
#加载测试图像
test_img1 = cv2.imread("test_data/test1.jpg")
test_img2 = cv2.imread("test_data/test2.jpg")
#执行预测
predicted_img1 = predict(test_img1)
predicted_img2 = predict(test_img2)
#显示两个图像
cv2.imshow(subjects[0], predicted_img1)
cv2.imshow(subjects[1], predicted_img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 爬取微信文章
Jan 30 Python
Python使用ntplib库同步校准当地时间的方法
Jul 02 Python
Python 中开发pattern的string模板(template) 实例详解
Apr 01 Python
Python smtplib实现发送邮件功能
May 22 Python
Python数据结构之栈、队列及二叉树定义与用法浅析
Dec 27 Python
Python基本数据结构与用法详解【列表、元组、集合、字典】
Mar 23 Python
Python中输入和输出(打印)数据实例方法
Oct 13 Python
python+opencv边缘提取与各函数参数解析
Mar 09 Python
基于python实现获取网页图片过程解析
May 11 Python
python利用proxybroker构建爬虫免费IP代理池的实现
Feb 21 Python
实例讲解Python中sys.argv[]的用法
Jun 03 Python
Python制作动态字符画的源码
Aug 04 Python
python 利用浏览器 Cookie 模拟登录的用户访问知乎的方法
Jul 11 #Python
PowerBI和Python关于数据分析的对比
Jul 11 #Python
pow在python中的含义及用法
Jul 11 #Python
Python简单处理坐标排序问题示例
Jul 11 #Python
如何使用Python自动控制windows桌面
Jul 11 #Python
python字典嵌套字典的情况下找到某个key的value详解
Jul 10 #Python
如何安装并使用conda指令管理python环境
Jul 10 #Python
You might like
PHP 和 MySQL 基础教程(二)
2006/10/09 PHP
在Windows下编译适用于PHP 5.2.12及5.2.13的eAccelerator.dll(附下载)
2010/05/04 PHP
php压缩多个CSS为一个css的代码并缓存
2011/04/21 PHP
php实现数组筛选奇数和偶数示例
2014/04/11 PHP
[原创]ThinkPHP中SHOW_RUN_TIME不能正常显示运行时间的解决方法
2015/10/10 PHP
分享一个漂亮的php验证码类
2016/09/29 PHP
PHP优化之批量操作MySQL实例分析
2020/04/23 PHP
HTML页面如何象ASP一样接受参数
2007/02/07 Javascript
关于js日期转化为毫秒数“节省20%的效率和和节省9个字符“问题
2012/03/01 Javascript
jquery+css实现的红色线条横向二级菜单效果
2015/08/22 Javascript
简单实现的JQuery文本框水印插件
2016/06/14 Javascript
基于JavaScript实现本地图片预览
2017/02/08 Javascript
如何在AngularJs中调用第三方插件库
2017/05/21 Javascript
微信web端后退强制刷新功能的实现代码
2018/03/04 Javascript
微信小程序地图实现展示线路
2020/07/29 Javascript
关于vue 结合原生js 解决echarts resize问题
2020/07/26 Javascript
Python基于checksum计算文件是否相同的方法
2015/07/09 Python
Python实现基本线性数据结构
2016/08/22 Python
Python爬虫实现爬取京东手机页面的图片(实例代码)
2017/11/30 Python
Python实现简单求解给定整数的质因数算法示例
2018/03/25 Python
mac安装scrapy并创建项目的实例讲解
2018/06/13 Python
Python计算开方、立方、圆周率,精确到小数点后任意位的方法
2018/07/17 Python
2020版Python学习路线图(附学习资料)
2020/09/15 Python
Python中的面向接口编程示例详解
2021/01/17 Python
详解如何在css3打包后自动追加前缀插件:autoprefixer
2018/12/18 HTML / CSS
我未来的职业规划范文
2014/01/11 职场文书
大学校园生活自我鉴定
2014/01/13 职场文书
嘉宾邀请函
2015/01/31 职场文书
大学生自我推荐信范文
2015/03/24 职场文书
胡桃夹子观后感
2015/06/11 职场文书
钢铁是怎样炼成的读书笔记
2015/06/29 职场文书
2015小学毕业班工作总结
2015/07/21 职场文书
员工聘用合同范本
2015/09/21 职场文书
史上最全书信经典范文大全(建议收藏)
2019/07/10 职场文书
2019奶茶店创业计划书范本!
2019/07/15 职场文书
Vue深入理解插槽slot的使用
2022/08/05 Vue.js