PCA算法:从一组照片中获取特征脸(特征向量)
来源:互联网 发布:初榨椰子油 知乎 编辑:程序博客网 时间:2024/04/30 02:29
本文介绍了对一组照片进行PCA处理的过程和结果。本文使用OpenCV的PCA处理函数,参考了夏天的味道的博客opencv pca。本文使用的照片来源于YelaFaces(直接Baidu就能找到在CSDN上的下载链接,就不上传了)。
一、操作步骤
PCA处理的基本步骤为:
1、获取m个样本,每个样本有n个特征。
2、每个样本作为一行,构成m*n的举证A。
3、将矩阵转置再乘以自己得到C=A(t)*A。
4、求出矩阵C的特征值及特征向量,特征向量即为特征脸。
二、代码及解释
#include "stdafx.h"#include <string>#include <opencv2\opencv.hpp> using namespace std;using namespace cv;int _tmain(int argc, _TCHAR* argv[]){//获取了mean_faceint num_sample = 38;int norm_row = 64, norm_col = 56;int num;Mat imgs = loadImages(num);Mat mean_face = Mat(norm_row, norm_col, CV_8UC1);vector<int> mean_face_total;mean_face_total.resize(norm_row * norm_col);for (int i = 0; i < num; i++){for (int j = 0; j < norm_row * norm_col; j++){mean_face_total.at(j) += imgs.at<uchar>(i * norm_row * norm_col + j);//eigen_face_total[j] += imgs.at<uchar>(i * 192 * 168 + j);}}for (int j = 0; j < norm_row * norm_col; j++){mean_face.at<uchar>(j) = (uchar)(mean_face_total.at(j) / num);}imwrite("C:/Users/dhj555/Desktop/YelaFaces/eigen_face/0001.jpg", mean_face);imshow("eigen_face", mean_face);//1、初始化数据CvMat* pData = cvCreateMat(num_sample, norm_row * norm_col, CV_32FC1);CvMat* pMean = cvCreateMat(1, norm_row * norm_col, CV_32FC1);//每个数标志一个特征值CvMat* pEigVals = cvCreateMat(1, min(num_sample, norm_row * norm_col), CV_32FC1);//每行表示一个特征向量CvMat* pEigVecs = cvCreateMat(min(num_sample, norm_row * norm_col), norm_row * norm_col, CV_32FC1);for (int i = 0; i < num_sample; i++){for (int j = 0; j < norm_row * norm_col; j++)cvmSet(pData, i, j, imgs.at<uchar>(i * norm_row * norm_col + j));}//2、PCA处理cvCalcPCA(pData, pMean, pEigVals, pEigVecs, CV_PCA_DATA_AS_ROW);//3、选出前P个特征向量(主成份),然后投影,结果保存在pResult中,pResult中包含了P个系数//CvMat* pResult = cvCreateMat(num_sample, 20, CV_32FC1);//cvProjectPCA(pData, pMean, pEigVecs, pResult);//4、重构, 结果保存在pRecon中//CvMat* pRecon = cvCreateMat(num_sample, norm_row*norm_col, CV_32FC1);//cvBackProjectPCA(pResult, pMean, pEigVecs, pRecon);//5、显示重构的图像//Mat mRecon = Mat(pRecon);//4、显示与保存特征向量for (int i = 0; i < min(num_sample, norm_row * norm_col); i++){float min = LLONG_MAX, max = LLONG_MIN, span = 0.0;for (int index = 0; index < norm_row*norm_col; index++){float d = cvmGet(pEigVecs, i, index);if (d>max)max = d;if (d < min)min = d;}span = max - min;Mat eigen_face = Mat(norm_row, norm_col, CV_8UC1);for (int index = 0; index < norm_row*norm_col; index++){float d = cvmGet(pEigVecs, i, index);eigen_face.at<uchar>(index) = (d - min) / span * 255.0;}char buffer[128];sprintf_s(buffer, "C:/Users/dhj555/Desktop/YelaFaces/eigen_face/001/1-000%d.jpg", i);string imgPath(buffer);imshow(imgPath, eigen_face);printf("%d st:\t%f\n", i, cvmGet(pEigVals, 0, i));imwrite(imgPath, eigen_face);}}1、第9至16行:声明变量。
2、第18至32行:读取文件到imgs中,总共读取了38张人脸,并将每张人脸缩放为64*56大小,所以imgs为38行,64*56列的矩阵。
3、第34至40行:声明了PCA计算相关的矩阵,具体说明见代码注释。
4、第42至46行:将imgs中的数据写入pData中,以用于PCA计算。
5、第49行:调用OpenCV的函数计算特征值及特征向量。
6、第64至88行:根据特征值导出特征脸并保存显示。
三、实验结果
求出的特征值及相应的特征脸(至上传了前11个,总共38个,可以在这里下载查看所有的):
特征值特征脸0 st: 1512882.0000001 st: 316433.8750002 st: 268737.5312503 st: 248890.3593754 st: 177919.6718755 st: 139744.7187506 st: 112001.9375007 st: 108768.9140638 st: 85501.7734389 st: 72161.31250010 st: 67518.43750011 st: 62258.648438
3 0
- PCA算法:从一组照片中获取特征脸(特征向量)
- PCA算法数学原理(可作为人脸特征)
- 从一组时间列表中获取一组最近的时间
- 特征向量物理意义(PCA)----转帖
- PCA提取特征脸(vs2013+opencv249)
- 人脸识别特征脸提取PCA算法
- 人脸识别特征脸提取PCA算法
- Yale人脸数据库、PCA算法实现Matlab中特征脸生成和简单的人脸识别
- 教程 | 从特征分解到协方差矩阵:详细剖析和实现PCA算法
- 直观上理解PCA中特征值和特征向量
- 直观上理解PCA中特征值和特征向量
- PCA原理及特征脸
- android:如何从照片中获取拍摄地址信息
- Android从摄像头或相册中获取照片
- 自动人脸识别基本原理 --基于静态图像的识别算法(一)特征脸补充知识 PCA
- PCA 的具体实现 (Eigenfaces特征脸)
- PCA 的具体实现 (Eigenfaces特征脸)
- PCA 的具体实现 (Eigenfaces特征脸)
- Codeforces Round #375 (Div. 2) D 连通块
- Android中Looper类
- 习题8.10
- python 学习笔记(4) python函数和模块
- Swift学习记录 -- 16.微博项目初体验
- PCA算法:从一组照片中获取特征脸(特征向量)
- linux下ScrollLock键盘灯不亮
- 欢迎使用CSDN-markdown编辑器
- CentOS 6.8 配置GO语言开发环境
- CSS3新特性(二)
- Navicat连接远程mysql数据库
- NYOJ.925国王的烦恼
- git常用命令总结(待补充)
- java.lang.ClassCastException: android.widget.RelativeLayout$LayoutParams cannot be cast to android.w