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

基于open3d的一些常见点云操作

Open3D 是一个强大的开源库,专门用于处理 3D 数据(如点云、网格等)。以下是 Open3D 中常见的点云操作总结:


1. 点云读取与写入

  • 读取点云:支持常见格式(.ply, .pcd, .xyz, .obj 等)。
    pcd = o3d.io.read_point_cloud("file.ply")
    
  • 写入点云
    o3d.io.write_point_cloud("output.ply", pcd)
    

2. 点云可视化

  • 快速可视化
    o3d.visualization.draw_geometries([pcd])
    
  • 自定义视图:支持调整背景色、点大小、视角等。

3. 点云预处理

  • 下采样(降采样)
    down_pcd = pcd.voxel_down_sample(voxel_size=0.05)
    
  • 去除离群点
    • 统计离群点移除:
      cl, ind = pcd.remove_statistical_outlier(nb_neighbors=20, std_ratio=2.0)
      
    • 半径离群点移除:
      cl, ind = pcd.remove_radius_outlier(nb_points=16, radius=0.05)
      
  • 滤波(平滑)
    • 高斯滤波或均值滤波需自定义实现(Open3D 未直接提供)。

4. 点云配准(Registration)

  • ICP(Iterative Closest Point)
    trans_init = np.identity(4)  # 初始变换矩阵
    reg_result = o3d.pipelines.registration.icp(
        source, target, max_distance, trans_init,
        o3d.pipelines.registration.TransformationEstimationPointToPoint())
    
  • 全局配准:基于特征描述子(如 FPFH)的 RANSAC 初始配准。

5. 点云分割与聚类

  • 平面分割(RANSAC)
    plane_model, inliers = pcd.segment_plane(
        distance_threshold=0.01, ransac_n=3, num_iterations=1000)
    
  • DBSCAN 聚类
    labels = np.array(pcd.cluster_dbscan(eps=0.1, min_points=10))
    

6. 点云变换

  • 旋转/平移/缩放
    pcd.rotate(rotation_matrix, center=(0, 0, 0))
    pcd.translate((tx, ty, tz))
    pcd.scale(scale_factor, center=(0, 0, 0))
    
  • 法线估计
    pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30))
    

7. 点云生成

  • 从深度图生成
    pcd = o3d.geometry.PointCloud.create_from_depth_image(
        depth, intrinsic, extrinsic=(np.identity(4)))
    
  • 从 RGB-D 数据生成
    pcd = o3d.geometry.PointCloud.create_from_rgbd_image(rgbd_image, intrinsic)
    

8. 点云特征提取

  • FPFH 特征(用于配准或识别):
    fpfh = o3d.pipelines.registration.compute_fpfh_feature(
        pcd, o3d.geometry.KDTreeSearchParamHybrid(radius=0.25, max_nn=100))
    

9. 点云与网格的转换

  • 泊松重建(生成网格)
    mesh, densities = o3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=9)
    
  • 凸包重建
    hull, _ = pcd.compute_convex_hull()
    

10. 其他实用操作

  • 点云拼接
    combined_pcd = pcd1 + pcd2
    
  • 计算点云距离
    dist = pcd1.compute_point_cloud_distance(pcd2)
    
  • KDTree 加速查询
    kdtree = o3d.geometry.KDTreeFlann(pcd)
    

11.具体操作实例

  • 求解外包络
    在 Open3D 中,计算点云的最小外包络(Bounding Volume)常用的三种方法包括 AABB(轴对齐包围盒)OBB(有向包围盒)最小外接球。以下是具体实现方法及代码示例:

1. AABB (Axis-Aligned Bounding Box)
特点:与坐标轴对齐的包围盒,计算速度快,但紧密性较差。
计算方法:直接取点云在 XYZ 轴上的最小/最大值。
代码

import open3d as o3d
import numpy as np

# 读取点云
pcd = o3d.io.read_point_cloud("point_cloud.ply")

# 计算AABB
aabb = pcd.get_axis_aligned_bounding_box()
aabb.color = (1, 0, 0)  # 设置为红色

# 可视化
o3d.visualization.draw_geometries([pcd, aabb])

2. OBB (Oriented Bounding Box)
特点:考虑点云的主方向,包围更紧密,但计算复杂度较高。
计算方法:基于 PCA(主成分分析)确定最优旋转方向。
代码

# 计算OBB
obb = pcd.get_oriented_bounding_box()
obb.color = (0, 1, 0)  # 设置为绿色

# 可视化
o3d.visualization.draw_geometries([pcd, obb])
手动实现PCA计算OBB(可选):

若需自定义,可通过 PCA 计算点云的主轴方向:

# 将点云转换为NumPy数组
points = np.asarray(pcd.points)

# 计算PCA
mean = np.mean(points, axis=0)
cov = np.cov((points - mean).T)
eigenvals, eigenvecs = np.linalg.eig(cov)

# 根据特征向量构造OBB的旋转矩阵
obb = pcd.get_oriented_bounding_box(rot=eigenvecs)  # 需进一步调整

有时候手动计算的主方向并不是我们想要的长宽方向,这时候可以考虑将其投影到2d方向然后再来计算pca主方向,完整操作实例如下,

import open3d as o3d
import numpy as np

