赞
踩
一、准备
链接:代码+数据集
提取码:led1
环境:win10,vs2013,opencv3.2
注:每个代码都可以在vs中单独运行
该项目所有文件如下:
其中只需要使用的文件如下:
详细代码:
- //这个是生成照片的代码
- #include <opencv2/opencv.hpp>
- #include <iostream>
-
- using namespace cv;
- using namespace std;
-
- //cv库,哈尔检测人脸使用的配置文件
- string haar_face_datapath = "E:/opencv/install/etc/haarcascades/haarcascade_frontalface_alt_tree.xml";
-
-
- int main(int argc, char** argv) {
- //打开摄像头
- VideoCapture capture(0);
- if (!capture.isOpened()) {
- printf("could not open camera...\n");
- return -1;
- }
- Size S = Size((int)capture.get(CV_CAP_PROP_FRAME_WIDTH), (int)capture.get(CV_CAP_PROP_FRAME_HEIGHT));
- int fps = capture.get(CV_CAP_PROP_FPS);
-
- //人脸检测库
- CascadeClassifier faceDetector;
- //人脸检测函数
- faceDetector.load(haar_face_datapath);
-
-
- Mat frame;
- namedWindow("camera-demo", CV_WINDOW_AUTOSIZE);
- vector<Rect> faces;
- int count = 0;
- while (capture.read(frame)) {
- flip(frame, frame, 1);
- faceDetector.detectMultiScale(frame, faces, 1.1, 1, 0, Size(100, 120), Size(380, 400));
- for (int i = 0; i < faces.size(); i++) {
- if (count % 10 == 0) {
- Mat dst;
- //重新把照片大小改成模板的大小
- resize(frame(faces[i]), dst, Size(112, 92));
- //保存照片
- imwrite(format("D:/else//led/face_%d.jpg", count), dst);
- }
- rectangle(frame, faces[i], Scalar(0, 0, 255), 2, 8, 0);
- }
- imshow("camera-demo", frame);
- char c = waitKey(10);
- //按键退出截图
- if (c == 27) {
- break;
- }
- count++;
- }
-
- capture.release();
-
- waitKey(0);
- return 0;
- }

