三、相机选型与图像采集:工业相机接口、分辨率与帧率权衡、触发模式设置、图像格式转换
各位同学,咱们今天聊点实在的。相机选型这事儿,说难不难,说简单也不简单。我见过太多项目,算法调得再好,相机没选对,最后全白搭。说白了,相机就是分拣机的眼睛,眼睛不好使,后面再折腾也没用。
3.1 工业相机接口:USB vs GigE,到底选哪个?
工业相机接口这块,目前主流就两个:USB3.0和GigE(千兆以太网)。我个人的习惯是,先看传输距离,再看带宽需求。
USB3.0接口:理论带宽5Gbps,实际能跑到3-4Gbps。优点是即插即用,延迟低。缺点也很明显——传输距离限制在5米以内。我在项目中遇到过,产线布局稍微远一点,USB线就得加中继器,麻烦得很。
GigE接口:带宽1Gbps,但传输距离能到100米。你想想看,大型分拣线,相机装在几十米外的工位上,用GigE一根网线就搞定了。而且PoE供电,少一根电源线,布线清爽很多。
| 接口类型 | 带宽 | 传输距离 | 供电方式 | 适用场景 |
|---|---|---|---|---|
| USB3.0 | 5Gbps | ≤5米 | USB供电 | 近距离、高帧率 |
| GigE | 1Gbps | ≤100米 | PoE/外接 | 远距离、多相机 |
3.2 分辨率与帧率权衡:别被参数忽悠了
很多新手选相机,上来就要最高分辨率、最高帧率。嗯,这里要注意——高分辨率和高帧率往往是矛盾的。
为什么?因为相机的数据带宽是固定的。你分辨率翻倍,帧率就得砍半。举个例子,500万像素的相机,在USB3.0接口下,理论最高帧率也就30fps左右。你非要跑60fps,那就得降低分辨率。
我在做物流分拣项目时,遇到过一个问题:客户要求识别小零件上的二维码,分辨率必须高。但传送带速度又很快,帧率低了会漏检。最后怎么解决的?我们选了200万像素、200fps的全局快门相机,配合合适的镜头,既保证了分辨率,又跟上了产线速度。
核心公式:
带宽需求 = 分辨率(像素) × 帧率(fps) × 像素深度(bit)
举个例子:1920×1080分辨率,8bit深度,30fps
带宽 = 1920×1080×8×30 ≈ 497Mbps
USB3.0能扛住,GigE就有点悬了。
所以,选型时先算清楚你的实际需求。分拣机物料识别,一般200-500万像素就够用了。帧率嘛,看产线速度,通常30-60fps就能覆盖大多数场景。
3.3 触发模式设置:软触发 vs 硬触发
触发模式,说白了就是「什么时候拍照」。分拣机里,物料是运动的,你不能一直拍,得在物料到达指定位置时精准抓拍。
软触发:软件发指令给相机拍照。优点是灵活,代码里随时可以控制。缺点是有延迟,不稳定。我刚开始做的时候,用软触发配合传送带编码器,结果发现每次触发时间都不一样,物料位置偏差很大。
硬触发:通过外部信号(比如光电传感器、编码器)直接触发相机。延迟低,精度高。分拣机里,我强烈建议用硬触发。传感器检测到物料到位,直接给相机一个脉冲信号,咔嚓一下,稳得很。
代码层面,设置触发模式很简单。以海康相机为例:
# Python示例:设置硬触发
camera.TriggerMode.set("On") # 开启触发模式
camera.TriggerSource.set("Line0") # 设置触发源为Line0
camera.TriggerActivation.set("RisingEdge") # 上升沿触发
# 软触发模式
camera.TriggerMode.set("On")
camera.TriggerSource.set("Software")
camera.TriggerSoftware.execute() # 软件发一次触发
3.4 图像格式转换:BGR、RGB、YUV,别搞混了
相机采集到的原始数据,通常是Bayer格式(拜耳阵列),需要经过ISP处理才能变成我们熟悉的BGR或RGB。而YUV格式,在视频传输中很常见。
为什么要注意这个?因为OpenCV默认用的是BGR顺序,而很多深度学习模型训练时用的是RGB。你想想看,如果搞反了,红色和蓝色通道互换,模型识别结果肯定一塌糊涂。
我在做水果分拣项目时,就踩过这个坑。模型训练时用的RGB图片,部署时相机输出BGR,结果把红苹果识别成了青苹果。后来加了一行转换代码才搞定。
# Python:BGR转RGB
import cv2
img_bgr = cv2.imread("image.jpg") # OpenCV默认BGR
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
# BGR转YUV
img_yuv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2YUV)
# 从相机直接获取BGR图像(以海康相机为例)
import numpy as np
# 假设frame是相机采集的原始数据
img_bgr = frame.get_image() # 返回BGR格式的numpy数组
另外,像素深度也要注意。8bit够用,但遇到高动态范围场景(比如金属反光),10bit或12bit能保留更多细节。不过,深度越大,数据量越大,传输和处理压力也越大。
3.5 实战经验总结
好了,说了这么多,我总结几条实战经验:
- 接口选型:距离近、帧率高用USB3.0;距离远、多相机用GigE。
- 分辨率与帧率:先算带宽,再定参数。别盲目追求高参数。
- 触发模式:分拣机必用硬触发,信号线做好屏蔽。
- 图像格式:搞清楚你的算法需要什么格式,BGR还是RGB,别搞反了。
最后,送大家一句话:相机选型不是越贵越好,适合你的产线才是王道。下一章,咱们聊聊镜头选型和光照设计,那个坑更多,到时候我给大家细讲。