一、人脸识别算法之特征脸方法(Eigenface)
1、原理介绍及数据收集
特征脸方法主要是基于PCA降维实现。
详细介绍和主要思想可以参考
http://blog.csdn.net/u010006643/article/details/46417127
上述博客的人脸数据库打不开了,大家可以去下面这个博客下载ORL人脸数据库
http://blog.csdn.net/xdzzju/article/details/50445160
下载后,ORL人脸数据库有40个人,每人10张照片。
2、流程
3、相关图示
4、代码
1 #include <opencv2/opencv.hpp>2 #include <opencv2/face.hpp>3 4 using namespace cv;5 using namespace cv::face;6 using namespace std;7 8 //对原图归一化9 Mat normal(Mat src, Mat dst) {10 if (src.channels() == 1)//若原图单通道11 normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);12 else //否则,原图三通道13 normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);14 return dst;15 }16 17 void main() {18 //读取文件,转换为数据流19 string filename = string("at.txt");20 ifstream file(filename.c_str(), ifstream::in);21 if (!file)22 cout << "error" << endl;23 24 string line, path, classlabel;25 vector<Mat>image;26 vector<int>labels;27 char separator = ';';28 while (getline(file,line))29 {30 stringstream liness(line);31 getline(liness, path, separator);32 getline(liness, classlabel);33 if (!path.empty()&&!classlabel.empty())34 {35 //cout << "path:" << path<< endl;36 image.push_back(imread(path, 0));37 labels.push_back(atoi(classlabel.c_str()));38 }39 }40 41 if (image.size() < 1 || labels.size() < 1)42 cout << "invalid image path..." << endl;43 44 int height = image[0].rows;45 int width = image[0].cols;46 //cout << "height:" << height << ",width:" << width<<endl;47 48 //最后一个人为测试样本49 Mat testSample = image[image.size() - 1];50 int testLabel = labels[labels.size() - 1];51 image.pop_back();52 labels.pop_back();53 54 //训练55 Ptr<BasicFaceRecognizer>model = createEigenFaceRecognizer();56 model->train(image, labels);57 58 //识别59 int predictLabel = model->predict(testSample);60 cout << "actual label:" << testLabel << ",predict label:" << predictLabel << endl;61 62 //获得特征值,特征向量,均值 平均脸63 Mat eigenvalues = model->getEigenValues();64 Mat eigenvectors = model->getEigenVectors();65 Mat mean = model->getMean();66 Mat meanFace = mean.reshape(1,height);67 Mat dst;68 dst= normal(meanFace,dst);69 imshow("Mean Face", dst);70 71 //特征脸72 for (int i = 0; i < min(10,eigenvectors.cols); i++)73 {74 Mat ev = eigenvectors.col(i).clone();75 Mat eigenFace = ev.reshape(1, height);76 Mat grayscale;77 grayscale = normal(eigenFace, grayscale);78 Mat colorface;79 applyColorMap(grayscale, colorface, COLORMAP_BONE);80 char* winTitle = new char[128];81 sprintf(winTitle, "eigenface_%d", i);82 imshow(winTitle, colorface);83 }84 85 //重建人脸86 for (int num = min(10, eigenvectors.cols); num < min(300, eigenvectors.cols); num+=15)87 {88 Mat evs = Mat(eigenvectors, Range::all(), Range(0, num));89 Mat projection = LDA::subspaceProject(evs, mean, image[0].reshape(1, 1));90 Mat reconstruction= LDA::subspaceReconstruct(evs, mean, projection);91 92 Mat result = reconstruction.reshape(1, height);93 reconstruction = normal(result, reconstruction);94 char* winTitle = new char[128];95 sprintf(winTitle, "recon_face_%d", num);96 imshow(winTitle, reconstruction);97 }98 99 waitKey(0); 100 }
二、FisherFace(LDA线性判别分析)
1、理论介绍
http://blog.csdn.net/feirose/article/details/39552997
2、流程
3、PCA和LDA的对比
4、代码(与特征脸代码几乎一致)
此处只列出修改部分
1 2 3 4 5 6 |
|
三、LBPH
1、原理介绍
大家可以参考http://blog.csdn.net/xiaomaishiwoa/article/details/46640377
二、流程
3、代码
#include <opencv2/opencv.hpp> #include <opencv2/face.hpp>using namespace cv; using namespace cv::face; using namespace std;//对原图归一化 Mat normal(Mat src, Mat dst) {if (src.channels() == 1)//若原图单通道normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);else //否则,原图三通道normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);return dst; }void main() {//读取文件,转换为数据流string filename = string("at.txt");ifstream file(filename.c_str(), ifstream::in);if (!file)cout << "error" << endl;string line, path, classlabel;vector<Mat>image;vector<int>labels;char separator = ';';while (getline(file,line)){stringstream liness(line);getline(liness, path, separator);getline(liness, classlabel);if (!path.empty()&&!classlabel.empty()){//cout << "path:" << path<< endl;image.push_back(imread(path, 0));labels.push_back(atoi(classlabel.c_str()));}}if (image.size() < 1 || labels.size() < 1)cout << "invalid image path..." << endl;int height = image[0].rows;int width = image[0].cols;//cout << "height:" << height << ",width:" << width<<endl;//最后一个人为测试样本Mat testSample = image[image.size() - 1];int testLabel = labels[labels.size() - 1];image.pop_back();labels.pop_back();//训练Ptr<LBPHFaceRecognizer>model = createLBPHFaceRecognizer();model->train(image, labels);//识别int predictLabel = model->predict(testSample);cout << "actual label:" << testLabel << ",predict label:" << predictLabel << endl;//打印参数int radius = model->getRadius(); //中心像素点到周围像素点的距离int neibs = model->getNeighbors(); //周围像素点的个数int grad_x = model->getGridX(); //将一张图片在x方向分成几块int grad_y = model->getGridY(); //将一张图片在y方向分成几块double t = model->getThreshold(); //相似度阈值 cout << "radius:" << radius << endl;cout << "neibs:" << neibs << endl;cout << "grad_x:" << grad_x << endl;cout << "grad_y:" << grad_y << endl;cout << "threshold:" << t<<endl;waitKey(0); }
致谢:
1、【技术共享(bin)】怎么把人脸检测的速度做到极致
2、boosting(AdaBoost)算法
3、AdaBoost 算法简介
4、Boosting算法简介