为什么视频系统普遍偏爱 YUV:从采样、存储到编码输入的工程取舍

前言:为什么很多图像系统最后都会绕回 YUV

如果你前面已经接触过:

  • Camera
  • FFmpeg
  • 编码器
  • 播放器
  • OpenCV
  • 硬件编解码

那你大概率已经发现一个现象:

虽然 RGB 看起来最直观,但真正的视频系统里,经常一路绕着绕着,最后还是会回到 YUV。

典型场景包括:

  • Camera 输出 NV12
  • 编码器要求 YUV420
  • FFmpeg 解码后给你 YUV420P
  • 硬件编解码器更喜欢 NV12 / P010 这类格式
  • 显示前往往再转回 RGB / RGBA

于是很多人会困惑:

为什么系统不干脆一直用 RGB?

这个问题如果只从“能不能显示”来看,确实容易觉得 RGB 更顺手。

但如果你从整个视频系统的目标来看,问题就不一样了。

因为视频系统真正长期面对的,不只是“显示出来”,而是:

  • 采样成本
  • 存储成本
  • 带宽压力
  • 压缩效率
  • 硬件兼容
  • 处理链路性能

也就是说,视频系统最终选择哪种数据表示方式,不是看谁最直观,而是看谁最符合整条链路的工程目标。

这篇文章的核心,就是把这件事讲清楚。

重点回答这些问题:

  • 为什么 YUV 比 RGB 更适合视频系统
  • 亮度 / 色度分离到底带来了什么工程价值
  • 为什么 4:2:0 这种降采样在视频里这么常见
  • Camera、编码器、FFmpeg、硬件路径为什么普遍围绕 YUV 设计
  • 为什么显示端常常又要把它转回 RGB

你会发现,这篇看起来像是在讲“格式偏好”,其实讲的是整个视频系统的底层取舍逻辑。


一、先给结论:视频系统偏爱 YUV,不是因为 RGB 不行,而是因为 YUV 更符合视频工程的总体目标

如果让我先给一句最核心的话,我会这样说:

视频系统普遍偏爱 YUV,不是因为 RGB 不能用,而是因为 YUV 在采样、带宽、压缩、存储和硬件实现上,更适合“视频”这件事。

换句话说:

  • RGB 更直观
  • 但 YUV 更工程化

这里的“工程化”,不是抽象词,而是它真的能在这些方面带来收益:

  • 数据量更低
  • 色度可以降采样
  • 更适合编码压缩
  • 更贴近硬件视频链路
  • 更容易沿着 Camera -> 编码 -> 传输 -> 解码 这条主链路流动

所以我们可以先把这件事理解成:

RGB 更像显示友好表示,YUV 更像视频友好表示。


二、先看全局:RGB 和 YUV 在整条链路里的角色为什么不同

先上总图。

flowchart LR
    A[Camera / Sensor / ISP] --> B[YUV/NV12]
    B --> C[编码器 H264/H265]
    C --> D[压缩码流]
    D --> E[解码器]
    E --> F[YUV420P/NV12]
    F --> G[渲染 / 色彩转换]
    G --> H[RGB / RGBA]
    H --> I[显示设备]

这张图有一个特别重要的信息:

YUV 常常活在视频主链路里,而 RGB 更常活在显示末端和某些图像处理链路里。

也就是说:

  • 采集、编码、传输、解码,往往偏 YUV
  • 显示、图形渲染、UI 合成,往往偏 RGB

这个角色分工,不是历史巧合,而是目标差异决定的。


三、为什么 RGB 对人类更直观,但对视频系统不够友好

3.1 RGB 的优点确实很明显

RGB 的优点主要有:

  • 好理解
  • 每个像素就是 R / G / B 三个分量
  • 很适合显示器、图形系统和图像编辑思维
  • 很多算法和图像处理库也支持得很好

从“读图”和“看图”的角度,RGB 几乎是最符合直觉的。

3.2 但视频系统不只是看图

视频系统真正面对的是:

  • 一秒几十帧
  • 每帧可能 720p、1080p、4K
  • 要编码、传输、存储、解码、显示
  • 还要考虑实时性和资源约束

这时候,RGB 的问题就会慢慢暴露出来:

  • 每个像素三个分量都完整保留,数据量大
  • 不方便利用人眼对色彩不敏感的特点降冗余
  • 对编码器来说不如 YUV 友好
  • 走硬件视频链路时经常不是首选格式

