基于PCA的人脸识别opencv代码
基于PCA+SVM人脸识别系统的设计与实现代码大全

基于PCA+SVM人脸识别系统的设计与实现1.1题目的主要研究内容(1)工作的主要描述本文主要研究了利用主成分分析算法并结合支持向量机分类器实现对人脸图像的识别,具体研究内容如下:1.图像预处理。
由于受到光照条件、拍摄角度、图像像素大小不同等因素的影响,摄取到的人脸图像往往无法直接进行识别,为达到系统识别要求,提高识别率,需要对获取的人脸图像进行预处理。
图像预处理的过程包括图像的灰度变换、图像直方图均衡化、图像的平滑处理、图像的几何归一化等。
2.特征提取。
特征提取是人脸识别系统中最关键的技术之一,本文利用SVD 定理算法对人脸进行特征提取和特征选择,进而建立一个降维后的特征人脸子空间,降维后的人脸图像大大节省了系统的数据计算量,从而大大缩短了识别时间,为系统的实时性提供了可行性。
3.特征识别。
人脸图像的分类识别是人脸识别系统中的一个环节,即将待测人脸图像的提取特征送给分类器和数据库中已提取的人脸特征相似度进行比较,通过相似性和根据特定标准确定待测人脸的属性的过程来进行分类。
传统的基于PCA的人脸识别算法利用距离函数实现人脸的分类,但该方法准确率较低,本文引入SVM分类器,通过SVM分类器对人脸进行分类识别,并设计了基于PCA+SVM的人脸识别系统,通过仿真实验对改进后系统与传统的基于PCA的人脸识别算法在识别率和识别速度进行了测试和比较,证明了改进后的基于PCA+SVM的人脸识别系统在识别率上要明显优于改进前的系统。
4.系统实现。
本文对基于PCA+SVM的人脸识别系统进行了总体设计,并利用ORL人脸数据库在AI Studio软件上运行python程序,对人脸识别系统的实现进行仿真,最终实现人脸识别功能。
(2)系统流程图1.2 题目研究的工作基础或实验条件(1)windows10(2)AI Studio进行python演示1.3 数据集描述首先建立预存、待识别人脸数据库,然后对预存人脸数据库进行训练,得到预存人脸库的特征脸空间,随后读取一张待识别人脸图像,降低维数和进行标准化,通过SVM分类器对待识别图像进行分类识别,最后显示识别人脸图像具体运行步骤如下:1、建立预存人脸库和待识别人脸库。
利用OpenCV实现基于PCA算法的人脸识别

A x1,x2,...,x10 T
• 其中向量xi为由第i个图像的每一列向量堆叠成一列的MN 维列向量,即把矩阵向量化,如下图所示:
训练阶段
•
如:第i个图像矩阵为
1 2 3 4 5 6 7 8 9
1
•
则xi为
4 7
2
5
系统优缺点分析
系统存在的问题: 1. 抗干扰能力较差。环境光照,遮挡物,人的表情和位置都对识别 结果造成较强的干扰。 2. 训练的时间较长,执行效率不够高。只能对小样本的图像进行识 别,如果图像库太大,则运行效率会比较低。
系统的优点: 1. 不需要对图像进行过多的预处理,PCA本身就能实现降噪的功能; 2. 能有效地识别人脸,且过程相对简单,主要是图像数据的处理和
OpenCV 对非商业应用和商业应用都是免费的,源代码公开, 具备强大的图像和矩阵运算能力,具有丰富的函数处理函数, 减少开发者的工作量,有效提高开发效率和程序运行的可靠 性。
应用:人机互动 、物体识别 、图象分割 、人脸识别 、 动作识别、运动跟踪 、机器人
人脸识别基本介绍
人脸识别,是基于人的脸部特征信
8
369Fra bibliotek 训练阶段
•
第二步:计算平均脸
计算训练图片的平均脸:
1 10
i 10 i 1
xi
训练阶段
•
第三步:计算差值脸
计算每一张人脸与平均脸的差值
di xi i 1
训练阶段
第四步:构建协方差矩阵
C
1 10
10
d
id
求出原协方差矩阵的特征向量
ui
1
PAC算法人脸识别

信号处理方向课程设计报告题目:采用PCA方法的人脸识别系统院系:电子信息学院专业:信息类班级:姓名:学号:指导教师:2013年1月16号目录1:绪论 (3)1.1:研究背景 (3)1.2:应用前景 (3)2:设计基本要求 (5)3:内容原理 (6)3.1 为什么设计PCA人脸识别系统 (6)3.2 PCA算法的原理 (6)3.3 Eigenface算法 (8)3.4 PCA算法在人脸识别中的应用 (9)4:设计步骤 (11)4.1:数据采集 (11)4.2.:文件的读入与显示 (11)4.3:载入要训练的人脸集图像并存储 (12)4.4.:获取训练图像集合的主成分特征向量 (13)4.5:显示特征脸 (14)4.6:平均脸显示 (15)4.7:由特征脸重构训练集内人脸图像 (15)5:心得体会 (17)附录1:参考文献 (18)附录2:课程设计源代码 (18)1:绪论1.1:研究背景为了帮助学生深入理解和消化基本理论、进一步提高综合应用能力并且锻炼独立解决问题的能力,我们将《数字信号处理》、《DSP原理与应用》、《语音信号处理》和《数字图象处理》几门课程融合在一起开设的DSP综合实验课程设计。
主要要求有:一:设计内容突出信号处理的理论和技术的综合应用。
如在信号滤波实验中,在语音信号中混有噪声,要求学生滤除该语音信号中的噪声。
学生首先要进行信号谱分析、然后选择滤波器类型,再确定滤波器参数,最后进行滤波器设计与应用。
而不是简单地给出滤波器类型和设计指标。
二:如何将《DSP原理与应用》、《语音信号处理》和《数字图象处理》三门课程有机的结合起来,设计一实际的系统。
由学生在所学知识的基础上,查阅相关资料,自主设计,通过实验装置进行实现,并对结果进行综合分析,寻找最佳设计方案。
希望学生通过完成一个与信号处理相关的课题的理论设计、程序设计和实验调试任务,提高他们分析解决实际问题的能力。
本设计要求运用课程所学知识,进行算法实现、Matlab仿真,程序设计,DSP开发平台上调试,加深对信号处理知识的理解与运用,培养对可编程DSP芯片的开发技能。
基于PCA算法的人脸识别系统的设计与实现代码大全

基于PCA算法的人脸识别系统的设计与实现1.1 题目的主要研究内容(1)工作的主要描述采用PCA算法,其原理就是运用统计学的方法,对人脸图像进行前期处理,及特征提取。
后期针对前面的特征问题,选择了一个测度对这个特征分类匹配,就是简单的欧式距离。
系统的是效果较佳,稳定性高,整体效果不错。
(2)系统框图图1系统框图1.2 题目研究的工作基础或实验条件(1)硬件环境计算机(2)软件环境matlab1.3 数据集描述脸库分为测试人脸库和训练人类库,在训练人脸库内的所有人脸数目有二十张,十个人的,一个人有两张图像,不同的表情。
在测试人脸库内有10张人脸,这10张人脸是在训练库内挑选的10个人脸表情。
每张人脸图像的大小为180*200,格式为JPG。
因为本系统针对的图像格式要求必须为JPG格式的图像。
我把这20张图片的命名,用数字1-20来代替,以便后面在识别阶段,可以读出对应的数字,类似人的名字。
1.4 特征提取过程描述特征提取首先把库内待训练的人脸图像,读入matlab转换成灰度图像,进而将人脸图像按行排列,构成协方差矩阵,这个协方差矩阵里面,每一行都代表一个人脸,所以求这个协方差矩阵的特征值和特征向量,也就是求每个人脸的特征,每个特征值对应的特征向量,构成了特征向量子空间,下图中曲线的就是库内内所有人脸图像进行特征提取获得特征值后,按特征值大小排列,由图可以看出,每张人脸图像对应特征值大小的区别性很大,只要提取数值较高的特征值对应的特征向量来组成特征子空间即可,大大的减少了特征矩阵的向量的数量,这样可以降低计算量,提高特征提取的运算速率。
也为后面的人脸识别系统运行提高速度。
图1 特征值分布图1.5 分类过程描述首先通过图像采集建立人脸库,这个人脸库里的人脸图像必须是格式及像素统一的,然后针对库里的人脸进行人脸训练,利用PCA进行人脸特征提取,获取特征矩阵向量组,将测试人脸投缘到特征子空间中,运用欧氏距离,在人脸库里查找相应的人脸图像,并输出。
基于PCA的人脸识别研究报告

