海思3559万能平台搭建:YUV格式简介

简介: YUV格式简介

前言

 想要搭建万能的适配平台,万里长征的第二步是YUV格式里颜色空间等的转化,只有了解熟悉了这一格式和修改方法才能自己根据需要做出调整不是

定义

 YUV模型是根据一个亮度(Y分量)和两个色度(UV分量)来定义颜色空间,细分常见的格式有很多,在存储方式部分展开细细说明。比如我们在海思平台下使用相机默认图像格式是NV21或者叫YUV420SP格式

 YUV 的原理是把亮度(Luma)与色度(Chroma)分离。

 “Y”表示亮度,也就是灰度值。

 “U”表示蓝色通道与亮度的差值。

 “V”表示红色通道与亮度的差值。

 其中 Y 信号分量除了表示亮度信号外,还含有较多的绿色通道量,单纯的 Y 分量可以显示出完整的黑白图像。

 U、V 分量分别表示蓝 (blue)、红 (red) 分量信号,只含有色度信息,所以 YUV 也称为 YCbCr,其中,Cb、Cr的含义等同于U、V,C 可以理解为 component 或者 color。

 并且,YUV不像RGB那样要求三个独立的视频信号同时传输,所以用YUV方式传送占用极少的频宽。

存储格式

 主要有两大类格式,packed和planer(后面会讲衍生的夹在中间的形式)

 packed就是说比如有对应每个像素Y0U0V0 Y1U1V1 Y2U2V2 Y3U3V3,先连续存储所有像素点的 Y,紧接着存储所有像素点的 U,随后是所有像素点的 V。相当于将 YUV 拆分成三个平面 (plane) 存储。

 planer就是Y0Y1Y2Y3 U0U1U2U3 V0V1V2V3,每个像素点的 Y,U,V 是连续交替存储的

 看起来好像和RGB换汤不换药啊。别急别急,听后面慢慢分析~

RGB相互转化

 谈到rgb顺便补充下和RGB的转换公式吧,

4aa94600bb614f29bb8ef5d809bba158.png

ba394bdd4cc34004b2f8341f5d20d881.png

 体现在代码上也可以是

Y      =  (0.257 * R) + (0.504 * G) + (0.098 * B) + 16
Cr = V =  (0.439 * R) - (0.368 * G) - (0.071 * B) + 128
Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128
B = 1.164(Y - 16) + 2.018(U - 128)
G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)
R = 1.164(Y - 16) + 1.596(V - 128)

 很明显,单单一张图片都有不小的浮点运算量的,还好海思平台有现成的硬件加速可以实现,不需要我们一个个像素硬转。

 在RGB色彩空间中,三个颜色的重要程度相同,所以需要使用相同的分辨率进行存储,最多使用RGB565这样的形式减少量化的精度,但数据量还是很大的。

 因为研究发现人眼对亮度的敏感超过色度。将图像的亮度信息和颜色信息分离,并使用不同的分辨率进行存储,这样在对主观感觉影响很小的前提下,可以更加有效地存储图像数据

YUV的取值范围

 与RGB每个像素点的每个分量取值范围为0-255不同(每个分量占8bit),YUV取值范围有两种:

 1. 以Rec.601为代表(还包括BT.709 / BT.2020)的广播电视标准中,Y的取值范围是16-235,U、V的取值范围是16-240。FFmpeg中称之为“mpeg”范围。

 2. 以JPEG为代表的标准中,Y、U、V的取值范围都是0-255。FFmpeg中称之为“jpeg” 范围。

实际中最常见的是第1种取值范围的YUV(可以自己观察一下YUV的数据,会发现其中亮度分量没有取值为0、255这样的数值)。很多人在这个地方会有疑惑,为什么会去掉“两边”的取值呢?

原因:

 • 在广播电视系统中不传输很低和很高的数值,实际上是为了防止信号变动造成过载,因而把这“两边”的数值作为“保护带”。

YUV的采样格式

 主要的采样格式有YUV4:4:4、YUV4:2:2、YUV4:2:0 ,其中YUV4:2:0是最常用的采样格式。

 采样就是根据一定的间隔取值。其中的比例是指 Y、U、V 表示的像素,三者分别占的比值。

 下图是YUV4:4:4,YUV4:2:2,YUV4:2:0的采样示意图,以黑点表示采样该像素点的Y分量,以空心圆圈表示采用该像素点的UV分量。0f61dbd64d10407c8dfdc98a2414e134.png

 • YUV 4:4:4采样,每一个Y对应一组UV分量。

 • YUV 4:2:2采样,每两个Y共用一组UV分量。

 • YUV 4:2:0采样,每四个Y共用一组UV分量。

YUV存储方式

 看到这里,就会发现到yuv的一个精髓了,开始从存储方式上与RGB渐行渐远

 下面用图的形式给出常见的YUV数据的存储方式,并在后面附有取样每个像素点的YUV数据的方法。开始根据YUV的数量进行排列组合吧!

(1) YUYV 格式 (属于YUV422)

7f9b0f179827c2d782c192a1f676333.png

相邻的两个Y共用其相邻的两个Cb、Cr,对于像素点Y’00、Y’01 而言,其Cb、Cr的值均为 Cb00、Cr00,其他的像素点的YUV取值依次类推。

(2) UYVY 格式 (属于YUV422)

b93d735fd62b3d38f9c597f2635c28b.png

 与YUYV不同的是UV的排列顺序不一样,还原其每个像素点的YUV值的方法与上面一样。

(3) YUV422P(属于YUV422)

9e67293cbecf4ab499a3cc299437d5cf.png

 YUV422P是一种平面模式,其每一个像素点的YUV值提取方法也是遵循YUV422格式的最基本提取方法,即两个Y共用一个UV。比如,对于像素点Y’00、Y’01 而言,其Cb、Cr的值均为 Cb00、Cr00。

