3. 图像采集与接口
图像采集是整个视觉系统的起点。接口选不对,后面再好的算法也白搭。我见过不少项目,前期没仔细考虑接口,结果现场布线、带宽、稳定性全出问题,最后只能换相机重来。
这一节,咱们把工业相机最主流的两个接口协议掰开揉碎讲清楚。再聊聊SDK怎么调、触发怎么配、帧率怎么控。嗯,都是实战里绕不开的硬骨头。
3.1 GigE Vision vs USB3 Vision:到底选哪个?
先看一张对比图,心里有个底。
说白了,选型就一句话:距离远、相机多、环境复杂 → GigE Vision;距离近、带宽高、响应快 → USB3 Vision。
我个人习惯,凡是超过10米的产线,直接上GigE。PoE供电一根线搞定,省心。但如果是高分辨率、高帧率的场景,比如5000万像素的晶圆检测,USB3 Vision的带宽优势就体现出来了。
3.2 相机SDK二次开发:Halcon vs OpenCV
接口协议定好了,接下来就是怎么把图像从相机里拽出来。这里有两个主流路线:Halcon 和 OpenCV。
3.2.1 Halcon 采集流程
Halcon的采集接口封装得比较完善。它通过HALCON Image Acquisition接口统一管理,底层自动适配GigE Vision、USB3 Vision、Camera Link等协议。你不需要关心具体的传输细节。
看个典型的采集代码:
// Halcon C++ 采集示例
HTuple hv_AcqHandle, hv_Image;
// 打开相机(自动枚举)
OpenFramegrabber("GigEVision2", 0, 0, 0, 0, 0, 0, "default",
-1, "default", -1, "false", "default", "cam1", 0, -1, &hv_AcqHandle);
// 循环采集
while (true) {
GrabImageAsync(hv_AcqHandle, &hv_Image, -1);
// 处理图像...
}
// 关闭
CloseFramegrabber(hv_AcqHandle);
嗯,代码很简洁。但要注意,GrabImageAsync 的最后一个参数是超时时间(毫秒)。我建议设成 -1 表示无限等待,否则在高帧率场景下容易超时报错。
3.2.2 OpenCV 采集流程
OpenCV本身不直接支持工业相机协议。你需要通过相机厂商的SDK(如Basler的pylon、海康的MVS)先拿到图像数据,再转成OpenCV的Mat格式。
以Basler相机为例:
// OpenCV + Basler pylon 采集示例
PylonInitialize();
CInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice());
camera.Open();
// 设置触发模式
camera.TriggerSelector.SetValue(TriggerSelector_FrameStart);
camera.TriggerMode.SetValue(TriggerMode_On);
camera.TriggerSource.SetValue(TriggerSource_Line1);
camera.AcquisitionFrameRateEnable.SetValue(true);
camera.AcquisitionFrameRate.SetValue(30.0);
CGrabResultPtr ptrGrabResult;
camera.StartGrabbing();
while (camera.IsGrabbing()) {
camera.RetrieveResult(5000, ptrGrabResult, TimeoutHandling_ThrowException);
if (ptrGrabResult->GrabSucceeded()) {
Mat img(ptrGrabResult->GetHeight(), ptrGrabResult->GetWidth(),
CV_8UC3, (uint8_t*)ptrGrabResult->GetBuffer());
// 处理图像...
}
}
camera.StopGrabbing();
camera.Close();
PylonTerminate();
你看,OpenCV路线需要多一层转换。但好处是灵活,你可以直接调用OpenCV的算法库,不用额外买Halcon的license。
| 对比项 | Halcon | OpenCV + 厂商SDK |
|---|---|---|
| 采集接口封装 | 统一接口,自动适配 | 需手动调用厂商SDK |
| 图像格式转换 | 原生HObject,无需转换 | 需转Mat,有性能开销 |
| 算法库 | 商业级,闭源 | 开源,社区丰富 |
| 成本 | 高(按节点收费) | 低(开源免费) |
| 适合场景 | 高端、复杂检测 | 快速原型、中小项目 |
3.3 触发模式与帧率控制
图像采回来了,但什么时候采?采多快?这两个问题直接决定检测系统的成败。
3.3.1 触发模式
工业相机一般支持三种触发模式:
- 自由运行模式(Free Run):相机按内部时钟连续采集。适合传送带匀速、无间断的场景。
- 软件触发(Software Trigger):通过API发送指令触发采集。适合需要精确控制采集时刻的场景。
- 硬件触发(Hardware Trigger):通过外部信号(如光电传感器、编码器)触发。适合高速、高精度同步场景。
我个人最常用的是硬件触发。为什么呢?因为产线上产品位置是随机的,靠软件触发总有延迟。硬件触发直接接光电开关,产品一到,信号一来,相机立刻拍,延迟在微秒级。
3.3.2 帧率控制
帧率不是越高越好。它受几个因素限制:
- 传感器读出时间:分辨率越高,读出越慢。
- 曝光时间:曝光越长,帧率越低。
- 传输带宽:GigE Vision理论125 MB/s,USB3 Vision理论500 MB/s。实际要打7折。
- 处理时间:算法处理完一帧才能处理下一帧。
帧率计算公式:
最大帧率 = 1 / (曝光时间 + 读出时间 + 传输时间)
实际帧率 = min(最大帧率, 处理帧率, 触发频率)
举个例子:一个500万像素的相机,曝光时间2ms,读出时间10ms,传输时间5ms。那么最大帧率 = 1 / (0.002 + 0.01 + 0.005) ≈ 58.8 fps。但如果你算法处理一帧要30ms,那实际帧率只有33 fps。
3.4 实战选型建议
最后,给几个实战中的选型建议:
- 远距离、多相机:GigE Vision + PoE交换机。布线简单,扩展方便。
- 高分辨率、高帧率:USB3 Vision。带宽优势明显。
- 高精度同步:硬件触发 + 编码器。确保每帧图像位置一致。
- 快速原型:OpenCV + 厂商SDK。成本低,迭代快。
- 量产项目:Halcon。稳定、可靠、技术支持好。
嗯,图像采集这块就聊到这儿。接口选对、SDK调好、触发配准、帧率控稳,你的视觉系统就成功了一半。剩下的,就是算法的事了。