最近一个项目需要用到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中提及了常用的所有色彩空间相互转换的方法,但是我们也必须知道是要从什么源色彩空间,转换到什么目标色彩空间。比如上述图片,如果不是供应商在群里告诉我要转为UYVY(UYVY又是啥啊?)格式,我可能得试几天。
色彩空间
RGB
也就是红绿蓝,三原色。采用加色模式。RGB有多种数据格式。
RGB888(24bit)
三个通道分别用8bit
,即2^8=256表示,如(255,255,255) ,每个通道的取值范围为[0,255]。或者采用0xFFFFFF
三个字节表示。
RGB565(16bit)
三个通道分别用 5bit, 6bit, 5bit
表示,比如(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更适合人类使用的界面仍存在争议。
YUV
重头戏来力!
YUV是编译true-color颜色空间(color space)的种类。Y'UV, YUV, YCbCr, YPbPr等都可以称为YUV,彼此有重叠,因此经常被人混淆。其中Y表示亮度,U和V表示色度。YUV 和 YCrCb都是8bit
,二者的区别在于:YUV取值范围为[0,255],YCrCb的取值范围为[-128,127]。
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平面的长度为w*h
,U和V的长度也均为w*h
。总长度w*h*3
。
NV42
Y分量单独存放,UV分量交错存放,UV排列顺序为VUVU。总长度w*h*3
。
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的长度为w*h
,U和V的长度w*h/2
,总长度w*h*2
。
IV16
平面顺序为Y-V-U。
semi planar
NV16
Y分量单独存放,U和V分量交错存放。UV平面存放顺序为UVUV。
其中Y的长度为w*h
,U和V共用长度也是w*h
,总长度w*h*2
。
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的长度为w*h
,U和V的长度w*h/4
,总长度w*h*1.5
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颜色空间详解 - 哔哩哔哩