(4) YUV420P格式(YVU420P)(属于YUV420)

25adb98ada5946efb4e10a349561531c.png

 YUV420P,Y,U,V三个分量都是平面格式,分为YU12(安卓平台下也通常叫I420)和YV12。I420格式和YV12格式的不同处在U平面和V平面的位置不同。注意,上图中,Y’00、Y’01、Y’10、Y’11共用Cr00、Cb00,其他依次类推。在I420格式中,U平面紧跟在Y平面之后,然后才是V平面(即:YUV);但YV12则是相反(即:YVU)。其实,只要注意从适当的位置提取U和V值,YU12和YV12都可以使用相同的算法进行处理。

23f3c2396bc34f91a8fbf4581b812f1e.png

I420: YYYYYYYY UU VV

dc35b88e32774bda8add91452927ac2e.png

YV12: YYYYYYYY VV UU

d51674d787034d85b6bcd7863fecba2a.png

 很明显,YV12和I420并没有很大区别,换了UV顺序罢了I420也叫YU12,,IYUV

(5) YUV420sp 分为NV12、NV21(YVU420SP),也属于YUV420。

bc6be54fc7e44fe28d353f9c3ad87af0.png

 这两种格式的不同在于UV交错排列的顺序不同,是一种two-plane模式,即Y和UV分为两个Plane,但是UV(CbCr)为交错存储,而不是分为三个plane。其提取方式与上一种类似,即Y’00、Y’01、Y’10、Y’11共用Cr00、Cb00,其他依次类推。

 假设一个分辨率为8X4的YUV图像,它们的格式如下图:

 YUV420sp格式如下图

8090aa3191b14c81b72f08b1d0cdc7ab.png

NV12: YYYYYYYY UVUV

5f7f9270b5414bad82a5da0785152f07.png

NV21: YYYYYYYY VUVU

57c7b6e0edfc4ba3823f086223802549.png

 同样的,NV12和NV21也是交换了uv的顺序而已

大小计算

 以w*h大小图像的YUV420数据为例,

 其存储格式是: 共大小为(w * h * 3/2)字节,

 Y分量:(w * h)个字节

 U(Cb)分量:(w * h/4)个字节

 V(Cr)分量:(w * h/4)个字节

特殊情况

 考虑到海思为了硬件加速采用的对齐机制,实际的数据可能是这样的,如果我们想进行更改切记考虑到padding的问题(最开始的分辨率选的刚刚好踩坑,下篇会提到)

f9a19e59c23a486a9f984e3844cbeef4.png

相关文章
|
5月前
|
Ubuntu Linux vr&ar
IM跨平台技术学习(十二):万字长文详解QQ Linux端实时音视频背后的跨平台实践
本文详细记录了新版QQ音视频通话在 Linux 平台适配开发过程中的技术方案与实现细节,希望能帮助大家理解在 Linux 平台从 0 到 1 实现音视频通话能力的过程。
192 2
|
3月前
|
XML Java Android开发
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
GSYVideoPlayer是一款国产移动端视频播放器,支持弹幕、滤镜、广告等功能,采用IJKPlayer、Media3(EXOPlayer)、MediaPlayer及AliPlayer多种内核。截至2024年8月,其GitHub星标数达2万。集成时需使用新版Android Studio,并按特定步骤配置依赖与权限。提供了NormalGSYVideoPlayer、GSYADVideoPlayer及ListGSYVideoPlayer三种控件,支持HLS、RTMP等多种直播链接。
119 18
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
|
3月前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
EasyPusher是一款国产RTSP直播录制推流客户端工具,支持Windows、Linux、Android及iOS等系统。尽管其GitHub仓库(安卓版:https://github.com/EasyDarwin/EasyPusher-Android)已多年未更新,但通过一系列改造,如升级SDK版本、迁移到AndroidX、指定本地NDK版本及更新Gradle版本等,仍可在最新Android Studio上运行。以下是针对Android Studio Dolphin版本的具体改造步骤。
66 3
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
|
7月前
|
存储 编解码 算法
【软件设计师备考 专题 】媒体系统基础知识,多媒体设备的性能特性,常用多媒体文件格式
【软件设计师备考 专题 】媒体系统基础知识,多媒体设备的性能特性,常用多媒体文件格式
153 0
|
7月前
|
编解码 Linux 5G
FFmpeg开发笔记(二十)Linux环境给FFmpeg集成AVS3解码器
AVS3,中国制定的第三代音视频标准,是首个针对8K和5G的视频编码标准,相比AVS2和HEVC性能提升约30%。uavs3d是AVS3的解码器,支持8K/60P实时解码,且在各平台有优秀表现。要为FFmpeg集成AVS3解码器libuavs3d,需从GitHub下载最新源码,解压后配置、编译和安装。之后,重新配置FFmpeg,启用libuavs3d并编译安装,通过`ffmpeg -version`确认成功集成。
136 0
FFmpeg开发笔记(二十)Linux环境给FFmpeg集成AVS3解码器
|
编解码 监控 开发工具
DirectShow捕获+mencoder+ffmpeg+sox 打造小巧的音视频制作、加工软件
DirectShow捕获+mencoder+ffmpeg+sox 打造小巧的音视频制作、加工软件
100 0
DirectShow捕获+mencoder+ffmpeg+sox 打造小巧的音视频制作、加工软件
|
编解码 人工智能 Linux
OpenHarmony 标准系统 HDF 框架音视频驱动开发
OpenHarmony 标准系统 HDF 框架音视频驱动开发
694 0
OpenHarmony 标准系统 HDF 框架音视频驱动开发
|
传感器 编解码 NoSQL
|
存储 编解码 算法