Split multiple planes using ransac in 3D Pointcloud

743 Views Asked by At

How to split multiple planes using ransac in 3D Pointcloud?My code can only split one plane at present.

Right now I am working to do plane segmentation of 3D point cloud data using RANSAC.My code can only split one plane at present. I want to remove one plane after splitting it and continue to split other planes. How can I do this.

`# -*-coding:utf-8 -*-
import os
import open3d as o3d
import numpy as np

test_data_dir = 'D:/test data'
point_cloud_file_name = 'Area6_office_5.pcd'
point_cloud_file_path = os.path.join(test_data_dir, point_cloud_file_name)
# 读取点云
pcd = o3d.io.read_point_cloud(point_cloud_file_path)
# 平面分割
plane_model, inliers = pcd.segment_plane(distance_threshold=0.03,
                                         ransac_n=3,
                                         num_iterations=1000)
# 模型参数
[a, b, c, d] = plane_model
print(f"Plane equation: {a:.2f}x + {b:.2f}y + {c:.2f}z + {d:.2f} = 0")
# 平面内的点
inlier_cloud = pcd.select_by_index(inliers)
inlier_cloud.paint_uniform_color([255.0, 0, 255.0])
# 平面外的点
outlier_cloud = pcd.select_by_index(inliers, invert=True)
# 可视化
o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud],
                                  zoom=0.8,
                                  front=[-0.4999, -0.1659, -0.8499],
                                  lookat=[2.1813, 2.0619, 2.0999],
                                  up=[0.1204, -0.9852, 0.1215])
`

enter image description here

2

There are 2 best solutions below

0
vicky Lin On

Since you already have outlier_cloud which is the point cloud with the first plane removed. You can easily do the same for outlier_cloud to get the rest planes. For example, try the code below after running your script.

plane_model_2, inliers_2 = outlier_cloud.segment_plane(distance_threshold=0.03,
                                         ransac_n=3,
                                         num_iterations=1000)

# inliner2
inlier_cloud_2 = outlier_cloud.select_by_index(inliers_2)
inlier_cloud_2.paint_uniform_color([1, 0, 1])
# outlier2
outlier_cloud_2 = outlier_cloud.select_by_index(inliers, invert=True)
# visualization
o3d.visualization.draw_geometries([inlier_cloud_2, outlier_cloud_2],
                                  zoom=0.8,
                                  front=[-0.4999, -0.1659, -0.8499],
                                  lookat=[2.1813, 2.0619, 2.0999],
                                  up=[0.1204, -0.9852, 0.1215])
1
rurouni On
def DetectMultiPlanes(points, min_ratio=0.05, threshold=0.01, iterations=1000):
""" Detect multiple planes from given point clouds

Args:
    points (np.ndarray): 
    min_ratio (float, optional): The minimum left points ratio to end the Detection. Defaults to 0.05.
    threshold (float, optional): RANSAC threshold in (m). Defaults to 0.01.

Returns:
    [List[tuple(np.ndarray, List)]]: Plane equation and plane point index
"""

plane_list = []
N = len(points)
target = points.copy()
count = 0

while count < (1 - min_ratio) * N:
    w, index = PlaneRegression(
        target, threshold=threshold, init_n=3, iter=iterations)

    count += len(index)
    plane_list.append((w, target[index]))
    target = np.delete(target, index, axis=0)

return plane_list

def PlaneRegression(points, threshold=0.01, init_n=3, iter=1000):
    """ plane regression using ransac
    Args:
        points (ndarray): N x3 point clouds
        threshold (float, optional): distance threshold. Defaults to 0.003.
        init_n (int, optional): Number of initial points to be considered inliers in each iteration
        iter (int, optional): number of iteration. Defaults to 1000.
    Returns:
        [ndarray, List]: 4 x 1 plane equation weights, List of plane point index
    """

    pcd = NumpyToPCD(points)

    w, index = pcd.segment_plane(
        threshold, init_n, iter)

    return w, index

the whole code from github