多媒体基础知识之YUV数据
1.什么是YUV格式
YUV,是一种颜色编码方法。Y表示明亮度(Luminance、Luma),也就是灰度值。U和V则是色度、浓度(Chrominance、Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。与我们熟知的RGB类似,YUV也是一种颜色编码方法,主要用于电视系统以及模拟视频领域,它将亮度信息(Y)与色彩信息(UV)分离,没有UV信息一样可以显示完整的图像,只不过是黑白的,这样的设计很好地解决了彩色电视机与黑白电视的兼容问题。并且,YUV不像RGB那样要求三个独立的视频信号同时传输,所以用YUV方式传送占用极少的频宽。
与RGB格式相比,RGB格式用红绿蓝三个颜色分量来表示一个像素,YUV则是用一个亮度分量(Y)加两个色度分量来表示一个像素。YUV也经常被称为YCbCr,Cb为蓝色色度分量,对应U;Cr为红色色度分量,对应V。
2.YUV格式采样方式
YUV采样方式主要描述像素Y、U、V分量采样比例,即表达每个像素时,Y、U、V分量的数目,通常有三种方式:YUV4:4:4,YUV4:2:2,YUV4:2:0。
用三个图直观地表示采集的方式,以黑点表示采样该像点的Y分量,以空心圆圈表示采用该像素点的UV分量。
YUV4:4:4采样,每一个Y对应一组UV分量;YUV4:2:2采样,每两个Y共用一组UV分量;YUV4:2:0采样,每四个Y共用一组UV分量。
4:4:4表示没有色度通道的压缩采样。
4:2:2表示2:1水平压缩采样,无垂直压缩采样。
4:2:0表示2:1水平压缩采样,2:1垂直压缩采样。
3.YUV格式的存储方式
YUV存储格式,主要描述像素的Y、U、V分量排列方式,分为两种格式:紧缩格式和平面格式。
紧缩格式(packed formats):将Y、U、V值储存成Macro Pixels阵列,和RGB的存放方式类似。每个像素点的Y,U,V是连续交差存储的。
这种YUV经常用在网络摄像机里,且大多是4:2:2的也就是只有在水平方向下采样。例如
UYVYUYVYUYVYUYVYUYVYUYVYUYVYUYVY
平面格式(planar formats):将Y、U、V的三个分量分别存放在不同的矩阵中。先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。
planar的YUV是比较合适视频编码的一种格式。像下面这样的4x4的图像
YYYYYYYYYYYYYYYY UUUU VVVV
这个例子所示的YUV常被称为YUV420P,其水平和竖直方向上均为每两个亮度分量才有一个色度分量,也就是每四个Y才需要一个U和V。除这种水平和竖直方向的色度分量都下采样的4:2:0,还有只有水平方向下采样的4:2:2格式,以及没有下采样的4:4:4格式。
上面的例子是按Y、U、V(YCbCr)的顺序存储的,如果改为Y、V、U(YCrCb),则称为YV12格式。
Semi-planar格式
这是Planar和Packed两种格式的混合体:Y分量单独一个plane,U和V则交叉存储。这种YUV一般都是4:2:0的。例如:
YYYYYYYYYYYYYYYY UVUVUVUV
这个示例称为NV12格式。如果交换UV的顺序,就成了NV21格式。NV21是Android系统中摄像头预览图片的默认格式。
下面我用图的形式给出常见的YUV码流的存储方式,并在存储方式后面附有取样每个像素点的YUV数据的方法,其中,Cb、Cr的含义等同于U、V。
(1) YUYV 格式 (属于YUV422 Packed format)
Byte Order. Each cell is one byte.
start + 0: | Y’00 | Cb00 | Y’01 | Cr00 | Y’02 | Cb01 | Y’03 | Cr01 |
start + 8: | Y’10 | Cb10 | Y’11 | Cr10 | Y’12 | Cb11 | Y’13 | Cr11 |
start + 16: | Y’20 | Cb20 | Y’21 | Cr20 | Y’22 | Cb21 | Y’23 | Cr21 |
start + 24: | Y’30 | Cb30 | Y’31 | Cr30 | Y’32 | Cb31 | Y’33 | Cr31 |
Color Sample Location
0 | 1 | 2 | 3 | ||||
0 | Y | C | Y | Y | C | Y | |
1 | Y | C | Y | Y | C | Y | |
2 | Y | C | Y | Y | C | Y | |
3 | Y | C | Y | Y | C | Y |
Packed format with ½ horizontal chroma resolution, also known as YUV 4:2:2
1/2水平色度分辨率采样的打包格式,也被称为YUV 4:2:2
In this format each four bytes is two pixels. Each four bytes is two Y’s, a Cb and a Cr. Each Y goes to one of the pixels, and the Cb and Cr belong to both pixels. As you can see, the Cr and Cb components have half the horizontal resolution of the Y component. V4L2_PIX_FMT_YUYV is known in the Windows environment as YUY2.
在这种格式中,每4个字节是两个像素,每4个字节上有两个Y分量,一个U和一个V分量。没个像素都有一个Y分量,两个像素共用一个U和一个V分量。
U和V分量在水平方向上的采样只有Y的一半,V4L2_PIX_FMT_YUYV在Windows环境中被称为YUY2。
(YUYV为YUV422采样的存储格式中的一种,相邻的两个Y共用其相邻的两个Cb、Cr,分析,对于像素点Y'00、Y'01 而言,其Cb、Cr的值均为 Cb00、Cr00,其他的像素点的YUV取值依次类推。)
(2) UYVY 格式 (属于YUV422 Packed format)
Byte Order. Each cell is one byte.
start + 0: | Cb00 | Y’00 | Cr00 | Y’01 | Cb01 | Y’02 | Cr01 | Y’03 |
start + 8: | Cb10 | Y’10 | Cr10 | Y’11 | Cb11 | Y’12 | Cr11 | Y’13 |
start + 16: | Cb20 | Y’20 | Cr20 | Y’21 | Cb21 | Y’22 | Cr21 | Y’23 |
start + 24: | Cb30 | Y’30 | Cr30 | Y’31 | Cb31 | Y’32 | Cr31 | Y’33 |
Color Sample Location
0 | 1 | 2 | 3 | |||
0 | Y | C | Y | Y | C | Y |
1 | Y | C | Y | Y | C | Y |
2 | Y | C | Y | Y | C | Y |
3 | Y | C | Y | Y | C | Y |
Variation of V4L2_PIX_FMT_YUYV with different order of samples in memory
UYVY格式也是YUV422采样的存储格式中的一种,只不过与YUYV不同的是UV的排列顺序不一样而已,还原其每个像素点的YUV值的方法与上面一样。
(3) YUV422P(属于YUV422 Planar format)
Byte Order. Each cell is one byte.
start + 0: | Y’00 | Y’01 | Y’02 | Y’03 |
start + 4: | Y’10 | Y’11 | Y’12 | Y’13 |
start + 8: | Y’20 | Y’21 | Y’22 | Y’23 |
start + 12: | Y’30 | Y’31 | Y’32 | Y’33 |
start + 16: | Cb00 | Cb01 | ||
start + 18: | Cb10 | Cb11 | ||
start + 20: | Cb20 | Cb21 | ||
start + 22: | Cb30 | Cb31 | ||
start + 24: | Cr00 | Cr01 | ||
start + 26: | Cr10 | Cr11 | ||
start + 28: | Cr20 | Cr21 | ||
start + 30: | Cr30 | Cr31 |
Color Sample Location
0 | 1 | 2 | 3 | |||
0 | Y | C | Y | Y | C | Y |
1 | Y | C | Y | Y | C | Y |
2 | Y | C | Y | Y | C | Y |
3 | Y | C | Y | Y | C | Y |
Format with ½ horizontal chroma resolution, also known as YUV 4:2:2. Planar layout as opposed to V4L2_PIX_FMT_YUYV
1/2水平色度分辨率采样,也称为YUV 4:2:2。 和V4L2_PIX_FMT_YUYV不同的是,它是平面布局的
This is a planar version of the YUYV format. The three components are separated into three sub-images or planes. The Y plane is first. The Y plane has one byte per pixel. The Cb plane immediately follows the Y plane in memory. The Cb plane is half the width of the Y plane (and of the image). Each Cb belongs to two pixels. For example, Cb0 belongs to Y’00, Y’01. Following the Cb plane is the Cr plane, just like the Cb plane.
这是YUYV格式的平面版本。 三个分量被分成三个子图像或平面,分别存放在三个不同的矩阵中。 首先存放Y分量。 每一个像素都有一个Y分量。 Cb分量紧跟着Y分量存储。 Cb分量是Y分量的宽度的一半。 每个Cb分量属于两个像素。 例如,Cb0属于Y'00,Y'01。 Cb分量之后是Cr分量,它和Cb分量一样。
(YUV422P也属于YUV422的一种,它是一种Planar模式,即平面模式,并不是将YUV数据交错存储,而是先存放所有的Y分量,然后存储所有的U(Cb)分量,最后存储所有的V(Cr)分量,如上图所示。其每一个像素点的YUV值提取方法也是遵循YUV422格式的最基本提取方法,即两个Y共用一个UV。比如,对于像素点Y'00、Y'01 而言,其Cb、Cr的值均为 Cb00、Cr00)
(4)YV12,YU12格式(属于YUV420 planar format)
Byte Order. Each cell is one byte.
start + 0: | Y’00 | Y’01 | Y’02 | Y’03 |
start + 4: | Y’10 | Y’11 | Y’12 | Y’13 |
start + 8: | Y’20 | Y’21 | Y’22 | Y’23 |
start + 12: | Y’30 | Y’31 | Y’32 | Y’33 |
start + 16: | Cr00 | Cr01 | ||
start + 18: | Cr10 | Cr11 | ||
start + 20: | Cb00 | Cb01 | ||
start + 22: | Cb10 | Cb11 |
Color Sample Location
0 | 1 | 2 | 3 | ||||
0 | Y | Y | Y | Y | |||
C | C | ||||||
1 | Y | Y | Y | Y | |||
2 | Y | Y | Y | Y | |||
C | C | ||||||
3 | Y | Y | Y | Y |
V4L2_PIX_FMT_YUV420 Planar formats with ½ horizontal and vertical chroma resolution, also known as YUV 4:2:0
V4L2_PIX_FMT_YUV420是1/2水平和垂直色度分辨率采样的平面格式,也称为YUV 4:2:0
V4L2_PIX_FMT_YVU420 (‘YV12’) and V4L2_PIX_FMT_YUV420 (‘YU12’) are planar formats, as opposed to a packed format. The three components are separated into three sub- images or planes. The Y plane is first. The Y plane has one byte per pixel. For V4L2_PIX_FMT_YVU420, the Cr plane immediately follows the Y plane in memory. The Cr plane is half the width and half the height of the Y plane (and of the image). Each Cr belongs to four pixels, a two-by-two square of the image. For example, Cr0 belongs to Y’00, Y’01, Y’10, and Y’11. Following the Cr plane is the Cb plane, just like the Cr plane. V4L2_PIX_FMT_YUV420 is the same except the Cb plane comes first, then the Cr plane.
V4L2_PIX_FMT_YVU420 (‘YV12’) 和 V4L2_PIX_FMT_YUV420 (‘YU12’),是planar模式, 三个分量被分成三个子图像或平面,分别存放在三个不同的矩阵中。首先存放Y分量。 每一个像素都有一个Y分量,对于V4L2_PIX_FMT_YVU420格式,Cr分量紧跟着Y分量存储Cr分量的长度和宽度各是Y分量的一半,每个Cr分量属于4个像素(一个2x2的图像)例如,Cr0属于Y'00,Y'01,Y'10和Y'11。 Cr分量之后是Cb分量,它和Cr分量一样。V4L2_PIX_FMT_YUV420和V4L2_PIX_FMT_YVU420是相同的,只是在存储方式上Cb分量在前,然后是Cr分量。
(YU12和YV12属于YUV420格式,也是一种Planar模式,将Y、U、V分量分别打包,依次存储。其每一个像素点的YUV数据提取遵循YUV420格式的提取方式,即4个Y分量共用一组UV。注意,上图中,Y'00、Y'01、Y'10、Y'11共用Cr00、Cb00,其他依次类推。)
(5)NV12、NV21(属于YUV420)
Byte Order. Each cell is one byte.
start + 0: | Y’00 | Y’01 | Y’02 | Y’03 |
start + 4: | Y’10 | Y’11 | Y’12 | Y’13 |
start + 8: | Y’20 | Y’21 | Y’22 | Y’23 |
start + 12: | Y’30 | Y’31 | Y’32 | Y’33 |
start + 16: | Cb00 | Cr00 | Cb01 | Cr01 |
start + 20: | Cb10 | Cr10 | Cb11 | Cr11 |
Color Sample Location
0 | 1 | 2 | 3 | |||
0 | Y | Y | Y | Y | ||
C | C | |||||
1 | Y | Y | Y | Y | ||
2 | Y | Y | Y | Y | ||
C | C | |||||
3 | Y | Y | Y | Y |
V4L2_PIX_FMT_NV21 Formats with ½ horizontal and vertical chroma resolution, also known as YUV 4:2:0. One luminance and one chrominance plane with alternating chroma samples as opposed to V4L2_PIX_FMT_YVU420
V4L2_PIX_FMT_NV21是是1/2水平和垂直色度分辨率采样的平面格式,也称为YUV 4:2:0。与V4L2_PIX_FMT_YVU420不同的是,它具有交替的色度采样(即Y和UV分为两个Plane,但是UV(CbCr)为交错存储,而不是分为三个plane)
V4L2_PIX_FMT_NV12 (‘NV12’) and V4L2_PIX_FMT_NV21 (‘NV21’) are two-plane versions of the YUV 4:2:0 format. The three components are separated into two sub-images or planes. The Y plane is first. The Y plane has one byte per pixel. For V4L2_PIX_FMT_NV12, a combined CbCr plane immediately follows the Y plane in memory. The CbCr plane is the same width, in bytes, as the Y plane (and of the image), but is half as tall in pixels. Each CbCr pair belongs to four pixels. For example, Cb0/Cr0 belongs to Y’00, Y’01, Y’10, Y’11. V4L2_PIX_FMT_NV21 is the same except the Cb and Cr bytes are swapped, the CrCb plane starts with a Cr byte.
V4L2_PIX_FMT_NV12('NV12')和V4L2_PIX_FMT_NV21('NV21')是 YUV 4:2:0 的 two-plane 版, 三个分量分成两个子图像或平面。首先存放Y分量。 每一个像素都有一个Y分量 ,对于V4L2_PIX_FMT_NV12格式,组合的CbCr分量紧跟着Y分量存储。 CbCr分量与Y分量宽度相同(以字节为单位),但是像素的高度是Y分量的一半。 每个CbCr对都属于四个像素。 例如,Cb0 / Cr0属于Y'00,Y'01,Y'10,Y'11。 除了Cb和Cr字节被交换之外,V4L2_PIX_FMT_NV21是相同的,CrCb分量以Cr字节开头。
(NV12和NV21属于YUV420格式,是一种two-plane(Semi-planar)模式,即Y和UV分为两个Plane,但是UV(CbCr)为交错存储,而不是分为三个plane。其提取方式与上一种类似,即Y'00、Y'01、Y'10、Y'11共用Cr00、Cb00)
4.YUV格式转换
4.1.YUV分量转换为NV12
void convertYUVpitchtoNV12(unsigned char *yuv_luma, unsigned char *yuv_cb, unsigned char *yuv_cr,
unsigned char *nv12_luma, unsigned char *nv12_chroma,
int width, int height, int srcStride, int dstStride)
{
int y;
int x;
if (srcStride == )
srcStride = width;
if (dstStride == )
dstStride = width; //内存地址中,前width * height 存Y分量
//之后的width * height * 1/2 交叉着存U和V分量 //拷贝Y分量
for (y = ; y < height; y++)
{
//第一次拷贝nv12_lume基地址,即第一行
//第二次拷贝第二行 。。。。
memcpy(nv12_luma + (dstStride*y), yuv_luma + (srcStride*y), width);
}
//拷贝UV分量
for (y = ; y < height / ; y++)
{
//每次步进两个位置
for (x = ; x < width; x = x + )
{
//UV分量是交叉存的
//nv12_chroma[0]存yuv_cb[0],nv12_chroma[1]存yuv_cr[0]
//nv12_chroma[2]存yuv_cb[1],nv12_chroma[3]存yuv_cr[1]
// ....
nv12_chroma[(y*dstStride) + x] = yuv_cb[((srcStride / )*y) + (x >> )];
nv12_chroma[(y*dstStride) + (x + )] = yuv_cr[((srcStride / )*y) + (x >> )];
}
}
}
4.2.YUY2转换为I420
#define uint8_t BYTE
void YUY2toI420(int inWidth, int inHeight, uint8_t *pSrc, uint8_t *pDest)
{
int i, j;
//首先对I420的数据整体布局指定
uint8_t *u = pDest + (inWidth * inHeight);
uint8_t *v = u + (inWidth * inHeight) / ; for (i = ; i < inHeight/; i++)
{
/*采取的策略是:在外层循环里面,取两个相邻的行*/
uint8_t *src_l1 = pSrc + inWidth***i;//因为4:2:2的原因,所以占用内存,相当一个像素占2个字节,2个像素合成4个字节
uint8_t *src_l2 = src_l1 + inWidth*;//YUY2的偶数行下一行
uint8_t *y_l1 = pDest + inWidth**i;//偶数行
uint8_t *y_l2 = y_l1 + inWidth;//偶数行的下一行
for (j = ; j < inWidth/; j++)//内层循环
{
// two pels in one go//一次合成两个像素
//偶数行,取完整像素;Y,U,V;偶数行的下一行,只取Y
*y_l1++ = src_l1[];//Y
*u++ = src_l1[];//U
*y_l1++ = src_l1[];//Y
*v++ = src_l1[];//V
//这里只有取Y
*y_l2++ = src_l2[];
*y_l2++ = src_l2[];
//YUY2,4个像素为一组
src_l1 += ;
src_l2 += ;
}
}
}
参考:
https://linuxtv.org/downloads/v4l-dvb-apis-new/uapi/v4l/yuv-formats.html
http://wenzongliang.iteye.com/blog/1902608
多媒体基础知识之YUV数据的更多相关文章
- 多媒体基础知识之PCM数据《 转》
多媒体基础知识之PCM数据 1.什么是PCM音频数据 PCM(Pulse Code Modulation)也被称为脉冲编码调制.PCM音频数据是未经压缩的音频采样数据裸流,它是由模拟信号经过采样.量化 ...
- 多媒体基础知识之PCM数据
1.什么是PCM音频数据 PCM(Pulse Code Modulation)也被称为脉冲编码调制.PCM音频数据是未经压缩的音频采样数据裸流,它是由模拟信号经过采样.量化.编码转换成的标准的数字音频 ...
- Python基础知识(六)------小数据池,集合,深浅拷贝
Python基础知识(六)------小数据池,集合,深浅拷贝 一丶小数据池 什么是小数据池: 小数据池就是python中一种提高效率的方式,固定数据类型使用同一个内存地址 代码块 : 一个文 ...
- 图像基础知识之YUV
一.YUV常用格式 YUV是编译true-color颜色空间(color space)的种类,Y'UV, YUV, YCbCr,YPbPr等专有名词都可以称为YUV,彼此有重叠.“Y”表示明亮度(L ...
- Oracle优化器基础知识之访问数据的方法
目录 一.访问数据的方法 1.直接访问数据 2.访问索引 一.访问数据的方法 Oracle访问表中数据的方法有两种,一种是直接表中访问数据,另外一种是先访问索引,如果索引数据不符合目标SQL,就回表, ...
- python基础知识四 小数据池,深浅拷贝,集合+菜中菜
四.小数据池,深浅拷贝,集合+菜中菜 1小数据池 --缓存机制(驻留机制) '==' 判断两边内容是否相等 'is' 基于内存地址进行判断是否相同 a = 10 b = 10 print(a ...
- 音视频处理基础知识扫盲:数字视频YUV像素表示法以及视频帧和编解码概念介绍
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一. ...
- SQL server基础知识(表操作、数据约束、多表链接查询)
SQL server基础知识 一.基础知识 (1).存储结构:数据库->表->数据 (2).管理数据库 增加:create database 数据库名称 删除:drop database ...
- [SQL]SQL Server数据表的基础知识与增查删改
SQL Server数据表的基础知识与增查删改 由张晨辉(学生) 于19天 前发表 | 阅读94次 一.常用数据类型 .整型:bigint.int.smallint.tinyint .小数:decim ...
随机推荐
- 用createinstallmedia创建可恢复的OSX安装DMG
准备 从App Store下载OS X安装程序,下载完成,会在应用程序目录 /Applications 下找到类似 Install OS X 10.xxxxxx.app(中文名如:安装 OS X 10 ...
- 20165210 Java第三次实验报告
20165210 实验二 敏捷开发与XP实践 一.敏捷开发与XP实践-1 实验要求: http://www.cnblogs.com/rocedu/p/4795776.html, Eclipse的内容替 ...
- UVA 11988 Broken Keyboard (a.k.a. Beiju Text) (链表,模拟)
使用list来模拟就行了,如果熟悉list,那么这道题真是分分钟秒掉... list是双向循环链表,插入和删除操作非常快,缺点是不能像数组一样随机按下标读取. 一下是wiki上说明的相关函数:http ...
- k-means算法的优缺点以及改进
大家接触的第一个聚类方法,十有八九都是K-means聚类啦.该算法十分容易理解,也很容易实现.其实几乎所有的机器学习和数据挖掘算法都有其优点和缺点.那么K-means的缺点是什么呢? 总结为下: (1 ...
- 分析 PHP升级导致系统负载过高问题(转载)
原文:http://chuansongme.com/n/797172 背景 据XX部门兄弟反应, 其在将PHP从5.3.8 升级到5.5.13 时, 开始运行正常, 运行一段时间后, 系统负载变高,达 ...
- Android 关于后台杀死App之后改变服务器状态的一些尝试
前言: 如题,我的需求是:我需要在App在后台运行(未退出),调出最近运行记录,杀死App服务时,程序能够向服务器发送一条指令,以此达到我想要的目的. Android方面刚刚才开始玩,我一开始想的是可 ...
- 使用open_read_write等底层函数来赋值一个文件
/* * 该程序是练习read(),write(),open(),create(),close(),lseek()等函数. * * 该程序的处理思路: * 1: 在程序所在的目录去打开一个文件,如 ...
- 康托展开与逆康托展开模板(O(n^2)/O(nlogn))
O(n2)方法: namespace Cantor { ; int fac[N]; void init() { fac[]=; ; i<N; ++i)fac[i]=fac[i-]*i; } in ...
- python_广州房价热力图
调用百度地图api,获取经纬度数据,然后在调用百度地图api,生成热力图 import pandas as pd import numpy as np data = pd.read_excel(r'D ...
- LeetCode Maximum Length of Pair Chain
原题链接在这里:https://leetcode.com/problems/maximum-length-of-pair-chain/description/ 题目: You are given n ...