簡體   English   中英

過濾點雲

[英]Filtering pointcloud

我希望盡可能有效地過濾加載了opend3d的點雲。

目前,我在用它們制作網格之前對點進行下采樣,並在我手動完成的包含體積網格上使用.contains 像這樣的東西:

    def load_pointcloud(self, pointcloud_path): 
        # Load Pointcloud
        print('target_pointcloud', pointcloud_path)
        self.pointcloud_path = pointcloud_path

        pcd = o3d.io.read_point_cloud(pointcloud_path)
        downpcd = pcd.voxel_down_sample(voxel_size=0.02)
        cl, ind = downpcd.remove_statistical_outlier(nb_neighbors=20,
                                                std_ratio=2.0)
        downpcd = downpcd.select_by_index(ind)
        pcd_points = np.asarray(downpcd.points, dtype=np.float32)

        self.verts = torch.from_numpy(pcd_points)
        self.verts = self.verts.to(device)

        # We construct a Meshes structure for the target mesh
        self.pointcloud_points = Pointclouds(points=[self.verts])
        self.points = pcd_points
        self.inclusion_pointcloud()

    def inclusion_pointcloud(self):
        vetices_in_mesh_states = self.mesh_inclusion.contains(self.points)
        vetices_in_mesh = self.points[vetices_in_mesh_states == True]

        # Creating cropped point cloud
        cropped_pc = o3d.geometry.PointCloud()
        cropped_pc.points = o3d.utility.Vector3dVector(vetices_in_mesh)
        cropped_pc.paint_uniform_color([0,0,0])

        self.points = np.asarray(cropped_pc.points, dtype=np.float32)
        self.verts = torch.from_numpy(self.points)
        self.verts = self.verts.to(device)
        self.pointcloud_points = Pointclouds(points=[self.verts])
        self.pc_mesh = trimesh.Trimesh(vertices=self.points)  

我想做的是,在下采樣之后,屏蔽掉 X、Y 和 Z 上的點,然后制作一個網格以在相同的包含體積中再次使用.contains 我認為這會減少.contains計算並運行得更快,而且確實如此,但只是邊際減少,如 10 或 15 毫秒,有時更少。 像這樣的東西:

    def new_load_pointcloud(self, pointcloud_path): 
        # Load Pointcloud
        print('target_pointcloud', pointcloud_path)
        self.pointcloud_path = pointcloud_path

        pcd = self.trim_cloud(pointcloud_path)
        downpcd = pcd.voxel_down_sample(voxel_size=0.02)
        cl, ind = downpcd.remove_statistical_outlier(nb_neighbors=20,
                                                std_ratio=2.0)
        downpcd = downpcd.select_by_index(ind)
        pcd_points = np.asarray(downpcd.points, dtype=np.float32)

        self.verts = torch.from_numpy(pcd_points)
        self.verts = self.verts.to(device)

        # We construct a Meshes structure for the target mesh
        self.pointcloud_points = Pointclouds(points=[self.verts])
        self.points = pcd_points
        self.inclusion_pointcloud()

    def trim_cloud(self, pointcloud_path):
        # pcd = o3d.io.read_point_cloud(pointcloud_path)
        pcd_clean = o3d.io.read_point_cloud(pointcloud_path)

        # X Axis
        points = np.asarray(pcd_clean.points)
        mask_x_1 = points[:,0] > -0.4
        mask_x_2 = points[:,0] < 0.4

        # Y Axis
        mask_y_1 = points[:,1] > -1.3
        mask_y_2 = points[:,1] < 0.9

        # Z Axis
        mask_z_1 = points[:,2] < 0.3 # Closer to floor     
        mask_z_2 = points[:,2] > -0.1 # Clooser to ceiling

        mask_x = np.logical_and(mask_x_1, mask_x_2) # Along table's wide
        mask_y = np.logical_and(mask_y_1, mask_y_2) # Along table's longitude
        mask_z = np.logical_and(mask_z_1, mask_z_2) # Along table's height
        mask = np.logical_and(mask_x, mask_y, mask_z)
        pcd_clean.points = o3d.utility.Vector3dVector(points[mask])

        return pcd_clean

    def inclusion_pointcloud(self):
        vetices_in_mesh_states = self.mesh_inclusion.contains(self.points)
        vetices_in_mesh = self.points[vetices_in_mesh_states == True]

        # Creating cropped point cloud
        cropped_pc = o3d.geometry.PointCloud()
        cropped_pc.points = o3d.utility.Vector3dVector(vetices_in_mesh)
        cropped_pc.paint_uniform_color([0,0,0])

        self.points = np.asarray(cropped_pc.points, dtype=np.float32)
        self.verts = torch.from_numpy(self.points)
        self.verts = self.verts.to(device)
        self.pointcloud_points = Pointclouds(points=[self.verts])
        self.pc_mesh = trimesh.Trimesh(vertices=self.points)  

我認為您對過濾器使用了太多 nb_neighbors 。 嘗試更少的分數,比如 6 或 10,以及更好的閾值,比如 1.0 甚至 0.5。 Here is the same filter on MATLAB documentation https://www.mathworks.com/help/vision/ref/pcdenoise.html , standard value for the threshold is 1.0 and for the knn is 6. You can also try the Radius Outlier Removal或中值濾波器: https://www.mathworks.com/help/lidar/ref/pcmedian.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM