跳转到内容

Open3D — 现代点云 / 几何库

待复核

Open3D 是一个面向 3D 数据处理 的开源库:C++ 做高性能内核,Python 暴露好用接口,让你能读点云、处理网格、配准两帧扫描、重建房间模型,还能接 PyTorch / TensorFlow 做 3D 机器学习。

日常类比:它像 3D 世界里的“厨房工具台”。原材料是相机、激光雷达、深度传感器吐出的点;Open3D 提供刀、筛子、尺子和展示台,把一堆乱点整理成能分析、能对齐、能可视化的几何对象。

最小例子来自 README 的快速演示思路:创建一个球,算顶点法线,再打开 3D 视图。

import open3d as o3d
mesh = o3d.geometry.TriangleMesh.create_sphere()
mesh.compute_vertex_normals()
o3d.visualization.draw(mesh, raw_mode=True)

这段代码背后的心智很简单:geometry 管几何对象,compute_* 做几何计算,visualization 负责看结果。

不理解 Open3D,下面这些事会很难解释:

  • 为什么激光雷达 / RGB-D 相机吐出来的是几十万到几百万个点,而工程里第一步常常不是训练模型,而是先下采样、估法线、去噪
  • 为什么 SLAM / 三维重建里“把两帧扫描对齐”是一件核心小事,ICP 这种老算法今天还在生产链路里出现
  • 为什么 3D 深度学习不能只靠 pytorch 张量,仍然需要点云读取、邻域搜索、可视化、数据集管线这些几何基础设施
  • 为什么同一个库同时提供 C++ 和 Python:研究员要快写实验,工程系统又要可嵌入、可并行、可跑大数据

Open3D 的脑子可以拆成 三件事

  1. 几何数据结构是容器:点云、三角网格、RGB-D 图像、相机内参都被包装成对象。类比:先把散装螺丝、木板、图纸分门别类放进盒子,后面工具才知道该怎么处理。

  2. 算法是流水线工具:下采样、估法线、分割平面、聚类、ICP、TSDF 融合都可以串起来。类比:先筛掉太密的点,再给每个点标方向,最后把两批点对齐。

  3. 可视化是调试仪表盘:3D 数据很难只靠数字判断对不对,Open3D 把中间结果直接画出来。类比:修自行车不能只看扭矩表,还要抬头看轮子有没有歪。

案例 1:读取点云、下采样、估法线

Section titled “案例 1:读取点云、下采样、估法线”

官方 Point Cloud 教程从一个 .ply 点云开始,先读入,再用 voxel grid 降低点数,最后估计每个点附近的法线方向。

import numpy as np
import open3d as o3d
data = o3d.data.PLYPointCloud()
pcd = o3d.io.read_point_cloud(data.path)
print(np.asarray(pcd.points).shape)
down = pcd.voxel_down_sample(voxel_size=0.05)
down.estimate_normals(
search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30)
)
o3d.visualization.draw_geometries([down], point_show_normal=True)
  • read_point_cloud:按文件后缀读取点云,把磁盘文件变成 PointCloud 对象
  • voxel_down_sample:把空间切成小立方格,每格用一个代表点,减少后续计算量
  • KDTreeSearchParamHybrid:找邻居时同时限制半径和最多点数,避免一个点附近邻居过多

官方 ICP 教程读入 source / target 两个点云,给一个粗略初始变换,再用 registration_icp 把 source 贴到 target 上。

import numpy as np
import open3d as o3d
demo = o3d.data.DemoICPPointClouds()
source = o3d.io.read_point_cloud(demo.paths[0])
target = o3d.io.read_point_cloud(demo.paths[1])
threshold = 0.02
trans_init = np.asarray([[0.862, 0.011, -0.507, 0.5],
[-0.139, 0.967, -0.215, 0.7],
[0.487, 0.255, 0.835, -1.4],
[0.0, 0.0, 0.0, 1.0]])
result = o3d.pipelines.registration.registration_icp(
source, target, threshold, trans_init,
o3d.pipelines.registration.TransformationEstimationPointToPoint(),
)
print(result.fitness, result.inlier_rmse)
print(result.transformation)
  • source / target:两次扫描看到的同一个场景,坐标系还没完全对齐
  • trans_init:初始猜测;ICP 不是魔法,起点太差会贴错地方
  • threshold:只把距离足够近的点当作候选对应点,太大容易吸进错误匹配

案例 3:把 RGB-D 序列融合成网格

Section titled “案例 3:把 RGB-D 序列融合成网格”

官方 RGBD integration 教程用 ScalableTSDFVolume 把多张彩色图 + 深度图融合成一个体素体,最后提取三角网格。

