4. 图像预处理
工业相机的原始图像很少能直接送进测量或缺陷判定环节。光照不均、对比度不足、随机噪声、边缘模糊,都会让后续的阈值分割、边缘提取或模板匹配变得不稳定。图像预处理的任务,就是在不破坏关键几何与灰度信息的前提下,把图像调整到更适合算法处理的状态。HALCON 提供了一整套算子来完成这些工作,本节按“点运算—滤波—锐化”的顺序展开,并给出可直接在 HDevelop 中运行的示例参数。
一、灰度变换:逐像素的点运算
灰度变换是最基础的一类预处理,它只依赖单个像素的灰度值,不涉及邻域,因此计算极快。HALCON 中最常用的是 scale_image 与 scale_image_max。前者按线性公式 g' = g * Mult + Add 逐像素映射,Mult 控制对比度(增益),Add 控制亮度(偏置)。当图像整体偏暗、动态范围只占 0~255 中的一小段时,用 scale_image 把有效区间拉伸到全量程,能显著提升后续阈值分割的稳定性。
例如一幅背光拍摄的金属件图像,灰度集中在 60~140。若希望把 60 映射到 0、140 映射到 255,可先由 min_max_gray 取得实际极值,再计算 Mult = 255/(140-60) ≈ 3.19,Add = -60 × 3.19 ≈ -191,然后调用 scale_image(Image, ImageScaled, 3.19, -191)。若只是想让图像用满灰度范围而不关心具体映射,直接用 scale_image_max 更省事。需要注意:线性拉伸会同时放大噪声,若原始图像噪声明显,应先滤波再拉伸,或改用 emphasize 这类带平滑的增强算子。
二、直方图均衡化:让灰度分布更均匀
当图像灰度分布集中在某一区间、整体发灰时,直方图均衡化通过累积分布函数把灰度重新映射,使输出直方图接近均匀分布,从而拉开原本拥挤的灰度级。HALCON 对应算子为 equ_histo_image。它适合纹理丰富、需要提升全局对比度的场景,例如表面划痕检测前的增强。
但它并非万能:均衡化是全局操作,会按整幅图的统计特性重排灰度,可能把原本均匀的背景区域也拉出噪声,或让某些灰度级被合并而丢失细节。对于光照不均的图像,更合适的是局部自适应方法,例如先做 illuminate 校正背景,再考虑均衡化。实践中建议先观察 gray_histo 输出的直方图,确认灰度确实集中且目标与背景可分,再决定是否均衡化。
三、图像平滑:均值与高斯滤波
平滑滤波通过邻域加权平均抑制随机噪声,代价是边缘被一定程度模糊。HALCON 中 mean_image 做矩形窗口均值滤波,参数为宽、高,例如 mean_image(Image, Mean, 5, 5) 表示 5×5 窗口。窗口越大,噪声抑制越强,但边缘越模糊,且矩形窗口会在水平/垂直方向产生方向性模糊。
gauss_filter 使用高斯核对邻域加权,中心权重高、边缘权重低,因此比均值滤波更符合“近处影响大”的物理直觉,边缘保持也更好。其参数为核大小,如 gauss_filter(Image, Gauss, 5)。高斯滤波的等效标准差约为核尺寸的 1/6 到 1/5,核越大平滑越强。对于需要保留细小缺陷的场合,核尺寸通常不超过 5;若噪声严重,可先高斯后中值组合使用。
四、中值滤波:对付椒盐噪声
中值滤波取邻域灰度的中位数作为输出,对孤立的极亮或极暗像素(椒盐噪声、坏点)有极强的抑制能力,同时比线性平滑更好地保留阶跃边缘。median_image(Image, Median, 'circle', 3, 'mirrored') 中,'circle' 指定圆形结构元,3 为半径,'mirrored' 指定边界延拓方式。半径 3 的圆形窗口约覆盖 29 个像素,足以滤除单像素噪声而不过度模糊。
选择滤波方式时可参考:随机高斯噪声优先高斯滤波;椒盐噪声或传感器坏点优先中值滤波;需要速度且噪声不严重时用均值滤波。三者都会模糊边缘,因此若后续要做亚像素测量,滤波强度必须克制。
五、图像锐化:增强边缘对比
锐化的本质是增强高频分量。HALCON 的 emphasize 是“锐化 + 平滑”的组合算子,参数为 MaskWidth、MaskHeight、Factor,例如 emphasize(Image, Sharp, 7, 7, 1.5):先用 7×7 窗口估计局部均值,再把原图与均值的差乘以 Factor 叠加回去。Factor 越大锐化越强,但超过 2 后噪声也会被明显放大。
若需要提取边缘强度图而非增强原图,可用 sobel_amp(Image, EdgeAmplitude, 'sum_abs', 3),它输出的是梯度幅值,常用于边缘检测的预处理。锐化应在滤波之后进行:先降噪再增强,否则噪声会被一并放大。
scale_image 拉伸对比度 → gauss_filter 或 median_image 降噪 → emphasize 锐化 → 送入 threshold 或 edges_sub_pix。每一步都建议用 dev_display 对比处理前后效果,避免过度处理。六、参数选择与效果判断
预处理没有万能参数,判断依据应回到任务目标。若后续是阈值分割,可观察目标与背景的灰度直方图是否出现明显双峰;若后续是边缘提取,可观察边缘是否连续、是否出现断裂或伪边缘;若后续是模板匹配,可观察匹配得分是否稳定。建议固定一组测试图像,记录不同参数下的分割面积、边缘点数或匹配得分,用数据而非主观观感来选定参数。
| 算子 | 作用 | 关键参数 | 适用噪声/场景 |
|---|---|---|---|
| scale_image | 线性灰度拉伸 | Mult, Add | 对比度不足、动态范围窄 |
| equ_histo_image | 直方图均衡化 | 无 | 灰度集中、纹理增强 |
| mean_image | 均值平滑 | 宽, 高 | 轻度随机噪声、追求速度 |
| gauss_filter | 高斯平滑 | 核大小 | 高斯噪声、需保边缘 |
| median_image | 中值滤波 | 结构元, 半径 | 椒盐噪声、坏点 |
| emphasize | 锐化增强 | 宽, 高, Factor | 边缘模糊、需增强细节 |
| sobel_amp | 梯度幅值 | 滤波类型, 核大小 | 边缘强度提取 |
最后强调一个工程习惯:预处理参数应写入配置文件或程序变量,而不是散落在代码各处。同一产品换批次、换光源后,往往只需微调 Mult、Add 或滤波核大小,集中管理能让调试和复现都更高效。