4. 图像预处理:光照不均、噪声干扰下的图像增强技巧
材料缺陷标注,说白了就是跟图像质量较劲。我做了这么多年,最头疼的不是缺陷本身,而是拍出来的照片——光照忽明忽暗,传感器噪声一堆,这种图直接扔给标注员,标注质量能好才怪。
今天咱们就聊聊怎么把这些「烂图」救回来。嗯,这里要注意,预处理不是炫技,目的是让缺陷特征更明显,标注更省力。
4.1 光照不均:最隐蔽的坑
金属表面、复合材料断面,这些场景下光照不均几乎是常态。中心亮、边缘暗,或者一侧打光过曝。你想想看,标注员在这种图上画缺陷,边界都看不清,怎么画得准?
我个人习惯,先做两步诊断:
- 看直方图:如果直方图有两个明显的峰,说明光照分层严重
- 看局部方差:图像四角亮度差异超过30%,必须处理
我的经验: 别一上来就用全局直方图均衡化。我在项目中遇到过,全局均衡把背景噪声也放大了,缺陷反而被淹没。先做局部校正,再做增强,顺序很重要。
4.2 光照校正三板斧
我常用的方法就三个,按效果从简单到复杂排:
| 方法 | 原理 | 适用场景 | 我踩过的坑 |
|---|---|---|---|
| 高斯差分滤波 | 大核模糊减原图,提取光照分量 | 均匀渐变光照 | 核大小选错,缺陷被当成光照抹掉了 |
| 自适应直方图均衡(CLAHE) | 分块均衡,限制对比度放大 | 局部过曝/欠曝 | clip limit设太大,出现块状伪影 |
| Retinex理论 | 分离反射分量和光照分量 | 复杂光照+多材质 | 计算慢,实时标注场景慎用 |
我最常用的是CLAHE。为什么?因为它可控。你设个clip limit=2.0,块大小8x8,大部分金属表面缺陷都能看清楚。
import cv2
import numpy as np
def clahe_enhance(img, clip_limit=2.0, grid_size=(8,8)):
# 转LAB空间,只增强L通道
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
clahe = cv2.createCLAHE(clipLimit=clip_limit,
tileGridSize=grid_size)
l_eq = clahe.apply(l)
lab_eq = cv2.merge([l_eq, a, b])
return cv2.cvtColor(lab_eq, cv2.COLOR_LAB2BGR)
注意: 不要在RGB空间直接做CLAHE!三个通道分别均衡会严重偏色。我吃过这个亏,标注员反馈说「这图颜色不对,我分不清是锈蚀还是阴影」。后来改成LAB空间只处理亮度通道,问题解决。
4.3 噪声干扰:小问题大麻烦
工业相机在低照度下,噪声是躲不掉的。尤其是高ISO拍摄的微观缺陷图,椒盐噪声和高斯噪声混在一起。标注员放大看细节,满屏噪点,标注精度直接掉到60%以下。
我建议的降噪策略:
- 先判断噪声类型:看直方图尾部,高斯噪声是平滑拖尾,椒盐噪声是孤立尖峰
- 混合噪声用中值+双边:先中值滤波去椒盐,再用双边滤波保边缘
- 千万别过度平滑:裂纹、划痕这些缺陷,边缘信息比噪声重要得多
4.4 实战降噪流程
这是我目前在产线上用的流程,效果比较稳定:
- 中值滤波:核大小3x3,去孤立噪点
- 双边滤波:d=9, sigmaColor=75, sigmaSpace=75,保边缘降噪
- 非局部均值去噪:如果噪声严重,再加一步fastNlMeansDenoising
def denoise_pipeline(img):
# 第一步:中值滤波去椒盐
img_median = cv2.medianBlur(img, 3)
# 第二步:双边滤波保边缘
img_bilateral = cv2.bilateralFilter(img_median, 9, 75, 75)
# 第三步:非局部均值(可选)
# img_denoised = cv2.fastNlMeansDenoisingColored(img_bilateral, None, 10, 10, 7, 21)
return img_bilateral
核心原则: 降噪的底线是「缺陷边缘清晰度不下降」。我一般会在降噪前后分别算一下Laplacian方差,如果下降超过15%,说明过度平滑了,得调参数。
4.5 光照+噪声联合处理策略
实际项目中,光照不均和噪声往往是同时出现的。我建议的顺序是:先校正光照,再降噪。为什么?因为光照校正可能会放大噪声,先降噪再校正,噪声会被CLAHE放大得更明显。
下面这张图是我总结的完整预处理流程:
4.6 参数调优:别死记硬背
很多同学问我:「CLAHE的clip limit到底设多少?」我的回答是:看你的图。不同材质、不同光照条件,参数天差地别。
我一般这样调:
- 金属反光表面:clip limit=1.5-2.0,块大小16x16,避免过度增强反光区域
- 复合材料断面:clip limit=3.0-4.0,块大小8x8,增强纤维纹理
- 陶瓷/玻璃:clip limit=2.0-2.5,块大小12x12,平衡细节和噪声
小技巧: 调参时别只看视觉效果。我会在增强后的图上跑一遍自动缺陷检测算法,看召回率变化。参数调到召回率最高点,那就是最佳值。视觉上「好看」不一定「好用」。
4.7 避坑指南
这些年我踩过的坑,列出来给大家参考:
- 别在压缩图像上做预处理:JPEG压缩带来的块效应,会被CLAHE放大成假缺陷。我建议用PNG或TIFF格式保存预处理结果
- 别忽略色彩空间转换:RGB直方图均衡容易偏色,HSV或LAB空间更安全
- 别一次性把所有增强都加上:我曾经把CLAHE+锐化+去噪+对比度拉伸全堆一起,结果图像出现严重伪影。每次只加一个操作,验证效果后再加下一个
- 注意边界效应:CLAHE在图像边缘会出现暗带,可以用镜像填充解决
曾经踩过的坑: 有一次我处理一批钢材表面裂纹图,用了很强的CLAHE增强。结果标注员反馈说「裂纹太多了,根本标不完」。我仔细一看,原来是把钢材表面的轧制纹理也增强成了裂纹状。从那以后,我每次增强完都会拿原图对比,确认没有引入假缺陷。