24  轮廓分析

章节 23 的 Blob 分析把目标当作一团像素来统计:面积、重心、惯性轴——它回答的是”这一块东西”的问题。但很多工业问题问的不是”块”,而是边界:这个冲压件的外形与图纸差多少?边缘上有没有毛刺、鼓包、缺料?这时需要的表示是轮廓(contour)——一串有序的亚像素点列,沿目标边界依次排开。有序,意味着可以沿边界逐点行走、分段、定位缺陷位置;亚像素,意味着精度不被像素网格钉死。轮廓是缺陷检测与形状测量的高分辨率语言:区域告诉你目标”有多少”,轮廓告诉你目标”长什么样”。

本章改用一组真实工业样图贯穿全部实验(图 24.1):一枚椭圆形工件在背光下成像,得到 2592×1944 的高对比剪影——亮白的工件压在纯黑的背景上,边界处是一条窄而陡的灰度过渡带,正是亚像素轮廓提取最理想的输入。样图共三张:001标准件(母版),外形是一枚干净的椭圆;003002 是两枚测试件,各自带有边缘缺陷——003 的顶缘有两处向外凸起的多料缺陷,002 的底缘有一处更大的鼓包。我们将提取三件的轮廓、测量母版的特征、对母版做平滑/重采样/分段操作,最终把测试件与母版逐点对比,让边缘缺陷自己浮出水面。

