首先给大家推荐一本书:机器学习算法原理与编程实践

本文内容全部转载于书中,相当于一个读书笔记了吧

绪论

1992年麻省理工学院通过实验对比了基于结构特征的方法与基于模版匹配的方法,发现模版匹配的方法要优于基于特征的方法。

以支持向量机为代表的统计学习理论在随后被应用到了人脸识别与确认中去。但是由于算法运行效率问题,很快被一种新的算法替代了。这就是2001年康柏研究院提出的基于简单矩形特征和AdaBoost的实时人脸检测系统。该方法的主要贡献包括:
1.可以快速计算简单矩形特征作为人脸图像特征
2.基于AdaBoost将大量弱分类器进行组合形成强分类器的学习方法。
3.采用了级联(Cascade)技术提高检测速度。目前,基于这种人脸/非人脸学习的策略已经能够实现准实时的多姿态人脸检测与跟踪,这为后端的人脸识别提供了良好的基础。

人脸检测

人脸检测主要用于人脸识别的预处理,即在图像中标注出人脸所处的位置和大小。为了能够确定图片中包含一张或几张人脸,首先要确定人脸的通用结构。我们都有:眼镜、鼻子,前额,颧骨和嘴,所有这些构成了一张通用的人脸结构。下图的特征组件分别标识了上述结构。

组合这些特征就可以得到一张近似的人脸:

人脸检测的主流方法是AdaBoost,它是一种用来分类的方法,通过把一些比较弱的分类方法合在一起,可以组合出新的更强的分类器。AdaBoost有一个迭代的过程,为了快速处理,在每次迭代中,我们仅仅快速地排除图片中不属于人脸的区域,保留那些我们还不确定的区域。在每次迭代中,我们都提高了对图片中人脸定位的概率,直到做出最终的决定。换句话说,不同于确定图片中人脸的位置,我们选择的排除图片中不包含人脸位置,因为排除算法的运算速度更快。我们称这个过程为级联过程。
OpenCV中常用的特征分类器有两类:Haar特征和LBP特征

在OpenCV中使用Haar特征检测人脸,那么需要使用OpenCV提供的xml文件(级联表)在sources\data目录下。这张级联表有一个训练好的AdaBoost训练集。首先要采用样本的Haar特征训练分类器,从而得到一个级联的AdaBoost分类器。训练的方式包含两个方面:
1.正例样本,即待检测的目标样本
2.反例样本,即其他任意的图片
然后将这些图片统一缩放为相同的尺寸,这个过程就是归一化。最后统计出分类结果。

实现效果:

代码:

