半径滤波与统计滤波器类似,根据空间点半径范围中临近点数量是否满足给定值来滤波。该滤波算法比统计滤波更加简单,计算速度更快。
在点云数据中以某点为中心画一个圆计算落在该圆中点的数量,当数量大于给定值时,则保留该点,数量小于给定值则剔除该点。此算法运行速度快,依序迭代留下的点一定是最密集的,但是圆的半径和圆内点的数目都需要人工指定。
(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],window_name = '源数据',width = 1080,height = 720,top = 30,left = 20) cl,index = pcd.remove_radius_outlier(nb_points=10,radius=0.2) new_pcd = pcd.select_by_index(index) print('半径滤波后的点云个数为:',np.array(new_pcd.points).shape[0]) o3d.visualization.draw_geometries([new_pcd],window_name= '半径滤波',width = 1080,height = 720,top = 20,left = 30)
(2)python代码实现半径滤波
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],window_name = '源数据',width = 1080,height = 720,top = 30,left = 20)
def radius_outlier(cloud,nb_points = 10,radius = 0.2): #点云数据构造kd树 pcd_tree = o3d.geometry.KDTreeFlann(cloud) #寻找每个点的邻近nb_points个数的点,并且计算他们之间的距离,如果距离大于radius,则舍弃该点,小于则保留 di = [] new_cloud = [] for i in range(np.array(cloud.points).shape[0]):#遍历所有点 [k,idx,_] = pcd_tree.search_knn_vector_3d(cloud.points[i],nb_points) #计算该点到每个点的欧式距离 euc_distance = [ np.linalg.norm(np.array(cloud.points)[j] - np.array(cloud.points)[idx[0]])for j in np.array(idx)[1:]] is_less_than_radius = [j for j in euc_distance if j > radius ] if len(is_less_than_radius) == 0 :#所有距离都符合 new_cloud.append(np.array(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('radius_deal_points.pcd',new_pcd,True) o3d.visualization.draw_geometries([new_pcd]) radius_outlier(pcd,10,0.2)