所以 RGB 在“显示”这件事上很自然,但在“视频系统整体成本”上,未必最优。


四、YUV 的真正价值,不是换一种表示法,而是把亮度和色度拆开

这是 YUV 真正值得理解的核心。

4.1 YUV 最重要的工程思想

YUV 的关键不在于“它是一种和 RGB 不一样的颜色表示”,而在于:

它把亮度和色度拆开了。

可以粗略理解成:

  • Y:亮度
  • U / V:色度

这件事为什么重要?

因为人眼对亮度变化特别敏感,但对色彩细节没那么敏感。

这意味着系统可以做一件很划算的事:

  • 亮度尽量保住
  • 色度适当减少

一旦接受这个前提,后面整套视频压缩、采样和存储策略就都成立了。

4.2 一张图看懂亮度 / 色度分离的价值

flowchart TD
    A[图像信息] --> B1[亮度信息 Y]
    A --> B2[色度信息 U/V]

    B1 --> C1[人眼更敏感]
    B2 --> C2[人眼相对不敏感]

    C1 --> D1[尽量保留]
    C2 --> D2[允许适度降采样]

    D1 --> E[主观视觉影响较小]
    D2 --> E
    E --> F[数据量降低 / 更利于压缩]

这张图本质上说明:

YUV 的价值,不只是表达颜色,而是让系统有机会更高效地存和传。


五、为什么 4:2:0 会成为视频系统里的常态

如果你已经理解了“亮度更重要,色度可以适当少一点”,那后面的 4:2:0 就不再神秘了。

5.1 4:2:0 的本质

它本质上是在表达:

亮度采样保得更多,色度采样保得更少。

也就是说,在同样的图像区域里:

  • Y 的信息保留得更密
  • U / V 的信息保留得更稀疏

5.2 为什么这很划算

因为这样做通常能同时得到两件事:

  • 数据量明显下降
  • 主观视觉损失不至于太大

这对视频系统简直太重要了。

因为视频从来不是单张图,而是持续帧流。

一旦每帧都能省一点,整秒、整分钟、整小时的存储和传输成本都会被放大地降下来。

5.3 一张结构图看懂 4:4:4 到 4:2:0 的变化

flowchart LR
    A[4:4:4] --> B[亮度完整 + 色度完整]
    C[4:2:2] --> D[亮度完整 + 色度横向减采样]
    E[4:2:0] --> F[亮度完整 + 色度横纵都减采样]

这也是为什么:

  • 图像编辑、专业图像链路可能会更在乎 4:4:4
  • 但大多数视频编码和分发场景,4:2:0 非常常见

因为它在质量和成本之间,通常是一个很实用的平衡点。


六、从存储角度看,YUV 为什么更划算

我们可以用一个很粗的量级感受一下。

假设一张 1920x1080 图像。

6.1 如果按 RGB24 来看

每个像素 3 个字节:

1
1920 × 1080 × 3 ≈ 6 MB

6.2 如果按 YUV420 来看

Y 平面完整,U / V 总量大约是 Y 的一半:

1
1920 × 1080 × 1.5 ≈ 3 MB

也就是说,还没开始真正编码之前,单从像素表示和采样方式上,YUV420 就已经把数据量降到大约 RGB24 的一半。

这件事有多重要?

非常重要。

因为后面所有环节都会受益:

  • buffer 更小
  • 内存带宽压力更低
  • copy 成本更低
  • 编码器输入数据量更少

这就是为什么 YUV 不只是“压缩友好”,它其实从一开始就已经更省。


七、从编码器角度看,为什么 YUV 更自然

视频编码器最喜欢处理的,不是“最直观的数据”,而是“最适合压缩的数据”。

7.1 编码器真正关心什么

编码器真正关心的是:

  • 亮度细节
  • 空间冗余
  • 时间冗余
  • 码率控制
  • 主观质量

而 YUV 的表示方式刚好很契合这个思路。

因为一旦亮度和色度分离,编码器就更容易:

  • 保住亮度主干
  • 对色度做更激进的压缩处理
  • 在主观质量可接受的前提下降低总码率

7.2 一张图看懂编码器为什么喜欢 YUV

flowchart TD
    A[输入图像] --> B[YUV]
    B --> C1[亮度 Y]
    B --> C2[色度 U/V]

    C1 --> D1[保留更多细节]
    C2 --> D2[允许更少采样 / 更高压缩]

    D1 --> E[编码效率与主观质量平衡]
    D2 --> E

