在点云处理中,PCA通常用于识别数据集中的主要方向,从而帮助理解数据的几何结构。
使用工具:python,open3d库
目的:计算狭长型点云的主方向
# -*- coding: utf-8 -*-
"""
Created on Sun Jul 7 11:50:22 2024
@author: ZHIYANG
"""
import open3d as o3d
import numpy as np
# Step 1: 加载点云数据
point_cloud = o3d.io.read_point_cloud("Cloud.pcd")
# Step 2: 计算点云的中心
points = np.asarray(point_cloud.points)
center = np.mean(points, axis=0)
points -= center
# Step 3: 计算协方差矩阵
covariance_matrix = np.dot(points.T, points) / points.shape[0]
# Step 4: 计算特征值和特征向量
eigen_values, eigen_vectors = np.linalg.eigh(covariance_matrix)
# Step 5: 创建主方向的点云
main_direction = eigen_vectors[:, -1] # 最大特征值对应的特征向量(主方向)
# 将原始点云数据投影到主方向上
main_direction_points = np.dot(points, main_direction)[:, np.newaxis] * main_direction[np.newaxis, :]
# 加上点云的中心,得到主方向点云在原始坐标系中的位置
main_direction_points += center
# 创建原始点云和主方向点云的Open3D对象
original_point_cloud = o3d.geometry.PointCloud()
original_point_cloud.points = o3d.utility.Vector3dVector(points + center)
original_point_cloud.paint_uniform_color([0.5, 0.5, 0.5])
main_direction_point_cloud = o3d.geometry.PointCloud()
main_direction_point_cloud.points = o3d.utility.Vector3dVector(main_direction_points)
red_color =[1.0, 0.0, 0.0]
main_direction_point_cloud.paint_uniform_color(red_color)
# 创建坐标系网格
frame = o3d.geometry.TriangleMesh.create_coordinate_frame(size=5.0, origin=[0,0,0])
frame.rotate(eigen_vectors.T) # 将坐标系网格旋转到主方向
# 将所有几何体添加到列表中
geometries = [original_point_cloud, main_direction_point_cloud, frame]
# 创建并显示可视化窗口
o3d.visualization.draw_geometries(geometries)
# 保存点云
# o3d.io.write_point_cloud("main_direction_point_cloud.pcd", main_direction_point_cloud)
计算结果如红色点所示:
但是,但是, 大家都知道“但是”之后的才是重点。在处理其他相关数据时遇到了问题,为什么采用同样的代码对不同数据处理,得到的效果却不太相同?(预估的生成效果应该都像上图一样,主成分方向沿走向方向且在点云内部,而有的数据得到的主方向并不是预想的方向)。
下面是存在问题的数据结果:
1.
2.
后续继续探究造成这样结果的原因。