我正在使用 o3d 处理点云,我想进行分割并从点云中提取对象。首先,我想拆除墙壁、地板等,因此我使用 RANSAC 来实现此目的。
问题是segment_plane函数选择找到的最大线段,但它并不总是我想要删除的线段。我使用循环来选择第 n 个最大的段,但例如,如果我想要保留的第 1 段的点可能位于我想要删除的第 3 段中,那么它们将不会像已经那样成为第 3 段的一部分在第一个。 一种解决方案可能是将我想保留的第一个段与其余段合并,但 RANSAC 会再次找到该段,因此它不起作用。
如何在 open3d 中使用 RANSAC 选择要删除的段而不是最大的段? (使用Python)
您需要检测多个平面,您可以使用这个也使用 open3d 的 repo。检测到平面后,由于我无法弄清楚您的删除标准,我只会让用户从点云中选取一个点并删除所选点所属的平面,您当然可以编辑此标准。我会一步步解释。
读取点云数据。
points = ReadPlyPoint('fragment.ply')
预处理数据
points = RemoveNan(points)
points = DownSample(points,voxel_size=0.025)
points = RemoveNoiseStatistical(points, nb_neighbors=50, std_ratio=0.5)
检测多个平面
results = DetectMultiPlanes(points, min_ratio=0.05, threshold=0.005, iterations=500)
生成彩色点云,以便用户可以选择她想要删除的平面。
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)
获取用户选择的点
selected_points_id = DrawResult(planes, colors)
重新处理数据以删除选定的平面
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)
此后您可以保存它或做任何您想做的事情。
我还想分享一些可以让事情变得更快的评论。