对于一张图片,对其进行yuv采样存放会有几种格式,常见的有YUV444 YUV422 YUV420

这些格式的显著的区别就是对每个像素的信息采样方式的不同

比如如下的一张图片,每个格子代表一个像素

P0

P1

P2

P3

P4

P5

P6

P7

P8

P9

P10

P11

P12

P13

P14

P15

yuv444采样方式进行采样:

采样每个像素的y、u、v分量,这样导致内存中占用的空间是 width * height *3 的大小

Y0 U0 V0

Y1 U1 V1

Y2 U2 V2

Y3 U3 V3

Y4 U4 V4

Y5 U5 V5

Y6 U6 V6

Y7 U7 V7

Y8 U8 V8

Y9 U9 V9

Y10 U10 V10

Y11 U11 V11

Y12 U12 V12

Y13 U13 V13

Y14 U14 V14

Y15 U15 V15

如果是YUV422的采样方式:

采样每个像素的y分量,然后每两个像素采样一次u和v分量,于是u和v分量占用的空间大小分别是原来像素数的一半

那么一帧图象被YUV422采样以后占用的总大小就是 width * height * 2

Y0 U0

Y1 V1

Y2 U2

Y3  V3

Y4 U4

Y5 V5

Y6 U6

Y7 V7

Y8 U8

Y9 V9

Y10 U10

Y11 V11

Y12 U12

Y13 V13

Y14 U14

Y15 V15

YUV420的采样方式:

y分量的采样方式与上两种一样,对每个像素进行采样;而u和v分量则变成了每2 * 2个像素取样一次。

比如第一行像素,采样每一个像素的y分量,并每两个像素采样一次u分量,本行不采样v分量。

而下一行像素,采样每一个像素的y分量,并每两个像素采样一次v分量,本行不采样u分量。

于是u和v分量占用的空间大小分别是原来像素数的1/4,占用的总大小就是 width * height * (3 / 2)

Y0 U0

Y1

Y2 U2

Y3

Y4 V4

Y5

Y6 V6

Y7

Y8 U8

Y9

Y10 U10

Y11

Y12 V12

Y13

Y14 V14

Y15

可以看出,对于这三种采样方式,每个像素的亮度信息(y分量)都被完整保存。不同的地方就是对色差信息(uv分量)的取舍。

通过上面三种方式对每个像素进行了信息的采样,接下来要考虑如何存储。

YUV的存储方式也分为打包(packed)格式存储和平面(plane)格式存储两种。

这就导致了和上面三种采样方式组合出了很多种令人痛苦的yuv格式。

我的理解,打包格式是以 像素点 为单位,连续存储每个像素点的yuv分量;

而平面格式是以 分量 为单位,将三个分量分别存储在三个数组中;

特别的,平面格式中还有一种半平面(semi-plane)的储存方式,这种方式的uv分量被交替存储在同一个数组里。

先来回顾一下yuv422采样方式:

Y0 U0

Y1 V1

Y2 U2

Y3  V3

Y4 U4

Y5 V5

Y6 U6

Y7 V7

Y8 U8

Y9 V9

Y10 U10

Y11 V11

Y12 U12

Y13 V13

Y14 U14

Y15 V15

对于YUV422采样,有以下几种常见的存储方式

YUYV格式(packed):

这是一种打包存储YUV422采出数据的方式

Y0

U0

Y1

V1

Y2

U2

Y3

V3

Y4

U4

Y5

V5

Y6

U6

Y7

V7

Y8

U8

Y9

V9

Y10

U10

Y11

V11

Y12

U12

Y13

V13

Y14

U14

Y15

V15

UYVY格式(packed):

与YUYV一样,也是一种打包存储YUV422采出数据的方式,只是分量的顺序不同

U0

Y0

V1

Y1

U2

Y2

V3

Y3

U4

Y4

V5

Y5

U6

Y6

V7

Y7

U8

Y8

V9

Y9

U10

Y10

V11

Y11

U12

Y12

V13

Y13

U14

Y14

V15

Y15

YUV422Pplane)格式

这是针对422采样的平面存储格式

Y0

Y1

Y2

Y3

Y4

Y5

Y6

Y7

Y8

Y9

Y10

Y11

Y12

Y13

Y14

Y15

U0

U2

U4

U6

U8

U10

U12

U14

V1

V3

V5

V7

V9

V11

V13

V15

如上这种先U后V的存储方式又称为YU16,而先V后U的方式就称为YV16

再来回顾一下yuv420采样方式:

Y0 U0

Y1

Y2 U2

Y3

Y4 V4

Y5

Y6 V6

Y7

Y8 U8

Y9

Y10 U10

Y11

Y12 V12

Y13

Y14 V14

Y15

对于420采样的存储格式主要有:

YUV420P格式:

这是针对420采样的平面存储格式