课程设计设计课程:模式识别题目基于PCA方法的人脸识别学生姓名学号学院专业指导教师2013 年12 月25 日目录摘要一、课程设计目的 (3)二、课程设计要求 (3)三、题目分析 (3)四、总体设计 (3)五、具体设计 (4)6.1、创建数据库 (4)6.2、计算特征脸 (5)6.3、人脸识别 (6)六、结果分析 (9)七、心得体会 (9)八、参考文献 (10)摘要随着人类社会的进步,以及科技水平的提高,一些传统的身份认证的方法逐渐暴露出各种问题,因此人们需要采用一种更加可靠安全的身份认证方法。
毫无疑问人体的生物特征的独一无二的,特别是其不容易丢失及复制的特性很好满足了身份识别的需要。
并且随着计算机科学技术和生物医学的发展使得利用生物特征识别成为了可能。
因此基于指纹、人脸、视网膜等生物特征的识别方法也越来越多。
由于人脸识别的操作快速简单,结果直观,准确可靠,不需要人的配合等优点已成为人们关注的焦点。
主成分分析(PCA)法通过提取高维度的人脸图像的主元,使得图像在低维度空间中被处理来降低了图像处理的难度。
由于其有效的解决了图像空间维数过高的问题,已经成为人脸识别领域非常重要的理论。
此次研究的就是基于PCA的人脸识别算法的实现。
本文按照完整人脸识别流程来分析基于PCA的人脸识别算法实现的性能。
首先使用常用的人脸图像的获取方法获取人脸图像。
本文为了更好的分析基于PCA人脸识别系统的性能分别选用了Essex人脸数据库和ORL人脸库,并在后期采用了自建的人脸库。
接下来是人脸图像预处理方法。
由于采用的人脸图像质量较好,而且已经做过相应的预处理,所以本文试验中只使用灰度处理。
接着使用PCA提取人脸特征,使用奇异值分解定理计算协方差矩阵的特征值和特征向量以及使用最近邻法分类器欧几里得距离来进行人脸判别分类。
在实验中我们发现基于PCA 的人脸识别系统的识别率很高,而且具有一定鲁棒性,所以基于PCA的人脸识别算法的实现的研究还是有意义。
基于PCA和SVM的人脸识别方法

基于PCA 和SVM 的人脸识别方法一、PCA 算法1 计算特征脸设人脸图像f(x,y)为二维m n ⨯灰度图像,用nm 维向量R 表示。
人脸图像训练集为{}p i R i,,2,1 =,其中p 为训练集中图像总数。
这p 幅图像的平均向量为:∑==pi i R p R 11对训练样本规范化,即每个人脸i R 与平均人脸R 的差值向量:R R A i i -= p i ,,2,1 =其中列向量i A 表示一个训练样本。
训练图像由协方差矩阵可表示为:T AA C =其中训练样本p nm ⨯维矩阵],,,[21p A A A A =特征脸由协方差矩阵C 的正交特征向量组成。
对于nm 维人脸图像,协方差矩阵C 的大小为nm ×nm ,对它求解特征值和特征向量是很困难的,由此引入奇异值分解定理来解决维数过高的问题。
2 奇异值分解定理奇异值分解定理( Singular Value Decomposition 简称SVD 定理)原理表述如下: 其中A 是一个秩为r 的r n ⨯维矩阵,则存在两个正交矩阵:r n r R u u u U ⨯-∈=],,,[110 I U U T =r r r R v v v V ⨯-∈=],,,[110 I V V T =以及对角矩阵r r r R diag ⨯-∈=Λ],,,[110λλλ且110-≥≥≥r λλλ满足下试:T V U A 21Λ=其中:)1,,1,0(-=r i i λ为矩阵T AA 和A A T 的非零特征值, i u 与i v 分别为T AA 和AA T对应于i λ的特征向量。
上述分解称为矩阵A 的奇异值分解(简称SVD ),i λ为A 的奇异值。
由上述定理可以得到一个推论:1Λ=AV U由于协方差矩阵TAA C =,故构造矩阵: pp TRA A L ⨯∈= ,容易求出其特征值i λ及相应的正交归一特征向量),,2,1(p i v i =。
人脸识别程序源代码

1 .利用OpenCV进行人脸检测人脸检测程序主要完成3部分功能,即加载分类器、加载待检测图象以及检测并标示。
本程序使用OpenCV中提供的"haarcascade_frontalface_alt.xml”文件存储的目标检测分类,用cvLoa d函数载入后,进行强制类型转换。
OpenCV中提供的用于检测图像中目标的函数是cvHaarDete ctObjects,该函数使用指针对某目标物体(如人脸)训练的级联分类器在图象中找到包含目标物体的矩形区域,并将这些区域作为一序列的矩形框返回。
分类器在使用后需要被显式释放,所用的函数为cvReleaseHaarClassifierCascade。
这些函数原型请参看有关OpenCV手册。
2 .程序实现1)新建一个VisualC++MFC项目,取名为“FaceDetection",选择应用程序类型为“单文档”。
将菜单中多余的项去掉,并添加一项“人脸检测”,其ID为"ID_FaceDetected”,并生成该菜单项的消息映射函数。
2)在“FaceDetectionView.h”头文件中添加以下灰底色部分程序代码:〃南京森林公安高等专科学校江林升//FaceDetectionView.h:CFaceDetectionView 类的接□#pragmaonce#include"cv.h"#include"highgui.h"classCFaceDetectionView:publicCView<protected:〃仅从序列口化创建CFaceDetectionView();DECLARE_DYNCREATE(CFaceDetectionView)精心整理public:CFaceDetectionDoc*GetDocument()const;CvHaarClassifierCascade*cascade;〃特征器分类CvMemStorage*storage;voiddetect_and_draw(IplImage*img);IplImage*src; 〃载入的图像3)在,小2。
基于opencv的人脸识别程序-代码详解

#include "cv.h"#include "highgui.h"#include <stdio.h>#ifdef _EiC#define WIN32#endifstatic CvMemStorage* storage = 0;static CvHaarClassifierCascade* cascade = 0;void detect_and_draw( IplImage* image );const char* cascade_name ="haarcascade_frontalface_alt.xml";//人脸检测分类器int main( int argc, char** argv ){CvCapture* capture = 0;IplImage *frame, *frame_copy = 0;int optlen = strlen("--cascade=");const char* input_name;if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 ){cascade_name = argv[1] + optlen;input_name = argc > 2 ? argv[2] : 0;}else{cascade_name = "E:\毕业设计\智能机器人动态人脸识别系统\陈建州程序.xml";//分类器路径input_name = argc > 1 ? argv[1] : 0;}cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );if( !cascade )//如果没有找到分类器,输出以下{fprintf( stderr, "ERROR: Could not load classifier cascade\n" );fprintf( stderr,"Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );return -1;}storage = cvCreateMemStorage(0);capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );//读取摄像头if(!capture)//如果没有摄像头读取视频文件capture = cvCaptureFromA VI("检测.avi");cvNamedWindow( "result", 1);//创建窗口if( capture ){for(;;){if( !cvGrabFrame( capture ))//从摄像头中抓取帧break;frame = cvRetrieveFrame( capture );//读取上边抓取的帧if( !frame )break;if( !frame_copy )frame_copy = cvCreateImage( cvSize(frame->width,frame->height),IPL_DEPTH_8U, frame->nChannels );if( frame->origin == IPL_ORIGIN_TL )cvCopy( frame, frame_copy, 0 );elsecvFlip( frame, frame_copy, 0 );detect_and_draw( frame_copy );if( cvWaitKey( 10 ) >= 0 )break;}cvReleaseImage( &frame_copy );cvReleaseCapture( &capture );}else//没检测到视频文件或者摄像头{const char* filename = (char*)"检测.jpg";//读图片IplImage* image = cvLoadImage( filename, 1 );if( image ){detect_and_draw( image );cvWaitKey(0);cvReleaseImage( &image );}else{FILE* f = fopen( filename, "rt" );if( f ){char buf[1000+1];while( fgets( buf, 1000, f ) ){int len = (int)strlen(buf);while( len > 0 && isspace(buf[len-1]) )len--;buf[len] = '\0';image = cvLoadImage( buf, 1 );if( image ){detect_and_draw( image );cvWaitKey(0);cvReleaseImage( &image );}}fclose(f);}}}cvDestroyWindow("result");return 0;}void detect_and_draw( IplImage* img ){static CvScalar colors[] ={{{0,0,255}},{{0,128,255}},{{0,255,255}},{{0,255,0}},{{255,128,0}},{{255,255,0}},{{255,0,0}},{{255,0,255}}};double scale = 1.3;IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),cvRound (img->height/scale)),8, 1 );int i;cvCvtColor( img, gray, CV_BGR2GRAY );cvResize( gray, small_img, CV_INTER_LINEAR );cvEqualizeHist( small_img, small_img );cvClearMemStorage( storage );if( cascade ){double t = (double)cvGetTickCount();CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,cvSize(30, 30) );//检测人脸返回矩形人脸t = (double)cvGetTickCount() - t;printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );for( i = 0; i < (faces ? faces->total : 0); i++ )//找到矩形中心,把矩形转化为圆形{CvRect* r = (CvRect*)cvGetSeqElem( faces, i );CvPoint center;int radius;center.x = cvRound((r->x + r->width*0.5)*scale);center.y = cvRound((r->y + r->height*0.5)*scale);radius = cvRound((r->width + r->height)*0.25*scale);cvCircle( img, center, radius, colors[i%8], 3, 8, 0 );}}cvShowImage( "result", img );cvReleaseImage( &gray );cvReleaseImage( &small_img );}OpenCV的人脸检测主要是调用训练好的cascade(Haar分类器)来进行模式匹配。
python使用opencv进行人脸识别

