【通过下采样提升DBSCAN聚类速度】

思路

对初始点云降噪 => 消除噪点,使聚类结果准确 => 下采样,降低聚类计算负担 => 再次消除由于下采样造成的噪点 => 聚类 => 包围盒

问题

  1. 对于点云降噪以后,聚类采用的是密度聚类,原则上每类之间的距离变得清晰,可以放大适当放大聚类半径,但结果出现错误

  2. 对于点云下采样以后,成为了稀疏点云,对于稀疏点云聚类,只要下采样控制的间距不大于聚类半径应该就能分类,十分内变得简便,但是下采样增大聚类结果反而不好

初始点云预处理

处理的点云原图

在这里插入图片描述在这里插入图片描述

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
pcl点云库(Point Cloud Library)是一个开源的库,用于处理三维点云数据。而DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一种基于密度的聚类算法,适用于点云数据的聚类任务。 要使用pcl库进行点云DBSCAN聚类,你可以按照以下步骤进行: 1. 导入pcl库,并读取点云数据。 2. 对点云数据进行预处理,例如滤波、降采样等,以提高聚类效果和性能。 3. 创建pcl::search::KdTree对象,用于点云数据的最近邻搜索。 4. 定义DBSCAN参数,例如邻域半径和最小点数等。 5. 使用pcl::RegionGrowing对象执行DBSCAN聚类,将点云数据分成不同的类别。 6. 可选地,根据聚类结果对点云进行可视化或后续处理。 具体实现代码如下所示(假设已经读取了点云数据到pcl::PointCloud<pcl::PointXYZ>对象中): ```cpp #include <pcl/point_cloud.h> #include <pcl/point_types.h> #include <pcl/search/kdtree.h> #include <pcl/segmentation/region_growing.h> int main() { // 读取点云数据到pcl::PointCloud<pcl::PointXYZ>对象中 // 创建pcl::search::KdTree对象 pcl::search::Search<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>); tree->setInputCloud(cloud); // 定义DBSCAN参数 float eps = 0.3; // 邻域半径 int minPts = 10; // 最小点数 // 创建pcl::RegionGrowing对象 pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg; reg.setMinClusterSize(minPts); reg.setMaxClusterSize(100000); reg.setSearchMethod(tree); reg.setNumberOfNeighbours(30); reg.setInputCloud(cloud); // 执行DBSCAN聚类 std::vector<pcl::PointIndices> clusters; reg.extract(clusters); // 可选:对聚类结果进行可视化或后续处理 return 0; } ``` 以上代码仅为一个简单示例,具体实现还需根据你的点云数据和需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值