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

Open3D 点云处理笔记

下载自带点云

下载自带点云素材:

import open3d as o3dpcd = o3d.data.PLYPointCloud()
pcd = o3d.io.read_point_cloud(pcd.path)# 显示点云
# o3d.visualization.draw_geometries([pcd])# 创建可视化窗口
vis = o3d.visualization.Visualizer()
vis.create_window()
# 添加点云到窗口
vis.add_geometry(pcd)
# 显示点云
vis.run()
vis.destroy_window()

在这里插入图片描述

显示坐标轴

import open3d as o3dpcd = o3d.io.read_point_cloud("fragment.ply")
# 创建可视化窗口
vis = o3d.visualization.Visualizer()
vis.create_window()
# 坐标轴显示
axis = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1, origin=(0, 0, 0))  # pcd.get_center()
vis.add_geometry(axis)vis.add_geometry(pcd)
# 显示点云
vis.run()
vis.destroy_window()

在这里插入图片描述

点云平移旋转
import open3d as o3d
import numpy as nppcd = o3d.io.read_point_cloud("fragment.ply")# 点云平移
pcd.translate([-2, -2, -1], relative=True)# 点云旋转  默认以点云质心为旋转中心,旋转前后点云质心不变
print(f'点云质心:{pcd.get_center()}')
# 生成旋转矩阵
rotation_matrix = o3d.geometry.get_rotation_matrix_from_xzy((np.pi, 0, np.pi/18))
# 应用旋转矩阵
pcd.rotate(rotation_matrix)
# 点云平移
pcd.translate([0, 0.55, -0.5], relative=True)# 保存点云
o3d.io.write_point_cloud("rotated_point_cloud.pcd", pcd)# 创建可视化窗口
vis = o3d.visualization.Visualizer()
vis.create_window()
# 坐标轴显示
axis = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1, origin=(0, 0, 0))
vis.add_geometry(axis)
# 显示点云
vis.add_geometry(pcd)
vis.run()
vis.destroy_window()

在这里插入图片描述

裁剪点云/直通滤波
import open3d as o3d
import numpy as nppcd = o3d.io.read_point_cloud("rotated_point_cloud.pcd")# # 点云平移
uppts = np.asarray(pcd.points)
uppts = uppts[uppts[:, 0] > 0] # 截取X轴方向坐标 > 0的点
uppts = uppts[uppts[:, 1] > -0.01] # 截取Y轴方向坐标 > -0.01的点
uppts = uppts[uppts[:, 2] > 0.1] # 截取Z轴方向坐标 > 0.1的点uppts = uppts[uppts[:, 0] < 0.75]
pcd.points = o3d.utility.Vector3dVector(uppts)# 保存点云
o3d.io.write_point_cloud("chair_point_cloud.pcd", pcd)# 创建可视化窗口
vis = o3d.visualization.Visualizer()
vis.create_window()
# 坐标轴显示
axis = o3d.geometry.TriangleMesh.create_coordinate_frame(size=1, origin=(0, 0, 0))
vis.add_geometry(axis)vis.add_geometry(pcd)
# 显示点云
vis.run()
vis.destroy_window()

在这里插入图片描述

点云滤波
统计滤波 Statistical Outlier Removal (SOR)

remove_statistical_outlier 的主要功能是去除点云中的异常点,有两个关键参数:
nb_neighbors(整数)指定每个点周围需要考虑的邻居点的数量。,计算平均距离时所使用的局部区域的大小。越大平均距离越平滑;越小平均距离越敏感。
std_ratio(浮点数)标准差比率,用于设置离群点的判定阈值。越大离群点的判定标准越宽松,越小离群点的判定标准越严格。
离群点的判定标准为:
平均距离+std_ratio * σ

