python实现人脸识别经典算法(一) 特征脸法


Posted in Python onMarch 13, 2018

近来想要做一做人脸识别相关的内容,主要是想集成一个系统,看到opencv已经集成了三种性能较好的算法,但是还是想自己动手试一下,毕竟算法都比较初级。

操作环境:python2.7

第三方库:opencv for python、numpy

第一种比较经典的算法就是特征脸法,本质上其实就是PCA降维,这种算法的基本思路是,把二维的图像先灰度化,转化为一通道的图像,之后再把它首尾相接转化为一个列向量,假设图像大小是20*20的,那么这个向量就是400维,理论上讲组织成一个向量,就可以应用任何机器学习算法了,但是维度太高算法复杂度也会随之升高,所以需要使用PCA算法降维,然后使用简单排序或者KNN都可以。

只当搬运工,送上链接。

PCA ,这篇博客讲得非常好了,从原理到实现基本看这个就能搞出来了:PCA的数学原理

特征脸法:PCA应用在人脸识别当中:人脸识别经典算法一:特征脸方法(Eigenface) ,这里与PCA有不同的操作就是特征值分解的时候,由于图像组成的列向量维度太高,直接按照PCA算法求解会很慢,所以这里有一种特殊的处理方法。

数据组织形式为若干样本图片分类放入对应文件夹中,然后在统一存放入face文件夹下,测试图像单独一张图像即可。

另外,由于PCA中维度是一个很麻烦的事情,所以在程序中,我打印了很多维度信息,有助于我们理解PCA的工作过程和调试。

代码如下:

#encoding=utf-8 
import numpy as np 
import cv2 
import os 
 
class EigenFace(object): 
 def __init__(self,threshold,dimNum,dsize): 
 self.threshold = threshold # 阈值暂未使用 
 self.dimNum = dimNum 
 self.dsize = dsize 
 
 def loadImg(self,fileName,dsize): 
 ''''' 
 载入图像,灰度化处理,统一尺寸,直方图均衡化 
 :param fileName: 图像文件名 
 :param dsize: 统一尺寸大小。元组形式 
 :return: 图像矩阵 
 ''' 
 img = cv2.imread(fileName) 
 retImg = cv2.resize(img,dsize) 
 retImg = cv2.cvtColor(retImg,cv2.COLOR_RGB2GRAY) 
 retImg = cv2.equalizeHist(retImg) 
 # cv2.imshow('img',retImg) 
 # cv2.waitKey() 
 return retImg 
 
 
 def createImgMat(self,dirName): 
 ''''' 
 生成图像样本矩阵,组织形式为行为属性,列为样本 
 :param dirName: 包含训练数据集的图像文件夹路径 
 :return: 样本矩阵,标签矩阵 
 ''' 
 dataMat = np.zeros((10,1)) 
 label = [] 
 for parent,dirnames,filenames in os.walk(dirName): 
  # print parent 
  # print dirnames 
  # print filenames 
  index = 0 
  for dirname in dirnames: 
  for subParent,subDirName,subFilenames in os.walk(parent+'/'+dirname): 
   for filename in subFilenames: 
   img = self.loadImg(subParent+'/'+filename,self.dsize) 
   tempImg = np.reshape(img,(-1,1)) 
   if index == 0 : 
    dataMat = tempImg 
   else: 
    dataMat = np.column_stack((dataMat,tempImg)) 
   label.append(subParent+'/'+filename) 
   index += 1 
 return dataMat,label 
 
 
 def PCA(self,dataMat,dimNum): 
 ''''' 
 PCA函数,用于数据降维 
 :param dataMat: 样本矩阵 
 :param dimNum: 降维后的目标维度 
 :return: 降维后的样本矩阵和变换矩阵 
 ''' 
 # 均值化矩阵 
 meanMat = np.mat(np.mean(dataMat,1)).T 
 print '平均值矩阵维度',meanMat.shape 
 diffMat = dataMat-meanMat 
 # 求协方差矩阵,由于样本维度远远大于样本数目,所以不直接求协方差矩阵,采用下面的方法 
 covMat = (diffMat.T*diffMat)/float(diffMat.shape[1]) # 归一化 
 #covMat2 = np.cov(dataMat,bias=True) 
 #print '基本方法计算协方差矩阵为',covMat2 
 print '协方差矩阵维度',covMat.shape 
 eigVals, eigVects = np.linalg.eig(np.mat(covMat)) 
 print '特征向量维度',eigVects.shape 
 print '特征值',eigVals 
 eigVects = diffMat*eigVects 
 eigValInd = np.argsort(eigVals) 
 eigValInd = eigValInd[::-1] 
 eigValInd = eigValInd[:dimNum] # 取出指定个数的前n大的特征值 
 print '选取的特征值',eigValInd 
 eigVects = eigVects/np.linalg.norm(eigVects,axis=0) #归一化特征向量 
 redEigVects = eigVects[:,eigValInd] 
 print '选取的特征向量',redEigVects.shape 
 print '均值矩阵维度',diffMat.shape 
 lowMat = redEigVects.T*diffMat 
 print '低维矩阵维度',lowMat.shape 
 return lowMat,redEigVects 
 
 def compare(self,dataMat,testImg,label): 
 ''''' 
 比较函数,这里只是用了最简单的欧氏距离比较,还可以使用KNN等方法,如需修改修改此处即可 
 :param dataMat: 样本矩阵 
 :param testImg: 测试图像矩阵,最原始形式 
 :param label: 标签矩阵 
 :return: 与测试图片最相近的图像文件名 
 ''' 
 testImg = cv2.resize(testImg,self.dsize) 
 testImg = cv2.cvtColor(testImg,cv2.COLOR_RGB2GRAY) 
 testImg = np.reshape(testImg,(-1,1)) 
 lowMat,redVects = self.PCA(dataMat,self.dimNum) 
 testImg = redVects.T*testImg 
 print '检测样本变换后的维度',testImg.shape 
 disList = [] 
 testVec = np.reshape(testImg,(1,-1)) 
 for sample in lowMat.T: 
  disList.append(np.linalg.norm(testVec-sample)) 
 print disList 
 sortIndex = np.argsort(disList) 
 return label[sortIndex[0]] 
 
 
 def predict(self,dirName,testFileName): 
 ''''' 
 预测函数 
 :param dirName: 包含训练数据集的文件夹路径 
 :param testFileName: 测试图像文件名 
 :return: 预测结果 
 ''' 
 testImg = cv2.imread(testFileName) 
 dataMat,label = self.createImgMat(dirName) 
 print '加载图片标签',label 
 ans = self.compare(dataMat,testImg,label) 
 return ans 
 
 
