YUV & RGB

RGB

RGB 相对比较简单。顾名思义,它就是指图像的每一个像素都有 R、G、B 三个值。RGB是我们平常遇到最多的一种图像颜色空间,比如摄像头采集的原始图像就是 RGB 图像,且显示器显示的图像也是 RGB 图像。

一般来说,我们的 RGB 图像,每一个像素都是分别存储 R、G、B 三个值,且三个值依次排列存储。比如对于一张 8bit 位深的 RGB 图,每个值占用一个字节。但是,需要注意的是 RGB 图像像素中 R、G、B 三个值并不一定是按 R、G、B 顺序排列的,也有可能是 B、G、R 顺序排列。

比如 OpenCV 就经常使用 BGR 的排列方式来存储图像。所以在存储和读取 RGB 图像的时候需要稍微注意一下。RGB 和 BGR 的存储方式如下图所示:

一般来说,我们的 RGB 图像,每一个像素都是分别存储 R、G、B 三个值,且三个值依次排列存储。比如对于一张 8bit 位深的 RGB 图,每个值占用一个字节。但是,需要注意的是 RGB 图像像素中 R、G、B 三个值并不一定是按 R、G、B 顺序排列的,也有可能是 B、G、R 顺序排列。

比如 OpenCV 就经常使用 BGR 的排列方式来存储图像。所以在存储和读取 RGB 图像的时候需要稍微注意一下。RGB 和 BGR 的存储方式如下图所示:

在这里插入图片描述
虽然 RGB 比较简单,同时在图像处理的时候也经常会用到。但是在视频领域,我们更多地是使用 YUV 颜色空间来表示图像的。这是因为 R、G、B 三个颜色是有相关性的,所以不太方便做图像压缩编码。那 YUV 究竟是怎么表示图像的呢?它又是如何存储在内存当中的呢?我们接下来就来揭开它的“面纱”。

YUV

YUV 跟 RGB 类似,也是一种颜色空间,但其种类会更多更复杂些,所以接下来我们会花大量的篇幅去讲解它。

YUV 最早主要是用于电视系统与模拟视频领域。现在视频领域基本都是使用 YUV 颜色空间。

跟 RGB 图像中 R、G、B 三个通道都跟色彩信息相关这种特点不同,YUV 图像将亮度信息Y 与色彩信息 U、V 分离开来。Y 表示亮度,是图像的总体轮廓,称之为 Y 分量。U、V表示色度,主要描绘图像的色彩等信息,分别称为 U 分量和 V 分量。这样一张图像如果没有了色度信息 U、V,只剩下亮度 Y,则依旧是一张图像,只不过是一张黑白图像。这种特点有什么好处呢?

在以前,世界上只有黑白电视机,每一帧电视画面都是黑白的,没有色彩信息。当然黑白电视机也不支持显示彩色图像。后来随着技术的发展,出现了彩色电视机,每一帧画面都是有颜色信息的,那当然我们可以使用 RGB、YUV 等颜色空间来表示一帧图像。

但是考虑到兼容老的黑白电视机,如果使用 RGB 表示图像,那么黑白电视机就没办法播放。这是因为 R、G、B 三个通道都是彩色的,而 Y、U、V 就可以。因为黑白电视机可以使用 Y 分量,Y 分量就是黑白图像,而且包含了图像的总体轮廓信息,只是没有色彩信息而已。

好了,讲了 YUV 的起源之后,我们来讲讲 YUV 颜色空间最重要的知识点,那就是 YUV的类型和存储方式。

YUV 主要分为 YUV 4:4:4、YUV 4:2:2、YUV 4:2:0 这几种常用的类型。其中最常用的又是 YUV 4:2:0。这三种类型的 YUV 主要的区别就是 U、V 分量像素点的个数和采集方式。

YUV 4:4:4 就是每一个 Y 就对应一个 U 和一个 V;而 YUV 4:2:2 则是每两个 Y 共用一个U、一个 V;YUV 4:2:0 则是每四个 Y 共用一个 U、V。我们可以通过图片来清晰地看一下三种 YUV 类型的区别。具体如下图所示:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总的来说:

  1. YUV 4:4:4,每一个 Y 对应一组 UV。
  2. YUV 4:2:2,每两个 Y 共用一组 UV。
  3. YUV 4:2:0,每四个 Y 共用一组 UV。

YUV 4:4:4 这种类型非常简单,所以存储的方式也非常简单。

那 YUV 4:2:2 和 YUV 4:2:0 这种共用 U、V 分量的情况,应该在内存中怎么存储呢?下面我就来为你介绍一下。

YUV 存储方式主要分为两大类:Planar 和 Packed 两种。Planar 格式的 YUV 是先连续存储所有像素点的 Y,然后接着存储所有像素点的 U,之后再存储所有像素点的 V,也可以是先连续存储所有像素点的 Y,然后接着存储所有像素点的 V,之后再存储所有像素点的 U。Packed 格式的 YUV 是先存储完所有像素的 Y,然后 U、V 连续的交错存储。