这也是为什么很多主流编码器的输入格式,天然就偏向:

  • YUV420P
  • NV12
  • P010

而不是 RGB24。


八、从 Camera 角度看,为什么很多采集链路天然就走 YUV

如果把视角再往前推到 Camera,你会发现这件事更合理。

8.1 Camera 不是只给显示用的

Camera 输出的图像,后面常常要服务很多目标:

  • 预览
  • 录像
  • 推流
  • 拍照
  • AI 分析

如果系统在 Camera 输出阶段就一直坚持 RGB,后面会遇到什么?

  • 数据量更大
  • 编码前还要再转
  • 硬件路径可能不友好
  • 带宽成本更高

所以很多 Camera 系统里,尤其是硬件视频链路,会天然偏向:

  • NV12
  • NV21
  • YUYV
  • 某些 raw 格式再转 YUV

8.2 一张 Camera 链路图看懂 YUV 为什么更顺

flowchart LR
    A[Sensor / ISP] --> B[NV12 / YUV]
    B --> C1[预览]
    B --> C2[编码]
    B --> C3[AI 前处理]
    C2 --> D[H264/H265]

你会发现,YUV 在这里的价值不是“最终显示更好”,而是:

它让主链路更统一。


九、从硬件路径看,为什么 NV12 这种格式特别常见

这也是很多人实际做工程时感受到最强的一点。

9.1 为什么硬件链路喜欢 NV12

因为 NV12 这种格式同时具备几个优点:

  • 属于 YUV420 路线,数据量低
  • 内存布局适合很多硬件模块处理
  • 适合 Camera -> 编码器 -> 解码器 这类链路
  • 被很多 SoC、GPU、硬编硬解模块广泛支持

所以很多时候你在代码里看到 NV12,不是因为它“最好懂”,而是因为:

它是硬件视频链路里的高频公约数。

9.2 一条典型硬件视频链路的时序图

sequenceDiagram
    participant Cam as Camera/ISP
    participant Buf as Buffer
    participant Enc as HW Encoder
    participant Dec as HW Decoder
    participant Disp as Display

    Cam->>Buf: 输出 NV12
    Buf->>Enc: 直接送编码器
    Enc->>Dec: 压缩码流 H264/H265
    Dec->>Buf: 解码后输出 NV12/YUV420
    Buf->>Disp: 渲染前转 RGB/RGBA

这张图最想说明的是:

YUV 常常在链路中间活得很久,直到最后显示前才转成 RGB。


十、为什么显示端又总要把 YUV 转回 RGB

说到这里,很多人会继续问:

既然 YUV 这么好,为什么最后还要转回 RGB?

答案也很简单。

因为显示设备和图形系统最终更擅长处理的,通常还是 RGB / RGBA 这一类表示。

10.1 显示和编码的目标不同

  • 编码 / 存储 / 传输更在乎效率
  • 显示 / 渲染更在乎显示友好和图形接口兼容

所以你会看到一种很常见的模式:

1
2
前面主链路偏 YUV
最后渲染显示前转成 RGB / RGBA

10.2 这不是折腾,而是分工

换句话说:

  • YUV 更适合“传、存、压”
  • RGB 更适合“显、画、合成”

所以很多视频系统最后呈现出来的结构,本质上就是:

中间走 YUV,末端转 RGB。


十一、用代码看一个最常见的现实:编码器为什么常常不爱吃 RGB

先给一个 FFmpeg 里常见的现实片段。

11.1 查看编码器支持的像素格式

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <libavcodec/avcodec.h>
#include <libavutil/pixdesc.h>
#include <stdio.h>

void print_encoder_pix_fmts(const AVCodec *codec) {
if (!codec || !codec->pix_fmts) return;

const enum AVPixelFormat *p = codec->pix_fmts;
while (*p != AV_PIX_FMT_NONE) {
printf("supported pix fmt: %s\n", av_get_pix_fmt_name(*p));
p++;
}
}

你在工程里经常会发现,很多编码器列出来的支持格式,往往是:

  • yuv420p
  • nv12
  • p010

而不是你最直观想到的 RGB24。

这本身就说明:

编码器接口层的偏好,已经在用工程现实告诉你它更喜欢 YUV。


十二、再看一段格式转换代码:为什么 RGB 经常只是“处理中间态”

