当前位置: 首页 > news >正文

Open3D 对点云进行去噪(下采样、欧式聚类分割)01

Open3D使用 下采样(Voxel Downsample)欧式聚类分割(Cluster DBSCAN) 优化点云的去噪效果,尤其是在面对大量噪声或孤立簇时非常有效。

  1. Voxel 下采样:降低点云密度,加速后续处理。
  2. DBSCAN 聚类分割:识别并移除孤立的小点簇(即噪声簇)。

在这里插入图片描述

✅ 方法一:Voxel 下采样(Voxel Downsample)

📌 原理说明:

通过将空间划分为体素(voxel),每个体素内只保留一个代表点(如中心点或平均点),从而达到降采样和初步去噪的目的。

# 设置 voxel_size,根据你的点云密度调整(单位与点云一致,例如米或毫米)
voxel_size = 0.05  # 例如:5厘米# 执行 Voxel 下采样
downsampled_pcd = filtered_pcd.voxel_down_sample(voxel_size=voxel_size)print(f"原始点数量: {len(filtered_pcd.points)}")
print(f"下采样后点数量: {len(downsampled_pcd.points)}")

✅ 方法二:欧式聚类分割(Cluster DBSCAN)

📌 原理说明:

DBSCAN 是一种基于密度的聚类算法,能识别出密集区域的点簇,并将稀疏的、孤立的小簇标记为噪声。

# 使用欧式聚类 DBSCAN 分割
with o3d.utility.VerbosityContextManager(o3d.utility.VerbosityLevel.Debug) as cm:labels = np.array(downsampled_pcd.cluster_dbscan(eps=0.3, min_points=10, print_progress=True))# eps: 搜索邻域半径(单位与点云一致)
# min_points: 成为一个簇所需的最小点数# 显示聚类结果
max_label = labels.max()
print(f"找到 {max_label + 1} 个簇")# 可选:给不同簇上色可视化
colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1))
colors[labels < 0] = 0  # 噪声点涂成黑色
downsampled_pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])# 可视化聚类结果
o3d.visualization.draw_geometries([downsampled_pcd])

✅ 方法三:结合使用 —— 移除孤立小簇(更彻底去噪)

如果你的目标是去除所有不属于大簇的点(即噪声),可以按如下方式操作:

# 将簇标签转换为整型数组
unique_labels, counts = np.unique(labels, return_counts=True)# 设置最小簇大小阈值(例如:50个点)
min_cluster_size = 50# 获取满足条件的簇标签
valid_clusters = unique_labels[counts >= min_cluster_size]# 构建 mask:仅保留属于“大簇”的点
mask = np.isin(labels, valid_clusters)# 应用 mask 到点云
cleaned_points = np.asarray(downsampled_pcd.points)[mask]
cleaned_colors = np.asarray(downsampled_pcd.colors)[mask] if downsampled_pcd.has_colors() else None# 创建新的干净点云
final_cleaned_pcd = o3d.geometry.PointCloud()
final_cleaned_pcd.points = o3d.utility.Vector3dVector(cleaned_points)
if cleaned_colors is not None:final_cleaned_pcd.colors = o3d.utility.Vector3dVector(cleaned_colors)# 可视化最终结果
o3d.visualization.draw_geometries([final_cleaned_pcd])

🧠 总结流程建议:

步骤目的
voxel_down_sample()减少点数量,提高效率,初步去噪
cluster_dbscan()识别点簇,区分主要结构与孤立噪声
mask + filter移除小簇噪声,保留主要结构

📦 完整函数封装示例(可直接调用)

def remove_noise_with_clustering(pcd, voxel_size=0.05, eps=0.3, min_points=10, min_cluster_size=50):# Step 1: 下采样downsampled_pcd = pcd.voxel_down_sample(voxel_size=voxel_size)# Step 2: DBSCAN 聚类labels = np.array(downsampled_pcd.cluster_dbscan(eps=eps, min_points=min_points, print_progress=False))# Step 3: 过滤小簇unique_labels, counts = np.unique(labels, return_counts=True)valid_clusters = unique_labels[counts >= min_cluster_size]mask = np.isin(labels, valid_clusters)# Step 4: 提取干净点云cleaned_points = np.asarray(downsampled_pcd.points)[mask]cleaned_colors = np.asarray(downsampled_pcd.colors)[mask] if downsampled_pcd.has_colors() else Nonecleaned_pcd = o3d.geometry.PointCloud()cleaned_pcd.points = o3d.utility.Vector3dVector(cleaned_points)if cleaned_colors is not None:cleaned_pcd.colors = o3d.utility.Vector3dVector(cleaned_colors)return cleaned_pcd