import numpy as np
import open3d as o3d
rgbd_data = o3d.data.SampleRedwoodRGBDImages()
volume = o3d.pipelines.integration.ScalableTSDFVolume(
voxel_length=4.0 / 512.0,
sdf_trunc=0.04,
color_type=o3d.pipelines.integration.TSDFVolumeColorType.RGB8,
)
color = o3d.io.read_image(rgbd_data.color_paths[0])
depth = o3d.io.read_image(rgbd_data.depth_paths[0])
rgbd = o3d.geometry.RGBDImage.create_from_color_and_depth(
color, depth, depth_trunc=4.0, convert_rgb_to_intensity=False
)
intrinsic = o3d.camera.PinholeCameraIntrinsic(
o3d.camera.PinholeCameraIntrinsicParameters.PrimeSenseDefault
)
volume.integrate(rgbd, intrinsic, np.eye(4))
mesh = volume.extract_triangle_mesh()
mesh.compute_vertex_normals()
o3d.visualization.draw_geometries([mesh])
  • ScalableTSDFVolume:把深度观测累计进三维体素网格,适合比单个小物体更大的场景
  • voxel_length:每个体素多大;越小越细,但更吃内存,也更怕深度噪声
  • integrate:把一帧 RGB-D 图像按相机内参和位姿写入体素体

这里把教程里的真实位姿读取简化成 np.eye(4),只保留 API 形状;真实重建必须使用每帧正确相机位姿,否则多帧会糊在一起。

  1. 把点云当图片处理:图片有规则网格,点云是稀疏 3D 坐标;很多 2D 直觉不能直接搬过来。

  2. voxel 太小导致没降采样:格子比传感器噪声还小,点数几乎不变,后面的邻域搜索和 ICP 仍然很慢。

  3. 法线方向不稳定:局部平面有正反两个方向,Open3D 可以估法线,但不知道全局“朝外”是哪边,需要额外定向。

  4. ICP 初值太差:ICP 是局部优化,不是全局搜索;两帧一开始离得太远或重叠太少,就可能收敛到错误姿态。

适用

  • 激光雷达、RGB-D 相机、机器人扫描数据的读取、清洗、可视化
  • SLAM / 三维重建里的点云配准、TSDF 融合、网格提取
  • 3D 机器学习前处理,尤其是点云数据集、邻域操作、结果可视化
  • Python 快速实验 + C++ 工程落地并存的团队

不适用

  • 只做 2D 图像处理 → 优先看 OpenCV / scikit-image
  • 只做离线 3D 建模、雕刻、动画 → 用 blender 更自然
  • 需要游戏引擎级实时渲染、物理、材质系统 → 用 Unity / Unreal / Bevy
  • 对几何完全不熟,只想“一键训练模型” → 先补点云、坐标系、相机内参基础
  • 2018 年:Open3D 论文和开源库公开,目标是给 3D 数据处理提供现代、易用、可扩展的基础库。
  • 早期重点:点云、网格、配准、重建、可视化,让研究者少写重复的几何工具代码。
  • 后来扩展:加入 tensor、GPU 加速、PBR 渲染和 Open3D-ML,开始连接深度学习工作流。
  • 今天:README 里强调 C++ / Python 双接口、并行后端、PyTorch / TensorFlow 支持和 GPU 核心操作,说明它已经从研究工具长成工程工具箱。
  1. 3D 工程的第一步通常不是模型,而是把点云变成“能算、能看、能对齐”的几何对象。
  2. Open3D 的价值在于把 IO、数据结构、几何算法和可视化放到同一套 API,不用每个项目重新拼工具。
  3. 点云算法很依赖尺度参数:voxel、radius、threshold 不是装饰,而是在表达真实世界的米、厘米和噪声。
  4. C++ 内核 + Python 接口是一种常见工程折中:底层跑得快,上层写得快,适合研究到落地的过渡。
  • numpy —— 点云坐标、法线、颜色经常转成数组做统计和调试。
  • pytorch —— Open3D-ML 支持 PyTorch,3D 模型训练前仍要处理几何数据。
  • tensorflow —— Open3D-ML 的另一个深度学习后端,用来对接不同训练生态。
  • cuda —— Open3D README 强调核心 3D 操作支持 GPU 加速。
  • blender —— Blender 更偏创作和渲染,Open3D 更偏几何计算和点云工程。
  • kepler-gl —— 都在可视化大量点,但 kepler.gl 偏 2D 地理数据,Open3D 偏 3D 几何。
  • luxcorerender —— LuxCoreRender — 物理光线追踪
  • openscad —— OpenSCAD — 脚本式 CAD
  • pcl —— PCL — 点云算法的学术工具箱