Open3d:如何使用RANSAC选择合适的平面

问题描述 投票:0回答:1

我正在使用 o3d 处理点云,我想进行分割并从点云中提取对象。首先,我想拆除墙壁、地板等,因此我使用 RANSAC 来实现此目的。

问题是segment_plane函数选择找到的最大线段,但它并不总是我想要删除的线段。我使用循环来选择第 n 个最大的段,但例如,如果我想要保留的第 1 段的点可能位于我想要删除的第 3 段中,那么它们将不会像已经那样成为第 3 段的一部分在第一个。 一种解决方案可能是将我想保留的第一个段与其余段合并,但 RANSAC 会再次找到该段,因此它不起作用。

如何在 open3d 中使用 RANSAC 选择要删除的段而不是最大的段? (使用Python)

python image-segmentation open3d ransac
1个回答
0
投票

您需要检测多个平面,您可以使用这个也使用 open3d 的 repo。检测到平面后,由于我无法弄清楚您的删除标准,我只会让用户从点云中选取一个点并删除所选点所属的平面,您当然可以编辑此标准。我会一步步解释。

  1. 读取点云数据。

    points = ReadPlyPoint('fragment.ply')
    
  2. 预处理数据

    points = RemoveNan(points)
    points = DownSample(points,voxel_size=0.025) 
    points = RemoveNoiseStatistical(points, nb_neighbors=50, std_ratio=0.5)
    
  3. 检测多个平面

    results = DetectMultiPlanes(points, min_ratio=0.05, threshold=0.005, iterations=500)
    
  4. 生成彩色点云,以便用户可以选择她想要删除的平面。

    planes = []
    colors = []
    
    for _, plane in results:
        r = random.random()
        g = random.random()
        b = random.random()
    
        color = np.zeros((plane.shape[0], plane.shape[1]))
        color[:, 0] = r
        color[:, 1] = g
        color[:, 2] = b
    
        planes.append(plane)
        colors.append(color)
    
    planes = np.concatenate(planes, axis=0)
    colors = np.concatenate(colors, axis=0)
    
  5. 获取用户选择的点

    selected_points_id = DrawResult(planes, colors)
    
  6. 重新处理数据以删除选定的平面

    result_pcd = o3d.geometry.PointCloud()
    planes_n = []
    colors_n = []
    
    # this will only remove one plane. a point may belong to several different planes, so you can make this a number
    # or change it however you want
    found = False
    for point in selected_points_id:
        # for each selected point iterate through the planes
        for _, plane in results:
            if planes[point] in plane and not found:
                found = True
                continue
            else:
                r = random.random()
                g = random.random()
                b = random.random()
    
                color = np.zeros((plane.shape[0], plane.shape[1]))
                color[:, 0] = r
                color[:, 1] = g
                color[:, 2] = b
    
                planes_n.append(plane)
                colors_n.append(color)
    
    planes_n = np.concatenate(planes_n, axis=0)
    colors_n = np.concatenate(colors_n, axis=0)
    
    result_pcd = o3d.geometry.PointCloud()
    result_pcd.points = o3d.utility.Vector3dVector(planes_n)
    result_pcd.colors = o3d.utility.Vector3dVector(colors_n)
    

此后您可以保存它或做任何您想做的事情。

我还想分享一些可以让事情变得更快的评论。

  • 可能你拥有的平面少于点。因此,检查飞机具有的点并比较飞机是否具有您想要删除的点的成本很高。相反,您可以设置一个阈值,例如 0.1,然后找到您的点相对于您检测到的所有平面的距离,如果距离小于阈值,则删除最近的一个。
  • 当然,这段代码很慢,因为它处理了两次数据。但是,如果您有一个选择标准,而不是让用户选择她想要删除的平面,则您只能处理数据一次。
© www.soinside.com 2019 - 2024. All rights reserved.