Y0

Y1

Y2

Y3

Y4

Y5

Y6

Y7

Y8

Y9

Y10

Y11

Y12

Y13

Y14

Y15

U0

U2

U8

U10

V4

V6

V12

V14

如上这种先U后V的存储方式又称为YU12,而先V后U就称为YV12

YUV420SP格式:

这是针对420采样的半平面(semi-planer)存储格式

Y0

Y1

Y2

Y3

Y4

Y5

Y6

Y7

Y8

Y9

Y10

Y11

Y12

Y13

Y14

Y15

U0

V4

U2

V6

U8

V12

U10

V14

有了上面比较直观的图片解释,可以来尝试几个简单的图片格式转换

void YUV422toYUV420(unsigned char *yuv420, unsigned char *yuv422, int Y_width, int Y_height)
{int UV_width_422 = Y_width >> 1;   //422采样的U和V信号在行方向是隔一个采样一次int UV_height_422 = Y_height;      //422采样的U和V信号在列方向是全采样的int UV_width_420 = Y_width >> 1;   //420采样的U和V信号在行方向是隔一个采样一次int UV_height_420 = Y_height >> 1; //420采样的U和V信号在列方向是隔一个采样一次int Ylen = Y_width * Y_height;     //有多少像素就有多少个Y分量/* YUV422P的存储方式:YYYYYYYYYYYYYYYYUUUUUUUUVVVVVVVV*/unsigned char *p_Y422 = yuv422 ;unsigned char *p_U422 = p_Y422 + Ylen ;unsigned char *p_V422 = p_U422 + Ylen / 2 ;/* YUV420P的存储方式:YYYYYYYYYYYYYYYYUUUUVVVV*/unsigned char *p_Y420 = yuv420 ;unsigned char *p_U420 = p_Y420 + Ylen ;unsigned char *p_V420 = p_U420 + Ylen / 4;//Y分量都是一样的,直接复制memcpy(p_Y420, p_Y422, Ylen);/* 对于一个4*4的YUV422来说,U分量的采样结果是:* U0  X  U2  X* U4  X  U6  X* U8  X  U10 X* U12 X  U14 X** 而同样大小的YUV420,U分量的采样结果:* U0  X  U2  X* X   X  X   X* U8  X  U10 X* X   X  X   X* * 在plane的存储方式下,这两种采样U分量的存放区别是:* YUV422P:* U0 U2|U4 U6|U8 U10|U12 U14* * YUV420P:* U0 U2|U8 U10* 用|隔开不表示在存储中被隔开,仅表示这是一个UV_width_422宽度*/int k = 0 ;unsigned char u1, u2 , v1, v2 ;for ( int i = 0 ; i < UV_height_422 ; i += 2){for ( int j = 0 ; j < UV_width_422 ; j++){// 取422p相邻行的两个U分量的平均,作为420取样的U分量u1 = *(p_U422 + i * UV_width_422 + j);u2 = *(p_U422 + (i + 1) * UV_width_422 + j);// 取422p相邻行的两个V分量的平均,作为420取样的V分量v1 = *(p_V422 + i * UV_width_422 + j);v2 = *(p_V422 + (i + 1) * UV_width_422 + j);*(p_U420 + k * UV_width_420 + j) = ((u1 + u2) >> 1);*(p_V420 + k * UV_width_420 + j) = ((v1 + v2) >> 1);}k++;}
}

需要注意的是上面的YUV422和YUV420都是plane方式存储的

完整代码可以参考我上传的资源,里面有一个简单的main,in case 你懒得自己写。此外还包括一个验证过可用性的YUV420P转YUV422P 方法,不过好像需求量不大,需要的可以下载或者没积分的话就喊我贴上来:

yuv422和yuv420相互转换-C++文档类资源-CSDN下载

接下来看如何将YUYV转成YUV422P

void YUYVtoYUV422P(unsigned char *yuyv, unsigned char *yuv422p, int width, int height) {int y_len = width * height;int yuyv_len = width * height * 2;unsigned char* y_plane = yuv422p;unsigned char* u_plane = yuv422p + y_len;unsigned char* v_plane = u_plane + y_len / 2;// 用于标记目前待处理的是哪个分量int component = 0;for (int index = 0; index < yuyv_len; index++) {// yuyv的存储方式下,分量存储顺序是:// Y U Y V Y U Y Vif (0 == component || 2 == component) {*y_plane++ = yuyv[index];component++;} else if (1 == component) {*u_plane++ = yuyv[index];component++;} else if (3 == component) {*v_plane++ = yuyv[index];component = 0;}}
}