下面我们就来看看每一种 YUV 类型的存储方式是怎么样的。

  1. YUV 4:4:4
    这种类型的 YUV 非常简单,因为每一个 Y 对应一个 U、一个 V,所以存储的方式也非常简单。例如,4 x 2 像素的 YUV 4:4:4 存储图如下图所示:
    在这里插入图片描述
    可以看到,YUV 4:4:4 和 RGB 图像存储之后的大小是一样的。如果是 8bit 图像,就是每一个像素点需要占用 3 个字节。

  2. YUV 4:2:2
    这种类型的 YUV 稍微复杂些,每左右两个像素的 Y 共用一个 U 和一个 V。存储方式主要有以下4种类型。

YU16(或者称为 I422、YUV422P)
该类型是 Planar 格式,先存储完 Y,再存储 U,之后存储 V。例如,4 x 2 像素的 YU16存储图如下图所示:

在这里插入图片描述
YV16(YUV422P)
该类型也是 Planar 格式,先存储完 Y,再存储 V,之后存储 U。例如,4 x 2 像素的 YV16存储图如下图所示:
在这里插入图片描述
NV16(YUV422SP)
这种类型是 Packed 格式,先存储完 Y,之后 U、V 连续交错存储。例如,4 x 2 像素的NV16 存储图如下图所示:

在这里插入图片描述
NV61(YUV422SP)
这种也是 Packed 格式,与 NV16 不同,这种格式是先存储完 Y,之后 V、U 连续交错存储。例如,4 x 2 像素的 NV61 存储图如下图所示:
在这里插入图片描述
可以看到,4 x 2 像素的 YUV 4:2:2 只需要 16 个字节,而 RGB 图像则需要 24 个字节。也就是说,如果是 8bit 图像,那么 RGB 每一个像素需要 3 个字节,而 YUV 4:2:2 只需要 2 个字节。

  1. YUV 4:2:0
    这是最常见也是最常用的 YUV 类型。通常视频压缩都是 YUV 4:2:0 格式的。它是每上、下、左、右 4 个像素点共用一个 U 和一个 V。存储方式主要分为以下4种。

YU12(I420、YUV420P)
这种类型是 Planar 格式,先存储完 Y,再存储 U,之后存储 V。例如,4 x 4 像素的YU12 存储图如下图所示:

在这里插入图片描述
YV12(YUV420P)
该类型也是 Planar 格式,先存储完 Y,再存储 V,之后存储 U。例如,4 x 4 像素的 YV12 存储图如下图所示:
在这里插入图片描述
NV12(YUV420SP)
这种类型是 Packed 格式,先存储完 Y,之后 U、V 连续交错存储。例如,4 x 4 像素的NV12 存储图如下图所示:

在这里插入图片描述
NV21(YUV420SP)

这种也是 Packed 格式,与 NV12 不同,这种格式是先存储完 Y,之后 V、U 连续交错存储。例如,4 x 4 像素的 NV21 存储图如下图所示:

可以看到,4 x 4 像素的 YUV 4:2:0 只需要 24 个字节相比 RGB 图像需要 48 个字节,存储的大小少了一半。也就是说,如果是 8bit 图像,RGB 每一个像素需要 3 个字节。而YUV 4:2:0 只需要 1.5 个字节。

以上就是 YUV 颜色空间的主要类型和存储方式。这里我用表格给你总结了一下。

在这里插入图片描述
RGB 和 YUV 之间的转换

我们刚才说到,一般来说,采集到的原始图像、给显示器渲染的最终图像都是 RGB 图像,但是视频编码一般用的是 YUV 图像。那么这中间一定少不了两者的相互转换。那 RGB 如何转到 YUV 呢?YUV 又如何转到 RGB 呢?

在讲转换之前,我们先了解 Color Range 这个东西。对于一个 8bit 的 RGB 图像,它的每一个 R、G、B 分量的取值按理说就是 0~255 的。但是真的是这样的吗?其实不是的。这里就涉及到 Color Range 这个概念。Color Range 分为两种,一种是 Full Range,一种是 Limited Range。Full Range 的 R、G、B 取值范围都是 0~255。而 Limited Range的 R、G、B 取值范围是 16~235。

了解了 Color Range 之后,我们怎么规范 YUV 和 RGB 之间的互转呢?其实这也是有标准的,目前的标准主要是 BT601 和 BT709(其实还有 BT2020,我们这里不展开讲)。简单来讲,BT709 和 BT601 定义了一个 RGB 和 YUV 互转的标准规范。只有我们都按照标准来做事,那么不同厂家生产出来的产品才能对接上。BT601 是标清的标准,而 BT709 是高清的标准。

下面我们来看看这两种标准分别在 Full Range 和 Limited Range 下的 RGB 和 YUV 之间的转换公式吧。

在做 RGB往 YUV 转换的时候我们需要知道是使用的哪个标准的哪种 Range 做的转换,并告知对方。这样对方使用同样的标准和 Range 才可以正确的将 YUV 转换到 RGB。

如果是系统采集出来给到用户的图像就是 YUV 的话,你也需要获取这个 YUV 的存储格式、转换标准和 Color Range。这样才能保证正确地处理 YUV 和 RGB 之间的转换。

在处理 YUV 图像的存储和读取的时候,也是有 Stride 这个概念的。事实上,YUV 出问题的情况更多。在这里举一个例子,比如说一张 1283x720 的图像,一个 Y 分量存储按 16字节对齐的话应该是每行占用 1296 个字节,所以每读取一行像素的 Y 应该是 1296 个字节,具体如下图所示。千万不要认为是 1283 个字节,不然就会出现“花屏”。这里一定要注意。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Learning together

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值