opencv 中SVM + PCA 人脸识别

这一周一直都在弄人脸识别的东西,这个也可以算是我个人第一个DIY项目,虽然没有在MFC框架下来实现,但我觉得 SVM + PCA 人脸识别这个东西 最主要的还是算法 和效果没有必要一定要在MFC框架下去实现。
从不懂到慢慢明白一些道理,写这样一个技术文档无非就是怕以后忘记这样一个过程。
这个项目得到的经验:
1:我真正领悟到了“二八法则”的真谛。准备加编程阶段看了不少论文,试了不少方法,但
最后真正用到的无非就只有20%不到,但并非是白用功,没有多余的付出,也就不会有多余的回报;
2:体会到了理论与应用之间有着一道很深的鸿沟,理论再扎实,到头来编程还是个新手。当然了,我并不是说我理论有多么深厚,本人也是个菜鸟而已;
3:在调试的时候切记耐心,细心;很多错误都是基于一时意识的模糊造成,并非水平问题, 细心可以解决一切问题;

好了,我再说说在编程中遇到的问题及解决方案吧!希望对来看的人有所帮助!
1:opencv 有PCA函数,用起来还是比较好用的,但是PCA各个函数的参数设置还是需要经过仔细推敲的;比如:
CvMat data;
cvInitMatHeader( &data, (训练样本数), (单一图片维数), CV_32FC1, (数据存储矩阵(行:训练样本数;列:单一图片维数));
CvMat *pMeanVector = cvCreateMat( 1, (单一图片维数), CV_32FC1); 
CvMat *pEigenValue = cvCreateMat( (用户取出的特征向量个数), 1, CV_32FC1); 
CvMat *pEigenVector = cvCreateMat( (用户取出的特征向量个数), (单一图片维数), CV_32FC1); 
这些事PCA中很重要的几个参数;当然了图片是需要做标准处理的;其余的原理什么的还希望大家都去找找论文;多看论文有很大的帮助;
2:SVM训练问题,这个也是整了我好久的一个问题,下面我说的只是我个人的经验,并不能代表绝对正确,只是在我的程序中这样做成功了而已:
其实SVM训练问题一定要看那个日本人写的例子,写的非常的好,但是他的例子有3个,人脸检测部分效果一般,我觉得这个跟我在做识别的时候效果不好可能有相同的不足之处。后来在经过别人指导,在做SVM训练之前一定要将用PCA提取出来能够代表人脸的权值矩阵归一化,这用到了cvNormalize函数,这个函数还是自己找找怎么用的吧!
不光在训练之前要做归一化,也要在识别的时候做归一化的处理。我未做归一化处理之前识别率为0;做了归一化后识别率为75%, 虽然识别率不是很高,这个可能与我选取的特征向量个数,还有就是人脸前期未进行预处理造成的。切记一定要归一化。


这样一个小项目,用了VS2008 + opencv2.0 这样的环境,其实接触opencv也不是很久,对于里面一些函数还不是很了解.
[cpp]  view plain copy
  1. // pca_svm.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "cv.h"  
  6. #include "highgui.h"  
  7. #include "cvaux.h"  
  8. #include "ml.h"  
  9. using namespace cv;  
  10. using namespace std;  
  11.   
  12. int _tmain(int argc, _TCHAR* argv[])  
  13. {     
  14.  vector<Mat> images; //This variable will be loaded with a set of images to perform PCA on.  
  15.  char filename[100];  
  16.  int imageFaceNum = 100;  
  17.  int imageNonFaceNum = 25;  
  18.  int num = 0;  
  19.  Mat src;   
  20.  Mat values(imageFaceNum+imageNonFaceNum, 1, CV_32SC1); //Values are the corresponding values to each of my images.  
  21.  for(int i=1; i<=imageFaceNum; i++) {  
  22.   sprintf(filename,"E:/图片数据库/MIT人脸库/train_face/%d.bmp",i);  
  23.   values.at<int>(i-1,0) = 1;  
  24.   src=cvLoadImage(filename,0);  
  25.   images.push_back(src);  
  26.   num++;  
  27.  }   
  28.  for(int i=1; i<=imageNonFaceNum; i++) {  
  29.   sprintf(filename,"E:/图片数据库/MIT人脸库/train_nonface/%d.bmp",i);  
  30.   values.at<int>(num-1,0) = 0;  
  31.   src=cvLoadImage(filename,0);  
  32.   images.push_back(src);  
  33.   num++;  
  34.  }  
  35.  int nEigens = images.size() - 1; //Number of Eigen Vectors.   
  36.  //Load the images into a Matrix   
  37.  Mat desc_mat(images.size(), images[0].rows * images[0].cols, CV_8UC1);   
  38.  for (int i=0; i<images.size(); i++) {   
  39.    desc_mat.row(i) = images[i].reshape(1, 1) + 0;   
  40.  }   
  41.  Mat average;   
  42.  PCA pca(desc_mat, average, CV_PCA_DATA_AS_ROW, nEigens);   
  43.  Mat data(desc_mat.rows, nEigens, CV_32FC1); //This Mat will contain all the Eigenfaces that will be used later with SVM for detection  
  44.  //Project the images onto the PCA subspace   
  45.  for(int i=0; i<images.size(); i++) {   
  46.    Mat projectedMat(1, nEigens, CV_32FC1);   
  47.    pca.project(desc_mat.row(i), projectedMat);   
  48.    data.row(i) = projectedMat.row(0) + 0;   
  49.  }   
  50.     
  51.  CvMat d1 = (CvMat)data;   
  52.  CvMat d2 = (CvMat)values;   
  53.  CvSVM svm = CvSVM();      
  54.  CvSVMParams param;      
  55.  CvTermCriteria criteria;      
  56.  criteria = cvTermCriteria( CV_TERMCRIT_EPS, 1000, FLT_EPSILON );      
  57.  param = CvSVMParams( CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL, criteria );           
  58.  //☆☆☆☆☆☆☆☆☆(5)SVM学习☆☆☆☆☆☆☆☆☆☆☆☆            
  59.  svm.train( &d1, &d2, NULL, NULL, param );      
  60.  svm.save("svmdata.xml");   
  61.   
  62.    
  63.   
  64.   
  65. PCA pca();  
  66.  Mat cs;  
  67.  Mat cs1(1,400,CV_32FC1);  
  68.  for(int i=1; i<=100; i++) {  
  69.   sprintf(filename,"E:/图片数据库/MIT人脸库/train_face/%d.bmp",i);  
  70.   src=cvLoadImage(filename,0);  
  71.   cs = src.reshape(1, 1) + 0;    
  72.   Mat projectedMat(1, nEigens, CV_32FC1);   
  73.      pca.project(cs, projectedMat);   
  74.   CvMat d3 = (CvMat)projectedMat;   
  75.   int ret = svm.predict(&d3);  
  76.   cout<<ret<<endl;  
  77.   
  78.  }  
  79.   
  80.   
  81.  return 0;  
  82. }  
思路:
所有的人脸看成一组数据,送入opencv里面的PCA做处理,得到平均脸,特征向量,特征值。
选择最大的几个特征值所对应的特征向量,(Opencv里面自己排好序了,所以只要取前几个),保留这一部分跟平均脸。
将原始的数据用Opencv里面一个pcaProject映射的函数,映射到刚才的平均脸上,得到一组系数。
将这组系数送入SVM进行训练。
识别的时候也是用新图像像PCA得到的平均脸,特征向量进行映射,得到相应的系数,再送入SVM进行预测。
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值