基础知识:https://blog.csdn.net/m0_37957160/article/details/107063223

https://mp.csdn.net/editor/html/107108718

PS:

先看一下PCA算法实现流程:(设有m条n维数据,意思就是有m个样本,每个样本有n维特征)

(1)将原始数据组成一个m行n列的矩阵X。

(2)将X的每一列(代表一个属性字段),进行零均值化处理,即减去这一列的均值。

(3)求出协方差矩阵。

(4)求出协方差矩阵的特征值及对应的特征向量。

(5)将特征向量按对应特征值大小,从上到下按行排列成矩阵,取前k行组成矩阵P。

(6)Y=PX即为降维到k维后的数据。(意思就是将原始数据旋转到特征矩阵P所在的空间中,得到的数据Y即为降维后的结果)

----------------协方差矩阵--------

协方差矩阵通常这样计算,先让样本矩阵中心化,即每一维度减去该维度的均值,使每一维度上的均值为0,然后直接用新得到的样本矩阵乘上它的转置,然后除以(N-1)即可。其实这种方法也是由前面的公式通道而来,只不过理解起来不是很直观,但在抽象的公式推导时还是很常用的!

协方差总结:

1、协方差矩阵是对称的

2、对角线是各个维度的方差

3、协方差矩阵表示各个维度之间的相关性

4、协方差矩阵中元素的正负值表示维度之间的正相关、负相关关系