# -*- coding: utf-8 -*-
"""
Created on Wed Jun 22 20:59:21 2016@author: Administrator
"""# -*- coding: utf-8 -*import numpy as np
import cv2
#要使用Haar cascade实现,仅需要把库修改为lbpcascade_frontalface.xml
face_cascade = cv2.CascadeClassifier('lbpcascade_frontalface.xml')img = cv2.imread('woman.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 识别输入图片中的人脸对象.返回对象的矩形尺寸
# 函数原型detectMultiScale(gray, 1.2,3,CV_HAAR_SCALE_IMAGE,Size(30, 30))
# gray需要识别的图片
# 1.03:表示每次图像尺寸减小的比例
# 5:表示每一个目标至少要被检测到4次才算是真的目标(因为周围的像素和不同的窗口大小都可以检测到人脸)
# CV_HAAR_SCALE_IMAGE表示不是缩放分类器来检测,而是缩放图像,Size(30, 30)为目标的最小最大尺寸
# faces:表示检测到的人脸目标序列
faces = face_cascade.detectMultiScale(gray, 1.03, 5)
for (x,y,w,h) in faces:if w+h>200:#//针对这个图片画出最大的外框img2 = cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),4)roi_gray = gray[y:y+h, x:x+w]roi_color = img[y:y+h, x:x+w]cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite("head.jpg", img) # 保存图片

AdaBoost算法概述

Haar级联检测和LBP检测都是使用AdaBoost算法实现的。AdaBoost算法是Adaptive Boosting算法的缩写,是Boosting算法的改进版本。AdaBoost与其前身Boost算法都是从决策树发展出来的一种算法,其算法思想是针对同一个训练集样本的不同特征,分别训练出不同的弱分类器,然后把这些弱分类器级联起来,构成一个最终分类器,即强分类器。
从结构上讲,AdaBoost与其他的机器学习算法不同,该算法可以分为两层,第一层是AdaBoost主算法,第二层是其他的二分类算法,所以该算法是一种复合型算法。第二层最常用的是单层决策树。当然也可以是其他任何二分类算法。例如梯度下降算法、SVM等。

人脸识别

目前最常用的自动人脸识别技术仍旧是特征脸提取方法。特征脸方法是从整体上对人脸识别的方法:一种面部图像可以表示为从高维图像空间映射到地位空间的一个点。这样可以使得分类边的更加容易。

降维

一幅图像只能表示为一个对象,对于w x h的灰度图像,只能表示为w*h维的向量,那么100*100像素大小的图像就需要10000维的向量空间。对于一副人脸图像,显然在维数空间中只有少量像素对我们有用。所以可以降维,矩阵可以近似的表示为一个特征值和特征向量的乘积,如果我们能够提取出高维向量中某些特有的特征或者相关变量,就能用一个低维空间的向量近似地表示这个高维向量。对于这个高维向量,只有高喊最多信息的那些维上的数据才有意义,不重要的维可以在计算中忽略,并且降维之后的低维向量不会损失掉特征间的差异性。这就是主成份分析的思想(PCA),1901年就由皮尔逊发布了基本原理:

PCA人脸识别算法

PCA人脸识别算法的实现步骤如下:
1.首先把所有的训练图片集的每张图片都转换为行向量的形式
2.计算向量集的PCA子空间,并得到特征值和特征向量及均值
3.将训练集的图片与对应的标签都投影到这个PCA子空间,行程一个投影矩阵
4.导入待识别的图像,并进行向量化,也投影到这个PCA子空间
5.计算PCA投影后的训练集向量与待识别图片投影后向量的距离,并找出最接近的那个

# -*- coding: utf-8 -*-
from numpy import *
import numpy as np
import sys,os
import copy
import cv2
import PIL.Image as Image
import matplotlib.pyplot as plt  class Eigenfaces(object):def __init__(self):self.eps = 1.0e-16self.X = []self.y = []self.Mat=[]self.eig_v = 0self.eig_vect = 0self.mu = 0self.projections = []self.dist_metric=0def loadimgs(self,path): # 加载图片数据集classlabel = 0for dirname, dirnames, filenames in os.walk(path):for subdirname in dirnames:sub_path = os.path.join(dirname, subdirname)for filename in os.listdir(sub_path):im = Image.open(os.path.join(sub_path, filename))im = im.convert("L") #数据转换为long类型self.X.append(np.asarray(im, dtype=np.uint8))self.y.append(classlabel)classlabel += 1 # 将图片变为行向量  # 生成图片矩阵def genRowMatrix(self):self.Mat = np.empty((0, self.X[0].size), dtype=self.X[0].dtype)for row in self.X:self.Mat = np.vstack((self.Mat, np.asarray(row).reshape(1,-1)))# 计算特征脸def PCA(self, pc_num =0):self.genRowMatrix() [n,d] = shape(self.Mat)if ( pc_num <= 0) or ( pc_num>n):       pc_num = nself.mu = self.Mat.mean(axis =0)self.Mat -= self.muif n>d:XTX = np.dot (self.Mat.T,self.Mat)[ self.eig_v , self.eig_vect ] = linalg.eigh (XTX)else :XTX = np.dot(self.Mat,self.Mat.T)[ self.eig_v , self.eig_vect ] = linalg.eigh (XTX)self.eig_vect = np.dot(self.Mat.T, self.eig_vect)for i in xrange(n):self.eig_vect[:,i] = self.eig_vect[:,i]/linalg.norm(self.eig_vect[:,i])idx = np.argsort(-self.eig_v)self.eig_v = self.eig_v[idx]self.eig_vect = self.eig_vect[:,idx ]       self.eig_v = self.eig_v[0:pc_num ].copy () # select only pc_numself.eig_vect = self.eig_vect[:,0:pc_num].copy ()def compute(self):self.PCA()for xi in self.X:self.projections.append(self.project(xi.reshape(1,-1))) def distEclud(self, vecA, vecB):  # 欧氏距离return linalg.norm(vecA-vecB)+self.eps def cosSim(self, vecA, vecB):    # 夹角余弦 return (dot(vecA,vecB.T)/((linalg.norm(vecA)*linalg.norm(vecB))+self.eps))[0,0]# 映射def project(self,XI):if self.mu is None: return np.dot(XI,self.eig_vect)return np.dot(XI-self.mu, self.eig_vect)    #预测最接近的特征脸def predict(self,XI):minDist = np.finfo('float').maxminClass = -1Q = self.project(XI.reshape(1,-1))for i in xrange(len(self.projections)):dist = self.dist_metric(self.projections[i], Q)if dist < minDist:minDist = distminClass = self.y[i]return minClass# 生成特征脸def subplot(self,title, images):fig = plt.figure()fig.text(.5, .95, title, horizontalalignment='center') for i in xrange(len(images)):ax0 = fig.add_subplot(4,4,(i+1))plt.imshow(asarray(images[i]), cmap="gray")plt.xticks([]), plt. yticks([]) # 隐藏 X Y 坐标plt.show()# 归一化def normalize(self, X, low, high, dtype=None):X = np.asarray(X)minX, maxX = np.min(X), np.max(X)X = X - float(minX)X = X / float((maxX - minX))X = X * (high-low)X = X + lowif dtype is None:return np.asarray(X)return np.asarray(X, dtype=dtype)
'''     # 重构def reconstruct(self,W, Y, mu=None):if mu is None:  return np.dot(Y,W.T)return np.dot(Y, W.T) + mu# 从外部数据计算投影def out_project(self,W,XI,mu):if mu is None:  return np.dot(XI,W)return np.dot(XI-mu, W)
'''

生成特征脸:


代码:

# -*- coding: utf-8 -*-from numpy import *
import sys,os
from pca import *reload(sys)
sys.setdefaultencoding('utf-8')ef = Eigenfaces()
ef.dist_metric=ef.distEclud
ef.loadimgs("orl_faces/")
ef.compute()
E = []
X = mat(zeros((10,10304)))
for i in xrange(16):X = ef.Mat[i*10:(i+1)*10,:].copy()# X = ef.normalize(X.mean(axis =0),0,255)X = X.mean(axis =0)imgs = X.reshape(112,92)E.append(imgs)
ef.subplot(title="AT&T Eigen Facedatabase", images=E)  

执行人脸识别:

from numpy import *
import sys,os
from pca import *reload(sys)
sys.setdefaultencoding('utf-8')ef = Eigenfaces()
ef.dist_metric=ef.distEclud
ef.loadimgs("orl_faces/")
ef.compute()
# 创建测试集
testImg = ef.X[30]
print "实际值 =", ef.y[30], "->", "预测值 =",ef.predict(testImg)

待续。。。

代码下载:

http://download.csdn.net/detail/wangyaninglm/9555895

参考文献

机器学习算法原理与编程实践

OpenCV+python 人脸识别相关推荐

  1. opencv python 人脸识别 相似度_OpenCV+Tensorflow实现实时人脸识别演示

    原标题:OpenCV+Tensorflow实现实时人脸识别演示 Facenet网络介绍 FaceNet是谷歌提出的人脸识别模型,它跟其他人脸识别模型最大的一个不同就是它不是一个中间层输出,而是直接在欧 ...

  2. OpenCV Python 人脸识别签到系统(超详细注释)

    文章目录 前言 1.1 具体功能描述 1.2 使用注意事项 2.1 具体代码实现 2.1.1 视频截取人脸代码 2.1.2 人脸识别代码 总结 前言 代码实现并不难,个人觉得本项目最大的难点在装库上, ...

  3. python人脸识别截图_Python OpenCV调用摄像头检测人脸并截图

    本文实例为大家分享了Python OpenCV调用摄像头检测人脸并截图的具体代码,供大家参考,具体内容如下 注意:需要在python中安装OpenCV库,同时需要下载OpenCV人脸识别模型haarc ...

  4. python使用opencv实现人脸识别系统

    1.首先安装过python环境,在这里就不过说    检测是否安装成功如下,在cmd中输入Python     2.安装numpy 现在开始安装numpy,打开cmd,输入pip install nu ...

  5. Python人脸识别黑科技(二):教你使用python+Opencv完成人脸解锁

    继上一篇"Python人脸识别黑科技(一):50行代码运用Python+OpenCV实现人脸追踪+详细教程+快速入门+图像识",那么今天我们来讲关于使用python+opencv+ ...

  6. 【优秀课设】基于OpenCV的Python人脸识别、检测、框选(遍历目录下所有照片依次识别 视频随时标注)

    基于OpenCV的Python人脸识别.检测.框选 (遍历目录下所有照片依次识别 视频随时标注) 移步: https://blog.csdn.net/weixin_53403301/article/d ...

  7. python人脸识别门禁_Python+Opencv+Tkinter指纹识别与人脸识别的门禁兼考勤(一)

    一.设计目标:旨在PC端上搭建一款具有指纹识别与人脸识别功能的门禁兼考勤系统.该系统同时具备普通用户模式.管理员模式与超级管理员模式,下面具体介绍每种模式下的功能. 1)普通用户模式 该模式可分为收集 ...

  8. python人脸识别考勤系统 dlib+OpenCV和Pyqt5、数据库sqlite 人脸识别系统 计算机 毕业设计 源码

    一.项目介绍 Python语言.dlib.OpenCV.Pyqt5界面设计.sqlite3数据库 本系统使用dlib作为人脸识别工具,dlib提供一个方法可将人脸图片数据映射到128维度的空间向量,如 ...

  9. Python基于OpenCV的人脸识别自助商店(源码&部署视频)

    1.模块功能介绍 实现人脸识别模块.人脸登录与注册功能.商店显示和用户余额页显示功能 用GUl图形界面实现(pyqt)语言python windows下软件pycharm 1.用户登录模块:刷脸登录 ...

