您的位置:首页 > 职场人生

程序员的机器学习入门笔记(十一):简单人脸识别系统实践

2017-03-06 13:03 591 查看

说明

机器学习的一个主要应用范围就是对客观事物的识别,也成为模式识别。模式识别的主要研究目标就是赋予机器可以对生物的信息进行识别和处理。

目前关于模式识别的应用已经得到了比较广泛的应用,例如 人脸识别,声音识别,瞳孔识别。

在 前面两篇文章中(http://blog.csdn.net/eric_sunah/article/details/60139602) http://blog.csdn.net/eric_sunah/article/details/60139824)分别对人脸检测以及人脸识别的核心算法进行了简单的介绍,本文主要从代码层面进行展示。

看代码前,先来看看人脸识别的大致流程。

人脸识别工作流程[摘自“百度百科”]

人脸识别系统主要包括四个组成部分,分别为:人脸图像采集及检测、人脸图像预处理、人脸图像特征提取以及匹配与识别。

人脸图像采集及检测

人脸图像采集:不同的人脸图像都能通过摄像镜头采集下来,比如静态图像、动态图像、不同的位置、不同表情等方面都可以得到很好的采集。当用户在采集设备的拍摄范围内时,采集设备会自动搜索并拍摄用户的人脸图像。

人脸检测:人脸检测在实际中主要用于人脸识别的预处理,即在图像中准确标定出人脸的位置和大小。人脸图像中包含的模式特征十分丰富,如直方图特征、颜色特征、模板特征、结构特征及Haar特征等。人脸检测就是把这其中有用的信息挑出来,并利用这些特征实现人脸检测。

主流的人脸检测方法基于以上特征采用Adaboost学习算法,Adaboost算法是一种用来分类的方法,它把一些比较弱的分类方法合在一起,组合出新的很强的分类方法。

人脸检测过程中使用Adaboost算法挑选出一些最能代表人脸的矩形特征(弱分类器),按照加权投票的方式将弱分类器构造为一个强分类器,再将训练得到的若干强分类器串联组成一个级联结构的层叠分类器,有效地提高分类器的检测速度。

人脸图像预处理

人脸图像预处理:对于人脸的图像预处理是基于人脸检测结果,对图像进行处理并最终服务于特征提取的过程。系统获取的原始图像由于受到各种条件的限制和随机干扰,往往不能直接使用,必须在图像处理的早期阶段对它进行灰度校正、噪声过滤等图像预处理。对于人脸图像而言,其预处理过程主要包括人脸图像的光线补偿、灰度变换、直方图均衡化、归一化、几何校正、滤波以及锐化等。

人脸图像特征提取

人脸图像特征提取:人脸识别系统可使用的特征通常分为视觉特征、像素统计特征、人脸图像变换系数特征、人脸图像代数特征等。人脸特征提取就是针对人脸的某些特征进行的。人脸特征提取,也称人脸表征,它是对人脸进行特征建模的过程。人脸特征提取的方法归纳起来分为两大类:一种是基于知识的表征方法;另外一种是基于代数特征或统计学习的表征方法。

基于知识的表征方法主要是根据人脸器官的形状描述以及他们之间的距离特性来获得有助于人脸分类的特征数据,其特征分量通常包括特征点间的欧氏距离、曲率和角度等。人脸由眼睛、鼻子、嘴、下巴等局部构成,对这些局部和它们之间结构关系的几何描述,可作为识别人脸的重要特征,这些特征被称为几何特征。基于知识的人脸表征主要包括基于几何特征的方法和模板匹配法。

人脸图像匹配与识别

人脸图像匹配与识别:提取的人脸图像的特征数据与数据库中存储的特征模板进行搜索匹配,通过设定一个阈值,当相似度超过这一阈值,则把匹配得到的结果输出。人脸识别就是将待识别的人脸特征与已得到的人脸特征模板进行比较,根据相似程度对人脸的身份信息进行判断。这一过程又分为两类:一类是确认,是一对一进行图像比较的过程,另一类是辨认,是一对多进行图像匹配对比的过程。

验证代码

本代码只含盖了“人脸识别工作流”章节中,第三部以及第四部。样本数据取自AT&T人脸数据库:http://www.cl.cam.ac.uk/Research/DTG/attarchive/pub/data/att_faces.zip

PCA算法思想请参考:http://blog.csdn.net/eric_sunah/article/details/60139824

# encoding:utf-8
import os
import sys
import cv2
import numpy as np
import copy
import PIL.Image as Image
import matplotlib.pyplot as plt
"""模拟一个人脸识别系统"""
test_face_dir='/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces'
test_face_paths=['%s/s10/7.pgm'%(test_face_dir),'%s/s10/6.pgm'%(test_face_dir),'%s/s22/1.pgm'%(test_face_dir),'%s/s18/5.pgm'%(test_face_dir),'%s/s16/3.pgm'%(test_face_dir),'%s/s12/1.pgm'%(test_face_dir)]
face_datasource_path=test_face_dir

# 定义脸部识别功能类
class FaceDetection(object):

def __init__(self,train_path):
self.eps=1.0e-16
#特征值
self.eig_v=0
#特征向量
self.eig_vect=0
self.mu=0
self.projections=[]
self.dist_metrics=0
self.path=train_path
self.Mat=[]
self.X=[]
self.Y=[]

#加载测试图片,将图片数据放到self.X中,将标签数据放到self.Y中
def load_images(self):
print 'start to loading face database images'
classlabel=0
for dirname,dirnames,filenames in os.walk(self.path):
for subdir in dirnames:
subdir_path=os.path.join(dirname,subdir)
for subdir_file in os.listdir(subdir_path):
subdir_file_path=os.path.join(subdir_path,subdir_file)
img=Image.open(subdir_file_path)
long_img=img.convert('L')
self.X.append(np.asarray(long_img,dtype=np.float64))
self.Y.append(subdir)
classlabel+=1
print self.Y

#将图片的数据放入到一个由行向量构成的集成
def gen_row_matrix(self):
print 'start converting images to matrix'
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)))

