3. 图像采集与数据预处理

图像采集,说白了就是让相机听话。你模型再强,拿到的图是糊的、歪的、曝光过度的,后面全白搭。我见过太多团队在算法上死磕,结果发现是相机触发没配好——嗯,这种坑踩一次就够了。

3.1 相机SDK二次开发:让相机听你指挥

工业相机不像手机摄像头,插上就能用。你得通过SDK跟它对话。我个人习惯把SDK调用分成三个层次:

层次 典型SDK 核心操作
设备枚举与连接 Halcon、MVS、Basler Pylon 枚举相机、打开设备、获取句柄
参数配置 同上 曝光时间、增益、触发模式、ROI
图像采集与回调 同上 软触发/硬触发、回调函数、缓冲区管理

拿海康MVS举个例子。你调用MV_CC_EnumDevices枚举设备,拿到设备信息后调用MV_CC_CreateHandle创建句柄,然后MV_CC_OpenDevice打开。配置参数时用MV_CC_SetFloatValue设曝光,用MV_CC_SetEnumValue设触发模式。最后启动采集,注册回调,图像数据就源源不断进来了。

关键点:回调函数里千万别做耗时操作。我曾经在回调里直接做图像预处理,结果丢帧丢到怀疑人生。正确的做法是回调里只做内存拷贝,把数据扔到队列里,另起线程处理。

3.2 图像格式转换:Bayer、RGB、灰度,别搞混了

工业相机输出的原始数据,大多是Bayer格式。每个像素只记录一种颜色分量,得通过插值才能变成RGB。我刚开始做视觉时,直接拿Bayer数据当灰度图用,结果检测精度惨不忍睹——后来才发现颜色信息全乱了。

常见的格式转换路径:

  • Bayer → RGB: 用双线性插值或边缘感知插值。Halcon里cfa_to_rgb一步搞定,MVS里用MV_CC_ConvertPixelType。
  • RGB → 灰度: 加权平均法,公式 Gray = 0.299R + 0.587G + 0.114B。别用简单平均,人眼对绿色最敏感。
  • Bayer → 灰度: 直接取绿色通道,因为Bayer阵列里绿色像素占一半,信噪比最高。

我的习惯: 如果后续只做缺陷检测,我建议直接转灰度。RGB三通道数据量是灰度的3倍,但很多缺陷在灰度图上已经足够明显。省下来的内存和算力,留给模型不香吗?

3.3 ROI提取:只关注关键区域

一张工业图像,往往只有10%-30%的区域包含有效信息。剩下的都是背景、传送带、夹具。ROI提取就是把这些无关区域切掉。

我常用的ROI提取方式:

  1. 固定坐标裁剪: 适用于相机和工件位置固定的场景。直接指定左上角和右下角坐标。
  2. 模板匹配定位: 工件位置有偏移时,先用模板匹配找到位置,再动态计算ROI。Halcon里find_shape_model配合reduce_domain。
  3. 边缘检测自适应: 用Canny或Sobel找工件边缘,然后外接矩形。适合形状不固定的工件。

注意: ROI不要切得太极限。留5-10像素的余量,防止工件轻微抖动导致缺陷被切掉。我曾经为了省计算量,把ROI卡得死死的,结果一个0.5mm的划痕刚好在边界上——漏检了。

3.4 图像增强:让缺陷无处遁形

图像增强不是为了好看,是为了让缺陷特征更明显。我把它分成两类:全局增强和局部增强。

3.4.1 直方图均衡化

直方图均衡化,说白了就是把图像的灰度分布拉开。原本集中在暗区的像素,会被映射到整个0-255范围。这样原本看不清的细节就出来了。

但要注意,全局直方图均衡化容易放大噪声。我更喜欢用自适应直方图均衡化(CLAHE),它把图像分成小块,每块单独做均衡化,然后用双线性插值消除块效应。OpenCV里cv2.createCLAHE就能实现。

实战经验: 检测金属表面的细微划痕时,CLAHE的效果远好于全局均衡化。我一般把clipLimit设在2.0-3.0,tileGridSize设为8x8。太大容易过增强,太小又没效果。

3.4.2 滤波:去噪与增强

滤波是双刃剑。去噪的同时,也可能把缺陷边缘磨平了。我常用的几种滤波:

滤波类型 适用场景 缺点
高斯滤波 去除高斯噪声,平滑图像 边缘模糊,细节丢失
中值滤波 去除椒盐噪声,保留边缘 计算量大,不适合实时
双边滤波 去噪同时保留边缘 参数难调,速度慢
非局部均值去噪 高质量去噪,纹理保留好 极慢,离线处理用

我个人在工业现场用得最多的是中值滤波。虽然慢一点,但边缘保留效果最好。如果对速度有要求,我会用高斯滤波配合后续的边缘增强算子来补偿。

3.5 完整流程:从相机到预处理

把上面这些串起来,一个典型的图像采集与预处理流程是这样的:

图像采集与预处理流程 相机SDK初始化 参数配置 图像采集 格式转换 ROI提取 直方图均衡化 滤波去噪 输出预处理图像 离线标定

这个流程看起来长,但实际在工业现场,大部分步骤都是固化在产线启动前的配置里。真正运行时,只有采集、转换、ROI、增强这几步在循环。

我的建议: 预处理流程一定要在项目初期就定下来。别等到模型训练完了,才发现图像格式不对或者ROI偏了。我见过一个项目,数据采集和模型训练是两拨人做的,结果采集的图是BGR,训练用的却是RGB——整整浪费了两周。

3.6 避坑指南

  • 相机触发延迟: 软触发有毫秒级延迟,高速产线必须用硬触发。我曾经用软触发检测每分钟600个工件,结果每10个就漏1个。
  • 缓冲区溢出: 采集速度大于处理速度时,缓冲区会满,导致丢帧。解决方案是用环形缓冲区,或者降低采集帧率。
  • 图像格式陷阱: 有些相机输出的是12位或16位深度图,直接当8位用会丢失细节。记得做位深映射。
  • 滤波参数过调: 滤波核太大,小缺陷直接被抹平了。我一般从3x3开始试,最多到7x7。

嗯,图像采集和预处理这部分,说白了就是给模型喂干净、标准化的数据。数据质量决定了模型的天花板,后面的训练和调参只是在逼近这个天花板。所以,别在这步偷懒。