1. 工业视觉系统概述与OpenCV定位
工业视觉系统本质上是一套“用相机代替人眼、用算法代替人脑判断”的自动化检测与测量装置。它并不只是“装一个摄像头跑一段识别代码”,而是由光学、机械、电气、计算与软件协同构成的完整链路。理解这条链路的组成与信号流向,是后续用OpenCV开发算法的前提。
1.1 工业视觉系统的组成
一套典型的工业视觉系统可以拆成五个部分:被检对象与照明、成像单元、图像采集与传输、计算与算法、执行与通信。它们之间是明确的信号与数据流关系,而不是并列的模块清单。
照明决定“能不能看清”。工业上常用环形光、条形光、同轴光、背光与穹顶光:背光用于轮廓与尺寸测量,同轴光用于高反光金属表面,穹顶光用于消除曲面反光。照明方式选错,后续算法再强也难以补救。
成像单元由镜头与相机组成。镜头焦距、工作距离、视场(FOV)与分辨率共同决定系统的空间分辨率。一个常用的估算关系是:单像素精度 ≈ 视场宽度 ÷ 相机水平像素数。例如视场宽100 mm、相机500万像素(水平约2448像素),则单像素约0.041 mm;若要求测量精度达到0.02 mm,通常需要让被测特征占据3~5个像素以上,此时应缩小视场或提高分辨率。
相机按接口分为GigE、USB3.0、Camera Link等;按传感器分为CCD与CMOS,当前工业主流为CMOS全局快门,适合运动中的工件拍摄。采集与传输环节负责把光信号转成数字图像并送入主机,涉及曝光时间、增益、触发方式(软触发/硬触发)等参数。
计算与算法环节是OpenCV发挥作用的主战场,负责图像预处理、特征提取、测量、定位、分类与缺陷判定。执行与通信环节则把判定结果通过I/O、PLC、Modbus TCP、串口等方式输出,驱动分拣、剔除或报警。
1.2 典型应用场景
工业视觉的应用可归为四类任务:定位(引导机器人抓取、对位贴合)、测量(尺寸、间距、角度)、检测(缺陷、划痕、缺件、错件)、识别(字符OCR、条码、颜色分类)。例如3C行业的连接器引脚共面度检测属于测量;汽车零部件表面的划痕与凹坑属于检测;食品包装上的生产日期识别属于识别;机械臂抓取散乱工件前的位姿计算属于定位。不同任务对精度、节拍与稳定性的要求差异很大,直接决定相机选型与算法复杂度。
1.3 OpenCV在工业视觉中的角色
OpenCV是一个开源计算机视觉库,提供C++、Python等接口,覆盖图像读写、滤波、几何变换、特征检测、模板匹配、轮廓分析、相机标定等基础能力。在工业视觉中,它的定位是算法开发与验证的主力工具:一方面可以快速验证成像方案与算法思路,另一方面可作为最终软件的核心图像处理库。
需要明确的是,OpenCV本身不提供相机驱动、不负责实时调度、也不直接对接PLC。实际系统通常由相机厂商SDK负责采集,OpenCV负责处理,再由通信库输出结果。因此学习OpenCV时要建立“它只是处理链中的一环”的认知,而不是把它当成整套系统。
1.4 开发环境搭建
推荐使用Python + OpenCV入门,环境搭建步骤如下:
# 建议 Python 3.9 ~ 3.11
python -m venv venv
venv\Scripts\activate # Windows
pip install opencv-python opencv-contrib-python numpy
# 验证
python -c "import cv2; print(cv2.__version__)"
若使用C++,则需配置OpenCV的include与lib路径,并在CMake中find_package(OpenCV REQUIRED)。工业现场更推荐C++以获得更稳定的实时性能,但算法验证阶段用Python效率更高。
1.5 第一个图像采集程序
下面是一个最小可运行的采集与显示程序,用于验证相机是否可用:
import cv2
cap = cv2.VideoCapture(0) # 0 为默认相机;工业相机常用 SDK 取流
if not cap.isOpened():
raise RuntimeError("相机打开失败")
while True:
ok, frame = cap.read()
if not ok:
break
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow("frame", gray)
if cv2.waitKey(1) & 0xFF == 27: # ESC 退出
break
cap.release()
cv2.destroyAllWindows()
运行后应能看到实时灰度画面。判断采集是否正常,可观察三点:画面是否连续无卡顿、曝光是否过亮或过暗、frame.shape是否与相机分辨率一致。若画面全黑,优先检查镜头盖、曝光时间与触发模式;若帧率明显偏低,检查传输接口带宽与waitKey的延时设置。