import open3d as o3d
import numpy as nppcd = o3d.io.read_point_cloud("chair_point_cloud.pcd")# 去除统计离群点
pcd, _ = pcd.remove_statistical_outlier(30, 2)# 创建可视化窗口
vis = o3d.visualization.Visualizer()
vis.create_window()
# 坐标轴显示
axis = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.2, origin=(0, 0, 0))
vis.add_geometry(axis)vis.add_geometry(pcd)
# 显示点云
vis.run()
vis.destroy_window()

在这里插入图片描述

体素滤波 Voxel Grid Filter

体素滤波:将空间划分为规则体素(voxel),每个体素保留一个代表点(如平均值),实现降采样和去噪


import open3d as o3d
import numpy as nppcd = o3d.io.read_point_cloud("chair_point_cloud.pcd")# 体素滤波
pcd = pcd.voxel_down_sample(voxel_size=0.02)# 创建可视化窗口
vis = o3d.visualization.Visualizer()
vis.create_window()
# 坐标轴显示
axis = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.2, origin=(0, 0, 0))
vis.add_geometry(axis)vis.add_geometry(pcd)
# 显示点云
vis.run()
vis.destroy_window()

在这里插入图片描述

Radius Outlier Removal (ROR)

基于半径范围内的邻域点数来剔除噪声点。

import open3d as o3d
import numpy as nppcd = o3d.io.read_point_cloud("chair_point_cloud.pcd")# 基于半径范围内的邻域点数来剔除噪声点
cl, ind = pcd.remove_radius_outlier(nb_points=30, radius=0.05)
pcd = pcd.select_by_index(ind)# 创建可视化窗口
vis = o3d.visualization.Visualizer()
vis.create_window()
# 坐标轴显示
axis = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.2, origin=(0, 0, 0))
vis.add_geometry(axis)vis.add_geometry(pcd)
# 显示点云
vis.run()
vis.destroy_window()

在这里插入图片描述

构建Octree
import open3d as o3d
pcd = o3d.io.read_point_cloud("chair_point_cloud.pcd")
print('octree 分割')
octree = o3d.geometry.Octree(max_depth=8)
octree.convert_from_point_cloud(pcd, size_expand=0.01)
print("可视化Octree...")
o3d.visualization.draw_geometries([octree])

在这里插入图片描述

import open3d as o3dpcd = o3d.io.read_point_cloud("chair_point_cloud.pcd")
print('体素化')
voxel_grid = o3d.geometry.VoxelGrid.create_from_point_cloud(pcd, voxel_size=0.04)
print("体素:", voxel_grid)
o3d.visualization.draw_geometries([voxel_grid])print('Octree 分割')
octree = o3d.geometry.Octree(max_depth=6)
octree.create_from_voxel_grid(voxel_grid)
print("Octree:", octree)
o3d.visualization.draw_geometries([octree])

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

法线估计
import open3d as o3dpcd = o3d.io.read_point_cloud("chair_point_cloud.pcd")
pcd, ind = pcd.remove_statistical_outlier(20, 2.0)
print("估计法线并可视化")
radius = 0.01  # 搜索半径
max_nn = 30  # 邻域内用于估算法线的最大点数
pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius, max_nn))  # 执行法线估计print("打印前20个点的法向量:")
print(np.asarray(pcd.normals)[:10, :])
o3d.visualization.draw_geometries([pcd], point_show_normal=True)

在这里插入图片描述

点云投影
import open3d as o3dpcd = o3d.io.read_point_cloud("chair_point_cloud.pcd")# 点云沿Z轴投影
side_view = o3d.geometry.PointCloud()
pts = np.asarray(pcd.points)
pts[:, 2] = 0
side_view.points = o3d.utility.Vector3dVector(pts)# 创建可视化窗口
vis = o3d.visualization.Visualizer()
vis.create_window()
# 坐标轴显示
axis = o3d.geometry.TriangleMesh.create_coordinate_frame(size=0.3, origin=(0, 0, 0))
vis.add_geometry(axis)vis.add_geometry(pcd)
# vis.add_geometry(side_view)
# 显示点云
vis.run()
vis.destroy_window()

在这里插入图片描述

