4  光源与照明

机器视觉行业流传着一句老话:“视觉项目的成败,一半在打光。”这并非夸张:相机与算法处理的都是灰度,而灰度差是照明与表面相互作用的产物。一道划痕、一处缺料、一行字符,只有在恰当的照明下才会以可分的灰度差成像;如果打光没有把目标和背景拉开,巧妇难为无米之炊,再精巧的后端算法也无从施展。反过来,一次恰当的打光常常能把算法从复杂的纹理分析简化为一次阈值分割。

本章回答两个问题。第一,面对一个新检测对象,照明方式怎么选——明场还是暗场、正向还是背光、什么颜色。第二,照明不均匀会造成什么后果,以及两条治理路线:硬件侧的平场标定(flat-field calibration)与软件侧的阴影补正(shading correction)。后一半配有完整的量化实验。

4.1 照明方式与选型

照明方式的核心变量是光的入射角与镜头视角的关系。若表面的镜面反射光直接进入镜头,背景被照亮,称为明场照明(bright-field illumination);若只有表面起伏散射的光进入镜头,平坦背景保持黑暗、起伏处发亮,称为暗场照明(dark-field illumination)。同一道划痕,明场下是亮底上的隐约暗纹,暗场下则是黑底上的明亮细线——对比度可以相差一个数量级。沿光路位置分,还有从相机一侧打光的正向照明(front lighting)与从目标背后打光的背光照明(backlight),后者把目标轮廓成像为干净的黑色剪影。常见方式及其适用场景汇总如下。

照明方式 原理要点 适合的表面与缺陷类型
明场正向光 反射光入镜头,背景亮 漫反射平面上的印刷、字符、污渍
低角度环光 / 暗场(low-angle ring light) 掠射角打光,仅起伏散射光入镜头 划痕、毛刺、压痕、边缘崩缺
背光(backlight) 轮廓成黑色剪影 外形尺寸、孔径、引脚间距测量
同轴光(coaxial light) 半透半反镜把光沿光轴打出 高反光平面:玻璃、晶圆、抛光金属
漫射穹顶(diffuse dome) 全角度漫射,消除高光 曲面与起伏金属:易拉罐底、焊球

颜色同样是设计变量。单色检测中常用互补色增强对比:红色印刷在绿光下几乎呈黑色,在红光下却近乎消失。工业现场偏爱红色 LED,除了器件成熟便宜,更因为配上窄带滤光片后能有效抵抗环境光——车间顶灯、天窗日光统统被滤掉,成像只由受控光源决定。顺带一提,暗场”用打光方向凸显表面起伏”的思想推到极致,就是用多个方向的光源反解表面法向的光度立体技术(章节 34)。

打光实验法:选型先打样,别先选算法。拿到新工件,第一件事是带上几种典型光源(环光、条光、同轴、背光)在样品上逐一试拍,选出缺陷对比度最高、背景最干净的组合,再开始考虑算法。照明阶段一小时的实验,往往省下算法阶段一个月的挣扎。

4.2 不均匀照明的危害

即便选对了照明方式,照明的空间均匀性仍可能出问题。不均匀有两大来源。一是渐晕(vignetting):镜头的自然失光遵循 \(\cos^4\theta\) 规律——照度随离轴角余弦的四次方(\(\cos^4\theta\))衰减,加上镜筒的机械遮挡,画面四角天然比中心暗。二是光源几何:光源离表面距离不等、单侧布光、灯珠老化不一致,都会叠加出侧向的亮度梯度。结果是同一种表面在图像不同位置呈现不同灰度——这恰恰打断了大多数算法的隐含假设。

我们用一个合成实验量化这件事。理想场景为 \(480\times360\) 像素:灰度 160 的均匀背景上,分布着五行仿文字暗条带、三个缺陷斑点和两条 2 px 宽的细划痕,目标灰度均为 60。再为它叠加一个合成的不均匀照明场:角部按 \(1-0.45(r/r_{\max})^2\) 径向衰减(四角失光 45%),并叠乘 \(0.9\)\(1.1\) 的水平梯度模拟单侧光源偏置。两幅图像见 图 4.1

(a) 理想均匀照明
(b) 叠加渐晕与侧向梯度
图 4.1: 同一场景在两种照明下的成像。(a) 理想照明:背景处处为 160,目标处处为 60;(b) 合成不均匀照明:角部失光 45% 并叠加水平梯度,左侧与四角明显变暗,但所有目标结构仍肉眼可辨。

注意 图 4.1 (b) 在人眼看来问题不大——目标依然清晰可辨。但算法不是人眼。背景 160、目标 60,取中间值 \(T=110\) 做固定阈值分割(暗于 \(T\) 判为目标),在理想图上误分类像素为 0;在渐晕图上,误分类像素高达 16327——占全图 172800 像素的约 9.4%。结果见 图 4.2