- //这个是生成csv文件的教程,直接用shell命令,不需要写代码
-
-
- 1. 打开cmd
-
-
- 2. 输入 F: (因为我的文件在F盘) 注意一定要先进入F盘才可以后续操作,不然会显示找不到文件
-
-
- 3. 输入cd 文件路径,点回车
-
-
- 4. 输入dir /b/s/p/w *.jpg>at.csv 注意,我的文件格式为.jpg
- #include <opencv2/opencv.hpp>
- #include <opencv2/face.hpp>
- #include <iostream>
-
- using namespace cv;
- using namespace cv::face;
- using namespace std;
-
- int main(int argc, char** argv) {
-
- //加载自己的csv文件
- string filename = string("D:/else/wyz/at.csv");
- ifstream file(filename.c_str(), ifstream::in);
- if (!file) {
- printf("could not load file correctly...\n");
- return -1;
- }
-
- string line, path, classlabel;
- vector<Mat> images;
- vector<int> labels;
- char separator = ';';
- while (getline(file, line)) {
- stringstream liness(line);
- getline(liness, path, separator);
- getline(liness, classlabel);
- if (!path.empty() && !classlabel.empty()) {
- //printf("path : %s\n", path.c_str());
- images.push_back(imread(path, 0));
- labels.push_back(atoi(classlabel.c_str()));
- }
- }
-
- if (images.size() < 1 || labels.size() < 1) {
- printf("invalid image path...\n");
- return -1;
- }
-
- int height = images[0].rows;
- int width = images[0].cols;
- printf("height : %d, width : %d\n", height, width);
-
- Mat testSample = images[images.size() - 1];
- int testLabel = labels[labels.size() - 1];
- images.pop_back();
- labels.pop_back();
-
- // train it,训练自己的模型,到这里已经完成训练操作
- Ptr<BasicFaceRecognizer> model = createEigenFaceRecognizer();
- model->train(images, labels);
- model->save("D:/else/wyz/led_wyz.xml");
-
-
- /* 以下两个方法训练模型同样操作
- Ptr<FaceRecognizer> model1 = createFisherFaceRecognizer();
- model1->train(images, labels);
- model1->save("MyFaceFisherModel.xml");
- Ptr<FaceRecognizer> model2 = createLBPHFaceRecognizer();
- model2->train(images, labels);
- model2->save("MyFaceLBPHModel.xml");
- */
-
-
-
- /* 以下内容用于检测验证自己重建的人脸模,可以直接跳过,本代码全部注释掉了
- // recognition face
- int predictedLabel = model->predict(testSample);
- printf("actual label : %d, predict label : %d\n", testLabel, predictedLabel);
- Mat eigenvalues = model->getEigenValues();
- Mat W = model->getEigenVectors();
- Mat mean = model->getMean();
- Mat meanFace = mean.reshape(1, height);
- Mat dst;
- if (meanFace.channels() == 1) {
- normalize(meanFace, dst, 0, 255, NORM_MINMAX, CV_8UC1);
- }
- else if (meanFace.channels() == 3) {
- normalize(meanFace, dst, 0, 255, NORM_MINMAX, CV_8UC3);
- }
- imshow("Mean Face", dst);
- // show eigen faces
- for (int i = 0; i < min(25, W.cols); i++) {
- Mat ev = W.col(i).clone();
- Mat grayscale;
- Mat eigenFace = ev.reshape(1, height);
- if (eigenFace.channels() == 1) {
- normalize(eigenFace, grayscale, 0, 255, NORM_MINMAX, CV_8UC1);
- }
- else if (eigenFace.channels() == 3) {
- normalize(eigenFace, grayscale, 0, 255, NORM_MINMAX, CV_8UC3);
- }
- Mat colorface;
- applyColorMap(grayscale, colorface, COLORMAP_JET);
- char* winTitle = new char[128];
- sprintf(winTitle, "eigenface_%d", i);
- imshow(winTitle, colorface);
- }
- // 重建人脸
- for (int num = min(25, W.cols); num < min(W.cols, 300); num += 1) {
- Mat evs = Mat(W, Range::all(), Range(0, num));
- Mat projection = LDA::subspaceProject(evs, mean, images[0].reshape(1, 1));
- Mat reconstruction = LDA::subspaceReconstruct(evs, mean, projection);
- Mat result = reconstruction.reshape(1, height);
- if (result.channels() == 1) {
- normalize(result, reconstruction, 0, 255, NORM_MINMAX, CV_8UC1);
- }
- else if (result.channels() == 3) {
- normalize(result, reconstruction, 0, 255, NORM_MINMAX, CV_8UC3);
- }
- char* winTitle = new char[128];
- sprintf(winTitle, "recon_face_%d", num);
- imshow(winTitle, reconstruction);
- }
- */
-
- waitKey(0);
- return 0;
- }

二、原理
原理1.PCA(主成分分析)原理
通过对高维数据分析发现他们的相同与不同表达为 一个低维数据模式
主成分不变
细微损失
高维数据到低维数据
原理2.API调用
主要是使用其中的三个函数,来训练自己的数据,函数如下:
- // train it
- Ptr<BasicFaceRecognizer> model = createEigenFaceRecognizer();
- model->train(images, labels);
- model->save("D:/else/wyz/led_wyz.xml");
-
- Ptr<FaceRecognizer> model1 = createFisherFaceRecognizer();
- model1->train(images, labels);
- model1->save("MyFaceFisherModel.xml");
-
- Ptr<FaceRecognizer> model2 = createLBPHFaceRecognizer();
- model2->train(images, labels);
- model2->save("MyFaceLBPHModel.xml");
三、步骤
1. 算法实现步骤
四、结果
结果1.方差均值作用
图像RGB矩阵
空白背景方差不为0,均值为0
结果2.PCA应用
N行2列表示所有的点
得到轮廓中心位置
Eigen得到特征值
结果3..Eigenface算法
平均脸
2. 一个图像N宽*N高*N个 112*92*100个矩阵
3.平均脸 矩阵计算得到均值
4.特征脸 矩阵计算得到特征值
5.开始、读训练数据、计算平均脸、计算协方差矩阵、计算特征值、特征矩阵、 PAC降维、子空间模型、检测
6.生成CSV文件
7.生成自己的xml
8.训练
9.识别
10. 识别率:
11. 侧脸影响
12.暗光条件下,找不到人脸,识别率也降低
结果4.Fisher算法
4.识别率问题,因为这里光亮作为主要因素,光亮无法做到细微控制,这里不做详细比较
5.人脸上半部分处在黑暗环境,与EigenFace比较,差不多同一张图片,这张图能识别出来
结果5.LBPH算法
此算法和前两种的比较,主要是在光照和侧脸角度上有所加强,这里不再多做比较。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。