if __name__ == '__main__': 
 eigenface = EigenFace(20,50,(50,50)) 
 print eigenface.predict('d:/face','D:/face_test/1.bmp')

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

Python 相关文章推荐
python导入时小括号大作用
Jan 10 Python
基于python的多进程共享变量正确打开方式
Apr 28 Python
python顺序的读取文件夹下名称有序的文件方法
Jul 11 Python
pycharm 在windows上编辑代码用linux执行配置的方法
Oct 27 Python
浅谈Python 敏感词过滤的实现
Aug 15 Python
python中seaborn包常用图形使用详解
Nov 25 Python
TensorFlow实现checkpoint文件转换为pb文件
Feb 10 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
Feb 10 Python
pip安装tensorflow的坑的解决
Apr 19 Python
PyTorch中model.zero_grad()和optimizer.zero_grad()用法
Jun 24 Python
基于Python爬取搜狐证券股票过程解析
Nov 18 Python
用Python将库打包发布到pypi
Apr 13 Python
tensorflow实现softma识别MNIST
Mar 12 #Python
wxpython实现图书管理系统
Mar 12 #Python
人生苦短我用python python如何快速入门?
Mar 12 #Python
tensorflow实现KNN识别MNIST
Mar 12 #Python
Python操作MySQL模拟银行转账
Mar 12 #Python
python3 图片referer防盗链的实现方法
Mar 12 #Python
tensorflow构建BP神经网络的方法
Mar 12 #Python
You might like
一棵php的类树(支持无限分类)
2006/10/09 PHP
PHP5.3安装Zend Guard Loader图文教程
2014/09/29 PHP
深入理解PHP中的Streams工具
2015/07/03 PHP
10个php函数实用却不常见
2015/10/13 PHP
php curl模拟post请求和提交多维数组的示例代码
2015/11/19 PHP
微信公众平台开发教程②微信端分享功能图文详解
2019/04/10 PHP
JavaScript 利用Cookie记录用户登录信息
2009/12/08 Javascript
easyui datagrid 键盘上下控制选中行示例
2014/03/31 Javascript
Jquery设置attr的disabled属性控制某行显示或者隐藏
2014/09/25 Javascript
使用JS画图之点、线、面
2015/01/12 Javascript
jQuery代码实现发展历程时间轴特效
2015/07/30 Javascript
简单介绍jsonp 使用小结
2016/01/27 Javascript
JS实现可编辑的后台管理菜单功能【附demo源码下载】
2016/09/13 Javascript
JavaScript闭包和范围实例详解
2016/12/19 Javascript
微信小程序事件对象中e.target和e.currentTarget的区别详解
2019/05/08 Javascript
vue 使用高德地图vue-amap组件过程解析
2019/09/07 Javascript
小程序怎样让wx.navigateBack更好用的方法实现
2019/11/01 Javascript
Vue向后台传数组数据,springboot接收vue传的数组数据实例
2020/11/12 Javascript
[03:57]2016完美“圣”典风云人物:rOtk专访
2016/12/09 DOTA
python中去空格函数的用法
2014/08/21 Python
分享python数据统计的一些小技巧
2016/07/21 Python
使用Anaconda3建立虚拟独立的python2.7环境方法
2018/06/11 Python
对python 匹配字符串开头和结尾的方法详解
2018/10/27 Python
Django中使用Celery的方法示例
2018/11/29 Python
python pyqtgraph 保存图片到本地的实例
2020/03/14 Python
详解Python中Pyyaml模块的使用
2020/10/08 Python
MoviePy常用剪辑类及Python视频剪辑自动化
2020/12/18 Python
全球最大的生存食品、水和装备专用在线市场:BePrepared.com
2020/01/02 全球购物
输入一行文字,找出其中大写字母、小写字母、空格、数字、及其他字符各有多少
2016/04/15 面试题
如果Session Bean得Remove方法一直都不被调用会怎么样
2012/07/14 面试题
公司前台辞职报告
2014/01/19 职场文书
开朗女孩的自我评价
2014/02/10 职场文书
应聘销售主管的求职信
2014/04/26 职场文书
幼师求职自荐信
2015/03/26 职场文书
实习单位鉴定意见
2015/06/04 职场文书
广告策划的实习心得体会总结!
2019/07/22 职场文书