第3章:点云数据基础——从结构到文件,再到Halcon读写

点云是什么?说白了,就是一堆三维空间里的点。每个点都带着自己的坐标信息(X, Y, Z)。有些点还带着颜色(R, G, B)。这就是我们常说的XYZ和XYZRGB。

我刚开始接触3D视觉时,觉得点云不就是一堆点嘛,有什么好学的?后来在项目里被文件格式坑过几次,才明白——数据结构搞不清楚,后面所有处理都是空中楼阁。

3.1 点云数据结构:XYZ与XYZRGB

先看最基本的。一个点云数据,核心就是点的集合。每个点至少有三个坐标值。

数据类型 字段 说明 典型场景
XYZ X, Y, Z 三维空间坐标,单位通常为毫米或米 激光扫描、结构光深度图
XYZRGB X, Y, Z, R, G, B 坐标 + 颜色信息,颜色值0-255 RGB-D相机(如Kinect、RealSense)
XYZI X, Y, Z, Intensity 坐标 + 反射强度 激光雷达(LiDAR)

核心理解:Halcon内部统一用3D对象模型(ObjectModel3D)来管理点云。不管你读进来的是XYZ还是XYZRGB,最终都变成一个object_model_3d句柄。颜色信息存储在属性里,不是单独的数据结构。

我在一个3C检测项目里遇到过这种情况:客户给的PLY文件带颜色,但我们的算法只需要坐标。一开始我傻傻地读了全部数据,内存直接爆了。后来才学会——读文件时可以指定只加载坐标,颜色不要。嗯,这个后面会讲。

3.2 点云文件格式:PLY、OBJ、CSV

市面上点云格式很多,但工业项目里最常见的就是这三种。我按自己的经验排个序:PLY > OBJ > CSV。

3.2.1 PLY格式(Polygon File Format)

这是我最推荐的格式。为什么?因为它既能存点云,又能存三角网格。而且支持ASCII和二进制两种编码。

  • 优点:结构清晰,支持XYZRGB,支持顶点法向量,文件头可读
  • 缺点:二进制版本跨平台有时字节序不对
  • Halcon支持:完美支持,读写速度最快

我的习惯:项目里所有中间结果都存PLY二进制格式。文件小,读写快。只有需要人工查看时才转ASCII。

3.2.2 OBJ格式(Wavefront OBJ)

OBJ是3D建模界的通用格式。它主要存网格,但也能存点云。

  • 优点:几乎所有3D软件都能打开,支持材质(MTL)
  • 缺点:点云数据量大时文件很臃肿,不支持直接存颜色
  • Halcon支持:支持读写,但速度比PLY慢

注意:OBJ格式里,颜色通常存在关联的MTL文件里。如果你只拿OBJ文件,颜色信息可能会丢。我曾经因为这个被坑过一次,调试了半天才发现是文件格式的问题。

3.2.3 CSV格式(Comma-Separated Values)

CSV就是纯文本表格。每一行一个点,列之间用逗号分隔。

  • 优点:人类可读,Excel直接打开,方便调试
  • 缺点:文件巨大,没有标准头信息,读写慢
  • Halcon支持:不直接支持,需要自己解析

你想想看,一个100万个点的点云,CSV文件可能有几十MB。而同样的数据用PLY二进制,可能只有10MB。所以CSV我只在调试阶段用,正式项目从来不用。

3.3 Halcon中读取与保存点云

终于到实操环节了。Halcon提供了两个核心算子:read_object_model_3d 和 write_object_model_3d。

3.3.1 读取点云:read_object_model_3d

这个算子的签名是这样的:

read_object_model_3d( : : FileName, Scale, GenParamName, GenParamValue : ObjectModel3D, Status)

参数说明:

参数 类型 说明
FileName string 文件路径,支持.ply、.obj、.dxf、.stl等
Scale real 缩放因子,默认1.0。单位转换时用
GenParamName tuple 控制参数名称,如'ply_type'
GenParamValue tuple 控制参数值
ObjectModel3D handle 输出:3D对象模型句柄
Status integer 输出:状态码,0表示成功

来个实际例子:

* 读取PLY文件,保持原始尺寸
read_object_model_3d ('pointcloud.ply', 1.0, [], [], ObjectModel3D, Status)

* 读取时只加载坐标,不加载颜色(节省内存)
read_object_model_3d ('pointcloud.ply', 1.0, ['load_color'], ['false'], ObjectModel3D, Status)

* 读取OBJ文件,并缩放到毫米单位
read_object_model_3d ('mesh.obj', 0.001, [], [], ObjectModel3D, Status)

避坑指南:我曾经在读取一个大型PLY文件时,程序直接卡死了。后来发现是文件里包含了三角网格信息,而我只想要点云。解决方案是加上参数 'ply_type' 设为 'point_cloud',只读点云部分。

3.3.2 保存点云:write_object_model_3d

保存的算子同样简洁:

write_object_model_3d( : : ObjectModel3D, FileType, FileName, GenParamName, GenParamValue : )

参数说明:

参数 类型 说明
ObjectModel3D handle 输入:3D对象模型句柄
FileType string 输出格式,如'ply'、'obj'、'dxf'
FileName string 输出文件路径
GenParamName tuple 控制参数,如'ply_encoding'
GenParamValue tuple 控制参数值

实际保存示例:

* 保存为PLY二进制格式(推荐)
write_object_model_3d (ObjectModel3D, 'ply', 'output.ply', ['ply_encoding'], ['binary'])

* 保存为OBJ格式
write_object_model_3d (ObjectModel3D, 'obj', 'output.obj', [], [])

* 保存为PLY ASCII格式(方便调试)
write_object_model_3d (ObjectModel3D, 'ply', 'output_ascii.ply', ['ply_encoding'], ['ascii'])

重要提醒:保存时如果点云包含颜色信息,Halcon会自动写入。但OBJ格式不支持颜色,颜色会丢失。所以如果你需要保留颜色,一定要用PLY格式。

3.4 知识体系结构图

下面这张图帮你理清本章的核心逻辑:

点云数据基础 · 知识体系 点云数据结构 XYZ(坐标) XYZRGB(坐标+颜色) XYZI(坐标+强度) 点云文件格式 PLY(推荐) OBJ(网格) CSV(调试用) Halcon读写:read / write_object_model_3d 核心流程:数据结构 → 文件格式 → Halcon读写,三者环环相扣

3.5 本章小结

这一章我们走了三个台阶:

  1. 数据结构:XYZ是骨架,XYZRGB是血肉。理解它们,你才知道读进来的数据是什么。
  2. 文件格式:PLY是首选,OBJ是备选,CSV是调试工具。选对格式,事半功倍。
  3. Halcon读写:两个算子搞定一切。但参数细节决定了你的程序是跑得飞快还是卡死。

一句话总结:点云数据基础,就是搞清楚「数据长什么样、存在什么文件里、怎么用Halcon搬进来搬出去」。这三件事搞定了,后面的点云处理才有根基。