Astra S 基于聚类的3D障碍检测以及包围盒绘制
本次是基于上一篇 Astra S 检测障碍并绘制最小包围盒 改进部分进行叙述,相同部分不再叙述
问题汇总(针对上一篇Astra S 检测障碍并绘制最小包围盒)
- ROI区域选择未根据3D检测特性选取
- 平面拟合数值阈值未根据特性选取,且未能拟合复杂3D图形
- 未实现视频流检测
- 检测速度慢
- 检测结果抽象
- 无法对同一图片多个目标进行检测
- 丢失部分深度信息,包围盒绘制与现实世界实际物体尺寸有差别
改进一(针对无法对同一图片多个目标进行检测)
增加聚类操作(DBSCAN聚类)
https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/
scene_pcd = o3d.io.read_point_cloud(f"./data/testDate/pcd_rect_roi.pcd")
distance_threshold = 0.11
cluster_labels = np.array(scene_pcd.cluster_dbscan(eps=distance_threshold, min_points=500, print_progress=True))
#最大值相当于共有多少个类别
max_label = np.max(cluster_labels)
print(max(cluster_labels))
print("聚类数量为:",max_label)
# print("测试数据为:",)
# draw_geometry([scene_pcd], window_name="测试数据")
box_draw_result = np.zeros((max_label),dtype=float)
#生成n+1个类别的颜色,n表示聚类成功的类别,1表示没有分类成功的类别
colors = np.random.randint(255, size=(max_label+1, 3))/255.
colors = colors[cluster_labels]
#没有分类成功的点设置为黑色
colors[cluster_labels < 0] = 0
scene_pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])
# 点云显示
o3d.visualization.draw_geometries([scene_pcd], #点云列表
window_name="DBSCAN聚类",
point_show_normal=False,
width=800, # 窗口宽度
height=600) # 窗口高度
for cluster_num_mode in range(max_label):
# class_indices = np.where(cluster_labels == cluster_num_mode+1)[0]
# obj_panel_cloud = scene_pcd.select_by_index(class_indices)
obj_panel_cloud = scene_pcd.select_by_index(np.where(cluster_labels == cluster_num_mode+1)[0])
draw_geometry([obj_panel_cloud], window_name="聚类分类")
o3d.io.write_point_cloud("./data/testDate/box_panel_pcd_cluster%d.pcd"%(cluster_num_mode+1), obj_panel_cloud)
结果
Precompute neighbors.[========================================] 100%
3lustering[=======================================>] 97%
聚类数量为: 3
问题
聚类速度慢(后续可能进行降采样操作测试一下能不能提高聚类速度)
改进二(针对检测结果抽象)
将显示结果拟合到原始彩色点云中
desktop_surface = o3d.io.read_point_cloud(f"./data/testDate/pcd_rect_roi.pcd")
#凸包
o3d.visualization.draw_geometries([desktop_surface,surroundding_box_panel_pcd, hull_ls1, hull_ls2, hull_ls3], window_name="点云凸包",
width=800, # 窗口宽度
height=600) # 窗口高度
# 绘制AABB
o3d.visualization.draw_geometries([desktop_surface,surroundding_box_panel_pcd,aabb1,aabb2,aabb3], window_name="点云AABB包围盒",
width=800, # 窗口宽度
height=600) # 窗口高度
结果
改进三(针对丢失部分深度信息)
显示的时候不对拟合的平面进行绘制包围盒,对初始信息进行包围盒绘制
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")
······
······
······
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))
结果
书包板凳对比(深度信息,拟合平面)
板凳对比(深度信息,拟合平面)
打印机对比(深度信息,拟合平面)
整体结果显示
凸包
包围盒
输出结果
拟合桌面平面的表达式: -0.25x + 0.10y + 0.96z + -1.95 = 0
Precompute neighbors.[========================================] 100%
3lustering[=======================================>] 97%
聚类数量为: 3
拟合盒子平面的表达式: 0.00x + 0.22y + 0.98z + -1.61 = 0
数组的测试值为: [[0.47526117 0.10843165 1.62754669]
[0. 0. 0. ]
[0. 0. 0. ]]
盒子点云中心点: [0.47526117 0.10843165 1.62754669]
拟合桌面平面的表达式: -0.25x + 0.10y + 0.96z + -1.95 = 0
盒子高度(点到平面距离) 0.496, 单位m
拟合桌面平面的表达式: -0.25x + 0.10y + 0.96z + -1.95 = 0
拟合盒子平面的表达式: 0.60x + 0.16y + 0.79z + -0.89 = 0
数组的测试值为: [[ 0.47526117 0.10843165 1.62754669]
[-0.33469457 0.14895489 1.34860472]
[ 0. 0. 0. ]]
盒子点云中心点: [-0.33469457 0.14895489 1.34860472]
拟合桌面平面的表达式: -0.25x + 0.10y + 0.96z + -1.95 = 0
盒子高度(点到平面距离) 0.554, 单位m
拟合桌面平面的表达式: -0.25x + 0.10y + 0.96z + -1.95 = 0
拟合盒子平面的表达式: -0.17x + 0.08y + 0.98z + -1.48 = 0
数组的测试值为: [[ 0.47526117 0.10843165 1.62754669]
[-0.33469457 0.14895489 1.34860472]
[-0.01192618 0.23401706 1.48593913]]
盒子点云中心点: [-0.01192618 0.23401706 1.48593913]
拟合桌面平面的表达式: -0.25x + 0.10y + 0.96z + -1.95 = 0
盒子高度(点到平面距离) 0.496, 单位m
拟合桌面平面的表达式: -0.25x + 0.10y + 0.96z + -1.95 = 0
数组1的测试值为: [[ 0.4752612 0.1084316 1.6275467]
[-0.3346946 0.1489549 1.3486047]
[-0.0119262 0.2340171 1.4859391]]
数组2的测试值为: [0.4959188760353526, 0.554133454033369, 0.49551602588643073]