最新文章

  1. spark1.4加载mysql数据 创建Dataframe及join操作连接方法问题
  2. 通知:正式迁移至新博客
  3. GitHub遭炮轰:Copilot“抄袭”已经失控,为训练AI侵权整个社区
  4. git add --all 为啥不能添加空文件夹,这样设计的初衷是
  5. golang 文件 文件夹 创建 读取 移动 复制 写入 遍历
  6. [链接]Python中的metaclass、装饰器
  7. java线程中的notifyAll唤醒操作
  8. java基础基本数据类型对象包装
  9. JQuer实战第一讲:验证用户名是否可用
  10. 1-1 软件构造过程中的多维视图
  11. 设计模式学习五、代理模式
  12. linux yum资源下载,yumdownloader命令 – 从yum存储库下载rpm包
  13. 2019美团技术沙龙合辑PPT下载
  14. 整理全网可视化大屏有关资料,学习大屏设计,大屏原型参考,大屏设计参考
  15. help指令和man指令的区别
  16. VUE解决IE不能用的方法
  17. 男儿当杀人!!!!(诗一首)
  18. 微信小程序面试题大全
  19. 【自学51单片机】3 -- 硬件基础知识(电容、三极管、74HC245、74HC138三八译码器)介绍和闪烁LED小灯
  20. Ubuntu18.04下安装Nvidia驱动和CUDA10.1+CUDNN

热门文章

  1. STREAMSETS自学——JDBC Query Consumer简述
  2. CAN总线要有两个120Ω终端电阻的原因和工作原理
  3. Java在服务器端生成Excel并下载到本地
  4. Android手机9008模式刷机教程(以小米手机为例)
  5. Android自定义View实现打钩签到动画
  6. 隔墙有耳之数据库的安全性
  7. linux远程cp命令,Linux cp scp命令使用
  8. Opencv2.4学习::二值化(1)OTSU算法
  9. Altium Designer尝试制作PCB尺
  10. 磁盘名称:裸设备名称、lvm卷、盘符的理解