def align_pcd_by_projected_pca(pcd):
    # Step 1: 转为 numpy
    pts = np.asarray(pcd.points)
    
    # Step 2: 计算法线方向(最小特征值方向)
    center = np.mean(pts, axis=0)
    pts_centered = pts - center
    cov = np.cov(pts_centered.T)
    eig_vals, eig_vecs = np.linalg.eigh(cov)
    
    # 法线方向是最小特征值方向
    normal = eig_vecs[:, 0]  # 最小特征值方向

    # Step 3: 投影点云到主平面(去掉法线方向)
    normal = normal / np.linalg.norm(normal)
    projection = pts - np.dot(pts - center, normal[:, None]) * normal

    # Step 4: 对投影后的点做 PCA,获得长宽方向
    proj_centered = projection - np.mean(projection, axis=0)
    cov_proj = np.cov(proj_centered.T)
    eig_vals_proj, eig_vecs_proj = np.linalg.eigh(cov_proj)

    # 主方向:最大特征值方向
    main_dir = eig_vecs_proj[:, 2]  # 对应最大特征值

    # 构造新坐标轴(main_dir, cross, normal)
    x_axis = main_dir / np.linalg.norm(main_dir)
    z_axis = normal
    y_axis = np.cross(z_axis, x_axis)
    y_axis = y_axis / np.linalg.norm(y_axis)
    x_axis = np.cross(y_axis, z_axis)  # 保正交
    
    # 构造旋转矩阵 R(世界 -> 对齐空间)
    R = np.stack([x_axis, y_axis, z_axis], axis=1)
    
    # Step 5: 旋转点云
    pcd_aligned = pcd.translate(-center)
    pcd_aligned.rotate(R.T, center=(0, 0, 0))
    
    # Step 6: 在旋转后的空间计算 OBB
    obb = pcd_aligned.get_oriented_bounding_box()

    # Step 7: 逆变换 OBB
    obb.rotate(R, center=(0, 0, 0))
    obb.translate(center)
    
    return obb, R, center

# ==== 可视化 ====
if __name__ == "__main__":
    # 读取点云
    pcd = o3d.io.read_point_cloud("your_point_cloud.ply")

    # 计算对齐后的 obb
    obb, _, _ = align_pcd_by_projected_pca(pcd)

    # 可视化结果
    obb.color = [1, 0, 0]
    o3d.visualization.draw_geometries([pcd, obb])

3. 最小外接球 (Minimum Bounding Sphere)
特点:球形的包围体积,适用于各向同性分布的点云。
计算方法:Open3D 未直接提供最小外接球 API,可借助 scipy.spatial 计算。
代码

from scipy.spatial import Miniball
import numpy as np

# 将点云转换为NumPy数组
points = np.asarray(pcd.points)

# 计算最小外接球
mb = Miniball(points)
center = mb.center()
radius = np.sqrt(mb.squared_radius())

# 在Open3D中创建球体网格
sphere = o3d.geometry.TriangleMesh.create_sphere(radius=radius)
sphere.translate(center)
sphere.paint_uniform_color((0, 0, 1))  # 设置为蓝色

# 可视化
o3d.visualization.draw_geometries([pcd, sphere])

对比总结

方法特点计算复杂度Open3D支持
AABB轴对齐,计算快,包围松散O(n)直接支持 (get_axis_aligned_bounding_box)
OBB方向自适应,包围紧密O(n^2)直接支持 (get_oriented_bounding_box)
最小外接球球形包围,适合均匀分布O(n^4)需借助 scipy.spatial.Miniball

可视化示例

# 同时显示三种包围盒
aabb.color = (1, 0, 0)  # AABB红色
obb.color = (0, 1, 0)    # OBB绿色
sphere = o3d.geometry.TriangleMesh.create_sphere(radius=radius).translate(center)
sphere.paint_uniform_color((0, 0, 1))  # 球蓝色

o3d.visualization.draw_geometries([pcd, aabb, obb, sphere])

注意事项

  1. 数据类型:Open3D 点云数据为 PointCloud 对象,与 NumPy 数组需通过 np.asarray(pcd.points) 转换。
  2. 性能:大规模点云需结合降采样和并行计算优化,OBB 和最小外接球计算较慢,建议对下采样后的点云使用。

Open3D 的 API 简洁且功能丰富,适合快速开发 3D 点云处理流程。详细文档参考:Open3D官方文档。

相关文章:

  • 【数据结构_4】顺序表
  • Adobe After Effects的插件--------Optical Flares之面板属性
  • KWDB创作者计划—KWDB场景创新:多模态数据融合与边缘智能的产业实践
  • 中厂算法岗面试总结
  • 【SLAM】在ORB_SLAM2的ROS模式下使用RealSense D435相机
  • R语言——直方图
  • (自用)若依生成左树右表
  • 【WORD】批量将doc转为docx
  • 搬运机器人的基本工作场景及原理
  • 202526 | 消息队列MQ
  • Pytorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(三)
  • 51c自动驾驶~合集17
  • jetpack之jetpack的概括和其中组件的简单使用
  • STM32 HAL库 HC - SR04 超声波测距模块驱动实现
  • IoT安全透视:D-Link DWR-932B固件全面逆向漏洞挖掘全面解析
  • 使用Python计算汉密尔顿路径
  • Python实现贪吃蛇二
  • Pandas 中透视表(`pivot_table`)和交叉表(`crosstab`)的区别
  • DeepSeek BLEU和ROUGE(Recall)的计算
  • torch.cat和torch.stack的区别
  • 49:49白热化,美参议院对新关税政策产生巨大分歧
  • “80后”杨占旭已任辽宁阜新市副市长,曾任辽宁石油化工大学副校长
  • 辽宁辽阳市白塔区一饭店发生火灾,当地已启动应急响应机制
  • 中国人保不再设监事会,国寿集团未再设置监事长职务
  • 招行一季度净利372.86亿降2.08%,营收降逾3%
  • A股三大股指小幅低收:电力股大幅调整,两市成交10221亿元