python使用opencv进行人脸识别欢迎来到小码哥的博客博客搬家啦/RvFZs2cpython使用opencv进行人脸识别环境ubuntu 12.04 LTSpython 2.7.3opencv 2.3.1-7安装依赖sudo apt-get install libopencv-*sudo apt-get install python-opencvsudo apt-get install python-numpy示例代码#!/usr/bin/env python#coding=utf-8import osfrom PIL import Image, ImageDrawimport cvdef detect_object(image):'''检测图片,获取人脸在图片中的坐标'''grayscale = cv.CreateImage((image.width, image.height), 8, 1)cv.CvtColor(image, grayscale, cv.CV_BGR2GRAY)cascade =cv.Load("/usr/share/opencv/haarcascades/haarcascade_frontalfa ce_alt_tree.xml")rect = cv.HaarDetectObjects(grayscale, cascade,cv.CreateMemStorage(), 1.1, 2,cv.CV_HAAR_DO_CANNY_PRUNING, (20,20))result = []for r in rect:result.append((r[0][0], r[0][1], r[0][0]+r[0][2],r[0][1]+r[0][3]))return resultdef process(infile):'''在原图上框出头像并且截取每个头像到单独文件夹''' image = cv.LoadImage(infile);if image:faces = detect_object(image)im = Image.open(infile)path = os.path.abspath(infile)save_path = os.path.splitext(path)[0]+"_face"try:os.mkdir(save_path)except:passif faces:draw = ImageDraw.Draw(im)count = 0for f in faces:count += 1draw.rectangle(f, outline=(255, 0, 0))a = im.crop(f)file_name =os.path.join(save_path,str(count)+".jpg")# print file_namea.save(file_name)drow_save_path = os.path.join(save_path,"out.jpg")im.save(drow_save_path, "JPEG", quality=80) else:print "Error: cannot detect faces on %s" % infileif __name__ == "__main__":process("./opencv_in.jpg")转换效果原图:转换后使用感受对于大部分图像来说,只要是头像是正面的,没有被阻挡,识别基本没问题,准确性还是很高的。
python基于opencv实现人脸识别

python基于opencv实现⼈脸识别将opencv中haarcascade_frontalface_default.xml⽂件下载到本地,我们调⽤它辅助进⾏⼈脸识别。
识别图像中的⼈脸#coding:utf-8import cv2 as cv# 读取原始图像img = cv.imread('face.png')# 调⽤熟悉的⼈脸分类器识别特征类型# ⼈脸 - haarcascade_frontalface_default.xml# ⼈眼 - haarcascade_eye.xml# 微笑 - haarcascade_smile.xmlface_detect = cv.CascadeClassifier('haarcascade_frontalface_default.xml')gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)# 检查⼈脸按照1.1倍放到周围最⼩像素为5face_zone = face_detect.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5)print ('识别⼈脸的信息:',face_zone)# 绘制矩形和圆形检测⼈脸for x, y, w, h in face_zone:# 绘制矩形⼈脸区域 thickness表⽰线的粗细cv.rectangle(img, pt1=(x, y), pt2=(x+w, y+h),color=[0,0,255], thickness=2)# 绘制圆形⼈脸区域 radius表⽰半径cv.circle(img, center=(x+w//2, y+h//2), radius=w//2, color=[0,255,0], thickness=2)# 设置图⽚可以⼿动调节⼤⼩dWindow("Easmount-CSDN", 0)# 显⽰图⽚cv.imshow("Easmount-CSDN", img)# 等待显⽰设置任意键退出程序cv.waitKey(0)cv.destroyAllWindows()注意,此算法只能检测正脸,并且任何算法都有⼀定的准确率。
基于PCA的人脸识别算法

基于PCA 的人脸识别算法摘 要:文章具体讨论了主成分分析( PCA)人脸识别算法的原理及实现。
它具有简单、快速和易行等特点,能从整体上反映人脸图像的灰度相关性具有一定的实用价值。
关键词:人脸识别;PCA;生物特征;识别技术1引言PCA ,即Principal Component Analysis ,主成分分析方法,是一种得到广泛应用的事实上的标准人脸识别方法。
传统主成分分析方法的基本原理是:利用K-L 变换抽取人脸的主要成分,构成特征脸空间,识别时将测试图像投影到此空间,得到一组投影系数,通过与各个人脸图像比较进行识别。
这种方法使得压缩前后的均方误差最小,且变换后的低维空间有很好的分辨能力。
2 K-L 变换PCA 方法是由Turk 和Pentlad 提出来的,它的基础就是Karhunen-Loeve 变换(简称K-L 变换),是一种常用的正交变换。
首先对K-L 变换作一个简单介绍: 假设X 为n 维的随机变量,X 可以用n 个基向量的加权和来表示: X= ∑=ni a 1i φi式中:αi 是加权系数,φi 是基向量,此式可以用矩阵的形式表示: X =(φ1 ,φ2,φ3 ,……,φn )( α1, α2 ,…… αn )= Φα 系数向量为:α=ΦT X综上所述,K-L 展开式的系数可用下列步骤求出:步骤一 求随机向量X 的自相关矩阵R=E[X TX],由于没有类别信息的样本集的μ均值向量,常常没有意义,所以也可以把数据的协方差矩阵∑=E[(x-μ)(x-μ)T ]作为K-L 坐标系的产生矩阵,这里μ是总体均值向量。
步骤二 求出自相关矩阵或者协方差矩阵R 的本征值λi 和本征向量φi ,Φ=(φ1 ,φ2,φ3 ,……,φn )步骤三 展开式系数即为α=ΦT XK-L 变换的实质是建立一个新的坐标系,将一个物体主轴沿特征矢量对齐的转变换,这个变换解除了原有数据向量的各个分量之间相关性,从而有可能去掉那些带有较少信息的坐标系以达到降低特征空间维数的目的。
基于PCA和BP神经网络的人脸识别方法

基于PCA和BP神经网络的人脸识别方法摘要:基于PCA 和BP 神经网络的人脸识别方法是针对PCA 方法中存在的问题和它对未训练过的样本识别率低的缺点而提出的。
该方法在预处理的基础上,利用PCA处理人脸特征,提取其中分类能力强的特征,实现在识别精度不变的情况下,有效的去除冗余信息;然后将约简后的属性输入到神经网络进行规则提取,利用神经网络非线性映射和并行处理的特点,增强对人脸图像识别的泛化能力。
实验证明,使用该方法在识别率上有一定的提高。
关键词:人类识别、BP神经网络、PCA、特征提取引言人脸识别特指利用分析比较人脸视觉特征信息进行身份鉴别的计算机技术。
人脸识别是一项热门的计算机技术研究领域,可以将人脸明暗侦测,自动调整动态曝光补偿,人脸追踪侦测,自动调整影像放大;它属于生物特征识别技术,是对生物体(一般特指人)本身的生物特征来区分生物体个体。
进行人脸图像识别研究具有很大的使用价值。
如同人的指纹一样,人脸也具有唯一性,也可用来鉴别一个人的身份。
现在己有实用的计算机自动指纹识别系统面世,并在安检等部门得到应用,但还没有通用成熟的人脸自动识别系统出现。
人脸图像的自动识别系统较之指纹识别系统、DNA鉴定等更具方便性,因为它取样方便,可以不接触目标就进行识别,从而开发研究的实际意义更大。
并且与指纹图像不同的是,人脸图像受很多因素的干扰:人脸表情的多样性;以及外在的成像过程中的光照,图像尺寸,旋转,姿势变化等。
使得同一个人,在不同的环境下拍摄所得到的人脸图像不同,有时更会有很大的差别,给识别带来很大难度。
因此在各种干扰条件下实现人脸图像的识别,也就更具有挑战性。
当前大多数人脸识别算法是基于统计的方法,如特征脸方法(PCA)、Fisher 脸方法、奇异值分解方法、神经网络方法和支持向量机等,这些方法中影响较大的是Turk 和Pentland 提出的特征脸(Eigen Face)方法即PCA 方法。
PCA是基于主元分析的特征提取,把所有的不同人脸的样本放在一起提取,以所有人的人脸样本最优重建为目的。
基于pca算法的eigenfaces人脸识别算法大学论文

河北农业大学现代科技学院毕业论文(设计)题目:基于PCA算法的Eigenfaces人脸识别算法摘要人脸识别技术就是利用计算机分析人脸图像,提取有效的识别信息来辨认身份或者判别待定状态的一门技术。
它涉及模式识别、图像处理、计算机视觉等诸多学科的知识,是当前研究的热点之一。
然而影响计算机人脸识别的因素非常之多,主要是人脸表情丰富,人脸随年龄增长而变化,人脸所成图像受光照、成像角度及成像距离等影响,极大地影响了人脸识别走向实用化。
基于PCA算法的人脸识别过程大致分为训练、测试、识别这三个阶段完成,在训练阶段,通过寻找协方差矩阵的特征向量,求出样本在该特征向量上的投影系数;在测试阶段,通过将测试样本投影到特征向量上,得到测试样本在该特征向量上的投影系数。
最后,采用最小欧氏距离,找到了与测试样本最相近的训练样本图像。
关键词Eigenfaces、PCA算法、人脸识别算法、matlab、SVD。
AbstractFace recognition technology is the use of computer analysis of facial images to extract valid identification information to identify or determine the identity of a technology Pending state. It involves knowledge of pattern recognition, image processing, computer vision, and many other disciplines, is one of the hotspots of current research. However, factors affecting the computer face recognition very much, mainly rich facial expression, face changes with age, face a picture of the affected light, imaging and imaging distance, angle, greatly influenced the Face to practical use.PCA algorithm based recognition process is roughly divided into training and testing, the identification of these three stages, in the training phase, to find the eigenvectors of the covariance matrix is obtained on the sample feature vector projection coefficient; in the test phase by the test feature vector is projected onto the sample to obtain a test sample on the projection of the feature vector of coefficients.Finally, the minimum Euclidean distance, the test sample to find the closest sample images.Keywords Eigenfaces PCA Algorithm、Face Recognition Algorithm、matlab、SVD.目录1 绪论---------------------------------------------------------------------- 11.1计算机人脸识别技术及应用--------------------------------------------- 11.2常用的人脸识别方法简介----------------------------------------------- 11.3本论文内容安排------------------------------------------------------- 12 PCA ----------------------------------------------------------------------- 32.1 PCA简介------------------------------------------------------------- 32.2 PCA的实质----------------------------------------------------------- 32.3 PCA理论基础--------------------------------------------------------- 32.3.1投影----------------------------------------------------------- 32.3.2最小平方误差理论----------------------------------------------- 42.3.3 PCA几何解释--------------------------------------------------- 82.4 PCA降维计算--------------------------------------------------------- 83 PCA在人脸识别中的应用--------------------------------------------------- 113.1 人脸识别技术简介--------------------------------------------------- 113.2 图片归一化--------------------------------------------------------- 113.3 基于PCA的人脸识别------------------------------------------------- 113.3.1 人脸数据特征提取---------------------------------------------- 113.3.2计算均值------------------------------------------------------ 123.3.3计算协方差矩阵C ----------------------------------------------- 123.3.4求出协方差C的特征值和特征向量-------------------------------- 123.4奇异值分解定理------------------------------------------------------ 123.5 基于PCA的人脸识别的训练------------------------------------------- 133.5.1 训练集的主成分计算-------------------------------------------- 133.5.2 训练集图片重建------------------------------------------------ 133.6 识别--------------------------------------------------------------- 144 实验--------------------------------------------------------------------- 154.1 实验环境----------------------------------------------------------- 154.2 PCA人脸识别实验过程------------------------------------------------ 154.2.1 训练阶段------------------------------------------------------ 154.2.2 测试阶段------------------------------------------------------ 224.2.3 采用欧氏最小距离识别------------------------------------------ 234.3实验结果------------------------------------------------------------ 245 总结--------------------------------------------------------------------- 265.1.1内容总结:---------------------------------------------------- 265.1.2工作总结:---------------------------------------------------- 26 6致谢--------------------------------------------------------------------- 27 参考文献------------------------------------------------------------------- 281 绪论1.1计算机人脸识别技术及应用计算机人脸识别技术就是利用计算机分析人脸图像,进而从中提取出有效的识别信息,用来“辨认”身份的一门技术,它涉及图像处理、模式识别、计算机视觉、神经网络、生理学、心理学等诸多学科领域的知识。
基于PCA的人脸识别方案

