三维点云处理02-surface_normal代码实现
基础知识点
surface_normal是PCA的应用,基础知识点与PCA相同,可以查看PCA
代码实现
import os
import numpy as np
from pyntcloud import PyntCloud
import open3d as o3d
def PCA(data,sort=True):
'''
PCA函数实现:
输入:
data:点云数据
sort:是否排序
输出:
w:特征值
v:特征向量
'''
N = data.shape[0]
X = data.to_numpy()
mu = np.mean(X,axis=0)
X_normalized = X - mu
func = np.cov
H = func(X_normalized, rowvar=False, bias=True)
eigenvalues, eigenvectors = np.linalg.eig(H)
if sort:
sort = eigenvalues.argsort()[::-1]
eigenvalues = eigenvalues[sort]
eigenvectors = eigenvectors[:,sort]
return eigenvalues,eigenvectors
def get_surface_normals(pcd,points,knn=5):
'''
获得点云的法向量
'''
pcd_tree = o3d.geometry.KDTreeFlann(pcd)
N = len(pcd.points)
normals = []
for i in range(N):
[k,idx,_] = pcd.tree.search_knn_vector_3d(pcd.points[i],knn)
w,v = PCA(points.iloc[idx])
normals.append(v[:,3])
return np.array(normals,dtype=np.float64)
def main(point_cloud_filename):
'''
主函数:
输入:点云文件名
'''
point_cloud_pynt = PyntCloud.from_file(point_cloud_filename)
point_cloud_o3d = point_cloud_pynt.to_instance("open3d",mesh=False)
points = point_cloud_pynt.points
normals = get_surface_normals(point_cloud_o3d,points)