(a) 标准件(母版,001
(b) 测试件(顶缘缺陷,003
图 24.1: 真实工业样图:背光椭圆工件剪影(2592×1944 灰度)。(a) 标准件:一枚干净的椭圆;(b) 测试件:顶缘有两处向外凸起的多料缺陷(左右各一处,肉眼需贴近才看得出)。背光使工件呈高对比剪影,边界过渡带窄而陡。

24.1 轮廓提取

轮廓提取站在边缘检测(章节 13)的肩膀上:边缘检测输出的是一幅”哪些像素是边缘”的图,像素之间没有次序;轮廓提取再做两件事——链接(linking),把相邻的边缘像素串成链,亚像素细化,沿链逐点把位置从整像素精化到亚像素(与 章节 13 的亚像素一节同一思路:对梯度方向上的三点幅值做抛物线插值;该章介绍的 Steger 式曲线提取器则直接输出亚像素线条轮廓)。链接的产物是有序点列,闭合目标的轮廓首尾相接成环。

实验在全图 ROI 上以亚像素 Canny 提取(滞后双阈值 20/40,平滑系数 2.0)。关键参数是最短轮廓长度 minLen=600:剪影边界以外的黑色背景近乎无梯度,几乎不产生杂散轮廓,长度过滤是一道保险——最终三件各只剩 1 条闭合轮廓,且都是 3627 个点:高对比剪影下,三幅图的边界链长几乎一致,母版周长 3826.3、顶缘件 3844.5、底缘件 3846.0——测试件周长比母版略大,正是凸起缺陷多绕了一小段路的直接证据。一般而言轮廓点数与链的走向、噪声实现有关,同一形状两次提取的点数不必相同,也无须相同——后面的对比算法按”最近距离”工作,不要求两条轮廓点数对齐。

区域与轮廓是同一目标的两种表示,可以互相转换:对区域求边界得轮廓,对闭合轮廓填充得区域。但信息的”易取性”完全不同——连通性、孔洞数适合在区域上算,局部边界偏差、分段几何适合在轮廓上算。选表示,就是选问题的语言。

图 24.2 把两条轮廓叠回原图:绿色为母版、橙色为测试件。亚像素点列紧贴灰度过渡带的中线,椭圆的高曲率端平滑连续——这是背光剪影把清晰边界忠实交给亚像素提取器的证据。

图 24.2: 两件的提取轮廓。左:母版(绿色,3627 点);右:顶缘缺陷件(橙色,3627 点)。背光剪影几乎不产生杂散轮廓,每幅图各剩一条闭合轮廓。

24.2 轮廓特征

闭合轮廓承载着与 Blob 特征对应的一整套几何量。周长(perimeter)是相邻点距之和;面积(area)不必填充像素再数——格林公式把区域积分化成边界上的环路积分(即鞋带公式),有序点列直接给出面积。中心(center)是外接框的几何中点,重心(gravity / centroid)是围合区域的质心,方向(orientation)取自二阶矩的主轴。两个无量纲形状因子:圆形度(circularity)衡量与圆的接近程度(圆为 1,越细长越小);矩形度(rectangularity)是面积与最小外接矩形面积之比。母版轮廓的实测值:

表 24.1: 母版轮廓的特征实测(SciSvContourFeature
特征 实测值
面积 751878.4 px²
周长 3826.33 px
中心 (1300.53, 950.50)
重心 (1300.53, 950.52)
方向 −0.00°
圆形度 circularity 0.321
矩形度 rectangularity 0.785
最小外接矩形 1726.7 × 555.0 @ −89.99°

这张表本身就是一次自检,而且每个数字都在说”这是一枚标准的椭圆”。最小外接矩形 1726.7 × 555.0、方向 −89.99°——长轴 1726.7 px 水平、短轴 555 px 竖直,长短轴比约 3.1。矩形度 751878.4/(1726.7×555.0)=0.785,恰好是 \(\pi/4\):椭圆面积 \(\pi ab\) 与其外接矩形面积 \(4ab\) 之比正是 \(\pi/4≈0.785\)——一个干净到可以反推几何身份的数字。圆形度 0.321 偏低,因为这是一枚 3:1 的扁椭圆,离圆甚远。尤其值得注意的是中心与重心几乎重合:(1300.53, 950.50) 对 (1300.53, 950.52),相差不到 0.02 px——标准件外形对称,质心自然落在几何中心;一旦工件带有不对称缺陷,这两点就会分开,中心与重心之差正是形状不对称的探针(后文配准一节将用到这一点)。

圆形度的定义各家不一:有的取 \(4\pi A/P^2\),有的取 \(A/(\pi r_{\max}^2)\)\(r_{\max}\) 为中心到轮廓的最大距离)。两种定义对同一形状给出不同数值,跨库比较圆形度没有意义,同一条产线内自洽即可。

这些特征与 Blob 特征(章节 23)是”边界版”与”区域版”的关系:数值上理应一致,但轮廓版凭借亚像素点列精度更高,且只依赖边界本身——当两个目标在区域上粘连成一个 Blob 时,各自的轮廓仍可能分得清清楚楚。一个如实的说明:当前 SDK 没有曲率(curvature)API;需要曲率时(如评估椭圆端部的圆角质量),可对平滑后的轮廓自算——以相邻点的切向角变化率除以弧长(或对点列做局部圆拟合)即得离散曲率估计。

24.3 轮廓操作

测量与对比之前,常需对轮廓做三类预处理操作。

平滑(smoothing):对点列坐标做滑动窗口平均。实验取窗口 31,母版轮廓周长从 3826.33 缩到 3820.25(约 0.16%)。收缩量很小,恰恰说明背光剪影的边界足够干净——没有多少高频抖动可滤。但收缩的方向是确定的:噪声让点列围绕真实边界来回抖动,抖出来的锯齿全是高频分量,逐点累加的周长把每个锯齿都计了长度;平滑即低通滤波(与 章节 6 对图像做的事在一维点列上重演),滤掉高频抖动,周长只减不增。工程推论:周长对噪声系统性偏大,测周长前要么平滑、要么固定平滑参数保证可比——干净的剪影下这个偏差很小,但换一幅噪声大的图,固定平滑策略就是可比性的前提。

重采样(resampling):把 3627 个点降到指定数目,实验以目标点数 300 重采样,得到沿轮廓近似等距的 300 个点——为后续逐点计算限定开销,或为拟合提供均匀样本。这里有个参数语义的坑,见 小节 24.5

分段(segmentation):把轮廓按几何性质切成直线段与圆弧段。母版轮廓分成 16 段 = 12 条直线 + 4 段圆弧图 24.3:直线段绿色、圆弧段红色、重采样点为青色刻度):椭圆顶部与底部较平缓的弧被近似成多条短直线段(绿色),左右两个高曲率端则被识别为圆弧(红色)——这正是”线弧分解”对椭圆的合理读法:曲率小处当直线、曲率大处当圆弧。段数与线弧归类对平滑量和两个距离阈值敏感,参数要按特征尺寸整定。线弧分解的价值在下游:每条线段可拟合出方向与位置、每段弧可拟合出圆心与半径,“轮廓”就升级成了可标注尺寸的几何图纸——这为几何测量与机器人轨迹编程铺了路。

图 24.3: 母版轮廓的操作结果:分段后直线段为绿色、圆弧段为红色(16 段 = 12 线 + 4 弧,平缓处为线、端部高曲率处为弧);青色为重采样到 300 点的近似等距刻度。

24.4 轮廓对比:缺陷检测

本章的高潮:把测试件轮廓与母版轮廓逐点对比,让偏差超过容差的位置自动现形。原理三步走——配准(registration):用参考点与参考角把母版轮廓变换到测试件坐标系;逐点最近距:对测试轮廓的每个点,求它到对齐后母版轮廓的最近距离;阈值判定:偏差超过容差 maxDis 的点记为超差,存在超差即判 NG。这正是 GD&T 中轮廓度(profile tolerance)公差的图像化检验:要求实际轮廓落在理论轮廓两侧各 maxDis 的容差带内。

实验取 maxDis=5 px。配准基准来自外部定位:对每幅图的亮区做零阶与二阶矩积分,得到各自的中心与主轴角(详见下文为何必须如此)。以顶缘缺陷件(003)对比母版,结果:

  • 最大偏差 18.70 px @ (1738.5, 695.4)——位置正是顶缘右侧那处凸起缺陷;判定 NG
  • 逐点偏差均值 1.64 px——这是两幅独立成像、独立配准的亚像素轮廓在全周长上的本底贴合度,相对 1726.7 px 的长轴约万分之九,是高分辨率剪影提取的精度底气。
  • 缺陷段自动定位两处:段 #1 pts[418..514](峰值 18.70 px,顶缘右侧凸起),段 #2 pts[3141..3232](峰值 17.86 px,顶缘左侧凸起)。GetOverThresholdContours 同样输出 2 段超差轮廓。
  • 换底缘鼓包件(002)对比母版,最大偏差升至 33.21 px @ (1554, 1250)、均值 2.36 px,同样判 NG——更大的鼓包给出更大的峰值偏差。

图 24.4 值得逐色精读:蓝色是对齐后的母版轮廓——“理论形状”;测试件轮廓按偏差着色,≤2 px 绿色、2~5 px 黄色、>5 px 红色;红叉标记最大偏差点。两团红色恰好罩住顶缘的两处凸起,其余轮廓几乎全绿。那两处肉眼需贴近才能分辨的多料缺陷,在偏差图上无所遁形——轮廓对比把”找缺陷”变成了”读温度计”

图 24.4: 轮廓对比结果。蓝:对齐后的母版轮廓;测试件轮廓按偏差着色(绿 ≤2 px、黄 2~5 px、红 >5 px);红叉为最大偏差点 18.70 px,位于顶缘右侧凸起。顶缘左侧的另一处凸起同样被红色段捕获,共两段超差。

逐点最近距是单向度量:只问”测试点离母版多远”,不问反向。测试件若了一段轮廓(如崩缺),测试点照样都离母版很近——严格的形状距离(如 Hausdorff 距离)取双向最大。工程上常以”双向各跑一次对比”覆盖两类缺陷。

最后是本节最重要的教学:配准参考点从哪来。先看一个被真实样图直接戳破的天真假设——“三幅图都是同一工件,位姿当然相同,做恒等配准即可”。外部定位的实测否决了它:母版亮区中心在 (1300.00, 950.00),顶缘件在 (1304.97, 954.02)、偏了 6.39 px,底缘件在 (1301.25, 951.38)、偏了 1.86 px。真实采集每次摆放都有位置漂移,配准不是恒等变换,必须做;若强行套恒等配准,这 6.39 px 的整体错位会被烘进每一个点,把缺陷信号彻底淹没。

那么配准基准用什么?一个看似顺手的做法是各用各的轮廓重心——免费算出来,缺陷件用缺陷件的重心。本例的探针给出了诚实的对照:顶缘件的轮廓重心相对母版漂移 6.385 px,与外部定位测得的 6.390 px 几乎完全一致——也就是说,缺陷对重心的”自身贡献”仅约 0.005 px,两种基准在此几乎等价(最大偏差 18.697 对 18.698 px)。原因很简单:缺陷相对整枚大椭圆太小(多出的料只占亮区百万分之几),重心位移被工件的真实摆放漂移主导,缺陷拖不动它。

纪律依然成立,且与缺陷大小成正比:用被测对象自身重心定位自身,是一种系统性风险——缺陷越大,多出(或缺失)的材料把重心拖偏越多,错位被读成更大的缺陷,测量被被测量污染。本例缺陷小,风险尚未兑现;换一组大块毛边的样件,这条路就会塌。稳妥做法是参考点取自外部定位:夹具、定位销、或对不受检区域做矩积分/模板匹配(章节 19 讨论的定位基准问题在此重现)。本章用的正是对整片亮区的矩积分——它一举两得:既校正了 6.39 px 的真实位移,又因覆盖百万像素而对局部缺陷天然免疫。缺陷越大,这条纪律越重要。

24.5 SciVision 实现

本章链路覆盖四个类。提取用 SciSvContourExtraction

SCIMV::SciSvContourExtraction ext;
SciContourArray mAll;
long rc = ext.ExtractContours(srcM, fullROI, /*precision 亚像素*/0, /*method canny*/1,
    /*filterCoeff*/2.0, /*lowThreshold*/20, /*highThreshold*/40,
    /*minContourLength*/600, /*maxContourLength*/100000, &mAll);

precision=0 输出亚像素轮廓;method=1 为 Canny 路线,filterCoeff 是其平滑尺度,双阈值即滞后阈值;minContourLength=600 是杂散轮廓的过滤门槛。注意 maxContourLength 的取值范围是 [0, 100000]——传更大的值(如 1000000)会直接报参数错误。特征用 SciSvContourFeature,每个特征一个调用:

SCIMV::SciSvContourFeature feat;
feat.GetContourArea(mC, &area);
feat.GetContourPerimeter(mC, &perim);
feat.GetContourCenter(mC, &center);
feat.GetGravityAndOrientation(mC, &gravity, &orient);
feat.GetContourCircularity(mC, &circ);
feat.GetContourRectangularity(mC, &rectg);
feat.GetSmallestRect(mC, &rcCenter, &rw, &rh, &rang);

操作用 SciSvContourOperation

SCIMV::SciSvContourOperation op;
op.SmoothContours(mOne, /*window*/31, &smoothed);
op.SampleContour(mOne, /*method 目标点数*/1, /*sampleSize*/300.0, &sampled);
op.SegmentContours(mOne, /*smooth*/5, /*maxLineDistance1*/8.0f,
                   /*maxLineDistance2*/4.0f, &segs, &segType);

SegmentContours 的两个距离阈值控制线段拟合的容许偏差,输出 segType 标注每段类型(0=直线,1=圆弧)。对比用 SciSvContourContrast,参考点/角来自外部定位(亮区矩):

SCIMV::SciSvContourContrast cmp;
rc = cmp.ContrastContour(tOne, mOne, /*normRefPt*/refM, /*actRefPt*/refTest,
                         /*normAng*/angM, /*actAng*/angTest, /*maxDis*/5.0, /*outputMode*/0,
                         &maxPair, &maxOff, &results, &minPair, &minOff, &avgOff, &allOff);
SciContourArray overs;
cmp.GetOverThresholdContours(&overs);   // 直接取超差轮廓段

参考点/角各两个:norm* 描述母版位姿、act* 描述测试件位姿,配准变换由两者之差导出——本例两者由各自亮区矩独立测得,从而校正真实摆放漂移。实测踩出的坑(已录入工程约定):

  • 只有 outputMode=0 的标量输出可靠outputMode=3maxOff 为无意义值(实测 −0.052)、results 误判 OK;逐点的 allPointsOffset 各模式均完整(本例 3627 个带符号偏差)。
  • avgPointsOffset 不可靠:实测返回 9.373,而由 allPointsOffset 自算的真实均值是 1.64——均值请自算。
  • SampleContourmethod=0/3 是上采样,只有 method=1 才按目标点数降采样——传 300 想减点,却可能收到更多点。
  • 部分轮廓相关头文件(SciSvContourOperation/ContourContrast 等)无条件 #define DLL_EXPORTS(SDK 笔误),把它们放在 dllimport 风格头文件之后包含即可正常链接。

生成本章全部图像与数字的完整工程位于 code/contour_analysis/,样图存于其 sample/ 子目录。

工业案例:密封圈毛边检测

橡胶密封圈硫化脱模后,分型面残留的毛边是主要缺陷,典型检测方案正是轮廓对比:背光取剪影,提取圈的外轮廓与标准轮廓逐点比对,超差即判毛边——与本章三张椭圆样图同出一辙。某产线初版方案图省事,用工件自身重心做配准参考点——小毛边时相安无事(正如本章实测,小缺陷对重心的拖动不足 0.01 px),一旦出现大块毛边,多出的材料把重心拖偏,对齐后的标准轮廓整体错位,对侧完好的边缘被大面积判为超差,“假缺陷”报警频发,复判工作量居高不下。改版方案改用模具自带的定位销孔做外部基准:先以两个销孔定位工件位姿,再做轮廓对比,误报率立即降到可忽略。教训与本章实验完全一致:缺陷越大,越不能让缺陷参与配准——配准基准必须取自不受缺陷影响的外部特征。

24.6 小结

  • 轮廓 = 有序的亚像素边界点列,是 Blob 区域表示的”边界版对偶”:区域适合统计与连通性,轮廓适合边界偏差、分段几何与高精度测量。提取链路是”边缘检测 → 链接 → 亚像素细化”,minLen 长度过滤负责清掉杂散轮廓;背光剪影把清晰边界交给亚像素提取器,三件各得一条 3627 点的闭合轮廓。
  • 轮廓特征与 Blob 特征一一对应而精度更高:面积由格林公式从边界直接积出,矩形度 0.785 恰为 \(\pi/4\)、自证这是一枚标准椭圆;对称的母版中心与重心几乎重合(差 <0.02 px),二者之差正是形状不对称的探针。圆形度等形状因子各库定义不一,不可跨库比较。
  • 平滑即低通:窗口 31 的平滑使周长 3826.33→3820.25——干净剪影下收缩仅 0.16%,但方向确定,周长测量必须固定平滑策略;分段把椭圆拆成 12 线 + 4 弧(平缓处为线、端部为弧),使其升级为可标尺寸的几何描述。
  • 轮廓对比 = 配准 + 逐点最近距 + 容差判定,是轮廓度检验的图像实现:本章实验以 1.64 px 的本底偏差,干净地捕获了顶缘的两处凸起(峰值 18.70 与 17.86 px)与底缘的鼓包(峰值 33.21 px),自动定位出缺陷段并判 NG。
  • 配准基准是成败的命门:真实样图的三枚工件并非同位(外部定位测得偏移 6.39 与 1.86 px),配准必须做、且基准须稳健——本章用整片亮区的矩积分一举校正真实位移又免疫局部缺陷;用被测件自身重心则随缺陷增大而失效(本例小缺陷对重心贡献仅 0.005 px,大毛边则会塌)。章节 26 将把基于对比的缺陷检测推广到更一般的形态。

轮廓提取(边界跟踪)的经典算法见 Suzuki 与 Abe (Suzuki 和 Abe 1985);轮廓的链码表示与处理可追溯到 Freeman 关于线画图像计算机处理的综述 (Freeman 1974);而本章分段操作所用的折线简化思想,其源头是 Douglas 与 Peucker 的经典算法 (Douglas 和 Peucker 1973)。关于亚像素轮廓提取、轮廓分割与基于轮廓的测量更系统的工程论述,可进一步阅读 Steger 等人的著作 (Steger, Ulrich, 和 Wiedemann 2018)