点云滤波:统计滤波器python代码以及open3d处理

统计滤波器主要是用于去除明显的离群点:离群点特征在空间中分布稀疏,定义某处点云小于某个密度,即点云无效。因此我们要计算每个点到其最近的K个点平均距离,则点云中所有点的距离应构成高斯分布,根据全部点集的均值和标准差,计算距离阈值,剔除阈值之外的点。

(1)使用open3d中的函数来实现

import open3d as o3d
import numpy as np
pcd = o3d.io.read_point_cloud('013205.pcd',remove_nan_points = True,remove_infinite_points = True)
print('原始点云个数是:',np.array(pcd.points).shape[0])
o3d.visualization.draw_geometries([pcd])
cl,index = pcd.remove_statistical_outlier(nb_neighbors = 50,std_ratio= 1.0)
new_cloud = pcd.select_by_index(index)
o3d.visualization.draw_geometries([new_cloud])

(2)自己写代码实现:

遍历全部点云数据,首先计算每个点到其他K个点的平均距离,然后计算该点对全部点集的均值和标准差,根据均值和标准差来计算阈值,根据阈值将符合条件的点留下,组成新的点云输出。

import open3d as o3d
import numpy as np
pcd = o3d.io.read_point_cloud('013205.pcd',remove_nan_points = True,remove_infinite_points = True)
print('原始点云个数是:',np.array(pcd.points).shape[0])
o3d.visualization.draw_geometries([pcd])
def statistical_outlier(cloud,k = 50,threshold = 2.0):#自己写一个统计滤波器
    #计算每个点到领域k内的平均距离di
    cloud_kdtree = o3d.geometry.KDTreeFlann(cloud)
    di = []
    new_cloud = []#用于存放新的点云集
    for i in range(np.array(cloud.points).shape[0]):
        [k,idx,_] = cloud_kdtree.search_knn_vector_3d(cloud.points[i],k)#k近邻搜索,拿到k个点的index,第一个点是搜索本身
        #计算K邻域的欧式距离
        eucDistance = [np.linalg.norm(np.array(cloud.points)[j] - np.array(cloud.points)[idx[0]]) for j in np.array(idx[1:])]
        eucdistance_mean = np.mean(eucDistance,axis=0)#计算出均值
        di.append(eucdistance_mean)
        #计算整个点集的均值和标准差
        distance = [np.linalg.norm(np.array(cloud.points)[j] - np.array(cloud.points)[idx[0]]) for j in range(np.array(cloud.points).shape[0])]
        cloud_points_mean = np.mean(distance,axis=0)
        cloud_points_std = np.std(distance)#计算出标准差
        #计算距离阈值
        dmax = cloud_points_mean + threshold*cloud_points_std
        dmin = cloud_points_mean - threshold*cloud_points_std
        #判断点是否符合距离阈值,符合则留下
        if dmin <= di[i] <= dmax :
            new_cloud.append(cloud.points[i])
    new_pcd = o3d.geometry.PointCloud()
    points = o3d.utility.Vector3dVector(np.array(new_cloud))
    new_pcd.points = points
    o3d.io.write_point_cloud('statistical_deal_points.pcd',new_pcd,True)
    o3d.visualization.draw_geometries([new_pcd])
statistical_outlier(pcd,50,1.0)

你可能感兴趣的:(python,深度学习)