最近一个项目需要用到 x86 控制器+ GMSL 相机的组合,这种情况一般会用一张图像采集卡来获取 GMSL 相机的图像,也就是PCIe-GL26设备将GMSL相机图像发送至HOST端 - FunnyWii's Zone 中使用的方案,但是其成本很高。

于是采购了一个 GMSL 转 USB 的转换器。官方也提供了工具的连接 SENSING-Technology/SensingCaptureV2: Host Software Tools for Use with the SG8-U30-xxxx Device,然后我发现这个工具是面向 Windows 平台的...

既然转换器是通过USB方式连接的,那ls /dev/video* 是不是应该有输出?插上一看,还真有。

但是直接使用 OpenCV 通过相机编号获取到的图像,很明显色彩空间有问题。(图丢了)

通过看相机说明书,得知相机的色彩空间是 YUV422@8bit,我就知道个 RGB 和 HSV...什么是 YUV 啊喂,422 又是什么啊喂,8bit 又是什么啊啊啊啊啊啊啊啊啊。在OpenCV: Color Space Conversions中提及了常用的所有色彩空间相互转换的方法,但是我们也必须知道是要从什么源色彩空间,转换到什么目标色彩空间。

比如上述图片(图丢了x2),如果不是供应商在群里告诉我要转为 UYVY(UYVY又是啥啊?)格式,我可能得试几天。

RGB

也就是红绿蓝,三原色。采用加色模式。RGB有多种数据格式。

RGB888(24bit)

三个通道分别用8bit,即28=2562^8=256表示,如(255,255,255)(255,255,255) ,每个通道的取值范围为[0,255][0,255]。或者采用 0xFFFFFF 三个字节表示。

RGB565(16bit)

三个通道分别用 5bit, 6bit, 5bit 表示,比如(31,63,31)(31,63,31),一般采用 0xFFFF 来表示。

RGB555(16bit)

每个通道用 5bit 来表示,最前面(高位)一位不用。

RGB1555(16bit)

ARGB的一种,每个通道用 5bit 来表示,最后一位(低位)表示透明度,0 为完全透明,1 为完全不透明。

RGB24(24bit)

似乎与 RGB888 是两种格式[4]。该提问下的意思是,RGB888 应该被叫做 RGB8888,其前面 8bit 是空的,而 RGB24 才是上面提到的 RGB888。但是并没有其他文章佐证这一说法,大部分 Wiki 和 Blog 仍然将 RGB888 和 RGB24 混为一谈。

所以本人也不清楚到底如何区分这两种格式。在内存中RGB各分量(从高到低)的排列顺序为:BGR BGR BGR ......

RGB32(32bit)

RGB分量用 8bit 表示,最后 8bit 保留。在内存中 RGB 各分量(从高到低)的排列顺序为:BGRX BGRX BGRX ......

ARGB32

本质上是带 Alpha 通道的 RGB32,保留的 8bit 用来表示透明度在内存中RGB各分量的排列顺序为:BGRA BGRA BGRA ......

HSV

