
搞机器视觉这些年前前后后接触了几十种检测需求从螺丝外观到手机中框尺寸从电子元器件引脚到玻璃盖板表面缺陷。说实话2D视觉做了三年之后我越来越觉得很多项目做到最后不是算法不行而是成像方案本身的天花板就摆在那里。尤其是遇到测高、测厚、测平面度、测凹陷这类需求2D相机怎么打光都救不回来。后来开始系统接触3D相机才感觉像是把一层窗户纸捅破了——原来很多折腾了几个月都搞不定的项目换个维度看就是十分钟的事。这篇是“机器视觉初步”系列的第13篇正好从头讲一讲3D相机。我用实际项目中真正会用到的角度来写不讲太飘的概念尽量把结构光、双目、ToF、线激光这四类主流方案讲清楚再结合我做过的玻璃划痕检测案例聊聊选型和落地。不管你是刚入行的新人还是被2D视觉方案折磨过的老油条这篇文章应该都能给你一些能直接用的思路。1. 为什么2D视觉搞不定的活儿3D相机接了1.1 先数一数2D视觉的死穴很多刚学机器视觉的新人有个错觉觉得2D相机加上好的光源和算法就能解决所有问题。我接触过的项目里至少有三类需求是2D视觉的硬伤。第一类是高度和厚度测量。2D图像本质是物体对光的反射强度的平面分布它记录的是“亮度”而不是“高度”。一个凸起和一个平面上的暗斑在2D图像里可能长一模一样。我做过一个项目是检测橡胶垫片的厚度是否均匀用2D相机加背光源拍了半天边缘轮廓倒是很清晰但厚度数值根本出不来因为厚度方向的信息在投影成像过程中直接丢了。第二类是平面度检测。想象一下你有一个塑料外壳要求检测表面是否平整。2D视觉只能看到表面灰度一个轻微鼓起的地方如果在均匀光照下反光差不多图像上几乎无法区分。就算你用特殊角度打光也只能看个大概趋势测不出0.1mm级别的起伏。第三类是在复杂光照和反光环境下做缺陷检测。典型的例子就是我后面要详细说的玻璃表面划痕检测2D图像里划痕和灰尘、水渍、擦痕混在一起对比度随打光角度剧烈变化今天调好的参数明天就可能大量误检。1.2 3D相机到底多“看”到一维信息3D相机和2D相机的本质区别就是额外获取了场景中每个点的深度信息。2D图像是一个二维数组每个像素存的是灰度值3D相机输出的是一幅深度图或者点云每个像素存的往往是该点的三维坐标。有了高度的维度很多问题就迎刃而解了。平面度检测变成对点云拟合平面的残差分析高度差直接在Z方向上一目了然缺陷检测变成找点云中的局部高度凹陷或凸起不再依赖表面的灰度对比度。一个很形象的比喻2D视觉像是闭上一只眼用单眼看世界3D视觉就像两只眼睛一起看能够看出物体表面的起伏和凹凸。我在实际项目中总结出3D相机真正发挥价值的几个场景物体高度/厚度测量、平面度/共面度检测、体积测量、2D视觉难以处理的低对比度表面缺陷检测、机器人引导抓取时的位姿估计。这几个场景里3D方案往往不是“锦上添花”而是“没有它就做不了”。2. 四大主流3D相机技术路线一次讲透2.1 结构光投影图案算高度3D结构光相机这几年热度很高原理可以概括成“主动投影三角测量”。相机内部有一个投影装置把特定的光栅条纹或编码图案投射到物体表面再用相机拍摄这些图案。因为物体表面高低不平投影到表面的条纹会发生变形通过计算条纹的形变程度就能还原出高度信息。具体到工业场景用得最多的是正弦条纹相移法。投影仪依次投射多幅相位差固定比如90度的正弦条纹相机同步拍摄通过相移算法计算出每个像素的包裹相位再用多频外差或者时间相位展开得到绝对相位最后利用标定好的相位-高度映射关系把相位转换为实际高度值。结构光的优点是精度高在合适的视野下Z向精度能做到0.01mm级别而且因为是主动投射图案对物体表面的纹理条件要求低不像双目那样依赖表面特征。缺点是对环境光敏感在强光环境下容易受干扰对黑色吸光物体、镜面反射物体的适应性差。我做玻璃检测项目时最开始试的就是结构光方案后面会详细说遇到了什么坑。2.2 双目立体视觉模仿人眼算视差双目相机的原理大家比较好理解就是用两个固定基线距离的普通相机同时拍摄同一个场景通过匹配左右图像中的同名点利用视差计算出深度。公式很简单深度Z等于焦距f乘以基线距离B除以视差d也就是Z fB/d。双目方案最大的优势是成本低结构简单两个相机加一个同步触发就可以搭起来而且不需要主动光源功耗低适合室外和远距离场景。但它的缺点同样明显非常依赖物体表面的纹理特征。一个纯色光滑的零件表面左图和右图看起来完全一样软件根本找不到同名点来算视差结果就是一大片空洞。在工业近距场景中双目通常只能达到0.1mm到1mm级别的精度应付粗定位还行精密测量就吃力了。不过在机器人抓取、三维重建这类对精度要求没那么极端的场景中双目依然是性价比很高的选择。2.3 ToF光速测距的粗活专家ToF的核心思路非常直接测量光从发射到接收的飞行时间光速已知时间乘速度除以二就是距离。工程上常用的有脉冲调制和连续波相位调制两种方式。脉冲ToF直接计数光子飞行时间而连续波ToF一般通过调制光波测量发射光和反射光之间的相位差来推算距离。ToF相机最大的优点是帧率高能做到几十甚至上百帧每秒适合动态场景作用距离远从几米到几十米都能工作而且对表面纹理和颜色不敏感。但它的精度在所有技术路线里是比较低的工业级ToF的Z轴精度通常也就在毫米级到几个毫米级别分辨率和X/Y精度同样受限。所以我的经验是ToF适合做大范围避障、人形识别、物流包裹体积测量这类“量级”精度要求精密检测基本用不上。2.4 线激光扫描运动中的高精度测量线激光轮廓仪是工业精密检测中我用得最多的一种3D方案。工作原理同样基于三角测量激光器投出一条激光线到物体表面相机从一个斜角度拍摄这条激光线。物体表面高度不同激光线在相机图像中的位置就会偏移通过标定关系把像素偏移转换为高度值。为了得到完整的三维轮廓需要物体与传感器之间做相对运动逐条扫过去拼成一整幅点云。线激光的Z轴精度通常是最高的好的设备能做到微米级而且对高反光、黑色物体等“难搞”材料有更强的算法补偿能力。缺点是需要运动机构配合节拍受限你要在“扫描速度”和“精度”之间做取舍。测玻璃划痕、锂电池极片涂布缺陷、PCB焊点高度这类项目线激光是主力方案。2.5 一张表看清四类3D相机的差别类型Z向典型精度工作距离帧率/速度优势短板典型场景结构光0.01~0.1mm近距为主中精度高纹理依赖低环境光敏感反光/透明适配难精密尺寸测量、缺陷检测双目0.1~1mm中远距中高成本低、被动式、室外可用依赖纹理弱纹理易空洞机器人抓取、三维重建ToF1~10mm中远距高帧率高、距离远精度低分辨率低避障、物流体积测量线激光0.001~0.05mm近距为主取决于扫描机构精度最高适应复杂材质需要运动支撑节拍受限精密轮廓测量、表面缺陷检测这张表只是一个大致区间实际性能跟具体产品、视野大小、景深都有关系。选型的时候我的习惯是先把精度需求卡死再考虑节拍和生产方式最后倒推技术路线。凡是要求Z向精度优于0.05mm的基本就在结构光和线激光里选0.5mm以上粗定位双目或者ToF都能凑合高速在线测量的选择余地其实很小。3. 3D相机怎么选关键参数与我的选型流程3.1 先理清5个关键参数刚接触3D相机的朋友容易一上来就问“这个相机精度多少”但实际上3D相机选型要考虑的参数要比2D相机多得多而且每个参数之间相互制约。第一个是Z轴精度也就是深度方向的测量精度。这通常跟视野高度和景深范围强相关而不是一个固定值。同样一款相机在200mm视野下Z精度可能是0.02mm换到500mm视野可能就变成0.05mm了。第二个是X/Y分辨率也就是点云中相邻点的间隔。它由相机的像素数和视野共同决定。视野宽度100mmX方向点数1000个那么X方向点距就是0.1mm。注意X/Y分辨率和Z精度是两个不同的概念别搞混。第三个是工作距离和景深。工作距离是相机正面到被测物体表面的距离景深则是Z向能清晰成像的范围。景深和Z精度往往是矛盾的景深越大Z精度越差。测一个平面很好办但要测一个有台阶、高低差很大的物体就要仔细算景深是否覆盖得住。第四个是扫描速度或者帧率。线激光相机看轮廓点数每秒多少千个结构光或者ToF看帧率。节拍紧张的项目必须先算清楚在要求的节拍内能不能扫出足够密的点云。第五个是材质适应性也就是黑、亮、透这三种“视觉杀手”材质。黑色吸光导致信号弱高反光导致过曝飞点透明材质产生多表面反射。选型阶段就要拿来实际样件测试不要只看规格书。3.2 Z向精度到底怎么算才靠谱很多厂商标称的Z轴重复精度很诱人但实际项目里你会发现现场测出来的根号下重复性方差往往比标称值大好几倍。我一般按这个逻辑来推算需求精度检测公差除以5到10作为Z向精度要求。假设你要检测0.05mm以下的划痕深度那么相机Z向精度至少需要0.005mm到0.01mm才行否则测量结果本身的噪声就淹没了真实缺陷。再举一个视野和分辨率匹配的例子。项目要求视野宽度80mm需要识别的最小X方向特征尺寸是0.05mm那么X方向至少需要1600个测量点。按照一维轮廓来说就需要选一款单帧轮廓点数不低于2000的线激光相机通常对应2048点或更高规格。直接在选型表上把这两个数对上基本就能排除一大批不合格产品。这里还有一条很实用的经验规格书上的精度数字看归看但真正可靠的是“重复性测试”。我拿到样机后会把一个高精度标准量块放在视野的不同位置每个位置扫50次统计Z向测量的标准差。如果最优位置标准差是0.003mm视野边缘变成0.008mm那你在设计视野和放置产品的位置时就要把这个边缘差异考虑进去。3.3 选型四步走从需求到样机验证第一步是明确检测的对象和判据。到底要测什么、公差范围是多少、缺陷最小尺寸是多少、节拍是多少秒一件。这步别偷懒因为后面的所有技术参数都是从这里推导出来的。第二步是确定技术路线。精度要求高选结构光或者线激光检测物体是静态摆放选结构光物体在产线上连续运动且精度要求高选线激光只做粗定位选双目或ToF。这里我特别提醒一句如果项目既有精度要求又有运动要求线激光几乎是唯一选择但你要确认现场有没有位置装运动编码器或者能否精确控制速度。第三步是缩小范围对比参数和价格。同一条技术路线下不同品牌的产品在Z精度、视野、扫描速度上差距很大。主流的进口品牌和国产品牌我都用过说实话近三年国产品牌在功耗、体积、SDK资料完整性上进步非常明显性价比很高。但如果你做的是全球部署的项目、需要严格的售后体系进口品牌仍然有优势。第四步是一定要“样件实测”。这一步省不了。实际样件和理想平面差了十万八千里黑色的、反光的、透明的各种材料的真实响应只有上机才能看出来。我会专门留出两到三周时间做样机验证包括精度测试、节拍测试、环境光干扰测试全部通过之后才会进入正式方案设计。4. 3D相机实战玻璃划痕检测到底怎么做4.1 玻璃为什么是机器视觉的“地狱难度”在机器视觉这个圈子里做检测的工程师大概都听过一句调侃“凡是透明的、反光的、黑色的东西都是调试工程师的噩梦。”玻璃三样全占了而且它还特别脆。先说说2D方案的实际困难。玻璃表面划痕在可见光下图像表现极不稳定同一道划痕在亮场打光下是一条暗线在暗场打光下可能变成亮线在漫射光下可能完全消失。更麻烦的是玻璃表面同时存在两个面的反射干扰前表面反射可能把划痕信号淹没而后表面的擦伤又会被误判成前表面的缺陷。灰尘、水渍、指纹的灰度特征和轻微划痕极其相似经常面临“阈值调松了误检爆炸调紧了漏检严重”的两难局面。用3D相机的核心逻辑就变了。划痕在3D点云里是一个局部高度凹陷或者侧壁突变的特征不再依赖灰度信息来分辨。有了深度的维度灰尘这种没有深度的污染会被自动过滤掉水渍的微弱起伏和真正划痕的尖锐沟槽在形态上也截然不同。这就是3D方案对2D方案“降维打击”的典型场景。4.2 结构光vs线激光玻璃检测选谁我最初给一个手机玻璃盖板划痕检测项目测试过3D结构光方案。结构光相机配合高分辨率的投影图案在普通塑料、金属表面的确表现不错但放到玻璃上就原形毕露了。玻璃表面会把投影条纹反射得几乎看不到而透明玻璃的体散射又会让一部分光穿到玻璃内部在后表面再形成一层模糊条纹前后两层条纹混叠在一起解算出来的点云出现大量飞点和空洞划痕的位置上反而没有有效数据。后来换成了线激光方案情况立刻好很多。线激光的原理对透明材质有天然优势激光线投到玻璃表面时前表面的散射信号和后表面的反射信号在图像上是分离的两条线只要算法只追踪前表面的激光线中心就能稳定提取玻璃的上表面轮廓。还有一点很关键线激光可以在扫描过程中逐条曝光方便针对现场的强弱信号做曝光参数调节适应能力更强。我的结论是有透明或强反光材质的精密检测优先考虑线激光别在结构光上浪费太多测试时间。但这也不是绝对的如果玻璃表面经过了丝印或镀膜处理显著降低了反光结构光也能用还是要以实测为准。4.3 现场要点打光、曝光、滤波线激光扫玻璃实现起来也有不少坑几个实操细节值得专门说。第一是激光波长的选择。蓝紫波段405nm左右在透明材料上的表面散射强、穿透浅远好于常规红光激光能让前表面的信号更清晰后表面干扰更少。第二是曝光和激光功率的配合。曝光时间太长玻璃内部的体散射会把后表面的信号也拍进来点云上出现“鬼影”层曝光太低又扫不出前表面。我是按“前表面信号亮度刚好不饱和、后表面信号尽量压缩”这个标准来调的。实际测试时白玻璃和有色玻璃的参数差距很大换一种玻璃就要重新标定参数这点要提前准备好快速切换的配方。第三是点云后处理。玻璃划痕往往只有几微米到几十微米的深度原始点云噪声必须压下去。我常用的处理顺序是先做高斯滤波或者中值滤波去随机噪声再做形态学操作——实际上就是把开闭运算的基本原理拿到3D点云里用先开运算去除小的孤立突起再闭运算填补细小的凹陷空洞这样处理后轻微划痕的轮廓就清晰了。第四是检测逻辑的设计。对扫描得到的点云先拟合一个基准平面玻璃的默认面形然后计算每个点到基准平面的距离生成高度残差图。划痕在残差图中表现为一条连续的负偏差区域通过区域生长算法把所有连续的高度异常连通域提取出来再根据长宽比、深度、面积几个特征判断哪条是划痕、哪条是细微擦花。5. 落地路上的坑常见问题与排查思路5.1 点云飞点与空洞飞点是指点云中孤立存在的、明显偏离真实表面的杂乱点。在反光物体、黑色吸光物体和透明物体上尤其严重。飞点会让高度残差图出现大量假缺陷直接导致误检率飙升。排查飞点的第一思路是回到原始激光线图像上看。对于线激光飞点往往是因为某列像素上没有找到可信的激光线峰值信号算法被噪声或者二次反射带偏了。解决办法包括降低曝光让最强信号永不饱和调整激光功率让信号和噪声拉开差距在相机镜头前加窄带滤光片只让激光波长通过把环境光干扰压到最低。有些高端线激光相机本身带“峰值置信度”输出根据信号的尖锐程度给每个点打分用阈值过滤掉低置信度的点效果立竿见影。5.2 透明和反光材质的处理前面聊了玻璃检测这里再系统地说一下透明和反光材质遇到的一般性问题。透明材质的主要麻烦是双表面混叠。我在测透明亚克力板厚度时同一个像素上既有前表面散射信号又有后表面反射信号如果两者亮度相当峰值提取就在两个峰之间来回跳导致厚度值忽高忽低。解决办法一是在材质表面做预处理比如喷显影粉工业上非常常用但会污染产品二是调整光学方案尽量让前后表面信号分离在图像上物理分离成两行像素算法上只追踪前表面信号。高反光材质的问题就是容易过曝。一过曝激光线的中心就会变宽提取中心坐标的误差随之增大。我在测抛光金属件表面时发现同一位置转个角度测出来的高度差了0.05mm后来查出来就是不同角度反光强度不同导致峰值提取偏移。临时对策是缩短曝光长期对策是换用具备HDR功能或智能增益控制的3D相机。5.3 标定与坐标系对齐很多刚上手3D相机的新人只关心点云长什么样结果到了要把检测结果和机器人对接、或者固定点位复测同一个特征位置时就懵了。3D相机交付的不只是一堆点还有坐标系之间的关系。线激光扫描测的是“传感器坐标系”下的轮廓如果把它合成3D点云需要精确知道每条轮廓的Z向移动距离这个移动量可以用外部编码器实时给出也可以让机构匀速运动用固定间隔换算。结构光和ToF测的是相机坐标系下的深度图如果要引导机器人抓取就必须做手眼标定把相机坐标系转换到机器人基坐标系。我见过不少项目在最后联调阶段卡在这个环节所以强烈建议选型时就把SDK里有没有现成的标定工具、文档是否完整纳入考核项。5.4 数据量和节拍的矛盾3D相机的一大“幸福烦恼”就是数据量特别大。一个几百毫米视野的零件扫出来几百万个点非常正常。如果算法把所有点云数据都做全量处理节拍经常跑不满。我的处理思路是按需降采样和ROI剪裁。缺陷检测关注的是局部高度突变完全可以把点云降采样到0.1mm间隔在保证缺陷特征不丢的前提下大幅压缩数据量。同时先用粗略ROI把背景区域裁掉只保留零件区域。还可以用“先计算高度残差图、再在残差图上做轻量化缺陷分析”的方式代替直接在原始点云上跑复杂算法速度能快几倍。如果还不够就要考虑GPU加速或者把3D处理算子放到独立工控机上。5.5 问题速查表现象可能原因排查顺序点云出现随机飞点反光过曝、透明多表面反射、环境光干扰1.看原始激光线图像2.加减光/滤光片3.调曝光和激光功率测透明材质厚度跳动大前后表面信号混叠1.换短波长激光2.缩短曝光3.算法限定峰值提取范围同位置重复测量偏差大外部振动、运动速度不均、标定松动1.固定夹具重新扫描2.检查编码器信号3.重新标定点云边缘出现大范围空洞视野边角处信号弱、反光角度剧烈变化1.调整相机姿态2.扩大视野留余量3.考虑多相机拼接检测速度跟不上节拍点云数量大、处理算法复杂1.降采样和ROI剪裁2.优化算法流程3.GPU并行加速最后说点实在的从我个人的经验来说3D相机的学习曲线比2D要陡峭一些。建议刚开始接触的朋友不要一上来就追着各种高深的深度学习重建先把三角测量的原理彻底吃透然后找一台线激光相机和一个标准样件从测平面、测台阶高度开始动手跑数据。点云可视化和基本处理可以用开源工具库上手先学会读xyz数据、做滤波、算平面拟合再逐步深入更复杂的算法。做项目遇到卡壳时多回头看看原始数据——绝大多数问题不是算法不够好而是成像环节有脏东西。3D相机不是万能的但在对的项目里它是真正的降维打击。希望这篇能把3D相机的技术路线和选型思路讲清楚大家少走点弯路。