2. 工业相机与图像采集

工业视觉系统的成像质量在相机曝光的那一刻就已基本确定,后续算法只能在此基础上做有限补偿。因此,相机接口、镜头、光源与采集参数必须作为一个整体来设计。本节围绕“如何把真实工件稳定地变成一张可处理的数字图像”展开,覆盖接口选型、镜头计算、打光方式、OpenCV 与相机 SDK 的集成,以及采集参数控制与图像质量评估。

一、工业相机接口类型与选型

接口决定了带宽、传输距离、线缆成本和同步能力。常见类型包括:

  • GigE Vision:千兆网口,线缆可达 100 m,支持 PoE 供电,带宽约 1 Gbit/s(实际有效约 110 MB/s),适合多相机、远距离产线。
  • USB3 Vision:带宽约 5 Gbit/s(有效约 400 MB/s),即插即用、成本低,但线缆一般不超过 3~5 m,且受主机控制器影响。
  • Camera Link:Base/Medium/Full 配置,带宽高、延迟确定,需专用采集卡,多用于高速线扫与多路同步。
  • CoaXPress(CXP):同轴线缆,单通道 6.25/12.5 Gbit/s,可同时传数据、供电与触发,适合高分辨率高速场景。

选型时先算数据率:分辨率 × 位深 × 帧率。例如 500 万像素(2448×2048)、8 bit、30 fps,原始数据率约 2448×2048×1×30 ≈ 150 MB/s,GigE 已接近上限,需考虑压缩、降帧或改用 USB3/CXP。同时确认触发方式(硬触发、软触发)、I/O 接口与是否支持 PTP 同步。

二、镜头选型与光学计算

镜头选型围绕视场(FOV)、工作距离(WD)、分辨率与景深展开。核心公式:

放大倍率 β = 传感器尺寸 / FOV
焦距 f ≈ WD × 传感器尺寸 / (FOV + 传感器尺寸)
所需像素分辨率 = FOV / 相机像素数(即每像素对应实际尺寸)

示例:检测 100 mm 宽工件,选用 1/1.8" 传感器(宽约 7.2 mm)、2448 像素相机。则 β ≈ 7.2/100 = 0.072,每像素对应约 100/2448 ≈ 0.041 mm。若最小缺陷为 0.1 mm,需至少 3 像素覆盖,即 0.1/0.041 ≈ 2.4 像素,偏紧,应提高分辨率或缩小 FOV。工作距离 300 mm 时,f ≈ 300×7.2/(100+7.2) ≈ 20.1 mm,可选 20 mm 定焦镜头。

此外需关注景深:光圈越小景深越大但进光量下降;远心镜头可消除透视误差,适合精密测量;畸变、MTF、C 口/CS 口法兰距也需匹配。

三、光源与打光方式

打光的目的是让目标特征与背景形成稳定对比。常见方式:

  • 环形光:均匀照明,适合平面字符、表面缺陷。
  • 条形光/线光:用于线扫或局部高亮,可组合成多角度。
  • 背光:工件轮廓与背景形成黑白剪影,适合尺寸测量、孔位检测。
  • 同轴光:经分光镜垂直照射,适合高反光金属表面、划痕检测。
  • 穹顶光:漫射均匀,适合曲面、反光件。
  • 暗场/低角度光:突出表面凸起、划痕、边缘。

选择依据是“特征对光的响应”:测量轮廓用背光,检测划痕用暗场或同轴,读码用环形或条形。光源控制器需支持频闪与相机触发同步,避免运动模糊。

四、OpenCV VideoCapture 与相机 SDK 集成

OpenCV 的 cv2.VideoCapture 可直接打开 UVC 相机或视频文件,适合快速验证:

import cv2
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)   # Windows 下指定后端
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 2448)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 2048)
cap.set(cv2.CAP_PROP_FPS, 30)
while True:
    ok, frame = cap.read()
    if not ok:
        break
    cv2.imshow("frame", frame)
    if cv2.waitKey(1) == 27:
        break
cap.release()
cv2.destroyAllWindows()

但工业相机通常需要 SDK 才能访问触发、增益、曝光、白平衡等完整参数。集成方式有两种:一是用 SDK 取流后把缓冲区转为 NumPy 数组交给 OpenCV 处理;二是通过 GenICam/GigE Vision 的通用接口(如 Harvesters、pylon、MVS)统一访问。以海康 MVS 为例,SDK 回调返回原始帧,用 np.frombuffer 转成图像:

import numpy as np, cv2
def on_frame(data):
    img = np.frombuffer(data, dtype=np.uint8).reshape(h, w, -1)
    gray = cv2.cvtColor(img, cv2.COLOR_BAYER_BG2GRAY)  # 按实际 Bayer 格式
    cv2.imshow("cam", gray)

关键点是像素格式(Mono8、BayerRG8、RGB8)与 OpenCV 转换码必须一致,否则会出现偏色或错位。

五、采集参数控制与图像质量评估

曝光时间、增益、帧率、触发模式是采集的核心参数。曝光过长会运动模糊,增益过高会放大噪声。建议先固定光源亮度,再调曝光使目标灰度落在 100~200(8 bit),最后用最小增益补足。触发模式选硬触发可保证与产线节拍同步。

图像质量评估可从以下指标入手:

  • 均值与标准差:判断整体亮度与对比度,cv2.meanStdDev。
  • 清晰度:Laplacian 方差,值越大越清晰,cv2.Laplacian(gray, cv2.CV_64F).var()。
  • 信噪比:目标区域均值与背景标准差之比。
  • 直方图:检查是否过曝(右侧堆积)或欠曝(左侧堆积)。

下图给出从相机接口、镜头、光源到采集与质量评估的整体信号链与关键参数关系,便于对照选型与调试。

工业图像采集信号链与关键参数 光源 / 打光 环形·背光·同轴 频闪与触发同步 被测工件 FOV / 缺陷尺寸 镜头 焦距 f / 倍率 β 景深·畸变·远心 工业相机 分辨率·位深·帧率 接口 / 传输 GigE·USB3·CXP 带宽 = 像素×位深×帧率 采集 / SDK 触发·曝光·增益 OpenCV 处理 Bayer→灰度/RGB NumPy 数组 质量评估 均值·方差·清晰度 关键参数与判断依据 曝光 目标灰度 100~200 过长→运动模糊 增益 尽量取小 过高→噪声放大 触发 硬触发同步节拍 避免丢帧/重影 清晰度 Laplacian 方差 越大越清晰

实际调试时,建议按“先光源、再镜头、后相机参数”的顺序固定变量:光源稳定后,用背光或同轴光把特征对比拉开;镜头确定 FOV 与工作距离;最后调曝光与增益,使目标灰度落在合理区间,并用 Laplacian 方差与直方图确认图像可用于后续算法。只有采集端稳定,后续的定位、测量与缺陷检测才有可靠输入。