最近一个项目需要用到 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,即表示,如 ,每个通道的取值范围为。或者采用 0xFFFFFF 三个字节表示。
RGB565(16bit)
三个通道分别用 5bit, 6bit, 5bit 表示,比如,一般采用 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 更适合人类使用的界面仍存在争议。
YUV
重头戏来力!
YUV 是编译 true-color 颜色空间(color space)的种类。Y'UV, YUV, YCbCr, YPbPr 等都可以称为 YUV,彼此有重叠,因此经常被人混淆。
其中 Y 表示亮度,U 和 V 表示色度。YUV 和 YCrCb 都是 8bit,二者的区别在于:YUV 取值范围为,YCrCb 的取值范围为。
YUV 格式分成三种:紧缩格式(packed formats),平面格式(planar formats)和半平面格式(semi planar)。
紧缩格式:将 Y、U、V 值存储成 Macro Pixels 数组,和 RGB 的存放方式类似,以每个像素为基本单位。紧缩格式中的 YUV 是混合在一起的,对于 YUV4:2:2 格式而言,用紧缩格式更合适,因此有了 UYVY、YUYV 等。
平面格式:将 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
不压缩,采用完整的三个分量表示一个像素点:

packed
按照像素点顺序排列:

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

YV24 和 I444 的区别在于,平面顺序为 Y-V-U
semi planar
NV24 Y分量单独存放,UV 分量交错存放,UV 排列顺序为 UVUV。假设 Y 平面的长度为 ,U 和 V 的长度也均 。总长度 。
NV42 Y分量单独存放,UV 分量交错存放,UV 排列顺序为 VUVU。总长度 。
YUV422
左右两个像素点公用一个 UV 分量。对于一帧图像的数据量而言,YUV422:YUV444 = 8:12 = 2:3。

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

UYVY 和 YUYV 比起来,只是存储顺序不同。图像存储顺序为 UY-VY-UY-VY。
VYUY 图像存储顺序 VY-UY-VY-UY。
planar
I422 YUV分量分别存放,平面顺序为 Y-U-V。其中Y的长度为 ,U和V的长度 ,总长度 。
IV16 平面顺序为Y-V-U。
semi planar
NV16 Y 分量单独存放,U 和 V 分量交错存放。UV 平面存放顺序为 UVUV。其中Y的长度为 ,U和V共用长度也是 ,总长度 。
NV61 Y 分量单独存放,U 和 V 分量交错存放。UV 平面存放顺序为 VUVU。
YUV420
进一步合并 UV 分量,4 个分量共享一组 UV。数据量对比,YUV420:YUV444 = 1:2。下图能看出 YUV420 格式不能以 packed 格式存储,因为无论如何 Y 分量和 UV 分量也没办法放在同一行中。

planar
I420 YUV 三个分量分别存放,平面顺序 Y-U-V。其中Y的长度为 ,U和V的长度 ,总长度
YV12 YUV 三个分量分别存放,平面顺序 Y-V-U。
semi planar
NV12 Y 分量单独存放,UV 分量交错存放,UV 平面存放顺序为 UVUV。
NV21 Y 分量单独存放,UV 分量交错存放,UV 平面存放顺序为 VUVU。
下图[9]描述了YUV不同格式的详细分类:

参考文章
[1] OpenCV: Color Space Conversions
[2] 常见的图像颜色空间解释(RGB HSV YUV LAB CMYK)-次世代BUG池
[4] sdl 2 - SDL2 - difference between RGB888 and RGB24 - Stack Overflow
[6] RGB,CMY,HSV,HSL,Lab,YUV颜色空间详解 - 哔哩哔哩
评论