PCA算法可以降低数据量,且最大程度保持原有信息,因此PCA算法在机器学习算法中得到广泛应用。(PCA证明详见“机器学习”板块中的“一、数据清洗”)
PCA算法流程:1 计算数据平均值。2 数据归一化(减掉平均值)。3 构造H矩阵。4 SVD分解。5 最大特征值对应特征向量为第一主成分,以此类推。
话不多说,直接上代码
import open3d as o3d
import numpy as np
from pyntcloud import PyntCloud
from pandas import DataFrame
def PCA(data,correlation=False,sort=True):
data_mean = np.mean(data,axis=0)
data_normalize = data - data_mean
H = np.dot(data_normalize.T,data_normalize)
eigenvectors,eigenvalues,eigenvectors_t=np.linalg.svd(H)
if sort:
sort = eigenvalues.argsort()[::-1]
eigenvalues = eigenvalues[sort]
eigenvectors = eigenvectors[:,sort]
return eigenvectors , eigenvalues
def main():
#创建数组表格数据 读取txt文档
raw_point_cloud_matrix = np.genfromtxt(r"F:\\point cloud\\三维点云课程\\3d数据集\\modelnet40_normal_resampled\\airplane\\airplane_0002.txt", delimiter=",")
#可以理解为建立表格,类似excel,且只需要前三列数据(x,y,z)
raw_point_cloud=DataFrame(raw_point_cloud_matrix[:,0:3])
raw_point_cloud.columns = ['x','y','z']
#将数据转化为open3d可以识别的格式
point_cloud_pynt = PyntCloud(raw_point_cloud)
#从点云中获取点
points = point_cloud_pynt.points
print("total points number is :"points.shape[0])
#使用PCA分析点云主方向
w,v = PCA(points)
#提取前两个主分量
point_cloud_vector = v[:,2]
print("the main orientation of this pointcloud is :",point_cloud_vector)
point = [[0,0,0],v[:,0],v[:,1]]
lines = [[0,1],[0,2]]
colors = [[1,0,0],[0,1,0]]
line_set = o3d.geometry.LineSet(points = o3d.utility.Vector3dVector(point),lines = o3d.utility.Vector2iVector(lines))
line_set.colors = o3d.utility.Vector3dVector(colors)
o3d.visualization.draw_geometries([point_cloud_o3d,line_set])
图1.保留第一第二主成分的点云
图二.原始点云