(a) 理想图二值化:误分类 0
(b) 渐晕图二值化:误分类 16327
图 4.2: 固定阈值 \(T=110\) 的二值化结果(白色 = 判为暗目标)。(a) 理想照明下分割完美;(b) 不均匀照明下四角整片背景灰度跌破阈值而翻白,角落附近的真实目标被淹没在误判区域中,无法再作为独立连通域提取。

失效的方式值得细看:左侧两角被增益场压到约 88、右侧两角约 106,全部跌破阈值 110 翻成”目标”;而落在角落的真实标记被这片误判区域吞没,再也分不出来。这不是”精度下降几个百分点”的渐变退化,而是整体失效——全局阈值的前提”同类表面处处同灰度”被照明直接摧毁了。应对手段有两类:算法侧改用局部自适应的阈值(见 章节 7),或者照明侧把不均匀本身治理掉。本章走第二条路。

4.3 平场标定与软件补正

治理不均匀照明有两条路线,分别对应”有参考”与”无参考”两种工况。

路线一:平场标定(flat-field calibration)。在产线上放一块均匀的白板(或漫反射标准板),拍一幅图——板子本身处处同灰度,拍出来的明暗起伏就纯粹是照明与镜头的增益场。本实验中对灰度 200 的空白靶施加同一增益场,得到的平场参考图见 图 4.3

图 4.3: 平场参考图:对均匀白板成像,得到的明暗分布就是照明系统的纯增益场,左暗右亮、角暗心亮的结构与 图 4.1 (b) 完全一致。

有了平场参考图 \(F\),校正就是一次逐像素除法:

\[ g_{\text{corr}}[n,m] = \frac{g[n,m]}{F[n,m]}\,\bar F, \]

其中 \(\bar F\)\(F\) 的均值,乘回它是为了让校正后的图像保持原有的整体亮度水平。增益场被除掉之后,照明不均匀从根源上消失。平场标定是产线的首选方案:物理上严格、计算上廉价。它的代价是需要参考图——换镜头、改光圈、光源老化后都要重标,而且有些工位(在线连续运动、大幅面)放不进一块白板。

更严格的平场标定还要扣除暗场帧(dark frame)——盖上镜头盖拍一幅图,得到传感器的固定偏置:\(g_{\text{corr}} = (g-D)/(F-D)\cdot\overline{(F-D)}\)。工业 8 位相机偏置很小,常被省略;科学级相机与长曝光场合则不可省。

路线二:自估计背景的软件补正(shading correction)。没有参考图时,可以从待处理图像自身估计照明分布:照明变化是大尺度的(横跨整幅图的缓变),而目标结构是小尺度的(十几像素的字符、几像素的划痕),两者在空间尺度上可分。用足够大的尺度做低通滤波(呼应 章节 6,只是这里把低频成分当作要去除的”照明层”而非要保留的信号),把小目标平掉,剩下的就是背景照明的估计;再把原图相对这个背景归一,即完成补正。前提条件也随之明确:目标必须显著小于照明变化的尺度——若缺陷本身就是大片渐变(如大面积色差),它会被当成照明一并抹掉。

我们用 SciVision SDK 的阴影补正(参数详见 小节 4.4)处理 图 4.1 (b),它正是自估计背景的实现,不需要平场参考图。结果见 图 4.4

(a) 阴影补正后的图像
(b) 补正后再做 \(T=110\) 阈值
图 4.4: 软件阴影补正的效果。(a) 背景被拉平到约 125 的统一电平,四角与中心不再有可见的亮度差;(b) 同一个固定阈值 \(T=110\) 重新生效,分割结果与理想图逐像素完全一致,误分类为 0。

量化对比四角与中心各 \(20\times20\) 背景小块的平均灰度:

表 4.1: 四角与中心背景块平均灰度:补正把 72 级的空间极差压缩到 4.5 级
图像 左上 右上 左下 右下 中心 极差
理想照明 160.0 160.0 160.0 160.0 160.0 0
渐晕图 87.6 105.9 87.6 105.9 159.9 72.3
补正后 125.4 125.2 125.4 124.5 129.0 4.5

背景极差从 72 级收敛到 4.5 级。注意补正后的电平约为 125 而非原始的 160——软件补正保证的是”平”,不是”恢复原值”;而对阈值分割而言,平就够了。同一个 \(T=110\) 阈值下,误分类像素从 16327 降到 0——与理想照明下的分割结果逐像素完全一致。

本实验早期版本曾报告”补正后残留 221 个误判、全部位于最外一圈 1 px”,并误判为 SDK 不处理最外侧行列。事后核查发现根因在调用侧:SciROI::GenRect1 的右下角是排他端点,当时传的 \((W-1,H-1)\) 把最后一行/列排除在 ROI 之外。改传 \((W,H)\) 覆盖全图后,残留误判消失为 0。

4.4 SciVision 实现

