22 亮度、颜色与间隙测量
并不是所有测量都关乎几何。一块 LED 背光板下线时,要问的不是”灯珠在不在位”,而是”亮度够不够、亮得匀不匀”;一批注塑外壳,要核对的是颜色与色板的偏差是否超标;一排连接器引脚,关心的是相邻间隙是否一致——任何一处偏宽或偏窄都意味着插接不良的风险。这三类问题分别落在亮度测量(intensity measurement)、颜色测量(color measurement)与间距测量(pitch measurement)的范畴,对象各不相同,骨架却完全一致:在 ROI 内做统计 → 与名义值比较 → 按容差判定。本章用三个真实运行的实验依次走完这条流水线。图 22.1 是第一个实验的场景:四颗 LED 圆斑,其中一颗暗得不正常——但凭肉眼,你能确定是哪一颗、暗了多少吗?
22.1 亮度测量
亮度测量的本质是对 ROI 内的灰度做统计。最常用的统计量各司其职:均值(mean)回答”整体亮不亮”,是判定亮度合格与否的首选;标准差(standard deviation)回答”内部匀不匀”,可用于发现局部坏点或污渍;最小值/最大值/中位数(median)则刻画分布的两端与中心,中位数对个别离群像素不敏感,在表面偶有反光或灰尘时比均值更稳健。一次测量调用同时返回这一组统计量,按需取用即可。
实验场景如 图 22.1:四颗半径 30 px 的 LED 圆斑,名义亮度 {220, 180, 220, 100},其中 2 号灯实际只渲染到 140(模拟暗灯缺陷),全图叠加 \(\sigma=4\) 的高斯噪声。我们在每颗灯中心放一个半径 24 px 的圆形 ROI——刻意比灯斑小一圈,避免把过渡边缘和背景算进统计。SDK 实测均值为 220.11、180.09、139.97、100.06,与真值的最大偏差仅 0.11 个灰度级;实测标准差 3.95~4.10,与注入噪声的 \(\sigma=4\) 高度吻合。这说明只要 ROI 干净,灰度统计的精度几乎只受噪声本身限制——上千个像素的平均把单像素 \(\sigma=4\) 的随机误差压到了 0.1 量级。
均值的标准误差按 \(\sigma/\sqrt{N}\) 收缩:ROI 内约 1800 个像素,\(4/\sqrt{1800}\approx 0.09\),与实测最大偏差 0.11 一致。测量精度可以远高于单像素噪声,这正是统计测量的价值。
判定环节,我们采用”实测均值低于名义值超过 40 个灰度级即判暗灯”的规则。四颗灯的名义值各不相同,所以比较必须逐灯对照各自的名义值,而不是设一个全局阈值——2 号灯的 140 若与 3 号灯的名义 100 相比反而是”亮”的。运行结果恰好只有 2 号灯被标记为 DIM DEFECT(图 22.2)。容差 40 不是拍脑袋来的:它应锚定工艺允许的亮度波动(例如 LED 分 bin 后同档亮度差异加驱动电流公差),再留出测量自身的不确定度余量。容差给小了,正常的批间波动会被误判;给大了,真缺陷漏网。
本实验用 8 位图像,4 个灯档之间灰度间隔充裕。若被测对象的合格与不合格只差几个灰度级(如玻璃镀膜的透过率分级),8 位的 256 级量化就成了精度瓶颈,应改用 10/12 位采集(见 章节 1)。
最后一个提醒:亮度测量测的是”像素灰度”,而像素灰度 = 物体反射/发光特性 × 照明 × 相机增益与曝光。算法只对第一项感兴趣,后两项的任何漂移都会原封不动地进入测量结果。照明老化、电压波动、环境光泄漏都会让同一块板子在不同时刻测出不同亮度(章节 4)。产线上稳妥的做法是在视野内固定一块光强参考块,每幅图先测参考块、再用其读数归一化目标读数,把照明漂移消掉。
22.2 颜色测量
把亮度测量推广到彩色图像,最直接的做法是对 R、G、B 三个通道分别做统计。实验场景为四个 80×80 的色块——蓝、绿、红、橙红,各通道叠加 \(\sigma=5\) 的噪声(图 22.3)。在每块内部取 64×64 的矩形 ROI 测量,三通道均值与真值的最大偏差 0.25,标准差与 \(\sigma=5\) 的最大偏差 0.12——通道级统计与灰度情形一样精确。
但”三个通道各差多少”不等于”人眼看着差多少”。RGB 空间在感知上是不均匀的:同样 20 个数值的欧氏距离,在绿色区域几乎察觉不到,在肤色区域却很扎眼。工业上对色差的标准语言是 CIELAB 空间中的色差(color difference) \(\Delta E\)。CIE76 定义为 Lab 坐标的欧氏距离:
\[ \Delta E_{76} = \sqrt{(\Delta L^*)^2 + (\Delta a^*)^2 + (\Delta b^*)^2}, \]
Lab 空间经过非线性变换,使得相同的 \(\Delta E\) 大致对应相同的感知差异。经验上 \(\Delta E \approx 2.3\) 为最小可觉差(just-noticeable difference, JND)——小于它的两种颜色,普通观察者并排看也分不出来。
实验中红与橙红两块的 BGR 真值仅差 (5, 20, 5)。用实测均值计算:BGR 欧氏距离 21.02,换算到 Lab 后 CIE76 \(\Delta E = 5.85\)——约 2.5 倍 JND。这正是”肉眼接近、仪器可分”的典型区间:目视挑选这两块色板很费劲,而测量系统能稳定区分并给出连续的偏差量。顺带说明:SDK 不提供 Lab 输出,这里的 \(\Delta E\) 是代码内按 sRGB(D65 白点)→XYZ→Lab 自行换算的,换算公式见配套工程。
颜色测量与颜色匹配(章节 18)的分工:测量回答”偏了多少”,输出连续量,适合品质分级与过程监控;匹配回答”是哪一类”,输出类别标签,适合分拣。同一条产线常常两者都要。
实测中 SDK 有两个必须知道的约定。其一,MeasureColor 在 colorSpace=0 时返回的均值/标准差数组按 R, G, B 顺序排列——与图像内存的 BGR 存储顺序恰好相反,直接按下标 0 当 B 用会把红蓝对调。其二,colorSpace=2 的 HSV 输出中,色相不是常见的 0~360 度或 0~180(OpenCV 8 位约定),而是 度数 × 256/360,量程 0~256;纯红的色相在 0 与 256 处回绕,实测红块返回 256.0 而非 0。做色相阈值判定时必须处理这个环绕,否则红色目标会被整段漏掉。
22.3 间隙与间距测量
第三类场景的代表是连接器、排针、IC 引脚:大量等间隔的重复结构,缺陷往往是其中某一根歪了、偏了或缺了。逐根架卡尺(章节 20)当然可行,但一个 64 脚的连接器要配置 64 个卡尺,繁琐且低效。间距测量器(pitch measurer)就是为这类场景设计的”批量卡尺”:在一条扫描带(band ROI)内沿单一方向提取全部符合极性约定的边缘,按”上升缘—下降缘”配成对,每对给出一根引脚的宽度与中心,相邻中心相减得到间距(pitch)序列——一次调用完成整排测量。
实验场景为 8 根竖直亮引脚(宽 14 px,名义中心距 40 px),其中 5 号引脚整体右移 3 px 模拟位置缺陷,叠加 \(\sigma=4\) 噪声(图 22.4)。扫描带横跨所有引脚,方向从左到右,边 1 取黑→白极性(引脚左缘)、边 2 取白→黑(右缘)。
实测结果:8 根引脚宽度 13.98~14.03(真值 14),中心定位误差 ≤0.01 px;7 段间距依次为 40.00、40.02、39.99、40.01、43.00、37.00、40.00。按”名义 40 ± 1.5 px”判定,恰好第 4–5 与 5–6 两段越界,SDK 自身输出的 maxPitchIdx=4、minPitchIdx=5 与之吻合。结果如 图 22.5。
注意这里有一个值得牢记的模式:一个位置缺陷表现为两个间距异常。5 号引脚右移 3 px,使它左边的间距变成 43、右边的变成 37——一段偏大紧跟一段偏小,且偏差等量反号。所以从间距序列反推缺陷位置时,不要分别报”4–5 段超差”和”5–6 段超差”两个缺陷,而要找异常对的公共端点:两段异常共享的 5 号引脚才是真正的肇事者。反过来,若只有孤立一段间距异常而相邻段正常,更可能是引脚宽度异常或边缘提取出错,值得换个判据复核。
间距测量与卡尺共享同一套亚像素边缘内核——本实验中心误差 ≤0.01 px 的量级与 章节 20 的单边定位精度一致。区别只在调度:卡尺一次测一对边,间距测量器一次测一整排。
22.4 SciVision 实现
三类测量分别由 SciSvIntensityMeasurement、SciSvColorMeasurement、SciSvPitchMeasurer 承担。亮度测量:
SCIMV::SciSvIntensityMeasurement im;
SciROI roi;
SciPoint ctr(LED_CX[k], LED_CY);
roi.GenCircle(ctr, 24.0); // 圆形 ROI,半径 24
double avg, sd, mn, mx, med, pixelTotal;
long rc = im.MeasureIntensity(img, roi, /*lower*/0, /*upper*/255,
NULL, &avg, &sd, &mn, &mx, &med,
NULL, &pixelTotal, NULL, NULL);
// pixelTotal:SDK 输出,实测 3324,并非 ROI 几何像素数 ~1810——语义存疑,工程中勿当面积用lower/upper 是参与统计的灰度门限(0..255 即全部像素),可用来排除过曝点;输出依次为均值、标准差、最小、最大、中位数与 pixelTotal(SDK 输出,实测 3324,并非 ROI 几何像素数 ~1810——语义存疑,工程中勿当面积用),不需要的输出传 NULL 即可。
颜色测量(注意两次调用的 ROI 须用不同变量——参数为非 const 引用):
SCIMV::SciSvColorMeasurement cmeas;
SciROI roi; roi.GenRect1(tl, br); // GenRect1 右下角为排他端点
SciVarArray avgRGB, stdRGB;
long rc = cmeas.MeasureColor(img, roi, /*colorSpace*/0, // 0=RGB, 2=HSV
0, 255, 0, 255, 0, 255, // 三通道统计门限
/*model*/0, NULL, &avgRGB, &stdRGB, NULL, NULL);
double B = avgRGB[2].D(), G = avgRGB[1].D(), R = avgRGB[0].D(); // 返回序为 R,G,B!间距测量:
SCIMV::SciSvPitchMeasurer pm;
SciROI band; band.GenRect1(SciPoint(50,100), SciPoint(410,140)); // 横跨引脚的扫描带
EdgeDirection dir; // 从左到右;边1 黑->白(左缘),边2 白->黑(右缘)
dir.direction1 = 2; dir.direction2 = 2; dir.polarity1 = 0; dir.polarity2 = 1;
EdgeFilter filter;
filter.searchLineCount = 1; filter.edgeWidth = 2; filter.projectWidth = 2;
filter.sensitivity = 30; filter.strengthThresh = 5; filter.strengthLimit = 255;
double avgWidth, avgPitch; SciVarArray widthArr, intervalArr, pitchArr, ang1, ang2;
SciPointArray edge1, edge2; int maxW, minW, maxP, minP;
long rc = pm.PitchMeasurer(img, band, region, dir, /*pattern*/0, filter,
0, 0, /*widthThresh*/5.0, /*widthLimit*/30.0,
/*pairsCount*/8,
&avgWidth, &avgPitch, &widthArr, &intervalArr, &pitchArr,
&maxW, &minW, &maxP, &minP, &edge1, &ang1, &edge2, &ang2);widthThresh/widthLimit 限定合法的引脚宽度区间(5~30 px),把噪声边缘对滤掉;pairsCount 为期望的边缘对数;pitchArr 返回 \(N-1\) 项间距,maxP/minP 直接给出最大/最小间距的下标。
实测踩到的坑汇总如下,均已在配套工程 code/intensity_color_gap_measurement/ 中处理:
MeasureColor的返回序是 R, G, B,与图像存储的 BGR 相反,取值必须倒序索引;- HSV 色相为 度数 × 256/360(0~256),红色回绕到 256.0,做色相区间判定需处理环绕;
PitchMeasurer的边缘点数组每条边输出 2 个端点(扫描带上、下沿各一,交错排列):8 根引脚的edge1长度为 16 而非 8,按引脚取中心时要把同一条边的两个端点先平均。
工业案例:背光模组的亮度均匀性
某背光模组产线按 9 点法验收均匀性(uniformity):屏面取 9 个测量点,要求最暗点与最亮点的均值之比 ≥80%。单点测量的重复性一直很好,但量产后客诉偏多。排查发现夹具的金属压边把光反射回屏面四角,使 4 个边角测点的均值系统性偏高约 5%——边角恰恰是背光最暗的位置,被抬高后 min/max 比值虚高,本应判废的低均匀性模组被放行。整改分两步:给夹具加遮光罩消除反光;同时把各测点统计量从均值改为中位数,抑制残余反光亮斑对读数的拉动。整改后判定与目视评价恢复一致。教训:统计量的选择是测量设计的一部分——均值对一切像素一视同仁,中位数天然丢弃少数离群值;测点环境不可控时,后者往往更接近”人看到的亮度”。
22.5 小结
- 三类非几何测量共享同一骨架:ROI 内统计 → 与名义值比较 → 按容差判定。ROI 要避开边缘与背景,容差要锚定工艺波动而非凭感觉。
- 统计把精度做到噪声之下:均值的标准误差按 \(\sigma/\sqrt{N}\) 收缩,本章亮度均值误差 0.11、通道均值误差 0.25、引脚中心误差 0.01 px,全部远小于单像素噪声。
- 色差要在感知均匀空间里算:RGB 距离不反映视觉差异,工业判据用 CIELAB 的 \(\Delta E\),JND ≈ 2.3;红 vs 橙红实测 \(\Delta E = 5.85\)——肉眼接近,仪器可分。
- 一个位置缺陷 = 两个间距异常:间距序列中等量反号的相邻异常对指向其公共端点;间距测量器本质是批量化的卡尺。
- 记住三个 SDK 约定:颜色均值按 R,G,B 序返回、HSV 色相为 256 制并在红色处回绕、间距测量的边缘点每条边输出上下两个端点。
亮度与颜色测量背后的辐射度学与色度学基础,以及边缘配对测量的系统讨论,可进一步阅读 Steger 等人的著作 (Steger, Ulrich, 和 Wiedemann 2018)。本章用到的 CIELAB、白点、\(\Delta E\) 等概念,其权威出处是 Wyszecki 与 Stiles 的色度学经典,几乎所有颜色空间与色差公式的定义、数据与推导都汇于此 (Wyszecki 和 Stiles 2000)。本章为简洁起见用的是 CIE76 \(\Delta E\),而工业现场更常用感知一致性更好的 CIEDE2000;Sharma 等人给出了该公式的完整实现细节、补充测试数据与若干数学注记,是把本节色差计算升级到现行标准公式的实用参考 (Sharma, Wu, 和 Dalal 2005)。




