第三章 图像采集与预处理:打好视觉检测的地基

做AOI这么多年,我越来越觉得一个道理:检测的成败,七分在采集,三分在算法。你想想看,如果图像本身质量就不好,再牛的算法也救不回来。这一章,我就把图像采集和预处理这块硬骨头,掰开了揉碎了讲给你听。

核心观点:图像采集是AOI系统的“眼睛”,预处理是“眼镜”。眼睛不好使,眼镜配得再贵也没用。

3.1 图像采集卡:不只是个“转接头”

很多人觉得图像采集卡就是个把相机信号转成电脑能认的数据的东西。其实没那么简单。

我个人习惯把采集卡分成三类:

  • 模拟采集卡:处理模拟信号(Camera Link Base/Medium/Full),适合老式线阵相机。我十年前在PCB板厂用过,现在基本淘汰了。
  • 数字采集卡:直接处理数字信号(GigE Vision、USB3 Vision、CoaXPress)。目前主流选择。
  • 智能采集卡:带FPGA或GPU,能直接在卡上做预处理。比如Basler的采集卡,可以硬件加速滤波。

选采集卡时,我建议你重点关注三个参数:

参数 说明 我的建议
带宽 决定每秒能传多少数据 至少是相机最大带宽的1.5倍
触发延迟 从收到触发信号到开始采集的时间 小于1微秒,否则高速产线会丢帧
缓存大小 板载内存,防止数据溢出 至少256MB,线阵相机建议1GB以上

避坑指南:我曾经在一个项目中,用了某品牌的入门级采集卡,结果产线速度一提升到200mm/s,就开始丢帧。排查了三天,最后发现是采集卡的FIFO缓存太小,数据来不及处理就被覆盖了。后来换了带大缓存的卡,问题解决。

3.2 增益与曝光时间:找到那个“黄金点”

增益和曝光时间,说白了就是控制图像亮度的两个旋钮。但怎么配合,有讲究。

曝光时间:决定传感器收集光的时间。时间越长,图像越亮,但运动模糊越严重。

增益:对信号进行电子放大。增益越大,图像越亮,但噪声也越明显。

我常用的经验法则是:

  1. 先调曝光时间:在保证不产生运动模糊的前提下,尽量用长曝光。比如检测静止的PCB,曝光时间可以到10ms以上;但如果是流水线上的移动产品,曝光时间要控制在1ms以内。
  2. 再调增益:如果曝光时间调到极限了,图像还是偏暗,再考虑加增益。但增益一般不超过12dB,否则噪声会严重影响检测精度。
  3. 最后调光源:如果增益加到12dB还不够亮,别硬扛了,回去加光源功率或者换更亮的光源。

我的小技巧:在调试时,我会先拍一张全黑图像(盖上镜头盖),看看传感器的本底噪声。然后拍一张标准白板,调整曝光和增益,让图像灰度值在200-220之间(8位图像)。这样既不会过曝,也留了足够的动态范围。

3.3 图像滤波:去噪的艺术

图像滤波,说白了就是“去脏东西”。但不同的脏东西,要用不同的扫帚。

3.3.1 高斯滤波:温柔的模糊

高斯滤波适合去除高斯噪声——那种随机出现的、幅度不大的噪点。它的原理是用一个高斯核(权重矩阵)对图像做卷积,每个像素的值被周围像素的加权平均替代。

我常用的高斯核大小是3×3或5×5。核越大,模糊越厉害,但细节丢失也越多。

// C++示例:OpenCV实现高斯滤波
cv::Mat src = cv::imread("pcb_defect.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat dst;
cv::GaussianBlur(src, dst, cv::Size(5, 5), 1.5);
// 参数说明:Size(5,5)是核大小,1.5是标准差
// 核越大,模糊越强;标准差越大,权重分布越平缓

3.3.2 中值滤波:椒盐噪声的克星

中值滤波对付椒盐噪声(黑白点噪声)特别有效。它的原理很简单:把每个像素的值替换成它邻域内所有像素的中位数。

为什么中值滤波对椒盐噪声有效?因为椒盐噪声的像素值要么是0(黑点),要么是255(白点),取中位数时,这些极端值会被周围的正常值“淹没”。

实战经验:我在检测手机屏幕的划痕时,发现高斯滤波会把划痕边缘也模糊掉,导致漏检。换成中值滤波(核大小3×3),既去掉了传感器噪声,又保留了划痕的锐利边缘。检测准确率从82%提升到了96%。

// C++示例:OpenCV实现中值滤波
cv::Mat src = cv::imread("screen_scratch.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat dst;
cv::medianBlur(src, dst, 3);
// 核大小必须是奇数:3, 5, 7...
// 核越大,去噪越强,但图像会变模糊

3.4 直方图均衡化:让暗部细节“现形”

直方图均衡化,说白了就是把图像的灰度分布“拉平”。如果一张图整体偏暗(灰度值集中在0-50),均衡化后会把暗部细节拉伸到整个0-255范围,让原本看不清的缺陷变得明显。

我举个例子:检测黑色塑料件上的划痕。黑色塑料本身灰度值很低(20-40),划痕的灰度值可能只有50-60,肉眼几乎看不出来。经过直方图均衡化后,划痕的灰度值被拉伸到150-200,一下子就显眼了。

// C++示例:OpenCV实现直方图均衡化
cv::Mat src = cv::imread("black_plastic.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat dst;
cv::equalizeHist(src, dst);
// 注意:只适用于单通道灰度图
// 如果是彩色图,需要先转成HSV或YUV,只对亮度通道做均衡化

注意:直方图均衡化不是万能的。如果图像本身对比度就很差(比如整张图都是同一个灰度值),均衡化后会产生“伪轮廓”——原本平滑的区域出现不自然的阶梯状。我曾经在检测均匀背景上的微小缺陷时吃过这个亏,后来改用自适应直方图均衡化(CLAHE)才解决。

3.5 本章知识体系

下面这张图,是我自己总结的图像采集与预处理的知识框架。你可以把它当成一张“地图”,随时回来对照。

图像采集与预处理知识体系 图像采集 采集卡选型 触发与同步 参数设置 曝光时间 增益控制 图像滤波 高斯滤波 中值滤波 直方图均衡化 全局均衡化 CLAHE 核心原则:先保证采集质量,再考虑预处理 曝光优先 → 增益辅助 → 滤波去噪 → 均衡化增强 每一步都要验证效果,不要盲目堆叠

嗯,这一章的内容就到这里。图像采集和预处理,说白了就是给AOI系统配一副好眼镜。眼镜配好了,后面的检测才能看得清、判得准。你把这些基础打牢了,后面学特征提取、缺陷分类才会事半功倍。


公众号:蓝海资料掘金营,微信deep3321