4. 图像采集与预处理基础

农产品表面缺陷检测的第一道“质量关口”并不在模型,而在进入模型之前的图像。同一条苹果分选线上,相机拍到的原始图像往往同时存在三类问题:传感器与光照带来的随机噪声、整体偏暗或反光造成的对比度不足、以及RGB三通道高度相关导致缺陷与果皮颜色难以区分。预处理的目标不是把图像“修得好看”,而是让缺陷区域在后续分割或分类中具有更稳定的可分性。本节围绕去噪、增强和色彩空间转换三个环节,结合农产品图像的实际特点展开,并给出可复现的对比实验思路。

一、去噪:先判断噪声类型,再选滤波器

工业相机在低照度或高增益下产生的噪声以高斯噪声为主,表现为全图细密的灰度起伏;传送带振动、镜头灰尘或果面细小绒毛则更接近椒盐噪声,表现为孤立的极亮或极暗像素。两类噪声的处理策略不同,选错滤波器会直接抹掉细小缺陷。

对高斯噪声,常用高斯滤波或双边滤波。高斯滤波以核内加权平均平滑图像,标准差 σ 越大平滑越强,但边缘也越模糊;双边滤波在空间距离权重之外叠加灰度差权重,能在平滑的同时保留果梗、虫眼等边缘。对椒盐噪声,中值滤波更合适,它取邻域中值,能有效剔除孤立极值点而较少损伤边缘。一个可操作的示例参数是:对 1280×1024 的苹果图像,先做 3×3 中值滤波去除椒盐点,再用 σ=1.0、窗口 5×5 的高斯滤波抑制残余高斯噪声。需要强调的是,这些是示例参数,实际应通过对比实验确定。

判断去噪是否“过头”的直观依据是:缺陷边缘是否仍然锐利、细小斑点是否被抹平。若中值滤波窗口取到 7×7 以上,直径仅几个像素的早期病斑就可能消失,因此窗口大小应与最小可检缺陷尺寸匹配。

二、增强:让缺陷与背景的灰度差拉开

农产品图像常见的问题是整体偏暗、光照不均或反光过强,导致缺陷与正常果皮的灰度差被压缩。增强的常用手段包括直方图均衡化、限制对比度自适应直方图均衡化(CLAHE)以及伽马校正。

全局直方图均衡化会按全图灰度分布重新映射,简单但对局部光照不均无能为力,甚至放大背景噪声。CLAHE 将图像分块后分别均衡,并用 clipLimit 限制对比度拉伸幅度,更适合果面这种光照渐变的场景。示例配置为:分块 8×8、clipLimit=2.0,可在提升暗部细节的同时抑制噪声放大。伽马校正则通过幂函数映射调整整体亮度,γ<1 提亮暗部,γ>1 压暗高光,适合处理逆光或过曝的反光区域。

增强效果的判断不能只看“是否更亮”,而应观察缺陷区域与正常区域的对比度是否提升、背景是否出现伪影。若增强后正常果皮出现明显块状纹理,说明 clipLimit 过大或分块过小。

三、色彩空间转换:把缺陷从颜色相关性中“解耦”出来

RGB 三通道高度相关,且受光照强度影响大,同一缺陷在不同光照下RGB值差异明显。HSV 将色调 H、饱和度 S、明度 V 分离,H 对光照变化相对不敏感,适合按颜色区分青果、熟果与病斑;Lab 则用 L 表示明度、a 和 b 表示色度,其色度分量与设备无关,常用于颜色一致性要求高的分级场景。

以苹果表面早期碰伤为例:在 RGB 中碰伤区域与正常果皮的 R、G、B 差值都很小,阈值分割困难;转换到 Lab 后,碰伤在 a 分量(红绿轴)上往往表现为向绿色方向偏移,a 分量差值被放大,更易分割。类似地,柑橘的青斑在 HSV 的 H 分量上区分度更好。因此色彩空间的选择应依据缺陷的显色机理,而不是固定使用某一种。

农产品图像预处理链路与色彩空间对比 原始采集图像 1280×1024 RGB 含噪声/光照不均 去噪 中值 3×3(椒盐) 高斯 σ=1.0(高斯) 增强 CLAHE 8×8, clip=2.0 伽马校正 γ=0.8 色彩空间转换 RGB → HSV / Lab 按缺陷显色选分量 同一碰伤区域在不同色彩空间下的可分性对比(示例) RGB 空间 碰伤与果皮 R/G/B 差值小 三通道高度相关 受光照强度影响大 可分性:弱 HSV 空间 H 分量对光照较不敏感 适合青果/熟果/病斑区分 H 在红色附近存在跳变 可分性:中~强 Lab 空间 a 分量放大红绿偏移 色度与设备无关 适合颜色一致性分级 可分性:强 注:图中颜色与可分性为教学示例,实际需以采集样本的对比实验为准

四、对比实验:用同一批样本量化“预处理是否有效”

预处理参数不能凭经验拍定,应设计对照实验。建议固定同一批采集图像(例如 60 张包含碰伤、虫眼、正常果的苹果图像),分别经过“不去噪”“中值+高斯”“中值+高斯+CLAHE”等组合,再统一转换到候选色彩空间,用同一套阈值分割或同一轻量分类器评估。评价指标可采用缺陷区域与正常区域的平均灰度差、分割的 IoU,或分类准确率。

一个可参考的示例流程如下(参数为示例值,非实测结果):

import cv2, numpy as np

img = cv2.imread("apple_001.png")          # BGR
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 1) 去噪:先中值去椒盐,再高斯抑高斯噪声
den = cv2.medianBlur(gray, 3)
den = cv2.GaussianBlur(den, (5, 5), 1.0)

# 2) 增强:CLAHE 提升局部对比度
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
enh = clahe.apply(den)

# 3) 色彩空间:Lab 的 a 分量用于碰伤分割
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
a = lab[:, :, 1]
a_eq = clahe.apply(a)

# 4) 阈值分割并计算缺陷占比(示例阈值)
_, mask = cv2.threshold(a_eq, 128, 255, cv2.THRESH_BINARY_INV)
ratio = np.count_nonzero(mask) / mask.size
print("defect_ratio =", round(ratio, 4))

运行后应重点观察三件事:一是 mask 中缺陷区域是否连续、是否出现大量碎点(碎点多说明噪声未被抑制或阈值过严);二是同一缺陷在不同预处理组合下的面积是否稳定(波动大说明增强过度);三是正常果图像是否被误判出大面积缺陷(误检高说明阈值或色彩分量选择不当)。据此在参数网格中择优,而不是追求单一指标最高。

实践建议:去噪窗口与最小可检缺陷尺寸挂钩,增强的 clipLimit 从小值开始逐步加大,色彩空间优先按缺陷显色机理选择,再用对比实验确认。三步的顺序一般为“先去噪、再增强、最后转换色彩空间”,避免在噪声未抑制时增强而放大伪影。
常见误区:把增强当成万能手段,反复叠加均衡化导致正常果皮出现块状伪影;或在 RGB 上直接对 R、G、B 分别阈值,忽略三通道相关性,造成漏检。另一个误区是只凭肉眼观感调参,缺少固定样本集上的量化对比,导致换批次后效果骤降。

把去噪、增强与色彩空间转换串成一条可复现的链路,并用同一批样本量化对比,才能让预处理真正服务于缺陷检测,而不是停留在“看起来更清楚”的层面。后续的缺陷分割与分类模型,其上限在很大程度上由这一步决定。