也有叫 HSB 的。把下方的 Value 替换为了 Brightness。

  • Hue(色调/色相)

  • Saturation(饱和度)

  • Value(明度

HSV 模型的三维表示从 RGB 立方体演化而来。设想从 RGB 沿立方体对角线的白色顶点向黑色顶点观察,就可以看到立方体的六边形外形。六边形边界表示色彩,水平轴表示纯度,明度沿垂直轴测量。与加法减法混色的术语相比,使用色相,饱和度等概念描述色彩更自然直观[6]

HSL

和 HSV 相似,将明度 Value 替换为了亮度 Lightness。二者的 H 可以认为是指代相同的性质,但是二者的 S 对于饱和度的定义是不同的。

对于 HSV 还是 HSL 更适合人类使用的界面仍存在争议。

Hsl-hsv_models.svg

YUV

重头戏来力!

YUV 是编译 true-color 颜色空间(color space)的种类。Y'UV, YUV, YCbCr, YPbPr 等都可以称为 YUV,彼此有重叠,因此经常被人混淆。

其中 Y 表示亮度,U V 表示色度。YUV 和 YCrCb 都是 8bit,二者的区别在于:YUV 取值范围为[0,255][0,255],YCrCb 的取值范围为[128,127][-128,127]

YUV 格式分成三种:紧缩格式(packed formats),平面格式(planar formats)和半平面格式(semi planar)。

  • 紧缩格式:将 Y、U、V 值存储成 Macro Pixels 数组,和 RGB 的存放方式类似,以每个像素为基本单位。紧缩格式中的 YUV 是混合在一起的,对于 YUV4:2:2 格式而言,用紧缩格式更合适,因此有了 UYVYYUYV 等。

  • 平面格式:将 Y、U、V 的三个分量分别存放在不同的矩阵中。

  • 半平面格式:将 Y 分量存储在一个平面中,而 U 和 V 分量交错存储在另一个平面中。

为了节约带宽,大部分 YUV 格式的每个像素都小于 24bit,格式有 YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1 和 YCbCr 4:4:4。YUV 的表示法称为 A:B:C 表示法:

  • 4:4:4 表示完全取样。

  • 4:2:2 表示 2:1的水平取样,垂直完全采样。

  • 4:2:0 表示 2:1的水平取样,垂直 2:1 采样。

  • 4:1:1 表示 4:1的水平取样,垂直完全采样。

下面引用图像来自【学习笔记】关于图像YUV格式分类和排布方式的全学习_yuv图像-CSDN博客

YUV444

不压缩,采用完整的三个分量表示一个像素点:

YUV444.png

packed

按照像素点顺序排列:

YUV444packed.png

planar

I444 YUV分量放在3个不同平面。平面顺序为 Y-U-V。

YUV444planar.png

YV24 I444 的区别在于,平面顺序为 Y-V-U

semi planar

NV24 Y分量单独存放,UV 分量交错存放,UV 排列顺序为 UVUV。假设 Y 平面的长度为 w×h\text w \times \text h,U 和 V 的长度也均 w×h\text w \times \text h 。总长度 w×h×3\text w \times \text h \times \text 3

NV42 Y分量单独存放,UV 分量交错存放,UV 排列顺序为 VUVU。总长度 w×h×3\text w \times \text h \times \text 3

YUV422

左右两个像素点公用一个 UV 分量。对于一帧图像的数据量而言,YUV422:YUV444 = 8:12 = 2:3。

YUV422.png

packed

YUYV 图像存储顺序为YU-YV-YU-YV。下图可以看到 Y(0,0) 和 Y(0,1) 共用同一个 U 和 V。

YUYV.png

UYVY 和 YUYV 比起来,只是存储顺序不同。图像存储顺序为 UY-VY-UY-VY。

VYUY 图像存储顺序 VY-UY-VY-UY。

planar

I422 YUV分量分别存放,平面顺序为 Y-U-V。其中Y的长度为 w×h\text w \times \text h ,U和V的长度w×h÷2\text w \times \text h \div \text 2 ,总长度 w×h×2\text w \times \text h \times \text 2

IV16 平面顺序为Y-V-U。

semi planar

NV16 Y 分量单独存放,U 和 V 分量交错存放。UV 平面存放顺序为 UVUV。其中Y的长度为w×h\text w \times \text h ,U和V共用长度也是 w×h\text w \times \text h ,总长度 w×h×2\text w \times \text h \times \text 2

NV61 Y 分量单独存放,U 和 V 分量交错存放。UV 平面存放顺序为 VUVU。

YUV420

进一步合并 UV 分量,4 个分量共享一组 UV。数据量对比,YUV420:YUV444 = 1:2。下图能看出 YUV420 格式不能以 packed 格式存储,因为无论如何 Y 分量和 UV 分量也没办法放在同一行中。

YUV420.png

planar

I420 YUV 三个分量分别存放,平面顺序 Y-U-V。其中Y的长度为 w×h\text w \times \text h ,U和V的长度 w×h÷2\text w \times \text h \div \text 2,总长度w×h×1.5\text w \times \text h \times \text 1.5

YV12 YUV 三个分量分别存放,平面顺序 Y-V-U。

semi planar

NV12 Y 分量单独存放,UV 分量交错存放,UV 平面存放顺序为 UVUV。

NV21 Y 分量单独存放,UV 分量交错存放,UV 平面存放顺序为 VUVU。

下图[9]描述了YUV不同格式的详细分类:

YUV格式.png

参考文章

[1] OpenCV: Color Space Conversions

[2] 常见的图像颜色空间解释(RGB HSV YUV LAB CMYK)-次世代BUG池

[3] YUV色彩空间 | NGGames

[4] sdl 2 - SDL2 - difference between RGB888 and RGB24 - Stack Overflow

[5] RGB24 - Avisynth wiki

[6] RGB,CMY,HSV,HSL,Lab,YUV颜色空间详解 - 哔哩哔哩

[7] HSL和HSV色彩空间 - 维基百科,自由的百科全书

[8] YUV - 维基百科,自由的百科全书

[9] 【学习笔记】关于图像YUV格式分类和排布方式的全学习_yuv图像-CSDN博客