python中使用Opencv进行人脸识别
上一节讲到人脸检测,现在讲一下人脸识别。具体是通过程序采集图像并进行训练,并且基于这些训练的图像对人脸进行动态识别。
人脸识别前所需要的人脸库可以通过两种方式获得:1.自己从视频获取图像 2.从人脸数据库免费获得可用人脸图像,如ORL人脸库(包含40个人每人10张人脸,总共400张人脸),ORL人脸库中的每一张图像大小为92x112。若要对这些样本进行人脸识别必须要在包含人脸的样本图像上进行人脸识别。这里提供自己准备图像识别出自己的方法。
1.采集人脸信息:通过摄像头采集人脸信息,10张以上即可,把图像大小调整为92x112,保存在一个指定的文件夹,文件名后缀为.png
def generator(data):
'''
打开摄像头,读取帧,检测该帧图像中的人脸,并进行剪切、缩放
生成图片满足以下格式:
1.灰度图,后缀为 .png
2.图像大小相同
params:
data:指定生成的人脸数据的保存路径
''' name=input('my name:')
#如果路径存在则删除路径
path=os.path.join(data,name)
if os.path.isdir(path):
shutil.rmtree(path)
#创建文件夹
os.mkdir(path)
#创建一个级联分类器
face_casecade=cv2.CascadeClassifier('../haarcascades/haarcascade_frontalface_default.xml')
#打开摄像头
camera=cv2.VideoCapture(0)
cv2.namedWindow('Dynamic')
#计数
count=1 while(True):
#读取一帧图像
ret,frame=camera.read()
if ret:
#转换为灰度图
gray_img=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#人脸检测
face=face_casecade.detectMultiScale(gray_img,1.3,5)
for (x,y,w,h) in face:
#在原图上绘制矩形
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
#调整图像大小
new_frame=cv2.resize(frame[y:y+h,x:x+w],(92,112))
#保存人脸
cv2.imwrite('%s/%s.png'%(path,str(count)),new_frame)
count+=1
cv2.imshow('Dynamic',frame)
#按下q键退出
if cv2.waitKey(100) & 0xff==ord('q'):
break
camera.release()
cv2.destroyAllWindows()
该程序运行后会在指定的data路径下创建一个你输入的人名的文件夹用于存放采集到的图像,在这里我输入了wjy,结果如图

