通过下采样提升DBSCAN聚类速度
思路
对初始点云降噪 => 消除噪点,使聚类结果准确 => 下采样,降低聚类计算负担 => 再次消除由于下采样造成的噪点 => 聚类 => 包围盒
问题
-
对于点云降噪以后,聚类采用的是密度聚类,原则上每类之间的距离变得清晰,可以放大适当放大聚类半径,但结果出现错误
-
对于点云下采样以后,成为了稀疏点云,对于稀疏点云聚类,只要下采样控制的间距不大于聚类半径应该就能分类,十分内变得简便,但是下采样增大聚类结果反而不好
初始点云预处理
处理的点云原图
scene_pcd = o3d.io.read_point_cloud(f"./data/testDate/pcd_rect_roi.pcd")
draw_geometry([scene_pcd], window_name="ROI检测区域")
移除初始图象的离群点
cl, ind = scene_pcd.remove_statistical_outlier(nb_neighbors=100,#nb_neighbors=10,
std_ratio=3.0)
display_inlier_outlier(scene_pcd, ind)
移除离群点后
box_delete_point = scene_pcd.select_by_index(ind)
draw_geometry([box_delete_point], window_name="移除离群点后点云")
o3d.io.write_point_cloud("./data/testDate/box_delete_point.pcd", box_delete_point)
点云下采样处理
下采样后点云图
box_panel_filter=box_delete_point.voxel_down_sample(voxel_size=0.01)
draw_geometry([box_panel_filter], window_name="下采样后点云")
再次移除离群点
cl1, ind1 = box_panel_filter.remove_statistical_outlier(nb_neighbors=100,#nb_neighbors=10,
std_ratio=10.0)
display_inlier_outlier(box_panel_filter, ind1)
移除利群点后
box_delete_point_final = box_panel_filter.select_by_index(ind1)
draw_geometry([box_delete_point_final], window_name="移除离群点后点云")
o3d.io.write_point_cloud("./data/testDate/box_delete_point_final.pcd", box_delete_point_final)
聚类
聚类结果
distance_threshold = 0.13 #120:2 #115:2 110:3 #105:3 #100:3 #090:4 #O80:5 #075:6 #050:9
cluster_result = box_delete_point_final.cluster_dbscan(eps=distance_threshold, min_points=100, print_progress=True)
cluster_labels = np.array(cluster_result)
max_label = np.max(cluster_labels)
print(max(cluster_labels))
print("聚类数量为:",max_label)
box_draw_result = np.zeros((max_label),dtype=float)
colors = np.random.randint(255, size=(max_label+1, 3))/255.
colors = colors[cluster_labels]
colors[cluster_labels < 0] = 0
box_delete_point_final.colors = o3d.utility.Vector3dVector(colors[:, :3])
# 点云显示
o3d.visualization.draw_geometries([box_delete_point_final], #点云列表
window_name="DBSCAN聚类",
point_show_normal=False,
width=800, # 窗口宽度
height=600) # 窗口高度
绘制包围盒
OBB包围盒
AABB包围盒
for creat_box_mode in range(max_label):
surroundding_box_panel_pcd = o3d.io.read_point_cloud("./data/testDate/pcd_rect_roi.pcd")
surroundding_box_panel_pcd1 = o3d.io.read_point_cloud("./data/testDate/box_panel_pcd_cluster1.pcd")
surroundding_box_panel_pcd2 = o3d.io.read_point_cloud("./data/testDate/box_panel_pcd_cluster2.pcd")
surroundding_box_panel_pcd3 = o3d.io.read_point_cloud("./data/testDate/box_panel_pcd_cluster3.pcd")
aabb1 = surroundding_box_panel_pcd1.get_axis_aligned_bounding_box()
aabb2 = surroundding_box_panel_pcd2.get_axis_aligned_bounding_box()
aabb3 = surroundding_box_panel_pcd3.get_axis_aligned_bounding_box()
aabb1.color = [1, 0, 0] # 红色
aabb2.color = [0, 1, 0] # 红色
aabb3.color = [0, 0, 1] # 红
hull1, _ = o3d.io.read_point_cloud("./data/testDate/box_panel_pcd_cluster1.pcd").compute_convex_hull()
hull_ls1 = o3d.geometry.LineSet.create_from_triangle_mesh(hull1)
hull_ls1.paint_uniform_color((1, 0, 1))
hull2, _ = o3d.io.read_point_cloud("./data/testDate/box_panel_pcd_cluster2.pcd").compute_convex_hull()
hull_ls2 = o3d.geometry.LineSet.create_from_triangle_mesh(hull2)
hull_ls2.paint_uniform_color((0, 1, 0))
hull3, _ = o3d.io.read_point_cloud("./data/testDate/box_panel_pcd_cluster3.pcd").compute_convex_hull()
hull_ls3 = o3d.geometry.LineSet.create_from_triangle_mesh(hull3)
hull_ls3.paint_uniform_color((0, 0, 1))
o3d.visualization.draw_geometries([desktop_surface,surroundding_box_panel_pcd, hull_ls1, hull_ls2, hull_ls3], window_name="点云凸包围",
width=800, # 窗口宽度
height=600) # 窗口高度
o3d.visualization.draw_geometries([desktop_surface,surroundding_box_panel_pcd,aabb1,aabb2,aabb3], window_name="点云AABB包围盒",
width=800, # 窗口宽度
height=600) # 窗口高度
x_min, y_min, z_min = aabb1.min_bound
x_max, y_max, z_max = aabb1.max_bound
length = x_max - x_min
width = y_max - y_min
height = z_max - z_min