简介:面向工业机器视觉初学者与缺陷检测从业者的工作小结PPT,围绕制造场景中的图像采集、图像处理与运动控制三条主线,梳理视觉检测系统的整体框架与常见落地环节。内容涵盖相机、数据接口、镜头和光源的选型要点,图像对比度、均匀性与真实性等质量标准,以及激光测试、隐裂测试、线阵相机成像等实验场景,适合用来建立知识地图、补齐零散概念并对照实际项目复盘。压缩包内共1个pptx文件,约9.76MB,以分模块汇报页组织,便于按主题查阅和二次整理。已有979人学习,可作为工业视觉缺陷检测从入门到实践衔接的参考材料,帮助读者理解硬件搭配、成像调试与测试报告之间的关联。
1. 一份 PPT 能当手册用吗:工业机器视觉缺陷检测的现场知识地图
工业机器视觉缺陷检测这件事,最麻烦的从来不是算法,而是知识太散。相机参数躺在一份 Excel 里,光源笔记在手机相册,镜头选型的经验在某个老工程师脑子里——新人接手一个工位,往往要花两周才能把「这张图为什么测不出来」问清楚。这份工业机器视觉缺陷检测工作小结 PPT 就是冲着这个痛点做的:它把图像采集、镜头光源选型、数据接口带宽、成像效果测试按链路串起来,配上现场实测参数和结论,形成一份能直接摊在工位上翻的资料,而不是又一篇讲原理的科普。它适合刚转岗做视觉的工程师、要给产线做检测方案评估的工艺人员,以及想把零散经验沉淀成文档的从业者。它不讲深度学习模型怎么训,讲的是「图怎么拍出来、拍成什么样才算合格、拍不合格该动哪个旋钮」。
2. 从光子到像素:采集链路四段拆解与选型账
制造现场的视觉系统通常被拆成图像采集、图像处理、运动控制三段。三段里最容易被轻视的是采集:算法工程师接手一个测不出来的工位,第一反应往往是改阈值、换算子、加模型,其实问题常常出在光源角度偏了五度,或者镜头靶面比芯片小了一圈。采集链路决定信息上限,图像处理只能在这个上限里做减法。下面按相机、接口、镜头、光源四段拆,每段都给可计算的选型依据,而不是凭手感挑。
2.1 相机选型:先定精度,再倒推分辨率
一台工业相机拆开看就是六件东西:传感器芯片、防尘片或滤光片、控制与信号转换电路板、光学接口、数据接口、外壳。真正决定成像能力的是第一项,其余五项决定它能不能稳定装进产线、能不能接上现有主机。
传感器分 CCD 和 CMOS 两条路线。CCD 电荷统一转移、像素一致性极好、动态范围宽,代价是帧率上不去、功耗高、成本高,新项目基本不选;CMOS 每像素自带放大与读出电路,帧率高、集成度高、全局快门机型成熟,主流工业相机已经全面转向 CMOS。选型时别背「CCD 更好」这种老经验,要看测什么:静态高精度测量可以接受卷帘快门,运动中的工件必须上全局快门,否则图像会斜切,尺寸测量直接失真。
| 维度 | CCD | CMOS |
|---|---|---|
| 像素一致性 | 好,适合高精度测量 | 早期偏弱,现主流机型已接近 |
| 帧率 | 低,读出串行 | 高,支持 ROI 提速 |
| 动态范围 | 宽 | 中高,HDR 机型可补 |
| 功耗与成本 | 高 | 低 |
| 快门形式 | 全局 | 卷帘 / 全局可选,运动件必须选全局 |
| 适用场景 | 老旧产线替换、特殊高动态场景 | 绝大多数新建检测工位 |
面阵还是线阵,取决于工件形态。面阵一次曝光得到二维图像,适合定位、有无检测、字符识别、装配确认;线阵一次只取一行,靠工件与相机的相对运动拼出整幅图,适合卷材带材、圆柱面展开、大幅面电池片。线阵的代价是必须解决同步:没有编码器信号,行频对不上,图像会被拉长或压扁,而这种变形在算法端几乎无法可靠修正。
分辨率不是越大越好,要从检测精度倒推。设视场宽度为 W 毫米,要可靠检出的最小缺陷为 d 毫米,工程上一般要求缺陷至少占 3 个像素(保守取 5 个),所需像素数 N ≈ W / (d/3)。举个能直接抄的例子:幅宽 200mm 的电池片,要检出 0.1mm 的细栅断线,按 3 像素算,像素当量必须 ≤ 0.033mm/px,需要 200/0.033 ≈ 6000 像素,选 8K 线阵(8192 像素)刚好留出余量。反过来,如果一开始就买了 16K,像素当量做到 0.012mm,单行数据量翻倍,行频上不去,反而拖累整线节拍——这是新手最容易踩的「参数过剩」坑。
黑白还是彩色也要先定死。缺陷检测绝大多数场景用黑白:同像素数下黑白相机量子效率更高、没有拜耳插值造成的分辨率损失、单帧数据量只有彩色的三分之一。只有涉及颜色判异(镀膜色差、油墨色偏、外观分级)才上彩色,而且优先考虑分时多光源合成彩色的方案,而不是直接买彩色相机。
还有一个常被忽略的参数是靶面尺寸。镜头必须覆盖相机芯片的靶面,镜头靶面小于芯片会出现四角暗角甚至黑边;靶面大于芯片则浪费视场。2/3 英寸镜头配 1 英寸芯片,这种错配在现场并不少见,表现就是图像四角亮度明显低于中心,很多人误以为是光源不均,调半天光源也没用。
2.2 数据接口与采集卡:把带宽账算在买之前
接口选错的代价很高,往往要换相机、换线、换主机,甚至改机架。常见接口的性能差异先摆出来,选型时按这张表对号入座。
| 接口 | 理论带宽 | 实际可用 | 线缆长度 | 是否需采集卡 | 典型场景 |
|---|---|---|---|---|---|
| GigE Vision | 1 Gbps | 约 110 MB/s | 100 m | 否,板载网卡即可 | 2MP 级面阵、多相机分布式 |
| 10GigE | 10 Gbps | 约 1 GB/s | 100 m(光纤更长) | 否,需万兆网卡 | 高帧率面阵、多台 8K 线阵 |
| USB 3.0 | 5 Gbps | 约 350 MB/s | 无源 3 m,有源可延长 | 否 | 单台中小面阵、实验室 |
| IEEE 1394b | 800 Mbps | 约 80 MB/s | 4.5 m | 需 1394 卡 | 老旧设备维护 |
| CameraLink Base | 2.04 Gbps | 约 255 MB/s | 约 10 m | 是 | 中高速线阵、稳定性优先 |
| CameraLink Medium/Full | 4.8 / 6.8 Gbps | 约 600 / 850 MB/s | 约 10 m | 是 | 8K 以上线阵、多通道 |
| CoaXPress | 每通道 12.5 Gbps | 可多通道聚合 | 同轴 40 m 以上 | 是 | 超高速、超高分辨率 |
带宽账要自己算,别信厂家标称的「支持 8K」。计算方法是:面阵单帧字节数 = 宽 × 高 × 位深 / 8,再乘以帧率;线阵则是 行像素 × 位深 / 8 × 行频。比如 8192 像素、8bit、6000 行/秒的线阵,数据率约 49 MB/s,也就是 393 Mbps,千兆 GigE 理论 125 MB/s,实际打七折约 87 MB/s,看起来够用,但只要位深升到 10bit 或行频提到 8kHz,立刻顶到天花板,出现丢帧、图像中间断行。很多人第一反应是换网线,其实该换的是接口方案。
# 采集链路带宽与行频核算,选型前先跑一遍,避免买回来才发现接口带不动 def line_scan_budget(pixels_per_line, bit_depth, line_rate_hz): bits_per_sec = pixels_per_line * bit_depth * line_rate_hz return { "Mbps": round(bits_per_sec / 1e6, 1), "MB/s": round(bits_per_sec / 8 / 1e6, 1), # 千兆网实际可用按理论值的 70% 估算,留出协议开销和突发余量 "gige_utilization": round(bits_per_sec / 1e6 / (1000 * 0.7) * 100, 1), } def line_rate_from_speed(line_speed_mm_s, pixel_pitch_mm): # 行频 = 产线速度 / 单像素对应实际长度,这是线扫最容易算错的公式 return round(line_speed_mm_s / pixel_pitch_mm, 1) print(line_scan_budget(8192, 8, 6000)) # {'Mbps': 393.2, 'MB/s': 49.2, 'gige_utilization': 56.2} print(line_rate_from_speed(300, 0.05)) # 6000.0,即 300mm/s 产线、0.05mm 像素当量下需要 6kHz 行频第一段函数的三个入参分别对应线阵相机的单行像素数、ADC 位深、行频,输出直接给出占比;gige_utilization超过 70% 就该考虑 10GigE、CameraLink 或双网口分流。第二段函数是两个现场最常混用的量:产线速度单位是 mm/s,像素当量单位是 mm/px,除出来的行频单位是 Hz,也就是每秒取多少行。之所以强调这个,是因为不少人会拿「产线速度 × 曝光时间」去估算模糊量,却忘了行频和曝光时间是两个独立参数——行频决定采样密度,曝光时间决定运动模糊,两者都要单独核。
采集卡和板载网卡的区别,核心在确定性。GigE 走标准网卡,靠中断和驱动收包,CPU 负载高、抖动大,多相机同时跑容易丢包;CameraLink 和 CXP 走专用采集卡加 DMA,数据直接进内存,抖动小。如果工位要求 7×24 小时连续跑、单班次几万件,宁可多花采集卡的钱。用 GigE 的话,记得开巨帧(Jumbo Frame 9014)、关掉网卡的节能与中断节流、把相机单独挂一个网段,这几步是「图像偶尔缺一行」的后悔药。
2.3 镜头与光源:对比度是打出来的,不是后期调出来的
镜头的作用只有一句话:把目标成像到传感器光敏面上,但这一句话里藏着焦距、工作距离、视场、景深、畸变、光圈六个互相牵制的量。
焦距估算用相似三角形即可:f ≈ 工作距离 × 靶面尺寸 / 视场。比如靶面 2/3 英寸(约 8.8mm × 6.6mm,取短边 6.6mm),要覆盖 100mm 宽的视场,工作距离 300mm,则 f ≈ 300 × 6.6 / 100 ≈ 19.8mm,选 20mm 或 25mm 定焦。反过来说,现场常见的「换了个 13mm 短焦,视场大了但边缘虚」,是因为短焦在大视场下畸变和场曲都明显,边缘解析力下降,测量类工位不能只图视场够。
光圈不只是调亮度。F 数越大(光圈越小),景深越大、进光越少、衍射越明显;F 数越小,进光多、景深浅、边缘像质下降。测有高度的工件(比如带栅线的电池片、有台阶的壳体),景深不够的表现是「中间清楚两边虚」,此时要么缩小光圈补光,要么上远心镜头。远心镜头的价值在于消除透视误差,测量孔径、间距、平行度这类尺寸时基本是必选项,代价是贵、重、工作距离固定。
| 光源类型 | 打光方式 | 适用对象 | 注意点 |
|---|---|---|---|
| 环形光(直射) | 相机同轴方向斜照 | 一般平面字符、标签 | 镜面工件会打出高光斑 |
| 环形光(漫射) | 加漫射板柔化 | 曲面、铸件、有纹理表面 | 亮度损失大,需提高功率 |
| 条形光 | 低角度掠射 | 划痕、凹坑、边缘毛刺 | 角度差 5° 效果可能天差地别 |
| 背光 | 工件背面透射 | 轮廓尺寸、透明件、通孔 | 工件必须离开背板,避免阴影 |
| 同轴光 | 半反镜同轴入射 | 高反镜面、金属镀层 | 只对垂直反射面有效 |
| 穹顶光 | 半球漫射 | 高反曲面、球面件 | 体积大,遮挡工位 |
| 红外/紫外 | 特定波段激发 | 隐裂、胶水、荧光标记 | 需匹配相机响应波段 |
好的图像有硬指标,不是「看着清楚」:目标与背景的灰度差至少 30(8bit 下),整体亮度均匀或差异不影响阈值分割,颜色真实且不过曝。频闪光源要和相机硬触发同步,曝光窗口外光源必须关断,否则运动工件会拖影。很多人把光源常亮、靠缩短曝光压拖影,结果是亮度不够、增益拉高、噪声上来,算法端再怎么滤波都是徒劳。
3. 图像质量三指标:把「这张图行不行」变成可量化判断
「这张图能不能测」在多数团队里靠老工程师看一眼拍板,这种判断没法交接、没法复现。把对比度、均匀性、真实性三个指标落成可计算的数,新人也能自己判断该不该调光。
3.1 三个指标的算法定义与阈值
对比度取目标区域与背景区域的灰度均值之差,行业里流传的「相差 30 以上」指的就是这个差值。低于 30 时,阈值分割的容差窗口被压缩到个位数灰阶,光源稍有衰减或工件表面状态波动,二值化结果就整体翻转,表现为「同一个产品有时判 OK 有时判 NG」。实测时不要只取一个点,目标区和背景区各取不少于 500 像素的 ROI,算均值差和标准差。
均匀性用分块法:把图像切成 8×8 或 16×16 的网格,算每块均值,取(最大块均值 − 最小块均值)/ 全图均值。这个比值超过 15% 就要查原因,常见是镜头暗角、光源两端衰减、或者相机靶面与镜头不匹配。均匀性差最直接的后果是同一套阈值参数在画面中心和四角表现完全不同,逼着人给每个区域单独设阈值,参数越堆越多。
真实性主要看过曝比例和颜色偏差。8bit 图像里灰度 255 的像素占比超过 0.5%,就说明有信息被削掉了,缺陷落在过曝区里直接消失。这一点在测高反金属件和镀膜件时特别致命,肉眼看着「亮堂堂很清楚」,实际过曝区的细节已经全没了。
3.2 用灰阶卡跑一遍标准调图流程
调图顺序错了会反复返工,正确顺序是:固定工作距离与角度 → 定光圈(先满足景深) → 调光源亮度与角度(满足对比度) → 调曝光时间(满足亮度且不拖影) → 最后才动增益。增益放在最后,是因为它同时放大信号和噪声,先加增益会把后面的调整空间吃掉。
| 步骤 | 操作 | 判据 | 常见错误 |
|---|---|---|---|
| 1 | 固定相机与工件相对位置 | 工作距离误差 < 1mm | 用手扶着调,参数无法复现 |
| 2 | 光圈开到满足景深的最小 F 数 | 工件高低面都清晰 | 先开大光圈提亮,景深不够 |
| 3 | 调光源角度与亮度 | 目标背景灰度差 ≥ 30 | 只调亮度不调角度 |
| 4 | 调曝光时间 | 运动模糊 < 1 像素 | 用曝光补亮度导致拖影 |
| 5 | 最后加增益 | 噪声不明显、过曝 < 0.5% | 一开始就拉满增益 |
import cv2 import numpy as np def quality_report(path, fg_roi, bg_roi, grid=8): img = cv2.imread(path, cv2.IMREAD_GRAYSCALE) if img is None: raise FileNotFoundError(path) x1, y1, x2, y2 = fg_roi fg = img[y1:y2, x1:x2].astype(np.float32) x1, y1, x2, y2 = bg_roi bg = img[y1:y2, x1:x2].astype(np.float32) contrast = float(fg.mean() - bg.mean()) # 目标与背景均值差,要求 >= 30 h, w = img.shape blocks = [img[i*h//grid:(i+1)*h//grid, j*w//grid:(j+1)*w//grid].mean() for i in range(grid) for j in range(grid)] uniformity = float((max(blocks) - min(blocks)) / img.mean()) # 要求 < 0.15 overexposed = float((img == 255).sum() / img.size) # 要求 < 0.005 return {"contrast": round(contrast, 1), "uniformity": round(uniformity, 3), "overexposed_ratio": round(overexposed, 4)} print(quality_report("station_a_001.bmp", (400, 300, 900, 700), (50, 50, 350, 250))) # {'contrast': 42.6, 'uniformity': 0.087, 'overexposed_ratio': 0.0012}函数里fg_roi和bg_roi是手工框出的目标区与背景区,格式为 (x1, y1, x2, y2);grid控制均匀性分块粒度,纹理复杂的工件用 16 更敏感,平整表面用 8 就够。输出的三个数分别对应上文的三个阈值,直接拿来做调图的验收标准。这段脚本我一般在试产阶段挂在采图目录上批量跑,几十张图一起出报告,比一张张肉眼看快得多,也避免了「凭感觉觉得差不多了」这种玄学判断。
4. 线扫与激光成像复盘:一拖二接线、808nm 亮源与隐裂参数
产线上的成像方案很少是标准品,多数要在现场改。这一章复盘三类典型场景:线阵相机一拖二、近红外激光激发成像、高反与遮挡工件的打光,每一类都给出参数怎么定、失败时看什么。
4.1 线阵相机一拖二:行频、编码器与硬触发的账
一拖二指的是两台线阵相机共用一套主机、一套触发源,常见于同一条产线的上下表面同时检测,或者前后两个工位串在一台机器上。这样做省主机、省布线,但对同步要求更严。
行频是第一笔账。行频 = 产线速度 / 像素当量,这个公式前面给过。假设产线 300mm/s、像素当量 0.05mm/px,行频 6kHz;两台相机各 6kHz,主机要能同时吃下两路数据。8K 8bit 单路 49MB/s,两路接近 100MB/s,千兆网卡(实际约 87MB/s)已经不够,这就是为什么一拖二方案通常直接上双万兆网口或 CameraLink 双通道采集卡,而不是硬塞进一个千兆口。
第二笔账是触发源。线扫的触发有两种:内部定时(相机自己按设定行频取图)和外部硬触发(编码器每走一个像素当量发一个脉冲)。产线速度恒定、精度要求一般的场合可以用内部定时,但只要有加减速、启停、速度波动,内部定时就会造成图像纵向拉伸或压缩,表现为圆形变椭圆、方形变矩形。正确做法是编码器信号进分频器,一路分成两路分别给两台相机,保证两台相机严格同步。
第三笔账是两台相机之间的空间对齐。上下表面检测时,两台相机的行起始位置、曝光时刻必须一致,否则同一片工件在上下两张图上的位置对不上,后续做配对分析时会持续偏移。做法是用同一个硬触发信号,并且把两路触发线做成等长,别小看这几十厘米的差异,在 6kHz 行频下就是几个像素的错位。
提示:一拖二方案上线前,用一片已知尺寸的标准件跑一遍纵向和横向的尺寸测量,两个方向的误差都在 1 个像素以内才敢放行,这一步省不得。
4.2 808nm 激光加近红外相机做隐裂与 PL 成像
硅片隐裂的检测靠的是光在材料内部的散射差异,可见光打不透硅,必须用近红外波段。常见两条路线:电致发光(给电池片通正向电流,复合发光)和光致发光(用激光激发,测发光强度分布)。光致发光的优势是非接触、速度快,适合在线抽检。
光源侧用高功率近红外激光,把光均匀铺成一条线或一个面照射到硅片上,硅片受激发后在 1100nm 以上波段发光,隐裂、断栅、杂质区域发光弱,在图像上表现为暗线或暗斑。这里有两个参数要反复试:激光功率和曝光时间。功率偏低,发光太弱,图像噪声占比大;功率偏高,硅片发热、发光饱和,暗场细节反而被压平。25W 级别的亮源在大幅面照射时通常够用,但要注意光斑均匀性——光斑中间亮两边暗,会直接传导成图像上的亮度梯度,看起来像整片区域缺陷,其实是光源的问题。
相机侧要匹配发光波段,普通硅基相机在 1100nm 附近量子效率已经很低,需要近红外增强机型或铟镓砷传感器。这里的血泪经验是:镜头也必须换。普通可见光镜头在近红外波段的镀膜透过率差,还会产生焦点偏移,表现为「怎么调焦都不够锐」。换近红外校正镜头之后,同样的相机和光源,图像清晰度能差一个档次。
散热不能忽略。大功率激光器连续工作会温漂,波长和输出功率都会变,图像亮度随之缓慢下降。做法是水冷或强制风冷,并且在软件里加一个亮度监控,每千片取一次全图均值,均值漂移超过 10% 就报警重新标定。
4.3 石墨舟、石英舟、花篮:高反与遮挡件的打光策略
载具类工件的检测难点不在缺陷本身,而在成像条件。
石墨舟表面深色、粗糙、有大量孔槽,吸光严重,常规环形光打上去一片死黑。这类工件要提亮 diffuse 成分,用大面积漫射光或者多组条形光从不同角度叠加,把孔槽内部也照亮;同轴光在这里基本无效,因为它只对垂直反射面有效,而石墨表面是漫反射。
石英舟是透明件,透明件的问题恰好反过来:光直接穿过去,正面打光拍出来几乎全白。检测轮廓和崩边要用背光,把工件放在光源和相机之间,边缘变成清晰剪影;如果还要检测表面附着物或雾化,就得用暗场照明,让散射光进入镜头,直射光被挡掉。
花篮是密集装载硅片的载具,遮挡严重。正面打光只能看到最外层,想看清层间就要靠斜侧光加高景深。这时候景深比分辨率更重要,宁可降一档分辨率、缩小光圈把景深拉起来,也不要追求极限解析力结果一半层数虚焦。
| 工件 | 表面特性 | 推荐打光 | 避免的做法 |
|---|---|---|---|
| 石墨舟 | 深色、粗糙、多孔槽 | 大面积漫射 + 多角度条形叠加 | 单点同轴光 |
| 石英舟 | 透明、高反 | 背光看轮廓,暗场看附着 | 正面直射 |
| 花篮 | 密排、遮挡、多层 | 低角度斜侧光 + 小光圈保景深 | 只求分辨率忽略景深 |
5. 排查清单:图像链路和一致性两类故障怎么定位
现场问题看起来千奇百怪,归归类其实就两大类:一类是图压根没拍好,另一类是图看着好但复现不了。分开排查能省掉大量试错。
5.1 图像链路类故障:从「拍不到」到「拍不清」
现象一:图像整体发灰,目标和背景灰度差只有十几。原因通常是光源角度不对或者亮度不够,而不是相机问题。低角度掠射对划痕有效,但对平面字符就几乎没贡献;漫射光能压掉高光但也会削掉边缘对比。解决方法是先把光源固定、只调角度,每转 15° 拍一张,量一次灰度差,找出峰值角度再细调,别一上来就换光源型号。
现象二:线扫图像出现规律性横纹,或者图像被拉长压扁。这是行频不匹配的典型症状。内部定时模式下,产线速度一变,行频没跟上,图像纵向比例就错了;横纹则多半是光源频闪与曝光窗口没对齐,频闪频率和行频存在拍频。解决办法是改用编码器硬触发,让行频跟着产线速度走;光源改成与相机曝光信号同步的频闪模式,确认曝光窗口完全落在光源点亮区间内。
现象三:图像中心清楚、四角发暗。先查镜头靶面是否覆盖芯片靶面,再查镜头暗角和光源两端衰减。镜头靶面小于芯片是最常见的原因,表现为四角亮度平缓下降、边界不锐利;光源两端衰减则是对称的、只在高宽比大的工件上明显。前者只能换镜头,后者靠加长光源或提高两端功率补偿。
现象四:相机能出图但偶尔丢一整行,图像中间断开。这是带宽或链路问题。千兆网卡没开巨帧、网线过长、交换机参与转发、CPU 中断被其他进程抢占,都会造成偶发丢包。排查顺序是先看相机端的丢帧计数,再看网卡的收包错误计数,最后用抓包工具确认丢在链路哪一段。多数情况下开巨帧、换直连、关掉网卡节能选项就能解决。
5.2 一致性与重复性类故障:图好看但复现不了
现象五:同一片工件隔几分钟重新拍,缺陷位置判读不一致。原因多半在机械侧——相机支架锁紧力矩不够、镜头调焦环没有锁死、工件定位面有松动。视觉系统对亚像素级位移很敏感,支架轻微振动就足以让边缘位置跳几个像素。解决办法是所有可调部件加防松结构,调完焦用锁紧螺钉固定,并在软件里加一个基准标记的位置监控,超过阈值就提示重新标定。
现象六:换班之后参数全变了。这是参数没有版本化的典型后果。每个人调完随手保存,文件名各写各的,谁也不知道哪一版是验证过的。做法是把曝光、增益、光源亮度、工作距离、产品型号、镜头型号全部记进一张参数表,与程序版本绑定管理,工位交接时按表核对,而不是凭记忆。
现象七:算法在样本图上很准,一上产线误报率飙升。这是典型的样本偏差。采样时挑的都是外观规整的良品,实际产线上有油污、有反光、有来料批次差异。规避办法是连续采集至少一个完整的生产班次,涵盖换料、换批次、启停阶段,从中挑出边界样本重新定阈值,而不是拿几张漂亮图就上线。
| 故障现象 | 最可能原因 | 优先动作 |
|---|---|---|
| 对比度不足 | 光源角度或亮度 | 扫角度、量灰度差 |
| 横纹 / 图像变形 | 行频与光源不同步 | 改编码器硬触发 |
| 四角发暗 | 镜头靶面不匹配 | 核对靶面尺寸 |
| 偶发丢行 | 带宽或网卡配置 | 开巨帧、检查丢包计数 |
| 重复性差 | 机械松动或参数未版本化 | 锁紧 + 参数表管理 |
6. 把参数固化成 SOP:从单次调试到可复用流程
调通一个工位只是开始,能把它交接出去才算完。我现在的做法是每次调试完,强制走一遍固化流程:先把最终参数写进一张工位交接单,包括相机型号、镜头焦距与光圈、工作距离、光源型号与角度、曝光、增益、行频或帧率、触发方式,一项不落;再把 Halcon 的处理链按算子顺序记下来,标注每一步的作用和关键阈值区间。
Halcon 这条链子本身不复杂,难在参数背后的理由要留痕。常见做法是:read_image读图后rgb1_to_gray转灰,emphasize或bilateral_filter增强缺陷与背景的差异,threshold粗分割,connection拆连通域,select_shape按面积、圆度、矩形度筛掉噪声,再用gen_measure_rectangle2配measure_pos做亚像素边缘测量。每一步的阈值都要写明「为什么是这个值」,比如面积下限为什么是 80 像素而不是 50——因为小于 80 像素的区域经统计全部来自光源反光,而不是真实缺陷。没有这句理由,下一个人接手只敢原样复制,产品一换就抓瞎。
# 工位固化的目录结构,直接照搬就能交接 station_07_top/ ├── config/ │ ├── camera.yaml # 曝光、增益、行频、触发方式 │ ├── optics.yaml # 镜头焦距、光圈、工作距离、光源角度 │ └── halcon.params # 各算子的阈值与理由注释 ├── calib/ │ ├── pixel_pitch.txt # 像素当量,标定日期与标准件编号 │ └── uniformity.png # 均匀性报告截图 ├── samples/ │ ├── ok/ # 连续一个班次的良品,含边界样本 │ └── ng/ # 各缺陷类型的代表图,注明判定依据 └── README.md # 一页纸:这个工位怕什么、调参从哪下手这个目录结构的价值在于:接手的人不用问人,打开 README 就知道该工位的历史问题,打开 config 就知道当前参数,打开 samples 就能自己复现验证。pixel_pitch.txt里必须写标定日期,因为相机或镜头一旦动过,这个数就失效,而我见过太多人拿着半年前的当量继续算尺寸,误差越积越大。
最后一条是验证闭环。每次改完参数,跑三件事:用标准件测一遍尺寸误差,误差必须在 1 个像素内;用连续一个班次的样本跑误报率,超过基线就得回退;用同一片工件重复拍 20 次,看判定结果是否完全一致。三关都过才算改完,否则宁可回退到上一版。这套流程听起来笨,但它是把「某个人的手感」变成「团队资产」的唯一路径。
从那以后我每次调完一个工位,哪怕只是把光源角度拧了两度,也会强制走一遍参数记录和样本留存,因为我知道下一次接手的人不会比现在的我更聪明,能靠的只有纸面留下的东西。希望帮到你。
本文还有配套的精品资源,点击获取