2.人脸识别
OpenCV有3中人脸识别方法,分别基于三个不同算法,分别为Eigenfaces,Fisherfaces和Local Binary Pattern Histogram
这些方法都有类似的一个过程,即先对数据集进行训练,对图像或视频中的人脸进行分析,并且从两个方面确定:1.是否识别到对应的目标,2.识别到的目标的置信度,在实际中通过阈值进行筛选,置信度高于阈值的人脸将被丢弃
这里介绍一下利用特征脸即Eigenfaces进行人脸识别算法,特征脸法本质上就是PCA降维,基本思路是先把图像灰度化,转化为单通道,再将它首位相接转换为列向量,假设图像的大小是20*20的,那么这个向量就是400维,但是维度太高算法复杂度也会升高,所以需要降维,再使用简单排序即可
#载入图像 读取ORL人脸数据库,准备训练数据
def LoadImages(data):
'''
加载图片数据用于训练
params:
data:训练数据所在的目录,要求图片尺寸一样
ret:
images:[m,height,width] m为样本数,height为高,width为宽
names:名字的集合
labels:标签
'''
images=[]
names=[]
labels=[] label=0 #遍历所有文件夹
for subdir in os.listdir(data):
subpath=os.path.join(data,subdir)
#print('path',subpath)
#判断文件夹是否存在
if os.path.isdir(subpath):
#在每一个文件夹中存放着一个人的许多照片
names.append(subdir)
#遍历文件夹中的图片文件
for filename in os.listdir(subpath):
imgpath=os.path.join(subpath,filename)
img=cv2.imread(imgpath,cv2.IMREAD_COLOR)
gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#cv2.imshow('1',img)
#cv2.waitKey(0)
images.append(gray_img)
labels.append(label)
label+=1
images=np.asarray(images)
#names=np.asarray(names)
labels=np.asarray(labels)
return images,labels,names #检验训练结果
def FaceRec(data):
#加载训练的数据
X,y,names=LoadImages(data)
#print('x',X)
model=cv2.face.EigenFaceRecognizer_create()
model.train(X,y) #打开摄像头
camera=cv2.VideoCapture(0)
cv2.namedWindow('Dynamic') #创建级联分类器
face_casecade=cv2.CascadeClassifier('../haarcascades/haarcascade_frontalface_default.xml') while(True):
#读取一帧图像
#ret:图像是否读取成功
#frame:该帧图像
ret,frame=camera.read()
#判断图像是否读取成功
#print('ret',ret)
if ret:
#转换为灰度图
gray_img=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) #利用级联分类器鉴别人脸
faces=face_casecade.detectMultiScale(gray_img,1.3,5) #遍历每一帧图像,画出矩形
for (x,y,w,h) in faces:
frame=cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2) #蓝色
roi_gray=gray_img[y:y+h,x:x+w] try:
#将图像转换为宽92 高112的图像
#resize(原图像,目标大小,(插值方法)interpolation=,)
roi_gray=cv2.resize(roi_gray,(92,112),interpolation=cv2.INTER_LINEAR)
params=model.predict(roi_gray)
print('Label:%s,confidence:%.2f'%(params[0],params[1]))
'''
putText:给照片添加文字
putText(输入图像,'所需添加的文字',左上角的坐标,字体,字体大小,颜色,字体粗细)
'''
cv2.putText(frame,names[params[0]],(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,1,255,2)
except:
continue cv2.imshow('Dynamic',frame) #按下q键退出
if cv2.waitKey(100) & 0xff==ord('q'):
break
camera.release()
cv2.destroyAllWindows()
在程序中,我们用cv2.face.EigenFaceRecognizer_create()创建人脸识别的模型,通过图像数组和对应标签数组来训练模型,该函数有两个重要的参数,1.保留主成分的数目,2.指定的置信度阈值,为一个浮点型。
下面就是基本重复人脸检测的相关操作,通过检测到视频中的人脸进行人脸识别,有如下两个步骤:
1.将检测到的人脸图像调整为92x112,即需要和训练的图像的尺寸相同
2.调用predict()函数进行人脸预测,该函数会返回两个元素的数组,第一个是识别个体的标签,第二个是置信度,越小匹配度越高,0表示完全匹配,需要了解的是不同算法的置信度评分机制不同。
附上结果图

这里附上全部源代码“
# -*- coding: utf-8 -*-
"""
Created on Sat Oct 27 11:43:47 2018 @author: Administrator
""" '''
调用opencv的库实现人脸识别
''' import cv2
import numpy as np
import os
import shutil #采集自己的人脸数据
def generator(data):
'''
打开摄像头,读取帧,检测该帧图像中的人脸,并进行剪切、缩放
生成图片满足以下格式:
1.灰度图,后缀为 .png
2.图像大小相同
params:
data:指定生成的人脸数据的保存路径
''' name=input('my name:')
#如果路径存在则删除路径
path=os.path.join(data,name)
if os.path.isdir(path):
shutil.rmtree(path)
#创建文件夹
os.mkdir(path)
#创建一个级联分类器
face_casecade=cv2.CascadeClassifier('../haarcascades/haarcascade_frontalface_default.xml')
#打开摄像头
camera=cv2.VideoCapture(0)
cv2.namedWindow('Dynamic')
#计数
count=1 while(True):
#读取一帧图像
ret,frame=camera.read()
if ret:
#转换为灰度图
gray_img=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
#人脸检测
face=face_casecade.detectMultiScale(gray_img,1.3,5)
for (x,y,w,h) in face:
#在原图上绘制矩形
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
#调整图像大小
new_frame=cv2.resize(frame[y:y+h,x:x+w],(92,112))
#保存人脸
cv2.imwrite('%s/%s.png'%(path,str(count)),new_frame)
count+=1
cv2.imshow('Dynamic',frame)
#按下q键退出
if cv2.waitKey(100) & 0xff==ord('q'):
break
camera.release()
cv2.destroyAllWindows() #载入图像 读取ORL人脸数据库,准备训练数据
def LoadImages(data):
'''
加载图片数据用于训练
params:
data:训练数据所在的目录,要求图片尺寸一样
ret:
images:[m,height,width] m为样本数,height为高,width为宽
names:名字的集合
labels:标签
'''
images=[]
names=[]
labels=[] label=0 #遍历所有文件夹
for subdir in os.listdir(data):
subpath=os.path.join(data,subdir)
#print('path',subpath)
#判断文件夹是否存在
if os.path.isdir(subpath):
#在每一个文件夹中存放着一个人的许多照片
names.append(subdir)
#遍历文件夹中的图片文件
for filename in os.listdir(subpath):
imgpath=os.path.join(subpath,filename)
img=cv2.imread(imgpath,cv2.IMREAD_COLOR)
gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#cv2.imshow('1',img)
#cv2.waitKey(0)
images.append(gray_img)
labels.append(label)
label+=1
images=np.asarray(images)
#names=np.asarray(names)
labels=np.asarray(labels)
return images,labels,names #检验训练结果
def FaceRec(data):
#加载训练的数据
X,y,names=LoadImages(data)
#print('x',X)
model=cv2.face.EigenFaceRecognizer_create()
model.train(X,y) #打开摄像头
camera=cv2.VideoCapture(0)
cv2.namedWindow('Dynamic') #创建级联分类器
face_casecade=cv2.CascadeClassifier('../haarcascades/haarcascade_frontalface_default.xml') while(True):
#读取一帧图像
#ret:图像是否读取成功
#frame:该帧图像
ret,frame=camera.read()
#判断图像是否读取成功
#print('ret',ret)
if ret:
#转换为灰度图
gray_img=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) #利用级联分类器鉴别人脸
faces=face_casecade.detectMultiScale(gray_img,1.3,5) #遍历每一帧图像,画出矩形
for (x,y,w,h) in faces:
frame=cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2) #蓝色
roi_gray=gray_img[y:y+h,x:x+w] try:
#将图像转换为宽92 高112的图像
#resize(原图像,目标大小,(插值方法)interpolation=,)
roi_gray=cv2.resize(roi_gray,(92,112),interpolation=cv2.INTER_LINEAR)
params=model.predict(roi_gray)
print('Label:%s,confidence:%.2f'%(params[0],params[1]))
'''
putText:给照片添加文字
putText(输入图像,'所需添加的文字',左上角的坐标,字体,字体大小,颜色,字体粗细)
'''
cv2.putText(frame,names[params[0]],(x,y-20),cv2.FONT_HERSHEY_SIMPLEX,1,255,2)
except:
continue cv2.imshow('Dynamic',frame) #按下q键退出
if cv2.waitKey(100) & 0xff==ord('q'):
break
camera.release()
cv2.destroyAllWindows() if __name__=='__main__':
data='./face'
#generator(data)
FaceRec(data)
2018.10.28
python中使用Opencv进行人脸识别的更多相关文章
- OpenCV-Python(1)在Python中使用OpenCV进行人脸检测
OpenCV是如今最流行的计算机视觉库,而我们今天就是要学习如何安装使用OpenCV,以及如何去访问我们的摄像头.然后我们一起来看看写一个人脸检测程序是如何地简单,简单到只需要几行代码. 在开始之前, ...
- python中使用Opencv进行人脸检测
这两天学习了人脸识别,看了学长写的代码,边看边码边理解搞完了一边,再又是自己靠着理解和记忆硬码了一边,感觉还是很生疏,就只能来写个随笔加深一下印象了. 关于人脸识别,首先需要了解的是级联分类器Casc ...
- 转:基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴等)【模式识别中的翘楚】
文章来自于:http://blog.renren.com/share/246648717/8171467499 基于开源项目OpenCV的人脸识别Demo版整理(不仅可以识别人脸,还可以识别眼睛鼻子嘴 ...
- 使用OpenCV进行人脸识别
不断维护的地址:http://plzcoding.com/face-recognition-with-opencv/ 怎样使用OpenCV进行人脸识别 本文大部分来自OpenCV官网上的Face Re ...
- 基于 OpenCV 的人脸识别
基于 OpenCV 的人脸识别 一点背景知识 OpenCV 是一个开源的计算机视觉和机器学习库.它包含成千上万优化过的算法,为各种计算机视觉应用提供了一个通用工具包.根据这个项目的关于页面,OpenC ...
- PyQt5+Caffe+Opencv搭建人脸识别登录界面
PyQt5+Caffe+Opencv搭建人脸识别登录界面(转载) 最近开始学习Qt,结合之前学习过的caffe一起搭建了一个人脸识别登录系统的程序,新手可能有理解不到位的情况,还请大家多多指教. 我的 ...
- opencv+opencv_contrib 人脸识别和检测 python开发环境快速搭建(30分钟)图文教程
很多朋友为了学习python.ML(机器学习).DL(深度学习).opencv等花费了大量时间配置安装环境(一个朋友花了4天时间才配置好)各种搜索.下载.安装配置,出问题等. 市面上的配置资料很多,选 ...
- python之OpenCv(四)---人脸识别
对特定图像进行识别,最关键的是要有识别对象的特征文件.OpenCV已经内置了人脸识别特征文件,我们只要使用OpenCV的CascadeClassifier类即可进行识别. 语法: https://gi ...
- python基于OpenCV的人脸识别系统
想获得所有的代码,请下载(来自我的CSDN): https://download.csdn.net/download/qq_40875849/11292912 主函数: from recognitio ...
随机推荐
- 关于Spring IOC (DI-依赖注入)
<Spring入门经典>这本书无论对于初学者或者有经验的工程师还是很值一看的,最近花了点时间回顾了Spring的内容,在此顺带记录一下,本篇主要与spring IOC相关 ,这篇博文适合初 ...
- 【Spring学习笔记-MVC-1.1--】@PathVariable与@RequestParam、@CookieValue等比较
作者:ssslinppp 1. 摘要 本文结构如下: 2. @RequestMapping 通配符方式: 3. @PathVariable URL请求时,使用占位符: 4. @Reques ...
- bzoj2656 数列
Description 小白和小蓝在一起上数学课,下课后老师留了一道作业,求下面这个数列的通项公式: A[0]=0 A[1]=1 A[2n]=A[n] A[2n+1]=A[n]+A[n+1] 小白作为 ...
- -Java-Runoob-高级教程-实例-数组:09. Java 实例 – 数组扩容
ylbtech-Java-Runoob-高级教程-实例-数组:09. Java 实例 – 数组扩容 1.返回顶部 1. Java 实例 - 数组扩容 Java 实例 以下实例演示了如何在数组初始化后 ...
- Jmeter接口压测
对于各个组件的使用,建议参考官方文档 1. Jmeter参数化,从txt文件读取. 1.txt
- php array_flip() 删除数组重复元素——大彻大悟
1. php array_flip() 删除数组重复元素,如果用于一维索引数组,好理解. [root@BG-DB:~]$more arr.php <?php $arr = ar ...
- EC20模块(mdm9607)复用pin脚当作普通gpio的设置方法
修改pin37~40,当作普通gpio的方法如下: 下面代码截图需要确认是否一样,如不一样请修改: 修改pin41~42 ,当作普通gpio方法如下: Pin24~27,当作普通gpio方法如下: P ...
- win10的坑之wifi找不到
安装了win10一周以来,win10的坑太多太多,微软搞什么pc/mobile二合一,真是脑残行为. 首先是usb设备无缘无故找不到,据说是和杀毒软件/防火墙有关,后来是关掉了windows defe ...
- 【Linux_Unix系统编程】chapter7 内存分配
Chapter7 内存分配本章将用于在堆或者栈上分配内存的函数.7.1 在堆上分配内存 通常将堆的当前的内存边界称为"program break" 7.1.1 调整program ...
- mongodb中查询返回指定字段
mongodb中查询返回指定字段 在写vue项目调用接口获取数据的时候,比如新闻列表页我只需要显示新闻标题和发表时间,点击每条新闻进入详情页的时候才会需要摘要.新闻内容等关于此条新闻的所有字段. ...