基于PCA的人脸识别方案摘要:分析了基于主成分分析方法(PCA)的人脸识别特点,并对其实现方法进行了分析和仿真,结果表明方案比较完整的实现了人脸识别的功能,对于实际应用也有参考价值。
关键词:PCA 人脸识别分析一概述生物特征识别技术所研究的生物特征包括人脸、指纹、手掌纹、掌型、虹膜、视网膜、静脉、声音(语音)、体形人脸识别、红外温谱、耳型等,相应的识别技术就有人脸识别、指纹识别、掌纹识别、虹膜识别、视网膜识别、静脉识别、语音识别(用语音识别可以进行身份识别,也可以进行语音内容的识别,只有前者属于生物特征识别技术)、体形识别、键盘敲击识别、签字识别等。
人脸识别特指利用分析比较人脸视觉特征信息进行身份鉴别的计算机技术。
人脸识别是一项热门的计算机技术研究领域,可以将人脸明暗侦测,自动调整动态曝光补偿,人脸追踪侦测,自动调整影像放大;它属于生物特征识别技术,是对生物体(一般特指人)本身的生物特征来区分生物体个体。
人脸识别的优势人脸识别的优势在于其自然性和不被被测个体察觉的特点。
所谓自然性,是指该识别方式同人类(甚至其他生物)进行个体识别时所利用的生物特征相同。
例如人脸识别,人类也是通过观察比较人脸区分和确认身份的,另外具有自然性的识别还有语音识别、体形识别等,而指纹识别、虹膜识别等都不具有自然性,因为人类或者其他生物并不通过此类生物特征区别个体。
不被察觉的特点这会使该识别方法不令人反感,并且因为不容易引起人的注意而不容易被欺骗。
人脸识别具有这方面的特点,它完全利用可见光获取人脸图像信息,而不同于指纹识别或者虹膜识别,需要利用电子压力传感器采集指纹,或者利用红外线采集虹膜图像,这些特殊的采集方式很容易被人察觉,从而更有可能被伪装欺骗。
本文是通过基于主成分分析的方法实现对人脸的识别,仿真结果也表明本文设计的算法的有效性,在特定场合下的应用具有一定的参考意义。
二PCA算法概述对同一个体进行多项观察时,必定涉及多个随机变量X1,X2,…,X p,它们都是的相关性, 一时难以综合。
pca人脸识别特征脸源代码

