导读工业相机的像素格式,同时描述颜色怎样组织、每个数值保留多少位,以及数据怎样装进字节。Bayer 和 RGB 的区别涉及颜色重建放在哪里,Mono10 和 Mono10p 的区别涉及传输占位与解包。沿着检测任务、数据量和算法输入建立选型顺序,才能判断哪些信息需要保留,哪些处理工作需要由主机承担。
本文 2701 字,阅读约 7 分钟|格式名称里,藏着三个不同的问题 → 需要颜色时,先决定在哪里重建颜色 → 位深决定编码层级,细节还要有信号支撑 → 打包改变占位,也改变读取方式 → 用同一组条件,算清格式的数据量 → 设置完成后,沿着数据走到算法输入
格式名称里,藏着三个不同的问题
打开工业相机的参数列表,会看到 Mono8、BayerRG8、RGB8、Mono10p 等选项。选哪个,关系到相机传多少数据,也关系到主机拿到数据后还要做什么。
Mono、Bayer、RGB 描述像素数据的组织方式;8、10、12 通常说明单个分量的有效位数;p 则涉及数据的打包布局。颜色信息、有效位深和传输占位,需要分开判断。
例如,Mono8 每个像素一个 8 位灰度值;RGB8 每个像素有红、绿、蓝三个分量,每个分量 8 位,因此合计 24 位。RGB8 名字里的“8”,不能直接拿来计算整帧大小。
像素格式控制的是相机怎样输出图像数据,具体选项由传感器和机型能力决定。单色传感器采集单通道数据;彩色相机即使选择 Mono 输出,也仍然使用原来的彩色传感器,只是输出转换后的灰度图。
先把任务说清楚:量零件轮廓需要明暗边界,按包装颜色分拣则需要颜色信息。这个区别,比先挑一个看起来更高级的格式更有用。
需要颜色时,先决定在哪里重建颜色
如果检测只使用明暗与形状,可以从 Mono 输出开始验证,让数据直接以单通道进入算法。是否能稳定分出目标,仍要通过照明、曝光和样本检查确认。
彩色相机的一条常见路线是 Bayer 滤色阵列:传感器上不同位置覆盖红、绿、蓝滤色片,每个位置只测量其中一种颜色。输出 Bayer8 时,每个像素位置只有一个 8 位数值,同时需要知道它对应什么颜色。
要得到每个位置完整的 RGB,系统根据周围采样估计缺少的颜色分量。这个过程叫去马赛克,也常称为 Debayering。
对同一台 Bayer 彩色相机,Bayer 与 RGB 输出的关键区别,是颜色重建在哪里完成。输出 Bayer 时,主机可以按正确的滤色排列执行去马赛克,再把 RGB 交给算法;输出 RGB 时,颜色重建由相机内的处理链路完成,主机拿到三个通道的数据。
图片说明:本文概念示意,比较同一 Bayer 彩色相机的两种输出;每分量 8 位,不含行填充与协议开销。
RGB 输出让接收端直接得到三个颜色通道。它的结果仍受去马赛克算法影响,锐利边缘可能出现伪色;颜色检测的精度需要在最终图像上验证。
如果检测网络需要三通道图像,选择 RGB8 可以把颜色重建交给相机,前提是链路容得下三个通道的数据。带宽紧张,而主机或相机 SDK 已有可用的去马赛克接口时,可以选择 Bayer8,再在接收端转换。选 Bayer 时,节省的传输量要和主机新增的处理工作一起评估。
BayerRG、BayerBG 等名称还说明滤色排列;RGB 与 BGR 则说明通道顺序。转换时用错排列,或把 BGR 当成 RGB,都会让后续颜色判断失去正确的输入依据。
另一个选项是 YCbCr,工业相机菜单中也常见 YUV 命名。这类格式分别保存描述明暗的亮度分量与描述颜色差异的色度分量。以每分量 8 位的 YCbCr 4:2:2 为例,两个水平相邻像素分别保留亮度值,共享一组色度值,合计 4 字节,平均每像素 16 位。
这种 4:2:2 布局通过减少色度采样来降低数据量,适合下游明确支持这种输入的链路;涉及细小颜色边界时,要验证这项取舍。读取时还应匹配具体的分量顺序、颜色转换规则和数值范围,不能只凭“YUV”三个字选择转换接口。
位深决定编码层级,细节还要有信号支撑
位深描述一个数值用多少位表示。8 位无符号整数有 256 个取值,10 位有 1024 个,12 位有 4096 个。位数增加,让同一数值范围可以分得更细。
但物体的微弱差异能否被检测出来,还受到曝光、传感器噪声和后续处理影响。已经过曝丢掉的信息,不能靠把输出改成更高位深找回来;噪声淹没的差异,也不会因编码级数增加就变得可靠。
这里还要分清数据经过的位置:传感器先输出数值,相机内部可以进行图像处理,最后按选定的像素格式发送给主机。
图片说明:从左到右为光、传感器、内部图像处理和输出像素格式。下方 Transfer bit depth 标在内部处理的数据路径上。图片来源:Basler 官方 Transfer Bit Depth 文档。
Basler 文档给出的一个例子是:在支持独立设置的相机上,可以基于 12 位传感器数据,输出 Mono8 图像。部分机型还提供 Transfer Bit Depth,用来设置内部图像处理路径的位深。
传感器输出位深、内部处理位深和最终输出格式,可以是不同的值。具体能否独立设置,要看机型。因此,仅凭 Mono8,不能断定传感器只进行了 8 位采集。
如果现有算法只接收 8 位灰度,可以先从 Mono8 验证;确实需要利用细微灰度差异,再评估 10 位或 12 位输入。此时应固定曝光和照明,检查低位是否包含有用信号,以及后续处理是否保留了它们。
打包改变占位,也改变读取方式
有效位数明确以后,才轮到存储布局。
一个字节有 8 位。按 GenICam 像素格式命名规范(PFNC)的 Mono10 未打包布局,每个像素使用两个字节,其中 10 位承载数据,其余为填充位。它的有效位深是 10 位,传输占位却是 16 位。
Mono10p 把数据连续打包,四个 10 位像素可以装进五个字节。类似地,两个 Mono12p 像素装进三个字节。
图片说明:两个 12 位像素共占三个字节。中间的 Byte 1 同时包含两个像素的数据;图中 Byte 0 在右侧,颜色区分两个像素。图片来源:Basler 官方 Pixel Format 文档。
打包保留原来的有效数据,减少填充占位。不过,接收端不能把 Mono10p 的字节缓冲区,直接当作“每像素两个字节”的数组读取。它需要按该格式的位布局解包,恢复每个像素数值。
相机输出省下了空间,主机解包后的数组仍可能变大。如果算法使用 16 位整数保存每个像素,解包以后又回到了每像素两个字节。计算相机链路负载与主机内存占用时,要分别看这两个阶段。
另外,旧的 Mono10Packed 与 Mono10p 不能只凭名称互换。Basler 的 API 文档明确说明两者内存布局不同。应把完整枚举值交给对应转换接口,而不是看到“10 位、打包”就套用同一段解析程序。
用同一组条件,算清格式的数据量
做一个计算示例:假设图像恰好有 200 万个像素,每秒传输 100 帧。每帧字节数等于像素数量乘以平均占位位数,再除以 8;乘以帧率,就得到每秒数据量。这里只计算图像数据,不含行填充、协议和其他附加数据,1 MB 按 100 万字节计算。
| 输出格式 | 平均占位 | 每帧大小 | 每秒数据量 |
|---|
| Mono8 / Bayer8 | 8 位/像素 | 2 MB | 200 MB/s |
| Mono10p | 10 位/像素 | 2.5 MB | 250 MB/s |
| Mono12p | 12 位/像素 | 3 MB | 300 MB/s |
| Mono10(未打包) | 16 位/像素 | 4 MB | 400 MB/s |
| YCbCr422_8 | 16 位/像素 | 4 MB | 400 MB/s |
| RGB8 | 24 位/像素 | 6 MB | 600 MB/s |
Mono8 和 Bayer8 大小相同,但含义和后续处理不同。Mono10 改成 Mono10p,则在保留 10 位数据的前提下,把每帧占位从 4 MB 降到 2.5 MB。YCbCr422_8 与未打包的 Mono10 同为 16 位占位,所装的信息也完全不同。
把这张表与接口规格对照时,还要统一单位:bit/s 是每秒多少位,MB/s 是每秒多少字节。标称 1 Gbit/s 的链路,理论数据率为 125 MB/s,已经低于示例中 Mono8 所需的 200 MB/s;实际传输还要计入协议等开销。
这只是带宽预算。相机能到多少帧,还受到曝光时间、传感器读出和图像采集区域等因素限制。缩小输出数据量主要释放传输环节的余量,能否涨帧要看原来的瓶颈在哪里。
主机还要完成接收、解包、颜色转换和检测。若采集帧率足够,处理速度跟不上,换一个更紧凑的传输格式仍需要结合转换开销判断。
24 帧的电影很顺,30 帧的相机却被说卡——问题不在帧率
设置完成后,沿着数据走到算法输入
实际配置时,我建议按下面的顺序检查:
1.确定任务需要的信息。颜色是否参与判定?需要利用哪些灰度差异?据此选择颜色组织与有效位深。
2.读取机型实际支持的格式。核对完整 PixelFormat 枚举、位布局和转换接口,再估算目标分辨率、帧率下的数据量。
3.按手册要求停止采集并设置格式。Basler 的官方顺序是在相机空闲、不采集图像时修改 PixelFormat;其他设备以实际参数的可写条件为准。
4.核对送入算法的数据。检查尺寸、每行实际占用的字节数、通道顺序和数值范围。打包数据先按匹配格式解包,Bayer 数据按正确排列转换;预览画面与算法实际读取的缓冲区要分别核对。
5.固定条件验证整条链路。保持分辨率、曝光和照明一致,检查接收是否完整、处理是否跟得上,以及代表性样本的检测结果。
最终把完整的格式枚举、接收端转换方式和验证结果一起记录下来。下次换相机、换 SDK 或调整帧率时,就能沿着同一条数据路径复查:需要的信息有没有保留,数值有没有读对,处理能不能跟上节拍。
参考资料
•Basler:Pixel Format,输出组织、打包示例与设置顺序: https://docs.baslerweb.com/pixel-format
•EMVA:GenICam Pixel Format Naming Convention 2.1,位深与存储布局: https://www.emva.org/wp-content/uploads/GenICam_PFNC_2_1.pdf
•Basler:PixelType,Mono10Packed 与 Mono10p 的布局区别: https://docs.baslerweb.com/pylonapi/net/T_Basler_Pylon_PixelType
•Basler:PGI Feature Set,相机内去马赛克与颜色伪影: https://docs.baslerweb.com/pgi-feature-set
•Basler:Sensor Bit Depth,传感器位深与输出格式: https://docs.baslerweb.com/sensor-bit-depth
•Basler:Transfer Bit Depth,内部处理路径与原始说明图: https://docs.baslerweb.com/transfer-bit-depth
•Basler:Resulting Acquisition Frame Rate,帧率限制因素: https://docs.baslerweb.com/resulting-acquisition-frame-rate
— THE END —
文章仅做学术分享,如有侵权请联系删除,非常感谢!