计算点云最小包围盒
import open3d as o3dpcd = o3d.io.read_point_cloud("chair_point_cloud.pcd")
pcd, ind = pcd.remove_statistical_outlier(10, 2.0)
print("计算点云轴向最小包围盒")
aabb = pcd.get_axis_aligned_bounding_box()
aabb.color = (1, 0, 0)
print("计算点云最小包围盒")
obb = pcd.get_oriented_bounding_box()
obb.color = (0, 1, 0)
o3d.visualization.draw_geometries([pcd, aabb])

在这里插入图片描述

计算点云凸包
import open3d as o3dpcd = o3d.io.read_point_cloud("chair_point_cloud.pcd")
pcd, ind = pcd.remove_statistical_outlier(10, 2.0)
# 计算点云凸包
hull, _ = pcd.compute_convex_hull()
hull_ls = o3d.geometry.LineSet.create_from_triangle_mesh(hull)
hull_ls.paint_uniform_color((0, 1, 0))
o3d.visualization.draw_geometries([pcd, hull_ls])

在这里插入图片描述

DBSCAN聚类
import open3d as o3dpcd = o3d.io.read_point_cloud("chair_point_cloud.pcd")
# DBSCAN聚类
eps = 0.1  # 同一聚类中最大点间距
min_points = 50  # 有效聚类的最小点数
with o3d.utility.VerbosityContextManager(o3d.utility.VerbosityLevel.Debug) as cm:labels = np.array(pcd.cluster_dbscan(eps, min_points, print_progress=True))
max_label = labels.max()  # 获取聚类标签的最大值 [-1,0,1,2,...,max_label],label = -1 为噪声,因此总聚类个数为 max_label + 1
print(f"point cloud has {max_label + 1} clusters")
colors = plt.get_cmap("tab20")(labels / (max_label if max_label > 0 else 1))
colors[labels < 0] = 0  # labels = -1 的簇为噪声,以黑色显示
pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])
o3d.visualization.draw_geometries([pcd])

在这里插入图片描述

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

相关文章:

  • 城市照明深夜全亮太浪费?智能分时调光方案落地贵州某市
  • threadlocal的实现说明
  • python46
  • 端到端自动驾驶研究:通过强化学习与世界模型的协同作用向VLA范式演进
  • 曼昆《经济学原理》第九版 第十三章生产成本
  • 智能呼入系统助力酒店客服服务
  • 使用mpu6500/6050, PID,互补滤波实现一个简单的飞行自稳控制系统
  • 2025.6.10【ZR NOI模拟赛 T3】 过啥题 题解(Lucas 定理, 数位dp, 组合意义)
  • Java设计模式基础问答
  • 通过Wrangler CLI在worker中创建数据库和表
  • QFuture的使用方式
  • vue的created和mounted区别
  • 替代爬虫!亚马逊API采集商品详情实时数据开发教程
  • 《Java开发者进击之路:掌握Spring AI与DL4J,实现AI模型API集成》
  • MCU Keil中支持的变量类型和定义方法
  • 美业门店/个案疗愈门店管理系统具备「活动促销」功能有哪些优势?
  • 多面体编译的循环分块
  • iOS和桌面双端抓包实战经验总结:Sniffmaster与常见工具组合解析
  • 算法工程师工作面试常考问题汇总
  • HarmonyOS 应用开发学习记录 - 从Windows开发者视角看鸿蒙开发
  • RabbitMQ的使用--Spring AMQP(更新中)
  • 期末考试复习总结-《从简单的页面开始(上)》
  • CentOS7下的Nginx部署
  • 行业 |5G六年,互联网改变了什么?
  • WHAT - 组件库开发场景 - 完全无样式的 UI 组件库 Headless UI
  • 看板更新不及时该如何规范
  • jQuery带动画特效的圆形导航菜单特效
  • Playwright 与 Selenium:自动化测试的两大主流工具对比
  • iOS超级签申请流程及环境部署
  • 从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路