多媒体(Multimedia)是多种媒体的综合,一般包括文本,声音和图像等多种媒体形式,多媒体技术就是通过计算机对语言文字、数据、音频、视频等各种信息进行存储和管理,所谓的媒体就是指承载和传输某种信息或物质的载体。
视频:基本组成单位一帧图像
图像设备分类(驱动是这么分类)
图像输入:camera + 媒介(csi、lvds、并口 )(dev2mem外设到内存)
图像存储:格式转换(颜色空间、分辨率等)、编解码(jpeg、h264、h265)
(mem2mem内存到内存)
图像输出:dpu(显示处理单元)+ 媒介(hdmi、dsi、lvds等)(mem2dev内存到外设)
1. 图像处理基础
像素(Pixel)
图像中的一个点称为一个像素,是图像处理的最小单位。例如:1600万像素的手机摄像头输出的图像数据最多包含1600万个像素点。
行(Line)
二维图像中水平方向上同一行的像素的集合称为一行。
帧(Frame)
连续的图像序列组成一段视频,视频中每一幅图像称为一帧,由若干行组成。
帧率(Frame Rate)
在视频信号中,每秒包含的帧数通常是固定的,称为帧频。帧频的单位是fps。通常播放软件中的1.5倍速、2倍速功能,其实就是提高了播放的帧频。
分辨率(Resolution)
一幅图像水平和垂直方向的像素个数称为分辨率,例如:常见的高清视频(1080p)格式的分辨率为1920x1080,也就是水平方向1920个像素,垂直方向1080个像素。
4k(3840x2160),720p(1280x720),2k(2560x1440)
颜色通道/分量(Channel / Component)
在彩色图像中,每个像素的数据应包含其亮度和颜色信息,其中,颜色信息由不同的颜色通道/分量来表示。每个颜色通道表示一种颜色,所有颜色通道中的颜色叠加混合产生图像中像素的颜色。例如:在RGB图像中有R、G、B三个颜色通道,YUV图像中有Y、U、V三个颜色通道。
颜色通道/分量(Channel / Component)
在彩色图像中,每个像素的数据应包含其亮度和颜色信息,其中,颜色信息由不同的颜色通道/分量来表示。每个颜色通道表示一种颜色,所有颜色通道中的颜色叠加混合产生图像中像素的颜色。例如:在RGB图像中有R、G、B三个颜色通道,YUV图像中有Y、U、V三个颜色通道。
灰阶/灰度图像(Gray Level)
只有亮度信息没有颜色信息的黑白图像我们称为灰度图像,每个像素的亮度值称为灰阶。灰度图像通常只有一个颜色分量,那就是亮度分量。
图像深度(Bit Depth)
数字图像中每个像素数据所占的bit数称为像素深度,单个像素每个颜色分量数据所占的bit数称为颜色深度,深度的单位是bpp(bits-per-pixel)。例如:颜色深度为8位的RGB图像,像素深度为24位,每个颜色分量占1个字节,取值0~255,每个像素3个颜色通道共占用3个字节,这就是我们通常说的24位彩色图像。
Alpha通道
Alpha通道是一种特殊的颜色分量,用来表示像素的透明度。例如:常见的RGBA颜色空间就是在RGB的基础上增加了表示图像透明度的颜色通道。
将两路视频流组合起来后,你需要决定在这些内容重叠的地方,哪一路将“胜出”。这就是Alpha混合发挥作用的地方。
混合后图像像素值 = α * (前景图像像素值) + (1 - α) * (背景图像像素值)
该公式表明,α值为0时,可以使前景图像完全透明,α值为1时,则前景图像完全不透明,相应区域的背景图像完全被遮盖。
这些图标就是argb的应用,他周围还有很多全透明的像素,才能让这个图标有这种悬浮效果同时图标的所有像素也可以共用同一个透明alpha属性
2. 颜色空间(Colorspace)
颜色空间又称色彩模型,定义了颜色的编码方法。常见的颜色空间有RGB、YUV、CMY、HSI、Lab等。
RGB是根据人眼识别的颜色定义的空间,可表示大部分颜色。它是最通用的面向硬件的彩色模型,广泛应用于彩色显示器等设备。
YUV主要用于电视系统以及模拟视频领域,它将亮度信息(Y)和色彩信息(UV)分离,很好的解决了彩色电视机和黑白电视机兼容的问题,与人眼的构成相关。
CMY是工业印刷采用的颜色空间。它与RGB对应,只不过RGB来源于物体发光,而CMY是依据反射光得到。
HSI是为了更好的数字化处理颜色而提出来的,其中H是色调,S是饱和度,I是强度。
Lab用于计算机色调调整和彩色校正,它既不依赖光线,也不依赖颜料,是独立于设备的彩色模型实现。
这里我们重点介绍RGB和YUV颜色空间。
2.1. RGB颜色空间
RGB是根据人眼可识别的颜色定义的一种颜色编码方式,有红(R)、绿(G)、蓝(B)三个颜色分量,能够混合出大部分颜色,常见的存储方式有RGB888、RGB565等。
RGB888又叫RGB24,单个像素每个颜色分量占8bit,每个像素24bit,是计算机显示设备中最常见的一种颜色编码方式。
RGB565使用16bit表示一个像素,其中R和B占5bit,G占6bit。这是因为人眼对绿色更敏感。
2.2. YUV颜色空间
YUV也是一种颜色编码方法,常使用在各个视频处理组件中。其中Y表示亮度(Luminance或Luma),也就是灰阶,UV表示色度(Chrominance或Chroma),用来描述图像的色彩及饱和度。常见的YUV、Y’UV、YCrCb、YPrPb等专有名词都可以称为YUV。
如下图表示YUV色彩空间从Y,U,V三个维度看到的图像。
2.3. YCrCb
YCbCr是被ITU定义在标准ITU-R BT.601(标清),ITU-R BT.709(高清),ITU-R BT.2020(超高清)中的一种色彩空间,用于数字电视系统。YCbCr不是一种绝对色彩空间,是一种针对RGB所做的编码,是YUV压缩和偏移的版本,其中Y与YUV 中的Y含义一致,Cb,Cr 同样都指色彩,只是在表示方法上不同而已,Cb,Cr是差值。
在视频通信系统中(特别是视频编解码)的“YUV”图像就是YCbCr。在平常的工作交流中,所称的YUV也是YCbCr。
Y = Kry· R + Kgy· G + Kby· B(R,G,B代表RGB色彩空间的红色,绿色,蓝色)
Cb= B – Y (Cb是差值)
Cr= R – Y(Cr是差值)
Kry+ Kgy+ Kby= 1(K 是比值或称权重, BT.601, BT.709,BT.2020中的权重是不同的。)
对应不同的颜色空间转换矩阵
2.4. 色彩空间转换
因为视讯系统中,视频采集和播放多用RGB的色彩空间,而视频编解码中多用YCrCb的色彩空间,所以RGB与YCrCb格式相互转换是必须的工作。
YUV – RGB 互转
YCbCr-RGB互转
按ITU-R BT.601标准。(这个公式是应用最广泛),由下面的公式可知,用YCbCr表示一幅全黑色的图,Y取值16,CbCr取值128。因为RGB色彩空间中,R,G,B的值全0为黑色,全255为白色。
公式定点化
上面的公式都是浮点的,为方便计算机运算和优化,实际工作中图像处理都是用定点化后的。以下面公式为例,按2的8次方做定点(当然也可以按2的6次方做定点)。
下面是定点化后的公式,我们的代码中都是这样实现的。
Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16
Cb = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128
Cr = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128
实际应用中,自己实现软件色彩空间转换,效率较低,对cpu的支持的并行加速接口调用不足,导致效率较低。更高级的实现可以调用gpu实现转换加速(opengl)
一般使用成熟图像处理库参考代码:10.0.210.2:/data/gaowj/uapi-app/yuv2rgb
2.5. YUV颜色空间下采样
YUV色彩空间的Y亮度和色度信号U、V是分离还有一个优点是,人眼对亮度敏感,对色度不敏感。减少部分UV的数据量,但人眼感知不到。
YUV编码允许降低色度的带宽而对图像质量不造成明显的影响。
YUV 4:4:4采样,每一个Y对应一组UV分量,一个YUV占8+8+8 = 24bits 3个字节。
YUV 4:2:2采样,每两个Y共用一组UV分量,一个YUV占8+4+4 = 16bits 2个字节。
YUV 4:2:0采样,每四个Y共用一组UV分量,一个YUV占8+2+2 = 12bits 1.5个字节。
YUV4:4:4
YUV444表示完全采样,每一个像素都有独立的YUV分量。
如右图 ,其中黑色实心圆点表示Y,空心圆圈表示UV。
YUV4:2:2
YUV422表示水平2:1采样,垂直完全采样,每个像素有独立的Y分量,水平方向每两个相邻的像素共用一组UV分量。常见的UYVY、YUYV都属于这种格式
YUV4:2:0
YUV420表示水平2:1采样,垂直2:1采样,每个像素有独立的Y分量,水平和垂直方向相邻的2x2个像素共用一组UV分量,如右图。常见的YV12、I420、YUV420P、YUV420SP均属于这种格式。
stride图像跨距又叫扫描宽度(存储地址行首偏移)
一行有 11 个像素(Width = 11), 对一个 32 位(每个像素 4 字节)的图像, Stride = 11 * 4 = 44.
但还有个字节对齐的问题, 譬如:
一行有 11 个像素(Width = 11), 对一个 24 位(每个像素 3 字节)的图像, Stride = 11 * 3 + 3 = 36.
为什么不是 Stride = 33? 因为它是按 4 字节对齐的.
根据上面道理, 我们可以手动计算 Stride 的值:
1、Stride = 每像素占用的字节数(也就是像素位数/8) * Width;
2、如果 Stride 不是 4 的倍数, 那么 Stride = Stride + (4 - Stride mod 4);
3. 存储格式
3.1.1. 平面Planar
YUV420P(YU12和YV12)格式
YUV420P又叫plane平面模式,Y , U , V分别在不同平面,也就是有三个平面,它是YUV标准格式4:2:0,主要分为:YU12和YV12
YU12格式在android平台下也叫作I420格式,首先是所有Y值,然后是所有U值,最后是所有V值。
YV12格式与YU12基本相同,首先是所有Y值,然后是所有V值,最后是所有U值。
stride0 = width stride1 = width/2 stride2 = width/2
3.1.2. 半平面 Simi-planar
YUV420SP(NV21和NV12)格式
YUV420SP又叫semi plane半平面模式,Y , UV分别在不同平面,也就是有两个平面,它是YUV标准格式4:2:0,主要分为:NV12和NV21
android手机从摄像头采集的预览数据一般都是NV21,存储顺序是先存Y,再VU交替存储,NV12,存储顺序是先存Y值,再UV交替存储
stride0 = width
stride1 = width
3.1.3. YUV存储格式 Packed
packed格式通常只有一个平面,亮度和色度数据交错。这类似于 RGB 像素格式,只是使用不同的颜色空间。
packed格式在网络摄像头和uvc中非常流行。在硬件中,使用单独的平面是低效的:每个像素都需要多次内存访问
UYVY
Known as UYVY, Y422 or UYNV.
YUY2
Known as YUY2, YUYV, V422 or YUNV.
YVYU
YVYU is just like YUY2, but with U and V order reversed.
VYUV
TBD.
stride0 = width*2
3.2. 格式汇总:
YUV444 每个Y对应一组UV分量,YUV422每两个Y共用一组UV分量。YUV420每四个Y共用一组UV分量。
SizeImg
444 | 422 | 420 | |
1p | YUV: Stride=Wx3 StridexH | YUYV: Stride=Wx2 StridexH | YYUYYV: Stride=Wx1.5 StridexH |
2p | 不常见 | Y:Stride0=W Stride0xH UV:Stride1=Wx2x0.5 Stride1xH | Y:Stride0=W Stride0xH UV:Stride1=Wx2x0.5 Stride1xHx0.5 |
3p | Stride=w Y:StridexH U:StridexH V:StridexH | Y:Stride=w;StridexH U:Stride=wx0.5; StridexH V:Stride=wx0.5; StridexH | Y:Stride=w;StridexH U:Stride=wx0.5; StridexHx0.5 V:Stride=wx0.5; StridexHx0.5 |
注意stride要4字节或者8字节地址对齐,表格中没做对齐操作(和axi databus位宽相关,这里取四字节):Stride = Stride + (4 - Stride mod 4);
3.3. stride(跨度)参数详解
一行有 11 个像素(Width = 11), 对一个 32 位(每个像素 4 字节)的图像, Stride = 11 * 4 = 44.
但还有个字节对齐的问题, 譬如:
一行有 11 个像素(Width = 11), 对一个 24 位(每个像素 3 字节)的图像, Stride = 11 * 3 + 3 = 36.
为什么不是 Stride = 33? 因为它是按 4 字节对齐的.
属性扩展应用:
裁剪:
osd的驱动中有实际使用case
色度下采样,yuv422转yuv420
dpu硬件只支持显示yuv420,但是加倍stride就能显示yuv422的图片
4. V4L2中的格式定义