✅ 使用示例:

import open3d as o3d
import numpy as npdef remove_noise_with_clustering(pcd, voxel_size=0.05, eps=0.3, min_points=10, min_cluster_size=50):# Step 1: 下采样downsampled_pcd = pcd.voxel_down_sample(voxel_size=voxel_size)# Step 2: DBSCAN 聚类labels = np.array(downsampled_pcd.cluster_dbscan(eps=eps, min_points=min_points, print_progress=False))# Step 3: 过滤小簇unique_labels, counts = np.unique(labels, return_counts=True)valid_clusters = unique_labels[counts >= min_cluster_size]mask = np.isin(labels, valid_clusters)# Step 4: 提取干净点云cleaned_points = np.asarray(downsampled_pcd.points)[mask]cleaned_colors = np.asarray(downsampled_pcd.colors)[mask] if downsampled_pcd.has_colors() else Nonecleaned_pcd = o3d.geometry.PointCloud()cleaned_pcd.points = o3d.utility.Vector3dVector(cleaned_points)if cleaned_colors is not None:cleaned_pcd.colors = o3d.utility.Vector3dVector(cleaned_colors)return cleaned_pcdif __name__ == "__main__":# 加载点云file_path = "demo.ply"pcd = o3d.io.read_point_cloud(file_path)# 将点云数据转化为numpy数组points = np.asarray(pcd.points)colors = np.asarray(pcd.colors)  # 获取颜色数据# 筛选Z轴小于设定阈值的点及其对应的颜色mask = (points[:, 2] > 500) & (points[:, 2] < 3000)filtered_points = points[mask]filtered_colors = colors[mask]# 交换X轴和Y轴的数据filtered_points[:, [0, 1]] = filtered_points[:, [1, 0]]# 创建新的点云对象并赋值筛选后的点和颜色filtered_pcd = o3d.geometry.PointCloud()filtered_pcd.points = o3d.utility.Vector3dVector(filtered_points)filtered_pcd.colors = o3d.utility.Vector3dVector(filtered_colors)cleaned_pcd = remove_noise_with_clustering(filtered_pcd, voxel_size=0.05*1000, eps=0.3*1000, min_points=10, min_cluster_size=50)o3d.visualization.draw_geometries([filtered_pcd],width=800, height=500)o3d.visualization.draw_geometries([cleaned_pcd],width=800, height=500)

原点云:
在这里插入图片描述
Voxel 下采样+欧式聚类分割(Cluster DBSCAN)
在这里插入图片描述

http://www.xdnf.cn/news/950743.html

相关文章:

  • 【论文阅读】大模型优化器(Large Language Models As Optimizers)
  • 第一章-数据通信网络基础
  • 无需布线的革命:电力载波技术赋能楼宇自控系统-亚川科技
  • 删除远程已经不存在但本地仍然存在的Git分支
  • AWS EKS 集群日志上报观测云实践
  • 1.6 http模块nodejs 对比 go
  • 【字节拥抱开源】字节团队开源视频模型 ContentV: 有限算力下的视频生成模型高效训练
  • 安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(质检)
  • 浅谈 ST 表(Sparse Table,稀疏表)
  • 基于ffmpeg+sdl的audio player
  • uniapp 实现腾讯云IM群文件上传下载功能
  • 基于亚博K210开发板——WiFi 模块联网
  • C语言 学习 文件操作(开关,读写,定位,大小)操作 2025年6月8日12:19:24
  • C语言 学习 模块化编程 2025年6月9日19:39:17
  • 论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
  • 触发DMA传输错误中断问题排查
  • Redis哨兵模式以及主从
  • LLM基础5_从零开始实现 GPT 模型
  • CMIP6气候模式资料概览
  • 免费在线PDF转图片工具
  • gephi绘制网络拓扑图:批量给节点着色
  • nginx安装和部署
  • 免费PDF转图片工具
  • NVIDIA CUDA 技术详解:开启 GPU 并行计算的大门
  • CocosCreator 之 JavaScript/TypeScript和Java的相互交互
  • 创建型模式-单例模式
  • Python网页自动化Selenium中文文档
  • 24.解释器模式:思考与解读
  • 从零手写Java版本的LSM Tree (四):SSTable 磁盘存储
  • 9个数据分析指令为工作赋能