一、结构光系统概述
大家好,我是老张。做结构光这行快十年了,踩过的坑比走过的路还多。今天咱们聊聊结构光系统的基础,这部分看似简单,但很多新手上来就翻车。嗯,我先把核心框架画出来,你心里有个谱。
1.1 结构光三维重建原理
说白了,结构光就是「主动投射 + 三角测量」。投影仪往物体上打光,相机从另一个角度拍,然后通过几何关系算出深度。我刚开始接触这行时,总觉得这跟人眼双目视觉差不多,后来才发现——主动投射的好处太大了,尤其遇到纹理很弱的物体,比如白墙、塑料件,双目视觉直接歇菜,结构光反而游刃有余。
核心公式其实就一个:
Z = (B * f) / (d + Δ)
其中 B 是基线距离(投影仪和相机光心之间的距离),f 是相机焦距,d 是视差,Δ 是系统误差项。嗯,这个 Δ 我当年调了整整两周才搞定,后面会细说。
关键点:结构光的精度取决于三个因素——基线长度、编码分辨率、标定精度。基线越长,深度分辨率越高,但遮挡问题也越严重。我个人习惯在 200mm-500mm 之间选,具体看被测物体大小。
1.2 系统组成:投影仪 + 相机
一个典型的结构光系统,硬件上就两样东西:投影仪和相机。但这里面的门道不少。
投影仪选型
- DLP 投影仪:我主力用的。刷新率高,能到 120Hz 甚至更高,适合相移法这种多帧编码。德州仪器的 DLP LightCrafter 系列我用过好几代,稳定性不错。
- LCD 投影仪:便宜,但刷新率低,而且像素边缘模糊。我建议只用在静态场景或者散斑方案里。
- 激光投影:散斑噪声大,但景深极深。做大型物体(比如汽车)时可以考虑。
相机选型
- 全局快门:必须的。卷帘快门拍运动物体会变形,我吃过这个亏——有一次拍流水线上的零件,结果重建出来的模型像面条一样扭曲。
- 分辨率:200万到500万像素最常见。分辨率越高,点云越密,但处理时间也越长。
- 帧率:至少 30fps,做动态重建建议 60fps 以上。
我的经验:投影仪和相机之间最好加一个同步触发线。用软件同步经常丢帧,尤其跑高速的时候。我后来全部改成硬件触发,再也没出过问题。
1.3 常见编码策略
编码策略是结构光的灵魂。说白了,就是怎么给每个像素一个「身份证」,让相机能认出投影仪打出来的是哪条光。目前主流的有三种,我一个个说。
相移法(Phase Shifting)
相移法是我最常用的方法。它通过投射多张正弦条纹图,每张之间相位偏移一定角度(通常是 90° 或 120°),然后通过反正切函数解出相位。精度很高,能达到亚像素级别。
// 三步相移法示例(相位偏移 120°)
I1 = A + B * cos(φ)
I2 = A + B * cos(φ + 2π/3)
I3 = A + B * cos(φ + 4π/3)
// 解相位
φ = atan2(√3 * (I1 - I3), 2*I2 - I1 - I3)
但相移法有个坑——解出来的相位是包裹的,范围在 [-π, π] 之间,需要做相位展开。我曾经在展开这一步栽过跟头,遇到物体表面有陡峭台阶时,展开算法直接崩了。后来我改用多频外差法,才彻底解决。
避坑指南:我曾经在金属反光表面用相移法,结果高光区域完全解不出相位。后来加了偏振片,效果立竿见影。记住——高光是相移法的天敌。
格雷码(Gray Code)
格雷码是二值化编码,每张图只有黑白两种灰度。它的好处是鲁棒性极强,对表面纹理不敏感,也不怕环境光干扰。我做过对比测试,在同样光照条件下,格雷码的误码率比相移法低一个数量级。
格雷码的编码方式很巧妙:相邻两个码字之间只有一位不同。这样即使解码时出现一位错误,也不会导致深度值跳变太大。
// 格雷码与二进制码的转换
// 二进制 → 格雷码
gray = binary ^ (binary >> 1)
// 格雷码 → 二进制
binary = gray;
while (mask >>= 1) binary ^= mask;
但格雷码的精度受限于投影分辨率。比如投影仪是 1024 像素宽,用 10 位格雷码,理论精度就是 1/1024。想提高精度?要么换更高分辨率的投影仪,要么跟相移法结合——这就是混合编码的思路。
散斑(Speckle)
散斑方案跟前面两种完全不同。它不投射规则条纹,而是投射随机散斑图案。相机拍一张图,然后跟参考图做块匹配,找到对应点,再算深度。
散斑最大的优势是——单帧就能重建。Kinect v1 用的就是散斑方案,能做到 30fps 实时。但缺点也很明显:精度低,而且依赖物体表面纹理。如果物体是纯色的,匹配效果就很差。
三种编码对比:
| 特性 | 相移法 | 格雷码 | 散斑 |
|---|---|---|---|
| 精度 | 高(亚像素) | 中(像素级) | 低(块匹配) |
| 帧数需求 | 3-12 帧 | 8-12 帧 | 1 帧 |
| 抗环境光 | 弱 | 强 | 中 |
| 适用场景 | 精密测量 | 工业检测 | 实时交互 |
最后说一句,实际项目中我很少只用一种编码。比如做高精度测量时,我会用「格雷码 + 相移法」混合——格雷码做粗定位,相移法做细定位,精度能到 0.01mm 级别。你想想看,这比单一编码强太多了。
好了,这一章就聊到这儿。结构光系统说复杂也复杂,说简单也简单——原理就一个三角测量,但真正落地时,每个环节都有坑。后面我会把调参的实战经验一点点掰开揉碎了讲给你听。
公众号:蓝海资料掘金营,微信 deep3321