% FaceRec.m ??????%CQUPT% PCA??识别率88%?% calc xmean,sigma and its eigen decompositionallsamples=[];%所有训练图片m=0;for i=1:40for j=1:5a=imread(strcat ('e:\ORL\s', num2str(i),'\', num2str(j),'.pgm'));b=a(1:112*92);%b是行矢量1*N,N=10304,提取顺序是先列后行,%即从上到下,从左到右b=double(b);allsamples=[allsamples;b];%allsamples是一个M*N矩阵,allsamples中每一行数据代%表一张图片,其中Mendendsamplemean=mean(allsamples);%平图片,1*Nfor i=1:200 xmean(i,:)=allsamples(i,:)-samplemean;%allsamples是一个M*N矩阵,allsamples 中每一行保存%的数据是“每个图片数据—平均图片”end;%获取特征植及特征向量sigma=xmean*xmean';% M* M矩阵[v d]=eig(sigma);d1=diag(d);%按特征值大小以降序排列dsort=flipud(d1);vsort=fliplr(v);%以下选择90%的能量dsum=sum(dsort);dsum_extract=0;p=0;while(dsum_extract/dsum<0.9)p=p+1;dsum_extract=sum(dsort(1:p));endp=199;% (训练阶段)计算特征脸形成的坐标系base = xmean' * vsort(:,1:p) * diag(dsort(1:p).^(-1/2));%生成特征脸for(k=1:p)temp=reshape(base(:,k),112,92);newpath=['e:\orl\test\' int2str(k) '.jpg'];imwrite(mat2gray(temp), newpath);m=m+1;subplot(10,20,m),imshow(mat2gray(reshape(temp, 112,92))); endavg = reshape(samplemean, 112,92);imshow(avg);title('训练图库')imwrite(mat2gray(avg), 'e:\orl\test\average.jpg');%将模型保存save('e:\orl\test\model.mat', 'base', 'samplemean');。
opencv人脸识别代码

opencv⼈脸识别代码opencv⼈脸识别C++代码/** Copyright (c) 2011,2012. Philipp Wagner <bytefish[at]gmx[dot]de>.* Released to public domain under terms of the BSD Simplified license.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions are met:* * Redistributions of source code must retain the above copyright* notice, this list of conditions and the following disclaimer.* * Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in the* documentation and/or other materials provided with the distribution.* * Neither the name of the organization nor the names of its contributors* may be used to endorse or promote products derived from this software* without specific prior written permission.** See </licenses/bsd-license>*/#include "precomp.hpp"#include <set>namespace cv{using std::set;// Reads a sequence from a FileNode::SEQ with type _Tp into a result vector.template<typename _Tp>inline void readFileNodeList(const FileNode& fn, vector<_Tp>& result) {if (fn.type() == FileNode::SEQ) {for (FileNodeIterator it = fn.begin(); it != fn.end();) {_Tp item;it >> item;result.push_back(item);}}}// Writes the a list of given items to a cv::FileStorage.template<typename _Tp>inline void writeFileNodeList(FileStorage& fs, const string& name,const vector<_Tp>& items) {// typedefstypedef typename vector<_Tp>::const_iterator constVecIterator;// write the elements in item to fsfs << name << "[";for (constVecIterator it = items.begin(); it != items.end(); ++it) {fs << *it;}fs << "]";}static Mat asRowMatrix(InputArrayOfArrays src, int rtype, double alpha=1, double beta=0) {// make sure the input data is a vector of matrices or vector of vectorif(src.kind() != _InputArray::STD_VECTOR_MAT && src.kind() != _InputArray::STD_VECTOR_VECTOR) {string error_message = "The data is expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< vector<...> >)."; CV_Error(CV_StsBadArg, error_message);}// number of samplessize_t n = src.total();// return empty matrix if no matrices givenif(n == 0)return Mat();// dimensionality of (reshaped) samplessize_t d = src.getMat(0).total();// create data matrixMat data((int)n, (int)d, rtype);// now copy datafor(unsigned int i = 0; i < n; i++) {// make sure data can be reshaped, throw exception if not!if(src.getMat(i).total() != d) {string error_message = format("Wrong number of elements in matrix #%d! Expected %d was %d.", i, d, src.getMat(i).total());CV_Error(CV_StsBadArg, error_message);}// get a hold of the current rowMat xi = data.row(i);// make reshape happy by cloning for non-continuous matricesif(src.getMat(i).isContinuous()) {src.getMat(i).reshape(1, 1).convertTo(xi, rtype, alpha, beta);} else {src.getMat(i).clone().reshape(1, 1).convertTo(xi, rtype, alpha, beta);}}return data;}// Removes duplicate elements in a given vector.template<typename _Tp>inline vector<_Tp> remove_dups(const vector<_Tp>& src) {typedef typename set<_Tp>::const_iterator constSetIterator;typedef typename vector<_Tp>::const_iterator constVecIterator;set<_Tp> set_elems;for (constVecIterator it = src.begin(); it != src.end(); ++it)set_elems.insert(*it);vector<_Tp> elems;for (constSetIterator it = set_elems.begin(); it != set_elems.end(); ++it)elems.push_back(*it);return elems;}// Turk, M., and Pentland, A. "Eigenfaces for recognition.". Journal of// Cognitive Neuroscience 3 (1991), 71–86.//特征脸类class Eigenfaces : public FaceRecognizer{private:int _num_components;//对应“数学上的事”中所提到的q个主成分double _threshold;vector<Mat> _projections;//原始向量投影后的坐标Mat _labels;//每幅图像的标签,⽤于分类Mat _eigenvectors;//特征向量Mat _eigenvalues;//特征值Mat _mean;//均值public:using FaceRecognizer::save;using FaceRecognizer::load;// Initializes an empty Eigenfaces model.Eigenfaces(int num_components = 0, double threshold = DBL_MAX) :_num_components(num_components),_threshold(threshold) {}// Initializes and computes an Eigenfaces model with images in src and// corresponding labels in labels. num_components will be kept for// classification.Eigenfaces(InputArrayOfArrays src, InputArray labels,int num_components = 0, double threshold = DBL_MAX) :_num_components(num_components),_threshold(threshold) {train(src, labels);}// Computes an Eigenfaces model with images in src and corresponding labels // in labels.void train(InputArrayOfArrays src, InputArray labels);// Predicts the label of a query image in src.int predict(InputArray src) const;// Predicts the label and confidence for a given sample.void predict(InputArray _src, int &label, double &dist) const;// See FaceRecognizer::load.void load(const FileStorage& fs);// See FaceRecognizer::save.void save(FileStorage& fs) const;AlgorithmInfo* info() const;};// Belhumeur, P. N., Hespanha, J., and Kriegman, D. "Eigenfaces vs. Fisher-// faces: Recognition using class specific linear projection.". IEEE// Transactions on Pattern Analysis and Machine Intelligence 19, 7 (1997),// 711–720.class Fisherfaces: public FaceRecognizer{private:int _num_components;double _threshold;Mat _eigenvectors;Mat _eigenvalues;Mat _mean;vector<Mat> _projections;Mat _labels;public:using FaceRecognizer::save;using FaceRecognizer::load;// Initializes an empty Fisherfaces model.Fisherfaces(int num_components = 0, double threshold = DBL_MAX) :_num_components(num_components),_threshold(threshold) {}// corresponding labels in labels. num_components will be kept for// classification.Fisherfaces(InputArrayOfArrays src, InputArray labels,int num_components = 0, double threshold = DBL_MAX) :_num_components(num_components),_threshold(threshold) {train(src, labels);}~Fisherfaces() {}// Computes a Fisherfaces model with images in src and corresponding labels // in labels.void train(InputArrayOfArrays src, InputArray labels);// Predicts the label of a query image in src.int predict(InputArray src) const;// Predicts the label and confidence for a given sample.void predict(InputArray _src, int &label, double &dist) const;// See FaceRecognizer::load.void load(const FileStorage& fs);// See FaceRecognizer::save.void save(FileStorage& fs) const;AlgorithmInfo* info() const;};// Face Recognition based on Local Binary Patterns.//// Ahonen T, Hadid A. and Pietikäinen M. "Face description with local binary// patterns: Application to face recognition." IEEE Transactions on Pattern// Analysis and Machine Intelligence, 28(12):2037-2041.//class LBPH : public FaceRecognizer{private:int _grid_x;int _grid_y;int _radius;int _neighbors;double _threshold;vector<Mat> _histograms;Mat _labels;// Computes a LBPH model with images in src and// corresponding labels in labels, possibly preserving// old model data.void train(InputArrayOfArrays src, InputArray labels, bool preserveData); public:using FaceRecognizer::save;using FaceRecognizer::load;// Initializes this LBPH Model. The current implementation is rather fixed// as it uses the Extended Local Binary Patterns per default.//// radius, neighbors are used in the local binary patterns creation.// grid_x, grid_y control the grid size of the spatial histograms.LBPH(int radius_=1, int neighbors_=8,int gridx=8, int gridy=8,double threshold = DBL_MAX) :_grid_x(gridx),_grid_y(gridy),_radius(radius_),_neighbors(neighbors_),_threshold(threshold) {}// Initializes and computes this LBPH Model. The current implementation is// rather fixed as it uses the Extended Local Binary Patterns per default.//// (radius=1), (neighbors=8) are used in the local binary patterns creation.// (grid_x=8), (grid_y=8) controls the grid size of the spatial histograms.LBPH(InputArrayOfArrays src,InputArray labels,int radius_=1, int neighbors_=8,int gridx=8, int gridy=8,double threshold = DBL_MAX) :_grid_x(gridx),_grid_y(gridy),_radius(radius_),_neighbors(neighbors_),_threshold(threshold) {train(src, labels);}~LBPH() { }// Computes a LBPH model with images in src and// corresponding labels in labels.void train(InputArrayOfArrays src, InputArray labels);// Updates this LBPH model with images in src and// corresponding labels in labels.void update(InputArrayOfArrays src, InputArray labels);// Predicts the label of a query image in src.int predict(InputArray src) const;// Predicts the label and confidence for a given sample.void predict(InputArray _src, int &label, double &dist) const;// See FaceRecognizer::load.void load(const FileStorage& fs);// See FaceRecognizer::save.void save(FileStorage& fs) const;// Getter functions.int neighbors() const { return _neighbors; }int radius() const { return _radius; }int grid_x() const { return _grid_x; }int grid_y() const { return _grid_y; }AlgorithmInfo* info() const;};//------------------------------------------------------------------------------// FaceRecognizer//------------------------------------------------------------------------------void FaceRecognizer::update(InputArrayOfArrays src, InputArray labels ) {if( dynamic_cast<LBPH*>(this) != 0 ){dynamic_cast<LBPH*>(this)->update( src, labels );return;}string error_msg = format("This FaceRecognizer (%s) does not support updating, you have to use FaceRecognizer::train to update it.", this->name().c_str());CV_Error(CV_StsNotImplemented, error_msg);}void FaceRecognizer::save(const string& filename) const {FileStorage fs(filename, FileStorage::WRITE);if (!fs.isOpened())CV_Error(CV_StsError, "File can't be opened for writing!");this->save(fs);fs.release();}void FaceRecognizer::load(const string& filename) {FileStorage fs(filename, FileStorage::READ);if (!fs.isOpened())CV_Error(CV_StsError, "File can't be opened for writing!");this->load(fs);fs.release();}//------------------------------------------------------------------------------// Eigenfaces特征脸训练函数//------------------------------------------------------------------------------void Eigenfaces::train(InputArrayOfArrays _src, InputArray _local_labels) {if(_src.total() == 0) {string error_message = format("Empty training data was given. You'll need more than one sample to learn a model.");CV_Error(CV_StsBadArg, error_message);} else if(_local_labels.getMat().type() != CV_32SC1) {string error_message = format("Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _local_labels.type());CV_Error(CV_StsBadArg, error_message);}// make sure data has correct size确保输⼊的图像数据尺⼨正确(所有尺⼨相同)if(_src.total() > 1) {for(int i = 1; i < static_cast<int>(_src.total()); i++) {if(_src.getMat(i-1).total() != _src.getMat(i).total()) {string error_message = format("In the Eigenfaces method all input samples (training images) must be of equal size! Expected %d pixels, but was %d pixels.", _src.getMat(i-1).total(), _src.getMat(i).total()); CV_Error(CV_StsUnsupportedFormat, error_message);}}}// get labelsMat labels = _local_labels.getMat();// observations in rowMat data = asRowMatrix(_src, CV_64FC1);//将_src中存放的图像列表中的每幅图像(reshape成1⾏)作为data的⼀⾏// number of samplesint n = data.rows;// assert there are as much samples as labelsif(static_cast<int>(labels.total()) != n) {string error_message = format("The number of samples (src) must equal the number of labels (labels)! len(src)=%d, len(labels)=%d.", n, labels.total());CV_Error(CV_StsBadArg, error_message);// clear existing model data_labels.release();_projections.clear();// clip number of components to be validif((_num_components <= 0) || (_num_components > n))_num_components = n;// perform the PCAPCA pca(data, Mat(), CV_PCA_DATA_AS_ROW, _num_components);// copy the PCA results_mean = pca.mean.reshape(1,1); // store the mean vector获取均值向量_eigenvalues = pca.eigenvalues.clone(); // eigenvalues by row获取特征值transpose(pca.eigenvectors, _eigenvectors); // eigenvectors by column获取特征向量// store labels for prediction_labels = labels.clone();//获取分类标签// save projectionsfor(int sampleIdx = 0; sampleIdx < data.rows; sampleIdx++) {Mat p = subspaceProject(_eigenvectors, _mean, data.row(sampleIdx));_projections.push_back(p);}}void Eigenfaces::predict(InputArray _src, int &minClass, double &minDist) const {// get dataMat src = _src.getMat();// make sure the user is passing correct dataif(_projections.empty()) {// throw error if no data (or simply return -1?)string error_message = "This Eigenfaces model is not computed yet. Did you call Eigenfaces::train?";CV_Error(CV_StsError, error_message);} else if(_eigenvectors.rows != static_cast<int>(src.total())) {// check data alignment just for clearer exception messagesstring error_message = format("Wrong input image size. Reason: Training and Test images must be of equal size! Expected an image with %d elements, but got %d.", _eigenvectors.rows, src.total()); CV_Error(CV_StsBadArg, error_message);}// project into PCA subspaceMat q = subspaceProject(_eigenvectors, _mean, src.reshape(1,1));// 投影到PCA的主成分空间minDist = DBL_MAX;minClass = -1;//求L2范数也就是欧式距离for(size_t sampleIdx = 0; sampleIdx < _projections.size(); sampleIdx++) {double dist = norm(_projections[sampleIdx], q, NORM_L2);if((dist < minDist) && (dist < _threshold)) {minDist = dist;minClass = _labels.at<int>((int)sampleIdx);}}}int Eigenfaces::predict(InputArray _src) const {int label;double dummy;predict(_src, label, dummy);return label;}void Eigenfaces::load(const FileStorage& fs) {//read matricesfs["num_components"] >> _num_components;fs["mean"] >> _mean;fs["eigenvalues"] >> _eigenvalues;fs["eigenvectors"] >> _eigenvectors;// read sequencesreadFileNodeList(fs["projections"], _projections);fs["labels"] >> _labels;}void Eigenfaces::save(FileStorage& fs) const {// write matricesfs << "num_components" << _num_components;fs << "mean" << _mean;fs << "eigenvalues" << _eigenvalues;fs << "eigenvectors" << _eigenvectors;// write sequenceswriteFileNodeList(fs, "projections", _projections);fs << "labels" << _labels;}//------------------------------------------------------------------------------// Fisherfaces//------------------------------------------------------------------------------void Fisherfaces::train(InputArrayOfArrays src, InputArray _lbls) {if(src.total() == 0) {string error_message = format("Empty training data was given. You'll need more than one sample to learn a model.");CV_Error(CV_StsBadArg, error_message);} else if(_lbls.getMat().type() != CV_32SC1) {string error_message = format("Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _lbls.type());CV_Error(CV_StsBadArg, error_message);}// make sure data has correct sizeif(src.total() > 1) {if(src.getMat(i-1).total() != src.getMat(i).total()) {string error_message = format("In the Fisherfaces method all input samples (training images) must be of equal size! Expected %d pixels, but was %d pixels.", src.getMat(i-1).total(), src.getMat(i).total()); CV_Error(CV_StsUnsupportedFormat, error_message);}}}// get dataMat labels = _lbls.getMat();Mat data = asRowMatrix(src, CV_64FC1);// number of samplesint N = data.rows;// make sure labels are passed in correct shapeif(labels.total() != (size_t) N) {string error_message = format("The number of samples (src) must equal the number of labels (labels)! len(src)=%d, len(labels)=%d.", N, labels.total());CV_Error(CV_StsBadArg, error_message);} else if(labels.rows != 1 && labels.cols != 1) {string error_message = format("Expected the labels in a matrix with one row or column! Given dimensions are rows=%s, cols=%d.", labels.rows, labels.cols);CV_Error(CV_StsBadArg, error_message);}// clear existing model data_labels.release();_projections.clear();// safely copy from cv::Mat to std::vectorvector<int> ll;for(unsigned int i = 0; i < labels.total(); i++) {ll.push_back(labels.at<int>(i));}// get the number of unique classesint C = (int) remove_dups(ll).size();// clip number of components to be a valid numberif((_num_components <= 0) || (_num_components > (C-1)))_num_components = (C-1);// perform a PCA and keep (N-C) componentsPCA pca(data, Mat(), CV_PCA_DATA_AS_ROW, (N-C));// project the data and perform a LDA on itLDA lda(pca.project(data),labels, _num_components);// store the total mean vector_mean = pca.mean.reshape(1,1);// store labels_labels = labels.clone();// store the eigenvalues of the discriminantslda.eigenvalues().convertTo(_eigenvalues, CV_64FC1);// Now calculate the projection matrix as pca.eigenvectors * lda.eigenvectors.// Note: OpenCV stores the eigenvectors by row, so we need to transpose it!gemm(pca.eigenvectors, lda.eigenvectors(), 1.0, Mat(), 0.0, _eigenvectors, GEMM_1_T);// store the projections of the original datafor(int sampleIdx = 0; sampleIdx < data.rows; sampleIdx++) {Mat p = subspaceProject(_eigenvectors, _mean, data.row(sampleIdx));_projections.push_back(p);}}void Fisherfaces::predict(InputArray _src, int &minClass, double &minDist) const {Mat src = _src.getMat();// check data alignment just for clearer exception messagesif(_projections.empty()) {// throw error if no data (or simply return -1?)string error_message = "This Fisherfaces model is not computed yet. Did you call Fisherfaces::train?";CV_Error(CV_StsBadArg, error_message);} else if(src.total() != (size_t) _eigenvectors.rows) {string error_message = format("Wrong input image size. Reason: Training and Test images must be of equal size! Expected an image with %d elements, but got %d.", _eigenvectors.rows, src.total());CV_Error(CV_StsBadArg, error_message);}// project into LDA subspaceMat q = subspaceProject(_eigenvectors, _mean, src.reshape(1,1));// find 1-nearest neighborminDist = DBL_MAX;minClass = -1;for(size_t sampleIdx = 0; sampleIdx < _projections.size(); sampleIdx++) {double dist = norm(_projections[sampleIdx], q, NORM_L2);if((dist < minDist) && (dist < _threshold)) {minDist = dist;minClass = _labels.at<int>((int)sampleIdx);}}}int Fisherfaces::predict(InputArray _src) const {int label;double dummy;predict(_src, label, dummy);return label;}// See FaceRecognizer::load.void Fisherfaces::load(const FileStorage& fs) {//read matricesfs["num_components"] >> _num_components;fs["mean"] >> _mean;fs["eigenvalues"] >> _eigenvalues;fs["eigenvectors"] >> _eigenvectors;readFileNodeList(fs["projections"], _projections);fs["labels"] >> _labels;}// See FaceRecognizer::save.void Fisherfaces::save(FileStorage& fs) const {// write matricesfs << "num_components" << _num_components;fs << "mean" << _mean;fs << "eigenvalues" << _eigenvalues;fs << "eigenvectors" << _eigenvectors;// write sequenceswriteFileNodeList(fs, "projections", _projections);fs << "labels" << _labels;}//------------------------------------------------------------------------------// LBPH//------------------------------------------------------------------------------template <typename _Tp> staticvoid olbp_(InputArray _src, OutputArray _dst) {// get matricesMat src = _src.getMat();// allocate memory for result_dst.create(src.rows-2, src.cols-2, CV_8UC1);Mat dst = _dst.getMat();// zero the result matrixdst.setTo(0);// calculate patternsfor(int i=1;i<src.rows-1;i++) {for(int j=1;j<src.cols-1;j++) {_Tp center = src.at<_Tp>(i,j);unsigned char code = 0;code |= (src.at<_Tp>(i-1,j-1) >= center) << 7;code |= (src.at<_Tp>(i-1,j) >= center) << 6;code |= (src.at<_Tp>(i-1,j+1) >= center) << 5;code |= (src.at<_Tp>(i,j+1) >= center) << 4;code |= (src.at<_Tp>(i+1,j+1) >= center) << 3;code |= (src.at<_Tp>(i+1,j) >= center) << 2;code |= (src.at<_Tp>(i+1,j-1) >= center) << 1;code |= (src.at<_Tp>(i,j-1) >= center) << 0;dst.at<unsigned char>(i-1,j-1) = code;}}}//------------------------------------------------------------------------------// cv::elbp//------------------------------------------------------------------------------template <typename _Tp> staticinline void elbp_(InputArray _src, OutputArray _dst, int radius, int neighbors) {//get matricesMat src = _src.getMat();// allocate memory for result_dst.create(src.rows-2*radius, src.cols-2*radius, CV_32SC1);Mat dst = _dst.getMat();// zerodst.setTo(0);for(int n=0; n<neighbors; n++) {// sample pointsfloat x = static_cast<float>(radius * cos(2.0*CV_PI*n/static_cast<float>(neighbors)));float y = static_cast<float>(-radius * sin(2.0*CV_PI*n/static_cast<float>(neighbors)));// relative indicesint fx = static_cast<int>(floor(x));int fy = static_cast<int>(floor(y));int cx = static_cast<int>(ceil(x));int cy = static_cast<int>(ceil(y));// fractional partfloat ty = y - fy;float tx = x - fx;// set interpolation weightsfloat w1 = (1 - tx) * (1 - ty);float w2 = tx * (1 - ty);float w3 = (1 - tx) * ty;float w4 = tx * ty;// iterate through your datafor(int i=radius; i < src.rows-radius;i++) {for(int j=radius;j < src.cols-radius;j++) {// calculate interpolated valuefloat t = static_cast<float>(w1*src.at<_Tp>(i+fy,j+fx) + w2*src.at<_Tp>(i+fy,j+cx) + w3*src.at<_Tp>(i+cy,j+fx) + w4*src.at<_Tp>(i+cy,j+cx));// floating point precision, so check some machine-dependent epsilondst.at<int>(i-radius,j-radius) += ((t > src.at<_Tp>(i,j)) || (std::abs(t-src.at<_Tp>(i,j)) < std::numeric_limits<float>::epsilon())) << n;}}}}static void elbp(InputArray src, OutputArray dst, int radius, int neighbors){int type = src.type();case CV_8SC1: elbp_<char>(src,dst, radius, neighbors); break;case CV_8UC1: elbp_<unsigned char>(src, dst, radius, neighbors); break;case CV_16SC1: elbp_<short>(src,dst, radius, neighbors); break;case CV_16UC1: elbp_<unsigned short>(src,dst, radius, neighbors); break;case CV_32SC1: elbp_<int>(src,dst, radius, neighbors); break;case CV_32FC1: elbp_<float>(src,dst, radius, neighbors); break;case CV_64FC1: elbp_<double>(src,dst, radius, neighbors); break;default:string error_msg = format("Using Original Local Binary Patterns for feature extraction only works on single-channel images (given %d). Please pass the image data as a grayscale image!", type); CV_Error(CV_StsNotImplemented, error_msg);break;}}static Mathistc_(const Mat& src, int minVal=0, int maxVal=255, bool normed=false){Mat result;// Establish the number of bins.int histSize = maxVal-minVal+1;// Set the ranges.float range[] = { static_cast<float>(minVal), static_cast<float>(maxVal+1) };const float* histRange = { range };// calc histogramcalcHist(&src, 1, 0, Mat(), result, 1, &histSize, &histRange, true, false);// normalizeif(normed) {result /= (int)src.total();}return result.reshape(1,1);}static Mat histc(InputArray _src, int minVal, int maxVal, bool normed){Mat src = _src.getMat();switch (src.type()) {case CV_8SC1:return histc_(Mat_<float>(src), minVal, maxVal, normed);break;case CV_8UC1:return histc_(src, minVal, maxVal, normed);break;case CV_16SC1:return histc_(Mat_<float>(src), minVal, maxVal, normed);break;case CV_16UC1:return histc_(src, minVal, maxVal, normed);break;case CV_32SC1:return histc_(Mat_<float>(src), minVal, maxVal, normed);break;case CV_32FC1:return histc_(src, minVal, maxVal, normed);break;default:CV_Error(CV_StsUnmatchedFormats, "This type is not implemented yet."); break;}return Mat();}static Mat spatial_histogram(InputArray _src, int numPatterns,int grid_x, int grid_y, bool/*normed*/){Mat src = _src.getMat();// calculate LBP patch sizeint width = src.cols/grid_x;int height = src.rows/grid_y;// allocate memory for the spatial histogramMat result = Mat::zeros(grid_x * grid_y, numPatterns, CV_32FC1);// return matrix with zeros if no data was givenif(src.empty())return result.reshape(1,1);// initial result_rowint resultRowIdx = 0;// iterate through gridfor(int i = 0; i < grid_y; i++) {for(int j = 0; j < grid_x; j++) {Mat src_cell = Mat(src, Range(i*height,(i+1)*height), Range(j*width,(j+1)*width));Mat cell_hist = histc(src_cell, 0, (numPatterns-1), true);// copy to the result matrixMat result_row = result.row(resultRowIdx);cell_hist.reshape(1,1).convertTo(result_row, CV_32FC1);// increase row count in result matrixresultRowIdx++;}}// return result as reshaped feature vectorreturn result.reshape(1,1);}// wrapper to cv::elbp (extended local binary patterns)//------------------------------------------------------------------------------static Mat elbp(InputArray src, int radius, int neighbors) {Mat dst;elbp(src, dst, radius, neighbors);return dst;}void LBPH::load(const FileStorage& fs) {fs["radius"] >> _radius;fs["neighbors"] >> _neighbors;fs["grid_x"] >> _grid_x;fs["grid_y"] >> _grid_y;//read matricesreadFileNodeList(fs["histograms"], _histograms);fs["labels"] >> _labels;}// See FaceRecognizer::save.void LBPH::save(FileStorage& fs) const {fs << "radius" << _radius;fs << "neighbors" << _neighbors;fs << "grid_x" << _grid_x;fs << "grid_y" << _grid_y;// write matriceswriteFileNodeList(fs, "histograms", _histograms);fs << "labels" << _labels;}void LBPH::train(InputArrayOfArrays _in_src, InputArray _in_labels) {this->train(_in_src, _in_labels, false);}void LBPH::update(InputArrayOfArrays _in_src, InputArray _in_labels) {// got no data, just returnif(_in_src.total() == 0)return;this->train(_in_src, _in_labels, true);}void LBPH::train(InputArrayOfArrays _in_src, InputArray _in_labels, bool preserveData) {if(_in_src.kind() != _InputArray::STD_VECTOR_MAT && _in_src.kind() != _InputArray::STD_VECTOR_VECTOR) {string error_message = "The images are expected as InputArray::STD_VECTOR_MAT (a std::vector<Mat>) or _InputArray::STD_VECTOR_VECTOR (a std::vector< vector<...> >)."; CV_Error(CV_StsBadArg, error_message);}if(_in_src.total() == 0) {string error_message = format("Empty training data was given. You'll need more than one sample to learn a model.");CV_Error(CV_StsUnsupportedFormat, error_message);} else if(_in_labels.getMat().type() != CV_32SC1) {string error_message = format("Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _in_labels.type());CV_Error(CV_StsUnsupportedFormat, error_message);}// get the vector of matricesvector<Mat> src;_in_src.getMatVector(src);// get the label matrixMat labels = _in_labels.getMat();// check if data is well- alignedif(labels.total() != src.size()) {string error_message = format("The number of samples (src) must equal the number of labels (labels). Was len(samples)=%d, len(labels)=%d.", src.size(), _labels.total());CV_Error(CV_StsBadArg, error_message);}// if this model should be trained without preserving old data, delete old model dataif(!preserveData) {_labels.release();_histograms.clear();}// append labels to _labels matrixfor(size_t labelIdx = 0; labelIdx < labels.total(); labelIdx++) {_labels.push_back(labels.at<int>((int)labelIdx));}// store the spatial histograms of the original datafor(size_t sampleIdx = 0; sampleIdx < src.size(); sampleIdx++) {// calculate lbp imageMat lbp_image = elbp(src[sampleIdx], _radius, _neighbors);// get spatial histogram from this lbp imageMat p = spatial_histogram(lbp_image, /* lbp_image */static_cast<int>(std::pow(2.0, static_cast<double>(_neighbors))), /* number of possible patterns */_grid_x, /* grid size x */_grid_y, /* grid size y */true);// add to templates_histograms.push_back(p);}}void LBPH::predict(InputArray _src, int &minClass, double &minDist) const {if(_histograms.empty()) {。
基于PCA的人脸识别

本文基于PCA算法,实现人脸识别。
首先,我们来看一下测试结果:由于本文只是简单地对训练人脸进行降维处理,并没有考虑其他影响因素,所以识别率相对来说比较低。
下面给出具体代码:function varargout = FaceRec(varargin)% FACEREC M-file for FaceRec.fig% FACEREC, by itself, creates a new FACEREC or raises the existing % singleton*.%% H = FACEREC returns the handle to a new FACEREC or the handle to% the existing singleton*.%% FACEREC('CALLBACK',hObject,eventData,handles,...) calls the local% function named CALLBACK in FACEREC.M with the given input arguments.%% FACEREC('Property','Value',...) creates a new FACEREC or raises the% existing singleton*. Starting from the left, property valuepairs are% applied to the GUI before FaceRec_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application% stop. All inputs are passed to FaceRec_OpeningFcn via varargin. %% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one% instance to run (singleton)".%% See also: GUIDE, GUIDATA, GUIHANDLES% Edit the above text to modify the response to help FaceRec% Last Modified by GUIDE v2.5 29-Nov-2013 19:23:02% Begin initialization code - DO NOT EDITgui_Singleton = 1;gui_State = struct('gui_Name', mfilename, ...'gui_Singleton', gui_Singleton, ...'gui_OpeningFcn', @FaceRec_OpeningFcn, ...'gui_OutputFcn', @FaceRec_OutputFcn, ...'gui_LayoutFcn', [] , ...'gui_Callback', []);if nargin && ischar(varargin{1})gui_State.gui_Callback = str2func(varargin{1});endif nargout[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); elsegui_mainfcn(gui_State, varargin{:});end% End initialization code - DO NOT EDIT% --- Executes just before FaceRec is made visible.function FaceRec_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn.% hObject handle to figure% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)% varargin command line arguments to FaceRec (see VARARGIN)set(handles.axes1,'xtick',[],'ytick',[])set(handles.axes2,'xtick',[],'ytick',[])% Choose default command line output for FaceRechandles.output = hObject;% Update handles structureguidata(hObject, handles);% UIWAIT makes FaceRec wait for user response (see UIRESUME)% uiwait(handles.figure1);% --- Outputs from this function are returned to the command line. function varargout = FaceRec_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)% Get default command line output from handles structurevarargout{1} = handles.output;% --- Executes on button press in btnFaceDataBase.function btnFaceDataBase_Callback(hObject, eventdata, handles)% 选择训练人脸库% hObject handle to btnFaceDataBase (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) DBPath = uigetdir( 'E:/','Select training database path' );if DBPath == 0msgbox('为选择任何文件夹!')return;endfile = dir(DBPath);img = [];imgray = [];dataBase = [];imageName = {};j = 1;for i = 1:size(file,1)ifnot(strcmp(file(i).name,'.')|strcmp(file(i).name,'..')|strcmp(file(i).name,'Thumbs.db'))imageName{j} = {file(i).name};%记录每张脸的名字j = j+1;img = imread(strcat(DBPath,'\',file(i).name));if size(img,3) == 3imgray = double(rgb2gray(img));elseimgray = double(img);enddataBase=[dataBase ; imgray(:)'];endendbase = DimentionDEC(dataBase);handles.faceDataBase = dataBase;handles.PCABase = base;handles.faceName = imageName;guidata(hObject, handles);% --- Executes on button press in btnTestFace.function btnTestFace_Callback(hObject, eventdata, handles)%选择测试人脸% hObject handle to btnTestFace (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) strPath = 'E:/';%'D:\Documents\MATLAB';[fname pname] = uigetfile({'*.jpg ; *.bmp ; *.pgm'},'choose a test face',strPath);%没选择文件处理,异常机制if isequal(fname,0)||isequal(pname,0)errordlg('没有选中文件','打开');return;endstring = strcat(pname,fname);img = imread(string);xy = size(img);btnReset_Callback(hObject, eventdata, handles)axes(handles.axes1)imshow(img)set(handles.textTest,'string',fname(1:length(fname)-4))imgray =[];if size(img , 3) == 3imgray = rgb2gray(img);elseimgray = img;endimTest = double(imgray);handles.MN = xy;handles.testFace = imTest;guidata(hObject,handles)% --- Executes on button press in btnMatching.function btnMatching_Callback(hObject, eventdata, handles)% hObject handle to btnMatching (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB% handles structure with handles and user data (see GUIDATA) [matchingFace index] = Test(handles.faceDataBase , handles.testFace , handles.PCABase , handles.MN);axes(handles.axes2)imshow(matchingFace)matchingFaceName = cell2mat(handles.faceName{index(1)});set(handles.textMatching,'string',matchingFaceName(1:length(match ingFaceName)-4))% --- Executes on button press in btnReset.function btnReset_Callback(hObject, eventdata, handles)% hObject handle to btnReset (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB% handles structure with handles and user data (see GUIDATA)axes(handles.axes1)claset(handles.axes1,'visible','on','xtick',[],'ytick',[]);set(handles.textTest,'string','')axes(handles.axes2)claset(handles.axes2,'visible','on','xtick',[],'ytick',[]);set(handles.textMatching,'string','')2.通过PCA降维,提取主成分function base = DimentionDEC(sampleFace)%parameter:input--sampleFace:训练人脸% output--base:空间变换基meansam = mean(sampleFace);dvalue = sampleFace - repmat(meansam,size(sampleFace,1),1);covMatT = dvalue * dvalue';% the convected matrix of covariance matrix of sample[V D] = eig(covMatT);%sort the eigenvector and eigenvalue in the order of decsend_eigenvalue D = diag(D);dsort = flipud(D);vsort = fliplr(V);%extract the 90% of the PCdsum = sum(dsort);dsum_extract = 0;p=0;while dsum_extract/dsum<0.9p = p+1;dsum_extract = sum(dsort(1:p));endvbase = vsort(:,1:p);base = dvalue' * vbase*diag(dsort(1:p).^(-1/2));%PCAFace = sampleFace * base;end3.输入测试人脸,匹配训练人脸库function [result index]= Test(faceDataBase , image , base , xy)%parameter:input--faceDataBase:训练人脸% image:待测试人脸% base:空间变换基% xy:图像大小% output--result:匹配的图像% index:2范数距离下排序的索引imTest = image(:)';PCADataBase = faceDataBase * base;coor = imTest * base;for k = 1:size(faceDataBase,1)kdist(k) = norm(coor-PCADataBase(k,:));end[~, index] = sort(kdist);result = reshape(uint8(faceDataBase(index(1),:)),xy(1),xy(2));end。
基于OpenCv的人脸识别系统设计与实现代码大全

基于OpenCv的人脸识别系统设计与实现1.1 题目的主要研究内容(宋体四号加粗左对齐)(1)工作的主要描述:本文设计了基于 OpenCV 库的人脸识别系统,采用Haar 人脸特征,详细描述了人脸识别设计实现的方式,并设计所对应阶段的逻辑框架,最后结合逻辑框架运用 Python 语言编写并验证本文设计的人脸识别系统。
通过多次训练验证并实现人脸识别及判别功能。
(2)系统流程图:1.2 题目研究的工作基础或实验条件(1)硬件环境笔记本电脑,处理器:R7 5800H(2)软件环境开发语言:Python开发工具:PyCharm20211.3 数据集描述一个程序能识别给定图像或视频中的人脸。
实现这一目标的方法之一是用一系列分类好的图像来“训练”数据,并基于这些图像来进行识别。
获取数据:可以通过网上搜索图片或者自己录入(我们选择的是从网上下载某些人的图片来训练数据)有了数据,需要将这些样本图像加载到人脸识别算法中。
所有的人脸识别算法在它们的train()函数中都有两个参数:图像数组和标签数组。
这些标签表示进行识别时候某人人脸的ID,因此根据ID可以知道被识别的人是谁。
要做的这一点需要生成一个.yml文件。
1.4 人脸特征提取过程描述特征提取是人脸识别的关键问题之一。
本设计中主要采用的是Harr特征提取方法。
摄影作品可能包含很多令人愉悦的细节。
但是,由于灯光、视角、视距、摄像头抖动以及数字噪声的变化,图像细节变得不稳定。
人们在分类时不会受这些物理细节方面差异的影响。
提取出图像的细节对产生稳定分类结果和跟踪结果很有用处。
这些提取的结果被称为特征,专业的表述为:从图像数据中提取特征。
Haar特征是一种用于实现实时人脸跟踪的特征。
每一个Haar特征都描述了相邻图像区域的对比模式。
1.5 人脸识别过程描述人脸识别采用的是LBPH算法,LBPH(Local Binary Pattern Histogram)将检测到的人脸分为小单元,并将其与模型中的对应单元进行比较,对每个区域的匹配值产生一个直方图。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
void printUsage();
//主函数,主要包括学习和识别两个阶段,需要运行两次,通过命令行传入的参数区分
int main()
{
//learn();
recognize();
}
//学习阶段代码
void learn()
{
cout<<"开始训练过程"<<endl;
//开始计时
clock_t start,finish;
double duration;
start = clock();
#include "StdAfx.h"
#include <stdio.h>
#include <string.h>
#include "cv.h"
#include "cvaux.h"
#include "highgui.h"
#include "time.h"
#include "iostream"
if( !fileStorage )
{
fprintf(stderr, "Can't open facedata.xml\n");
return 0;
}
nEigens = cvReadIntByName(fileStorage, 0, "nEigens", 0);
cout<<"训练过程结束,共耗时:"<<duration<<"秒"<<endl;
}
//识别阶段代码
void recognize()
{
cout<<"开始识别过程"<<endl;
//开始计时
clock_t start,finish;
truth = personNumTruthMat->data.i[i];
nearest = trainPersonNumMat->data.i[iNearest];
printf("nearest = %d, Truth = %d\n", nearest, truth);
//加载保存过的训练结果
int loadTrainingData(CvMat ** pTrainPersonNumMat)
{
CvFileStorage * fileStorage;
int i;
fileStorage = cvOpenFileStorage( "facedata.xml", 0, CV_STORAGE_READ );
for(i=0; i<nTrainFaces; i++)
{
//int offset = i * nEigens;
cvEigenDecomposite(
faceImgArr[i],
nEigens,
eigenVectArr,
0, 0,
pAvgTrainImg,
//projectedTrainFaceMat->data.fl + i*nEigens);
projectedTrainFaceMat->data.fl + i*offset);
{
int iNearest, nearest, truth;
//将测试图像投影到子空间中
cvEigenDecomposite(
faceImgArr[i],
nEigens,
if( !loadTrainingData( &trainPersonNumMat ) )
return;
projectedTestFace = (float *)cvAlloc( nEigens*sizeof(float) );
for(i=0; i<nTestFaces; i++)
eigenVectArr,
0, 0,
pAvgTrainImg,
projectedTestFace);
iNearest = findNearestNeighbor(projectedTestFace);
}
//结束计时
finish = clock();
duration = (double)(finish-start) / CLOCKS_PER_SEC;
cout<<"识别过程结束,共耗时:"<<duration<<"秒"<<endl;
}
doPCA();
//将训练图集投影到子空间中
projectedTrainFaceMat = cvCreateMat( nTrainFaces, nEigens, CV_32FC1 );
offset = projectedTrainFaceMat->step / sizeof(float);
double duration;
start = clocຫໍສະໝຸດ (); // 测试人脸数
int i, nTestFaces = 0;
// 训练阶段的人脸数
CvMat * trainPersonNumMat = 0;
float * projectedTestFace = 0;
eigenValMat = (CvMat *)cvReadByName(fileStorage, 0, "eigenValMat", 0);
projectedTrainFaceMat = (CvMat *)cvReadByName(fileStorage, 0, "projectedTrainFaceMat", 0);
for(i=0; i<nEigens; i++)
{
char varname[200];
sprintf( varname, "eigenVect_%d", i );
eigenVectArr[i] = (IplImage *)cvReadByName(fileStorage, 0, varname, 0);
cvWriteInt( fileStorage, "nTrainFaces", nTrainFaces );
"Need 2 or more training faces\n"
"Input file contains only %d\n", nTrainFaces);
return;
}
// 进行主成分分析
int nTrainFaces = 0; // 训练图像的数目
int nEigens = 0; // 自己取的主要特征值数目
IplImage * pAvgTrainImg = 0; // 训练人脸数据的平均值
//// 函数原型
void learn();
void recognize();
void doPCA();
void storeTrainingData();
int loadTrainingData(CvMat ** pTrainPersonNumMat);
int findNearestNeighbor(float * projectedTestFace);
pAvgTrainImg = (IplImage *)cvReadByName(fileStorage, 0, "avgTrainImg", 0);
eigenVectArr = (IplImage **)cvAlloc(nTrainFaces*sizeof(IplImage *));
int i;
fileStorage = cvOpenFileStorage( "facedata.xml", 0, CV_STORAGE_WRITE );
//存储特征值,投影矩阵,平均矩阵等训练结果
cvWriteInt( fileStorage, "nEigens", nEigens );
using namespace cv;
using namespace std;
////定义几个重要的全局变量
IplImage ** faceImgArr = 0; // 指向训练人脸和测试人脸的指针(在学习和识别阶段指向不同)
CvMat * personNumTruthMat = 0; // 人脸图像的ID号
nTrainFaces = cvReadIntByName(fileStorage, 0, "nTrainFaces", 0);
*pTrainPersonNumMat = (CvMat *)cvReadByName(fileStorage, 0, "trainPersonNumMat", 0);
}
//将训练阶段得到的特征值,投影矩阵等数据存为.xml文件,以备测试时使用
storeTrainingData();
//结束计时
finish = clock();
duration = (double)(finish-start) / CLOCKS_PER_SEC;
int i, offset;
//加载训练图像集