ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

结构光、ToF、双目视觉:三大3D传感器原理对比与选型指南

结构光、ToF、双目视觉:三大3D传感器原理对比与选型指南 3D传感器这几年在搞机器人、AR、工业检测、自动驾驶的人都绕不开。就在前几年一个靠谱一点的深度相机还要几千上万现在几百块搞个入门模块回来玩也已经很常见。不过东西多了就乱很多人来问我“结构光、ToF、双目到底怎么选”甚至搞不清它们本质上的区别。这篇文章我就把三种常见的3D传感器拉到一起从上手角度和工程落地角度给你盘个明白适合正在选型、刚入门、或者手头项目被深度测量卡住的人。1. 三种主流3D传感器先看全局再聊细节1.1 为什么市场里基本是这三家说话市面上叫得上名的深度相机拆开看核心基本都是这三类结构光、ToF飞行时间法、双目视觉。你可能还听说过激光雷达但消费级和工业级的3D传感器主力其实就是这三家在唱戏。原因很简单要实现“测量深度”只有两条路一是主动给场景打上已知的“记号”再观察记号怎么变形结构光就是这个思路二是主动测量光走一个来回的时间ToF就是这个思路还有就是完全被动地靠两个视角的自然光图像做三角测量也就是双目。这三种路线各自把“硬件复杂度”“算法复杂度”“场景适应性”放在不同侧重上没有哪个能通吃。理解了这一点你在选型时就不会被一堆宣传参数带偏。下面我先给一张对照表后面再逐个拆开讲原理和实操。1.2 一张表看懂三者核心参数差异维度结构光ToF双目视觉典型量程0.2m-5m消费级多在0.3-3m0.1m-15m远距离看激光功率0.2m-几十米取决于相机布局近距精度很高可达0.1mm-1mm量级一般1-3cm远距离衰减不大基线合理时0.5-2cm随距离平方恶化深度分辨率可以做到接近RGB分辨率通常320x240到640x480左右取决于相机分辨率可做高帧率30fps左右受匹配/解码开销影响可以做到60-90fps高帧率取决于立体匹配算力户外强光基本是短板易失效相对抗光但强直射也有影响理想场景之一弱纹理物体强主动投影图案一般弱像纯白墙基本没法测静态/动态场景静态精度极佳动态有伪影风险动态场景表现好校准和算力到位也能跑动态这张表先留着后面操作的时候会对得上“为什么会出现这种问题”。2. 核心细节解析三种方案到底在用什么逻辑测距2.1 结构光投一组加密“码书”再读变形结构光的基本逻辑特别像给物体盖一层二维码。相机不直接找物体身上的纹理而是把已知编码图案投射到物体表面图案随物体表面凹凸产生变形相机捕捉到变形后的图案反解出每个像素对应的高度信息。这里面有几个工程点必须注意。首先是投影图案的选择常见的有格雷码、正弦条纹、随机散斑。格雷码的好处是鲁棒、每个区域都有唯一的编码正弦条纹适合做相移法可以获得亚像素级精度散斑则是Kinect初代和RealSense早期设备的思路通过局部窗口的散斑图案相关性计算视差对动态物体也相对友好。其次是投射器与相机的标定。结构光系统本质上是一个“带有投影仪的双目系统”投影仪相当于一个反向相机。你用投影仪投射编码那相机-投影仪之间的外参、内参、畸变都必须标定得明明白白。一个小教训投影仪自身也有镜头畸变很多人标定时只标相机不标投影仪后期点云边缘会出现明显的弯曲越往视场边缘越夸张。第三个坑是环境光干扰。结构光依赖投影图案对比度室外强光会把投影图案直接淹没导致深度图大片空洞。解决办法一般是提高投影光源功率、加对应波段的窄带滤光片、缩短相机曝光时间。实际项目中要在清晨的室外用结构光滤光片是必备的不然点云质量根本没法看。结构光适合在室内的固定工位、近距离静态或者慢动态场景里拿精度这样的环境能把它的优势最大化。2.2 ToF光走个来回时间差就是距离ToF听起来很简单测激光/红外光从发射到返回的时间差乘光速除2就是距离。不过消费级和工业级绝大多数用的是间接飞行时间法iToF不是直接测纳秒级的时间而是测发射波和接收波之间的相位差。相位差转换距离公式大致是距离 d c * φ / (4π * f) 其中 c 是光速φ 是相位差f 是调制频率这里就能引出一个关键概念——距离模糊。因为相位是周期性的超过一定距离就会“绕圈”同一相位可能对应多个距离这就是模糊距离。提高调制频率可以提升近距离精度但模糊距离变短降低频率则反过来。所以不少ToF方案会使用多个调制频率做组合或者根据量程需求选择固定频率。iToF还有个先天的“多径干扰”问题。光线打到场景里不会只反射一次尤其遇到墙角、金属、玻璃这些位置接收器收到的是多重路径反射光的叠加表现在深度图上就是边缘拖影、内凹角距离被拉长。这一点在手机后摄ToF上极其常见拍柜子角的时候测出来的距离比实际要远。dToF直接飞行时间法就不一样它真正在测单个光子的往返时间比如iPhone后置LiDAR用的就是dToF抗多径能力明显好精度也更均匀代价是分辨率通常做不高硬件成本更高。ToF的优点是不依赖环境纹理也没有基线长度限制体积可以做得很小动态场景效果好。缺点是分辨率上不去边缘容易拖影多径干扰会影响精度。适合做机器人避障、手势交互、体感捕捉这类“要速度不要极致精度”的场景。2.3 双目视觉靠“左右眼”的视差反推远近双目视觉是我们人眼立体视觉的模仿。两台相机相隔一定距离基线同时拍摄同一场景同一个空间点在左右图像上的成像位置会有差异这个差异叫视差。离得近的物体视差大离得远的视差小。通过三角测量就能反推出深度。核心公式经典又简洁深度 Z f * B / d f 是焦距B 是基线距离d 是视差这个式子引出了双目的第一个工程特性深度与视差成反比所以越远的地方一点点视差误差就会被放大成很大的深度误差。用微分式表达更直观深度误差 σZ ≈ Z² * σd / (f * B)什么意思如果你要求10米内的深度误差小于2厘米那视差匹配精度和基线长度就会有硬性要求。这也是为什么手机上的双目做不远的原因——基线太短精度天然受限。反过来远距离监控系统会把两台相机拉得很开基线几十米也有。所以不是你相机买得贵就能测远基线长度决定了上限。双目的另外一个痛点是没有主动光场景纹理直接决定了匹配质量。拿两台相机对着一面白墙拍边角区域全都是空白因为找不到可以匹配的特征点。纹理丰富的书架没问题纯色地面、大白墙、反光金属就非常吃力。方案通常是在相机前面加一个红外纹理投影器用不可见光打出一堆散斑其实就是向主动方案妥协变成“主动立体”。双目最大的好处是可以用普通CMOS传感器成本低、升级灵活、户外表现好RGB信息也是天然的。算法上需要做立体校正、代价计算、代价聚合、视差优化一套流程走下来计算量不小实时性很吃算力。很多入门项目在PC上跑OpenCV的SGBM算法勉强有30帧边缘还带一大片噪声真正要落地到嵌入式平台得用专用深度引擎或者NPU上优化过的立体匹配算法。3. 实操过程从选型到跑通一个深度模块3.1 场景拆解后再做技术选型拿到一个要做深度测量的项目不要先看芯片厂家推荐什么先拆场景。你问自己三个问题距离多近多远室内还是室外测静态还是动态我举个例子。之前有人做货架抓取机器人要识别0.6到1.2米左右的货物固定在室内机械臂上方。这类场景要求的就是近距精度高、点云清晰动态性不急结构光是最合适的。实际用的方案是RealSense D415类产品在0.5米到1米阶段深度误差可以控制在毫米级内。选结构光的决策点只有一个室内、近距、高精度、慢静态。如果是做扫地机器人或者服务机器人的避障需要0.1米到5米甚至更远的量程而且要实时快速响应传统结构光就不太行了。一是量程不够二是投影图案在扫地机这种小设备上功耗撑不住。ToF在这里更合适帧率随便能到30fps以上功耗也相对可控。当时我们试过用ToF模块深度图上有边缘拖影但因为只用来做避障不是做物体重建拖影通过简单滤波就能压住。户外巡检、测绘、无人车这类场景首选双目或者激光雷达。双目能直接用环境光做被动测量没有强光失效的问题。如果怕夜晚没有光就配合主动补光和红外投影。在户外远距离的项目里双目最大的优势是算法可控、分辨率可选、传感器可以挑大靶面的不会被一颗专用ToF芯片锁死。3.2 深度分辨率、FOV和量程的计算逻辑先算一个很实际的例子。假设你有一个双目相机焦距f是6mm基线B是60mm传感器像素尺寸是3μm视差匹配精度可以达到0.1像素。当目标距离Z是1米时深度误差大约是σZ ≈ (1000² / (60 * 6)) * (0.1 * 0.003) mm ≈ (1,000,000 / 360) * 0.0003 mm ≈ 2777.8 * 0.0003 mm ≈ 0.83 mm听起来挺不错。但如果把距离拉到3米σZ ≈ (3000² / 360) * 0.0003 mm ≈ 25000 * 0.0003 mm ≈ 7.5 mm误差一下子扩大了约9倍原因就是深度误差跟距离的平方成正比。所以在列方案时不要只看“最远能测多少米”要看“我关心的距离上误差能不能满足要求”。这个公式在写方案汇报PPT时也非常好用拿着它跟老板解释为什么晚上几米精度差一算一个准。ToF的精度计算则更依赖于调制频率和信噪比。比如一个调制频率30MHz的iToF方案模糊距离大概是5米理想信噪比下相位精度能到0.5%对应距离误差在几个厘米量级。具体数字每家芯片手册都会给但要注意那是在高反射率、低环境光下的实验室数据实际场景墙上刷的黑漆一测误差可能翻倍。3.3 快速验证方案用一个现成的双目模块跑通深度图选型前后我最建议的做法是先在PC上跑一遍数据链路再决定要不要量产方案。以双目为例OpenCV的SGBM就是一个可用的参考实现。下面这段代码是标准的快速验证流程import cv2 import numpy as np # 左右图路径 img_left cv2.imread(left.png, cv2.IMREAD_GRAYSCALE) img_right cv2.imread(right.png, cv2.IMREAD_GRAYSCALE) # 立体校正参数来自标定文件这里为示意值 K1 np.array([[700, 0, 320], [0, 700, 240], [0, 0, 1]], dtypenp.float64) K2 np.array([[700, 0, 320], [0, 700, 240], [0, 0, 1]], dtypenp.float64) D1 np.zeros(5) D2 np.zeros(5) R np.eye(3, dtypenp.float64) T np.array([-0.06, 0.0, 0.0], dtypenp.float64) # 基线60mm R1, R2, P1, P2, Q, _, _ cv2.stereoRectify(K1, D1, K2, D2, img_left.shape[::-1], R, T) map1x, map1y cv2.initUndistortRectifyMap(K1, D1, R1, P1, img_left.shape[::-1], cv2.CV_32FC1) map2x, map2y cv2.initUndistortRectifyMap(K2, D2, R2, P2, img_right.shape[::-1], cv2.CV_32FC1) rect_left cv2.remap(img_left, map1x, map1y, cv2.INTER_LINEAR) rect_right cv2.remap(img_right, map2x, map2y, cv2.INTER_LINEAR) # 参数minDisparity、numDisparities、blockSize需要调 stereo cv2.StereoSGBM_create(minDisparity0, numDisparities64, blockSize11) disparity stereo.compute(rect_left, rect_right).astype(np.float32) / 16.0 depth cv2.reprojectImageTo3D(disparity, Q) # 用中值滤波去掉明显的噪声 depth cv2.medianBlur(depth, 5)要注意的是这套SGBM只是让你快速理解流程远达不到工业级水平。实际产品里要么用专门深度引擎芯片要么在GPU上跑优化过的Census变换和代价聚合不然“勉强能看”和“能稳定用”之间差很远。用现成的ToF或结构光模块更简单一般厂商都会给SDK像RealSense的pyrealsense2一打开就能拿到对齐后的深度图import pyrealsense2 as rs pipeline rs.pipeline() config rs.config() config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30) config.enable_stream(rs.stream.color, 640, 480, rs.format.rgb8, 30) pipeline.start(config) for _ in range(100): frames pipeline.wait_for_frames() depth_frame frames.get_depth_frame() color_frame frames.get_color_frame() if not depth_frame or not color_frame: continue depth_image np.asanyarray(depth_frame.get_data()) color_image np.asanyarray(color_frame.get_data()) # 此处可转成点云或送入后续处理这类SDK最大的帮助是省掉标定、同步、底层滤波的重复劳动让你能立刻聚焦到业务层。3.4 从设备选型到集成的完整步骤复盘一个典型项目从选型到落地我理下来通常走七步量程、精度、帧率指标先写成表格不允许模糊词。比如“误差5mm1m”要比“高精度”靠谱得多。筛出2-3个候选传感器去厂家官网下载真实depth图的样例跑自己的代表性物体。做光照和材质对照测试拉一个标准白墙、黑植绒布、哑光纸箱、镜面不锈钢来测优先看出问题的场景。设计安装方式检查基线、倾斜角、震动等约束。特别是双目和结构光安装角度的变化会直接影响标定。进行深度图质量评估不只看肉眼还要量化坑洞率、深度噪声标准差、边缘误差。小批量试产前留出标定产线或出厂自动标定的时间手动标定一只相机在量产时是噩梦。嵌入式端性能预研用目标芯片跑一遍深度算法或SDK确认算力够用。这个流程走完踩坑比例会大幅下降。很多人一上来就装个传感器看图像效果然后直接写方案后面被量产卡得死死的多半是前两步没做扎实。4. 常见问题与排查技巧实录4.1 户外强光下为什么结构光会集体“失明”不少结构光用户第一次拿到户外去测深度图直接黑白一大片第一反应是“我传感器坏了吧”。其实不是坏了是环境光太强。结构光投影的红外/近红外图案到达传感器后本身反射信号就弱太阳光里的红外成分又很强图像信噪比急剧下降。你可以试的排查路径是确认是否配了对应波段的窄带滤光片。很多模块默认不带需要自己加。在SDK里调短曝光时间和模拟增益但这是杯水车薪。加遮阳罩物理降低环境光进入镜头。如果阴天或室内表现正常说明光功率/滤光不匹配而不是模块故障。在室外强烈阳光比如中午下市面主流结构光产品基本都不好使这不是品牌问题是物理原理决定的。别硬撑直接换双目或者ToF更省时间。4.2 纯白墙、黑真空棉上为什么双目视差全是花点双目靠自然纹理找同名点。纯白墙在左右相机里拍出来几乎一模一样每个窗口内的特征都差不多匹配容易跳到错误位置输出一堆随机视差。黑植绒布则是反光率太低左右图都太暗边缘噪声大。这类问题排查顺序如下查看左右图本身的对比度和纹理先用肉眼确认“路人看了都能匹配吗”。如果图像清晰但没有纹理加一个红外散斑投射器是最直接的办法。如果图像本身就暗或者过曝先调曝光别急着调匹配参数。场景允许的话增加环境光方向性让阴影多一点也能改善。我也见过有团队把双目用于夜间无人巡检结果没有补光一到晚上就歇菜。这事在选型阶段就要想到立体视觉的“被动性”在光线好的时候是优点在光线差的时候就是硬伤。4.3 ToF边缘拖影、测距偏大是怎么回事ToF的边缘拖影是深度不连续处最容易犯的病。比如桌角边缘前面桌面和后面背景的距离差距大接收器一个像素会同时收到两条路径的光算出来的相位就是两者混合深度值可能出现突变或中间值。这也是为什么ToF深度图边缘看起来有一圈毛边。另一个典型现象是测得比实际远常见于墙角凹面。凹面会形成二次反射光线多绕了一段距离相位差变大所以测得偏大。解决建议在深度后处理里做边缘像素滤波用邻域中值或形态学开运算清理。排查曝光设置过高的曝光会让低反射区域饱和干扰相位计算。用多频率ToF方案或者dToF可以减少多径影响但成本会上去。结构上尽量避免让传感器正对镜面或玻璃安装漫反射优先。4.4 工程问题速查表现象可能原因解决方向结构光深度图强光下大面积空洞红外投影被环境光淹没加窄带滤光片、缩短曝光、遮阳结构光近距离精度很好一拉远马上崩编码条纹周期在表面被拉伸得不够明显换多频编码或增加投影分辨率ToF深度图玻璃区域出现“凹坑”玻璃透明导致光穿透反射丢失避开强镜面场景考虑多传感器融合ToF边缘毛刺严重混合像素/多径干扰收缩视场、中值滤波、调曝光双目对白墙无法匹配缺少纹理加红外散斑投影、加环境纹理双目远距离深度误差大基线和焦距限制算法无力回天增大基线、使用更长焦镜头或换ToF/LiDAR点云有系统性弯曲标定畸变补偿不足重新做整机内参外参标定重点检查边缘区域这个表基本覆盖了新手上手最容易遇到的问题你把它打印出来放在工位上调试效率会快很多。5. 最后聊几句选型心得折腾了这么多年三种方案都碰过我最深的体会是不要迷信参数表上的“最远距离”和“精度”那都是实验室条件下的静态数值。真正决定项目成败的是你选型时有没有把自己的场景细节写清楚。室内固定工位、近距离、高精度结构光大概率是最优解动态、中远距、体积受限ToF更稳户外、低成本、分辨率高双目是基本面。预算足的话多传感器融合是更稳的路子比如结构光加双目做补盲ToF加双目补边缘甚至ToF和RGB融合做语义深度。做项目最怕的不是技术太复杂而是中途发现选错了方向返工成本远比前期多测几轮要高。
返回列表