阴影补正由 SCIMV::SciSvShadingCorrection 类提供,本章实验的调用与工程代码完全一致:

SCIMV::SciSvShadingCorrection sc;
SciImage dst;
long rc = sc.CorrectShading(src, roi,
    2,      // lightOrDark=2:明暗都保留(只拉平背景)
    1.0,    // gain:增益 1 倍,不额外放大对比
    15,     // extractSize:抽取大小,略大于目标块高度(文字块高 12px)
    2,      // correctionMethod=2:阴影补正
    0,      // filterValue:不排除干扰灰度
    0,      // direction=0:XY 两个方向
    5,      // filterkernelSize:背景估计滤波核
    &dst);

各参数的含义与选取依据如下。

  • lightOrDark:指定保留比背景亮的目标、暗的目标还是两者;取 2 表示明暗目标都保留,补正只动背景。
  • gain:补正后的对比增益,1.0 表示不额外拉伸;目标本身对比偏弱时可适当调大。
  • extractSize:背景估计时被当作”前景”剔除的结构尺度,取 15 略大于文字块高度 12 px,配合滤波已足够;取得太小,目标会被误当背景抹掉。
  • correctionMethod必须取 2(阴影补正)。我们在调参试验中观察到(该扫描未收录进配套工程),取 0(中间值)或 1(平均值)只做全局电平归一——整图统一移到同一均值,四角照旧偏暗,空间不均匀纹丝不动。
  • filterValue:排除指定灰度的干扰像素,0 为不排除。
  • direction:背景渐变的方向。调参试验中观察到,取 1(仅 X)或 2(仅 Y)时数值上也能拉平,但单方向的背景估计会把另一方向的目标条带误收进背景,在文字带处留下可见的条纹伪影;取 0(XY 双向)最干净。
  • filterkernelSize:背景估计的平滑核,小核(5)配合双向已经足够;核越大背景越平滑,但靠近大目标处的背景估计偏差也越大。

生成本章全部图像与统计数字的完整工程位于 code/illumination/,可修改增益场强度与各参数复现上述参数扫描结论。

工业案例:玻璃划痕检测的照明翻车

某盖板玻璃检测项目初期采用明场正向照明:玻璃表面把光均匀反入镜头,划痕只造成约 5 个灰度级的扰动,检出率不足三成,团队一度试图用复杂的纹理增强算法硬撑。后改为低角度暗场环光:平整玻璃面不向镜头散射、背景近黑,划痕散射成亮线,对比度提升到 80 级以上,算法简化为一次阈值分割。但暗场也带来新问题——掠射角下照度对距离与角度极其敏感,视场边缘背景明显发灰,固定阈值在边缘区域频繁误报;叠加本章的软件阴影补正拉平背景后,系统才真正稳定。教训有二:照明与算法是一个系统,要一起设计;打光每提高一倍对比度,省下的算法复杂度以十倍计。

4.5 小结

  • 照明决定灰度差,灰度差决定算法上限。选型口诀:漫反射表面看明场,划痕毛刺看暗场(低角度),轮廓尺寸用背光,高反光平面用同轴,曲面高光用穹顶;选型先打样,再定算法。
  • 不均匀照明(渐晕 + 侧向梯度)让全局阈值整体失效,而非渐变退化:本章实验中固定阈值的误分类从 0 飙升到 16327 像素,四角背景成片翻转。
  • 平场标定用白板参考图逐像素除掉增益场(\(g/F\cdot\bar F\)),物理严格、计算廉价,是有条件放参考板时的首选;换镜头、改光圈、光源老化后需重标。
  • 软件阴影补正从图像自身以大尺度低通估计背景再归一,无需参考图;前提是目标尺度远小于照明变化尺度。本章实验中背景极差 72 级压到 4.5 级,误分类 16327 → 0(注意 GenRect1 的右下角为排他端点,全图 ROI 须传 \((W,H)\))。
  • 参数不是玄学correctionMethod 必须取阴影补正(0/1 只做全局归一),direction 单向会留条纹伪影,extractSize 要略大于最大目标——这些都是可复现的实测结论。

关于照明工程与辐射标定(radiometric calibration)的系统论述,可进一步阅读 Steger 等人的著作 (Steger, Ulrich, 和 Wiedemann 2018)。本章的平场标定与阴影补正处理的是空间不均匀,而灰度与场景辐照度之间的非线性响应(相机响应函数)则需另行标定:Mitsunaga 与 Nayar (Mitsunaga 和 Nayar 1999) 提出仅凭多档曝光图像、无需标准辐射源即可恢复响应曲线的辐射自标定方法,是高精度测光与 HDR 成像的基础。若反过来主动利用受控照明来获取信息,Woodham (Woodham 1980) 的光度立体法用同一视角下多个已知光源方向的图像逐像素求解表面法向,是”主动打光做测量”的经典范式。