YUV444、YUV422、YUV420知识存档相关推荐

  1. 音视频编解码: YUV采样格式中的YUV444,YUV422,YUV420理解

    YUV各种采样格式的说明 通常我们用RGB表示一种彩色.计算机系统里的LCD显示的数据就是RGB来表示每个像素的颜色. 而在我们生活里,有黑白电视机与彩色电视机两种,拍摄节目源时不可以用两种不同的摄像 ...

  2. YUV图解 (YUV444, YUV422, YUV420, YV12, NV12, NV21)

    如果你认为本系列文章对你有所帮助,请大家有钱的捧个钱场,点击此处赞助,赞助额1元起步,多少随意 锋影 email:174176320@qq.com YUV图解 (YUV444, YUV422, YUV ...

  3. YUV图解 (YUV444, YUV422, YUV420, YV12, NV12, NV21)-- 转

    YUV图解 (YUV444, YUV422, YUV420, YV12, NV12, NV21)

  4. 图像原始格式(YUV444 YUV422 YUV420)一探究竟

    前段时间搞x264编码测试,传参的时候需要告诉编码器我的原始数据格式是什么,其中在x264.h头文件中定义了如下一堆类型. /* Colorspace type */ #define X264_CSP ...

  5. YUV图解 (YUV444, YUV422, YUV420, YV12, NV12, NV21)

    YUV格式有两大类:planar和packed. 对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V. 对于packed的YUV格式,每个像素点的Y ...

  6. yuv图解(YUV444,YUV422,YUV420,YV12,NV12,NV21)

    参考文章 图解YUV YUV是什么 YUV(444,422,420) And YUV(Packed,Planar,Semi-Planar) 知识点 YUV是用一个称为Y(相当于灰度)的亮度分量和两个色 ...

  7. YUV和RGB的区别(以及YUV444 YUV422 YUV411 YUV420的介绍)

    RGB是构成多种颜色的三基色(红绿蓝),也称为加成色.主要是图像的采集和显示.YUV是优化彩色视频信号的编码和传输,和rgb相比,YUV占用的带宽少. YUV中Y表示的是亮度,是通过RGB输入信号确定 ...

  8. YUV422/YUV420

    YUV三种数据格式占用空间计算: YUV444 ==> YUV444 1920*1080 ==>  1920*1080个Y+1920*1080个U+1920*1080个V = 1920*1 ...

  9. YUV422 YUV420 Planar Semi-Planar详解

    前言 YUV 格式通常有两大类:打包(packed)格式和平面(planar)格式.前者将 YUV 分量存放在同一个数组中, 通常是几个相邻的像素组成一个宏像素(macro-pixel);而后者使用三 ...

  10. YUV422 YUV420 Planar \ Semi-Planar \ Interleaved

    关于yuv 格式 YUV 格式通常有两大类:打包(packed)格式和平面(planar)格式.前者将 YUV 分量存放在同一个数组中, 通常是几个相邻的像素组成一个宏像素(macro-pixel); ...

最新文章

  1. opencv3 图像处理(一)图像缩放( python与c++ 实现)
  2. 数据集超越MS COCO,2020智源x旷视Objects365物体检测挑战赛开赛
  3. spring --AOP
  4. 2019牛客暑期多校训练营(第九场) E All men are brothers
  5. spring restful遇到的问题
  6. Postgresql日志配置
  7. [PAT乙级]1030 完美数列
  8. 打破冷漠僵局文章_研究僵局–第3部分
  9. Linux中搭建YUM
  10. 大学c语言基本程序,一个大学C语言试题的简单实现--员工信息管理程序
  11. file input 移动端选择文件夹_免费 |《MNN For Swift》移动端机器学习实战课程
  12. php成长之路--1.composer下载依赖
  13. 几本很不错的C++Builder的电子书
  14. Windows下QT配置librdkafka
  15. 目标检测-爬虫-利用百度识图的方法来批量的爬取图片生产数据集
  16. 最新爱云发卡系统源码公益版
  17. 解密猫晚直播技术:如何保障全球200多个国家和地区同时在线狂欢?
  18. java excel 导出数据文件格式无效
  19. linux mysql 登录报1045_【mysql】linux登录MySQL_报错ERROR_1045_(28000)解决办法
  20. [Caffe]:关于ReLU、LeakyReLU 、PReLU layer

热门文章

  1. 零基础 Java 学习笔记
  2. 慧荣SM2258XT+B17颗粒,固态硬盘无法格式化已开卡成功,经验分享+量产工具,SM2259XT2类似
  3. springboot毕业设计 基于springboot旅游景区景点购票系统毕业设计设计与实现参考
  4. 全国 下拉框 选项值:35个省级行政区
  5. GEE开发之Landsat8计算MNDWI和数据分析
  6. 最新声音鉴定鉴卡引流神器PHP源码
  7. linux下输入法终极解决方案
  8. 斯坦福大学最新-机器学习导论
  9. php与sap系统,sap系统是什么意思
  10. 【RF】射频集成电路与系统设计