#图片库数据的PCA转换,并计算出特征向量和均值
def pca(self,k=3):
[n,d]=np.shape(self.Mat)
if k>n:k=n
self.mu=self.Mat.mean(axis=0)
# 进行零均值话,减去平均值
self.Mat-=self.mu
# 计算协方差矩阵,以及算出特征值与特征向量
if n>d:
XTX=np.dot(self.Mat.T,self.Mat)
[self.eig_v,self.eig_vect]=np.linglg.eig(XTX)
else:
XTX=np.dot(self.Mat,self.Mat.T)
[self.eig_v,self.eig_vect]=np.linalg.eig(XTX)
self.eig_vect=np.dot(self.Mat.T,self.eig_vect)
for i in range(n):
self.eig_vect[:,i]=self.eig_vect[:,i]/np.linalg.norm(self.eig_vect[:,i])
# 将特征向量按照特征值大小进行从上倒下排列,取前K个
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:k].copy()
self.eig_vect=self.eig_vect[:,0:k].copy()

#对所有的图片进行投影操作
def compute(self):
print 'start executing pca compute'
for xi in self.X:
self.projections.append(self.project(xi.reshape(1,-1)))

#投影
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 distEclud(self,vecA,vecB):
return np.linalg.norm(vecA-vecB)+self.eps
#余旋距离
def comSim(self,vecA,vecB):
return (np.dot(vecA,vecB.T)/((np.linalg.norm(vecA)*np.linalg.norm(vecB))+self.eps))[0,0]

def train(self):
print 'start to trainging face database'
self.load_images()
self.gen_row_matrix()
self.pca()
self.compute()

# 列出每个分类的平均脸
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(np.asarray(images[i]),cmap='gray')
#隐藏坐标
plt.xticks([]),plt.yticks([])
plt.show()

# 根据路径生成矩阵对象
def generate_matrix_obj_by_path(self,test_img_path):
img=Image.open(test_img_path)
long_img=img.convert('L')
return np.asarray(long_img,dtype=np.float64)

#对目标图片进行预测
def predict(self,test_img_path):

img=self.generate_matrix_obj_by_path(test_img_path)

print 'start predicting......'
min_dist=np.finfo('float').max
min_class=-1
#计算预测图片的投影
Q=self.project(img.reshape(1,-1))
for i in xrange(len(self.projections)):
dist=self.dist_metric(self.projections[i],Q)
if dist<min_dist:
min_dist=dist
min_class=self.Y[i]
print 'actualy image is:%s predict result is:%s' %(test_img_path,min_class)

def face_detection():
fd=FaceDetection(face_datasource_path)
# 指定相似性比较算法
fd.dist_metric=fd.distEclud
fd.train()
E=[]
X=np.mat(np.zeros((10,10304)))
#预览16个人脸库的数据
for i in xrange(16):
# 每种脸包含10张图片
X=fd.Mat[i*10:(i+1)*10,:].copy()
#生成平均脸
X=X.mean(axis=0)
imgs=X.reshape(112,92)
E.append(imgs)
#fd.subplot('AT$T Face Database!',images=E)
for test_face_path in test_face_paths:
fd.predict(test_face_path)

if __name__ =='__main__':
face_detection()


运行结果:

start to trainging face database
start to loading face database images
start converting images to matrix
start executing pca compute
start predicting......
actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s10/7.pgm predict result is:s10
start predicting......
actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s10/6.pgm predict result is:s10
start predicting......
actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s22/1.pgm predict result is:s22
start predicting......
actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s18/5.pgm predict result is:s18
start predicting......
actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s16/3.pgm predict result is:s16
start predicting......
actualy image is:/root/source/git/MachineLearning/PythonDataAnylize/testdata/face_detection/att_faces/s12/1.pgm predict result is:s12
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息