下面这段很有代表性。

12.1 OpenCV 做图像处理时经常转 BGR

1
2
3
4
5
6
cv::Mat nv12(height * 3 / 2, width, CV_8UC1, nv12_data);
cv::Mat bgr;
cv::cvtColor(nv12, bgr, cv::COLOR_YUV2BGR_NV12);

// 做算法处理
cv::Mat result = bgr.clone();

12.2 处理完又经常要转回去送编码器

1
2
3
4
5
6
7
8
9
10
11
12
struct SwsContext *sws = sws_getContext(
width, height, AV_PIX_FMT_BGR24,
width, height, AV_PIX_FMT_YUV420P,
SWS_BILINEAR, NULL, NULL, NULL);

sws_scale(sws,
(const uint8_t * const *)src->data,
src->linesize,
0,
height,
dst->data,
dst->linesize);

这两段代码背后的现实其实非常典型:

  • 算法 / 图像处理为了方便,常常喜欢 RGB/BGR
  • 但一旦进入视频主链路,往往又要回到 YUV

所以 RGB 在很多视频系统里,更像是:

局部处理友好格式,而不是整条视频主链路的常驻格式。


十三、工程里最常见的几个误区

13.1 误区一:RGB 更高级,所以应该优先用 RGB

不是。

格式选择从来不是“谁高级”,而是谁更适合当前链路目标。

  • 做显示和图像处理,RGB 很自然
  • 做编码和视频主链路,YUV 往往更自然

13.2 误区二:既然最终要显示,前面一直用 RGB 最省事

看起来省事,实际往往不省。

因为前面还有:

  • 编码
  • 传输
  • 存储
  • 硬件模块支持
  • 带宽和 buffer 压力

这些目标会直接把系统拉回 YUV。

13.3 误区三:YUV 只是历史包袱

也不是。

YUV 背后真正站着的是:

  • 视觉感知特性
  • 视频压缩需求
  • 硬件实现成本
  • 大规模系统效率

它不是“旧格式没淘汰掉”,而是它确实解决了视频系统的核心问题。


十四、面试里怎么讲,才能像真的理解过系统取舍

如果面试官问:

为什么视频系统普遍偏爱 YUV?

我建议你按下面这个结构讲。

14.1 先讲本质

YUV 的核心优势不只是换了一种颜色表示方式,而是把亮度和色度拆开了,使得系统可以在尽量保住主观视觉质量的同时,对色度做降采样,降低数据量。

14.2 再讲工程收益

这会直接带来这些收益:

  • 存储成本更低
  • 带宽压力更小
  • 更适合视频编码
  • 更适合 Camera 和硬件视频链路

14.3 最后讲角色分工

所以视频主链路里很多模块都会偏爱 YUV,比如 Camera 输出、编码器输入、硬件编解码器输出;而显示端通常又会把 YUV 转成 RGB,因为显示和渲染更偏向 RGB 体系。

如果你能这么讲,回答会明显比“因为 YUV 压缩率高”更完整。


总结:YUV 不是为了取代 RGB,而是为了让“视频”这件事更现实

回到这篇文章的核心问题:

为什么视频系统普遍偏爱 YUV?

我的理解是:

它不是为了取代 RGB 在所有场景下的价值,而是因为它在视频系统最关心的几个目标上,更符合现实:

  • 它允许亮度和色度分离
  • 它允许色度降采样
  • 它能显著减少数据量
  • 它更适合编码器
  • 它更适合 Camera 到编码器的主链路
  • 它也更适合很多硬件编解码路径

所以视频系统最后形成的典型分工,往往是:

  • 主链路偏 YUV
  • 显示末端偏 RGB

如果你把这个分工理解透了,后面再看:

  • NV12 为什么常见
  • YUV420P 为什么常见
  • Camera 为什么不直接给 RGB
  • 编码器为什么不爱 RGB24
  • 为什么显示前总要做色彩转换

这些问题都会自然很多。

这也是我觉得理解 YUV 最重要的一点:

它不是一种“奇怪的图像格式”,而是整个视频工程世界里最核心的一种妥协与优化结果。


为什么视频系统普遍偏爱 YUV:从采样、存储到编码输入的工程取舍
https://breaker505.github.io/2026/03/16/why-video-systems-prefer-yuv/
作者
爱发呆的鱼
发布于
2026年3月16日
许可协议