PCA算法:从一组照片中获取特征脸(特征向量)

2024-05-30 05:58

本文主要是介绍PCA算法:从一组照片中获取特征脸(特征向量),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文介绍了对一组照片进行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.000000
1 st:   316433.875000
2 st:   268737.531250
3 st:   248890.359375
4 st:   177919.671875
5 st:   139744.718750
6 st:   112001.937500
7 st:   108768.914063
8 st:   85501.773438
9 st:   72161.312500
10 st:  67518.437500
11 st:  62258.648438


 

这篇关于PCA算法:从一组照片中获取特征脸(特征向量)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1015753

相关文章

代码随想录算法训练营:12/60

非科班学习算法day12 | LeetCode150:逆波兰表达式 ,Leetcode239: 滑动窗口最大值  目录 介绍 一、基础概念补充: 1.c++字符串转为数字 1. std::stoi, std::stol, std::stoll, std::stoul, std::stoull(最常用) 2. std::stringstream 3. std::atoi, std

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

大林 PID 算法

Dahlin PID算法是一种用于控制和调节系统的比例积分延迟算法。以下是一个简单的C语言实现示例: #include <stdio.h>// DALIN PID 结构体定义typedef struct {float SetPoint; // 设定点float Proportion; // 比例float Integral; // 积分float Derivative; // 微分flo

AI学习指南机器学习篇-朴素贝叶斯处理连续特征和离散特征

AI学习指南机器学习篇-朴素贝叶斯处理连续特征和离散特征 在机器学习领域,朴素贝叶斯是一种常用的分类算法,它的简单性和高效性使得它在实际应用中得到了广泛的应用。然而,在使用朴素贝叶斯算法进行分类时,我们通常会面临一个重要的问题,就是如何处理连续特征和离散特征。因为朴素贝叶斯算法基于特征的条件独立性假设,所以对于不同类型的特征,我们需要采取不同的处理方式。 在本篇博客中,我们将探讨如何有效地处理

【青龙面板辅助】JD商品自动给好评获取京豆脚本

1.打开链接 开下面的链接进入待评价商品页面 https://club.jd.com/myJdcomments/myJdcomments.action?sort=0 2.登陆后执行脚本 登陆后,按F12键,选择console,复制粘贴以下代码,先运行脚本1,再运行脚本2 脚本1代码 可以自行修改评价内容。 var content = '材质很好,质量也不错,到货也很快物流满分,包装快递满

LeetCode 算法:二叉树的中序遍历 c++

原题链接🔗:二叉树的中序遍历 难度:简单⭐️ 题目 给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 示例 1: 输入:root = [1,null,2,3] 输出:[1,3,2] 示例 2: 输入:root = [] 输出:[] 示例 3: 输入:root = [1] 输出:[1] 提示: 树中节点数目在范围 [0, 100] 内 -100 <= Node.

【Java算法】滑动窗口 下

​ ​    🔥个人主页: 中草药 🔥专栏:【算法工作坊】算法实战揭秘 🦌一.水果成篮 题目链接:904.水果成篮 ​ 算法原理 算法原理是使用“滑动窗口”(Sliding Window)策略,结合哈希表(Map)来高效地统计窗口内不同水果的种类数量。以下是详细分析: 初始化:创建一个空的哈希表 map 用来存储每种水果的数量,初始化左右指针 left

ROS2从入门到精通4-4:局部控制插件开发案例(以PID算法为例)

目录 0 专栏介绍1 控制插件编写模板1.1 构造控制插件类1.2 注册并导出插件1.3 编译与使用插件 2 基于PID的路径跟踪原理3 控制插件开发案例(PID算法)常见问题 0 专栏介绍 本专栏旨在通过对ROS2的系统学习,掌握ROS2底层基本分布式原理,并具有机器人建模和应用ROS2进行实际项目的开发和调试的工程能力。 🚀详情:《ROS2从入门到精通》 1 控制插

el-upload 上传图片及回显照片和预览图片,文件流和http线上链接格式操作

<div v-for="(info, index) in zsjzqwhxqList.helicopterTourInfoList" :key="info.id" >编辑上传图片// oss返回线上地址http链接格式:<el-form-itemlabel="巡视结果照片":label-width="formLabelWidth"><el-upload:action="'http:

算法与数据结构面试宝典——回溯算法详解(C#,C++)

文章目录 1. 回溯算法的定义及应用场景2. 回溯算法的基本思想3. 递推关系式与回溯算法的建立4. 状态转移方法5. 边界条件与结束条件6. 算法的具体实现过程7. 回溯算法在C#,C++中的实际应用案例C#示例C++示例 8. 总结回溯算法的主要特点与应用价值 回溯算法是一种通过尝试各种可能的组合来找到所有解的算法。这种算法通常用于解决组合问题,如排列、组合、棋盘游