---------------基于协方差矩阵的特征值特征向量求解------------------

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
#include <string>
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <vector>
#include <pcl/visualization/pcl_visualizer.h>
#include <Eigen/Core>
#include <pcl/common/transforms.h>using namespace std;
typedef pcl::PointXYZ PointType;
typedef pcl::Normal NormalType;int main(int argc, char **argv)
{pcl::PointCloud<PointType>::Ptr cloud(new pcl::PointCloud<PointType>());pcl::PointCloud<NormalType>::Ptr cloud_normal(new pcl::PointCloud<NormalType>());//导入点云std::string fileName(argv[1]);pcl::io::loadPCDFile(fileName, *cloud);//加载点云// PCA:计算主方向Eigen::Vector4f pcaCentroid;//质心pcl::compute3DCentroid(*cloud, pcaCentroid);//估计质心的坐标 // 齐次坐标,(c0,c1,c2,1)cout << "质心坐标:"<<pcaCentroid << endl;Eigen::Matrix3f covariance;pcl::computeCovarianceMatrixNormalized(*cloud, pcaCentroid, covariance);//计算归一化协方差矩阵cout << "协方差矩阵:" << covariance << endl;// 计算主方向:特征向量和特征值Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigen_solver(covariance, Eigen::ComputeEigenvectors);Eigen::Matrix3f eigenVectorsPCA = eigen_solver.eigenvectors();//特征向量std::cout << "特征向量:" << eigenVectorsPCA << std::endl;//输出特征向量Eigen::Vector3f eigenValuesPCA = eigen_solver.eigenvalues();//特征值std::cout << "特征值:" << eigenValuesPCA << std::endl;//输出特征值//eigenVectorsPCA.col(2) = eigenVectorsPCA.col(0).cross(eigenVectorsPCA.col(1));//cross叉乘//校正主方向间垂直(特征向量方向: (e0, e1, e0 × e1) --- note: e0 × e1 = +/- e2)// 转到参考坐标系,将点云主方向与参考坐标系的坐标轴进行对齐Eigen::Matrix4f transform(Eigen::Matrix4f::Identity());transform.block<3, 3>(0, 0) = eigenVectorsPCA.transpose();//转置// R^(-1) = R^Ttransform.block<3, 1>(0, 3) = -1.0f * (transform.block<3, 3>(0, 0)) * (pcaCentroid.head<3>());// t^(-1) = -R^T * t//获取向量的前n个元素:vector.head(n);//利用block()函数,可以从Matrix中取出一个小矩阵来进行处理,使用的语法为matrix.block(i, j, p, q); //和 matrix.block<p, q>(i, j)。其中i,j是block左上角元素位于矩阵中的位置,p、q是block的大小,如果是小块的话,pcl::PointCloud<PointType>::Ptr transformedCloud(new pcl::PointCloud<PointType>);//变换后的点云pcl::transformPointCloud(*cloud, *transformedCloud, transform);//转换到原点时的主方向PointType o;o.x = 0.0;o.y = 0.0;o.z = 0.0;Eigen::Affine3f tra_aff(transform);Eigen::Vector3f pz = eigenVectorsPCA.col(0);//列Eigen::Vector3f py = eigenVectorsPCA.col(1);Eigen::Vector3f px = eigenVectorsPCA.col(2);pcl::transformVector(pz, pz, tra_aff);pcl::transformVector(py, py, tra_aff);pcl::transformVector(px, px, tra_aff);PointType pcaZ;pcaZ.x = 1000 * pz(0);pcaZ.y = 1000 * pz(1);pcaZ.z = 1000 * pz(2);PointType pcaY;pcaY.x = 1000 * py(0);pcaY.y = 1000 * py(1);pcaY.z = 1000 * py(2);PointType pcaX;pcaX.x = 1000 * px(0);pcaX.y = 1000 * px(1);pcaX.z = 1000 * px(2);//初始位置时的主方向PointType c;c.x = pcaCentroid(0);c.y = pcaCentroid(1);c.z = pcaCentroid(2);PointType pcZ;pcZ.x = 1000 * eigenVectorsPCA(0, 0) + c.x;pcZ.y = 1000 * eigenVectorsPCA(1, 0) + c.y;pcZ.z = 1000 * eigenVectorsPCA(2, 0) + c.z;PointType pcY;pcY.x = 1000 * eigenVectorsPCA(0, 1) + c.x;pcY.y = 1000 * eigenVectorsPCA(1, 1) + c.y;pcY.z = 1000 * eigenVectorsPCA(2, 1) + c.z;PointType pcX;pcX.x = 1000 * eigenVectorsPCA(0, 2) + c.x;pcX.y = 1000 * eigenVectorsPCA(1, 2) + c.y;pcX.z = 1000 * eigenVectorsPCA(2, 2) + c.z;//visualizationpcl::visualization::PCLVisualizer viewer;pcl::visualization::PointCloudColorHandlerCustom<PointType> color_handler(cloud, 255, 0, 0);//对输入原始点云处理//这句话的意思是:对输入为pcl::PointXYZ类型的点云,着色为红色。其中,cloud表示真正处理的点云,color_handler表示处理结果.pcl::visualization::PointCloudColorHandlerCustom<PointType> tc_handler(transformedCloud, 0, 255, 0);viewer.addPointCloud(cloud, color_handler, "cloud");viewer.addPointCloud(transformedCloud, tc_handler, "transformCloud");//将点云transformedCloud,处理结果为tc_handler,添加到视图中,其中,双引号中的transformCloud,表示该点云的”标签“,//我们依然可以称之为”名字“,之所以设置各个处理点云的名字,是为了在后续处理中易于区分; //v1表是添加到哪个视图窗口(pcl中可设置多窗口模式)viewer.addArrow(pcaZ, o, 0.0, 0.0, 1.0, false, "arrow_Z");//给变化坐标的绿色点云tc_handler添加箭头viewer.addArrow(pcaY, o, 0.0, 1.0, 0.0, false, "arrow_Y");viewer.addArrow(pcaX, o, 1.0, 0.0, 0.0, false, "arrow_X");viewer.addArrow(pcZ, c, 0.0, 0.0, 1.0, false, "arrow_z");viewer.addArrow(pcY, c, 0.0, 1.0, 0.0, false, "arrow_y");viewer.addArrow(pcX, c, 1.0, 0.0, 0.0, false, "arrow_x");//viewer.setCameraPosition(100.0, 20.0, 35.0, 4.0, 5.0, 6.0);//设置坐标原点viewer.addCoordinateSystem(100);//建立空间直角坐标系//viewer.initCameraParameters();    //初始化相机参数,让用户在默认的角度下观察点云viewer.setBackgroundColor(1.0, 1.0, 1.0);while (!viewer.wasStopped()){viewer.spinOnce(10000);}return 0;
}

显示结果如下:

PCA(3):PCA实现C++代码相关推荐

  1. 主成分分析(PCA)方法步骤以及代码详解

    主成分分析(PCA)方法步骤以及代码详解 前言 上一节我们了解到在构建神经网络模型,除了掌握如何搭建神经网络架构,了解参数具体含义,规避风险等方法.第一步是要对采用数据集的详细了解,无需接触任何神经网 ...

  2. PCA降维算法原理及代码实现(python和matlab)

    常见的数据降维算法有:奇异值分解(SVD).主成分分析(PCA).因子分析(FA).独立成分分析(ICA). PCA降维的基本思想:通过计算数据矩阵的协方差矩阵,然后得到协方差矩阵的特征值.特征向量. ...

  3. matlab mysvd代码解释,关于使用SVD进行PCA主成分提取的代码问题!也是必须涉及到原理的!...

    如标题所示,目的是将矩阵进行PCA分析最终得到降维后的新主成分,对于特征值特征向量的提取方法是通过svd.代码和函数名称定义如下/如图所示 function [Xm,U,L]=pca(X,K); % ...

  4. 【主成分分析】PCA降维算法及Matlab代码实现

    前言   机器学习中经常会遇到高维变量的大数据集,并且大数据集的很多高维变量之间并不是独立的,它们之间往往存在相关关系.这些变量一方面为机器学习提供了大量的信息,另一方面由于信息冗余也增加了数据处理的 ...

  5. 机器学习—数据压缩(PCA)—特征值分解、奇异值分解+代码理解

    一.特征值 协方差:协方差表示的是两个变量的总体的误差,这与只表示一个变量误差的方差不同. 如果两个变量的变化趋势一致,也就是说如果其中一个大于自身的期望值,另外一个也大于自身的期望值,那么两个变量之 ...

  6. matlab pca svd,关于使用SVD进行PCA主成分提取的代码问题!也是必须涉及到原理的!...

    如标题所示,目的是将矩阵进行PCA分析最终得到降维后的新主成分,对于特征值特征向量的提取方法是通过svd.代码和函数名称定义如下/如图所示 function [Xm,U,L]=pca(X,K); % ...

  7. PCA算法的原理以及代码实现

    目录 PCA算法是如何实现的? 1.对原始数据零均值化(中心化) 2.求协方差矩阵 3.对协方差矩阵求特征向量和特征值 评价模型的好坏,K值的确定 PCA算法的优缺点: 优点: 缺点: PCA算法的实 ...

  8. PCA降维工作原理及代码案例实现

    PCA降维工作原理 PCA利用了协方差矩阵的特征值分解.过程分为四个步骤: (1)创建数据集的协方差矩阵 协方差:用来度量两个随机变量关系的统计量 (2)保留协方差矩阵的特征值 (3)保留前K个特征值 ...

  9. matlab做pca程序,PCA 程序代码  matlab版

    1.eigenface_example.m(主程序) % load function files from subfolders aswell addpath (genpath ('.')); % l ...

  10. matlab pca和逆pca函数,PCA的原理及MATLAB实现

    关于PCA原理可以直接参考下面的文章 深入理解PCA PCA是经常用来减少数据集的维数,同时保留数据集中对方差贡献最大的特征来达到简化数据集的目的. PCA的原理就是将原来的样本数据投影到一个新的空间 ...

最新文章

  1. OpenCV读写图像文件解析
  2. Winform中对自定义xml配置文件进行Xml节点的添加与删除
  3. Spark Core
  4. Java Bean 命名规则
  5. 动态规划——零钱兑换(Leetcode 322)
  6. Spring : @EnableConfigurationProperties注解
  7. 「管理数学基础」4.1 模糊数学:模糊现象与模糊集、隶属函数、模糊集的运算、水平截集与分解定理
  8. 深度学习的应用:语音识别、图像理解、自然语言处理
  9. python 图形库有哪些_Python基本图形绘制库——turtle
  10. 最长回文子串-----Manacher算法
  11. springboot开源热门项目-bootdo修改支持多数据源
  12. 机器学习实战 --- sklearn
  13. Exception processing template “xxx“: An error happened during tem
  14. 阿伯丁大学计算机科学硕士申请,又双叒有更多硕士专业可以一月入学了 | 阿伯丁大学2021年春季入学专业名单更新(2020年8月更新)...
  15. C++ exception with description “bad optional access“ thrown in the test body.
  16. Kotlin语言中的泛型设计哲学
  17. 精伦iDR210读卡器驱动安装教程
  18. 研发内部控制浅谈(三)(转)
  19. 企业是否需要引入OA系统要考虑的几个问题
  20. (javascript)vue项目打包后,写的覆盖element的样式无效了。这是什么原因?

热门文章

  1. 2021年大数据Spark(九):Spark On Yarn两种模式总结
  2. [JAVA EE]session 和 token 机制
  3. mysql链接数据库properties_mysql 之通过配置文件链接数据库
  4. Intel HAXM is required to run this AVD VT-x is disabled in BIOS的处理方法
  5. 003_如何学好英语?
  6. 2022-2028年中国相变蜡行业市场前瞻与投资战略规划分析报告
  7. 用友二次开发——工资导入
  8. 使用maven搭建ssm框架的javaweb项目
  9. 汇编寄存器(内存访问)基础知识之三---mov指令
  10. 安卓Design包之AppBar和Toolbar的联用