3、图像预处理技术:灰度化、直方图均衡化、高斯滤波与中值滤波去噪、图像增强

图像预处理,说白了就是给原始图像“洗把脸”。

我做了这么多年缺陷检验,见过太多因为预处理没做好,导致后续算法崩溃的案例。你想想看,一张满是噪声、对比度极低的照片,再好的检测模型也白搭。

这一章,我们就来聊聊预处理的核心四步:灰度化、直方图均衡化、滤波去噪、图像增强。每一步都有讲究,每一步都可能成为你项目中的“坑”。

3.1 灰度化:丢掉颜色,保留结构

大多数缺陷检验场景,颜色信息其实是冗余的。裂纹、气孔、划痕,这些缺陷在灰度图上反而更清晰。

为什么一定要灰度化?

  • 减少计算量:三通道变单通道,数据量直接降到1/3。
  • 消除光照干扰:彩色图像容易受光源色温影响,灰度图更稳定。
  • 算法兼容性:很多经典算子(如Canny边缘检测)只接受灰度输入。

常用的灰度化方法有三种:

方法 公式 特点
平均值法 Gray = (R+G+B)/3 简单,但丢失对比度
加权法 Gray = 0.299R + 0.587G + 0.114B 符合人眼感知,最常用
最大值法 Gray = max(R,G,B) 保留亮度,但噪声放大
我的习惯: 除非有特殊需求,否则一律用加权法。OpenCV里直接 cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 就行,底层就是那个经典系数。

3.2 直方图均衡化:让暗部细节“浮出水面”

我遇到过一批铸件X光片,整体偏暗,缺陷区域几乎淹没在背景里。直方图均衡化就是专门解决这个问题的。

它的核心思想很简单:把像素值的分布“拉平”,让亮部和暗部都有足够的灰度级。

效果对比:

  • 原图:直方图集中在低灰度区,图像偏暗。
  • 均衡化后:直方图分布更均匀,对比度明显提升。

代码实现也很直接:

import cv2
import numpy as np

img = cv2.imread('defect.jpg', 0)  # 灰度读取
equ = cv2.equalizeHist(img)        # 直方图均衡化
cv2.imwrite('equ.jpg', equ)
注意: 直方图均衡化会放大噪声。如果原图噪声严重,建议先滤波再均衡,或者改用自适应直方图均衡化(CLAHE),它能限制对比度放大幅度,效果更可控。

3.3 滤波去噪:高斯滤波 vs 中值滤波

噪声是缺陷检验的头号敌人。我见过一个项目,因为没做滤波,把传感器噪声误判成了微裂纹,导致误报率飙升到40%。

两种主流滤波方式:

滤波类型 原理 适用场景 缺点
高斯滤波 加权平均,中心权重最大 高斯噪声、一般平滑 边缘模糊
中值滤波 取邻域中值代替中心像素 椒盐噪声、脉冲噪声 计算稍慢

我的经验:

  • 如果是CCD传感器热噪声(高斯型),用高斯滤波,核大小选3×3或5×5。
  • 如果是传输过程中的丢点(椒盐噪声),用中值滤波,核大小选3×3,效果立竿见影。
  • 如果两种噪声都有,我会先中值后高斯,顺序不能反。
# 高斯滤波
gaussian = cv2.GaussianBlur(img, (5,5), 1.5)

# 中值滤波
median = cv2.medianBlur(img, 3)
避坑指南: 我曾经在一个项目中,为了追求去噪效果,把高斯核设成了9×9。结果噪声是没了,但裂纹边缘也糊了,后续分割根本找不到缺陷边界。记住:滤波核越大,细节丢失越严重。能用3×3就别用5×5。

3.4 图像增强:对比度拉伸与锐化

滤波之后,图像干净了,但可能还不够“清晰”。这时候就需要增强处理。

3.4.1 对比度拉伸

说白了就是把像素值的范围拉开。比如原图灰度范围是[50, 150],拉伸到[0, 255],细节就出来了。

# 线性对比度拉伸
min_val, max_val = np.min(img), np.max(img)
stretched = ((img - min_val) / (max_val - min_val) * 255).astype(np.uint8)

更灵活的做法是用 分段线性拉伸,只增强感兴趣的区域。比如我只关心灰度100-200之间的缺陷,那就把这段斜率加大,其他区域压缩。

3.4.2 锐化

锐化的目的是让边缘更“锋利”。我常用的是 拉普拉斯算子 和 Sobel算子。

# 拉普拉斯锐化
laplacian = cv2.Laplacian(img, cv2.CV_64F)
sharpened = cv2.addWeighted(img, 1.5, laplacian, -0.5, 0)
一个小技巧: 锐化前一定要确保噪声已经去除。否则锐化会把噪声也一起放大,结果就是图像变得“毛刺刺”的,反而更难判断。

3.5 本章知识体系

下面这张图,把整个预处理流程串起来了。你可以把它当作一个检查清单:

图像预处理完整工作流 原始图像 步骤1:灰度化 加权法 Gray = 0.299R+0.587G+0.114B 步骤2:直方图均衡化 增强对比度,让暗部细节浮现 步骤3:滤波去噪 高斯滤波(高斯噪声) / 中值滤波(椒盐噪声) 步骤4:图像增强 对比度拉伸 + 拉普拉斯/Sobel锐化 预处理完成图像 ⚠️ 关键原则 先滤波,后增强 核越小,细节保留越好 CLAHE 优于全局均衡

这四步走完,你的图像基本就“干净、清晰、对比度高”了。接下来就可以放心地交给缺陷分割和识别算法了。

总结一下: 预处理不是越复杂越好,而是越“对症”越好。我见过有人把十几种滤波轮番上阵,结果图像面目全非。记住你的目标——让缺陷更明显,而不是让图像更“漂亮”。