图像格式入门:RAW、RGB、YUV的采样存储与工程转换指南

发布时间:2026/9/17 6:01:12
图像格式入门:RAW、RGB、YUV的采样存储与工程转换指南 做图像相关开发的人迟早会碰到这样一个场景手里同时握着RAW、RGB、YUV三种格式的数据——相机驱动吐出来的是RAW或者YUVOpenCV默认给你摆成BGR显示链路要RGB编码器又要YUV。我第一次调摄像头采集链路的时候就是在这种格式切换里翻车的图像偏绿、颜色串位、暗部发紫查了半天以为是传感器坏了最后才发现是格式理解出了问题。所以这篇就把RAW、RGB、YUV这三种图像格式的采样与存储原理按我从传感器到屏幕再到编码器的完整链路重新梳理一遍。这里不聊太玄的相机理论聚焦在实际开发中最需要搞明白的几个问题三种格式各自解决什么问题、采样时丢了哪些信息、存储时字节怎么摆、转换时坑在哪里。适合刚进入嵌入式视觉、图像算法或视频处理方向的同学阅读那些一直在用cvtColor但没想清楚原理的人也能在这篇文章里找到答案。1. 三种格式的真实分工传感器保存现场、主机交换数据、链路压缩视野很多人一开始都会犯一个错误把RAW、RGB、YUV当成三种等价格式觉得反正都是图像数据转来转去只是换个排列。但它们的定位差异非常大理解这点之后很多工程问题根本不用踩坑。1.1 RAW的本质是没有结论的数据它不定义颜色CMOS传感器上的每个感光单元物理上只能感知光的强度不能感知颜色。为了让图像有色彩传感器表面会覆盖一层彩色滤光片阵列最常见的是Bayer阵列——每四个像素里排两个绿色、一个红色、一个蓝色也就是RGGB或BGGR等变体。于是RAW数据本质上是每个像素只有一个通道的灰度值但这个灰度值带了颜色滤镜的标记。关键就在这里RAW里没有任何色彩结论。它没有白平衡、没有色彩矩阵、没有Gamma校正甚至没有映射到某个具体色域。打个比方RAW是审讯现场的原声录音保留了一切细节但没法直接拿来当判决书RGB才是整理好的文字记录能直接看但已经丢失了部分原始信息。这就是为什么相机的RAW文件打开后往往发灰、发暗不是因为拍坏了而是因为ISP还没做加工。实际工程中RAW最容易被误用的场景是有人直接把它当灰度图丢给深度学习模型或者做直方图统计。如果是做前处理也许问题不大但如果你要做颜色相关的分析或显示必须先把RAW完整走一遍ISP流程否则Bayer阵列的排布规律会让算法结果完全错乱。1.2 RGB是计算机世界的通用语但它的代价是带宽人类视网膜里有三种视锥细胞分别对长波、中波、短波敏感RGB色彩空间正是对这种感知机制的近似建模。显示器上每个像素也由红、绿、蓝三个子像素构成所以RGB对计算机极友好——每个像素三个数值直接对应屏幕点亮方式。但RGB的问题也摆在明面上每个像素需要三个通道数据存储和带宽开销非常大。1080p分辨率、8bit位深、RGB888排列一帧是1920×1080×3字节约6.2MB按60fps算每秒数据量接近373MB。到了4K分辨率直接翻四倍嵌入式设备的内存带宽根本扛不住。另一个容易被忽略的点RGB三个通道之间的相关性很高。一张蓝天照片里相邻像素的R通道都偏低、B通道都偏高这种冗余对压缩很不友好。所以视频编码很少直接在RGB域做而是会先转换到YUV再进入压缩流程。顺带提醒OpenCV里默认的COLOR_BGR2RGB顺序是有历史渊源的Windows BMP和小内存设备喜欢BGR排列网上很多代码报错或者图像颜色错乱往往就是RGB和BGR没有分开。可能只是byte order差一点但整个画面看起来像中毒。1.3 YUV把亮度当干线、色度当支线专门对付人眼YUV的核心思想非常简单人眼对亮度细节的分辨能力远高于对颜色细节的分辨能力。把图像的亮度和色度分开编码亮度通道保留全部细节色度通道能省则省观感上几乎不受影响。严格来说YUV和YCbCr在行业里经常被混用但它们有细微差别。YUV源自模拟电视时代YCbCr是数字域标准化后的定义实际代码里看到的YUV420、NV12通常指的都是YCbCr。Y是亮度LumaCb和Cr是蓝色差、红色差信号本质上是当前颜色减去亮度后的残差。这个设计的历史原因很有画面感当年黑白电视时代为了兼容黑白信号和彩色信号工程师把亮度单独拎出来黑白电视直接收Y彩色电视再叠加Cb、Cr。到今天H.264/H.265内部处理的也都是YUV数据编码器可以单独对亮度通道做高精度变换、对色度通道做降采样压缩效率能提高不少。2. 采样原理拆解从光子到数字每个环节都在做取舍采样是把连续的光信号转成离散数字量的过程。这个过程并不复杂但每个环节都在做信息取舍了解取舍逻辑才知道为什么RAW要那么多位深、为什么YUV可以名正言顺地降采样。2.1 RAW采样Bayer阵列、去马赛克与位深选择CMOS传感器对每个感光单元输出的电压做ADC量化这就是RAW层面的采样。因为是Bayer阵列每个像素只采样了一种颜色这本质上是一种欠采样——每个像素位置少了另外两个颜色通道的信息需要通过去马赛克算法补出来。去马赛克的思路很直接把相邻像素同颜色的值拿来做插值。最简单的双线性插值只看四个邻居效果一般边缘容易发虚、出现伪彩色现代ISP会用边缘导向插值沿边缘方向插值以减少锯齿和彩色纹路。到了计算摄影时代还有基于深度学习的去马赛克算法能进一步提升解析度。RAW的位深选择是我见过很多初学者没想透的地方。普通RGB图8bit足够但传感器输出必须给到10bit、12bit甚至14bit原因在于传感器需要保留更大的动态范围。如果直接量化到8bit暗部的细微层次会被量化噪声吃掉亮部也容易一下过曝。10bit有1024级12bit有4096级14bit有16384级越多的量化级数后期拉亮暗部时越能保留平滑过渡。还有一个坑藏在黑电平Black Level里。传感器在没有光照时由于暗电流等因素ADC输出并不总是零而是一个不为零的偏置比如10bit下输出64。RAW解码的第一步通常是减去黑电平如果忽略这一步整个画面的暗部会发灰、发雾色彩也不准。这个值一般放在RAW文件的元数据里DNG、CR2、NEF等格式都有专门字段记录。2.2 RGB采样三通道量化与色域选择RGB图像的采样是空间上的均匀采样每个像素位置对R、G、B三个通道都做量化没有谁多谁少的问题。每个通道的位深直接决定颜色分级数量8bit每通道就是1670万色10bit每通道能到10.7亿色。但RGB数值相同不代表颜色相同因为还需要色域来约定坐标。sRGB是普通显示器的主流标准Gamma约2.2Adobe RGB覆盖了更多印刷色在专业摄影流程中更常用Display P3是苹果显示器的标准BT.2020则是4K/HDR视频的广色域标准。同一组RGB(255,0,0)在sRGB和P3下是两个不同的红色。做跨设备色彩管理时如果没有做色域映射颜色偏得离谱很正常。采样阶段还有个容易忽略的点是Gamma。人眼对暗部变化更敏感对亮部变化迟钝所以信号传输时往往给暗部分配更多量化级这就是Gamma校正的由来。很多从传感器直接读出的线性数据如果直接按8bit量化显示暗部会明显出现色阶断层。这也是为什么RAW转到RGB时线性域数据通常需要做一次非线性映射。2.3 YUV采样4:4:4、4:2:2、4:2:0到底少了什么YUV采样里最出名的就是4:4:4、4:2:2、4:2:0这三组数字很多视频开发天天见到但不一定每个数字都说得清楚。这套表示法规定的是在一个宽度为4像素的参考块内亮度通道和色度通道的样本数量。4:4:4每4个亮度像素色度也是4个完全不降采样。相当于YUV数据量和RGB一样大但分离了亮色之后对编码更友好。4:2:2每4个亮度像素色度水平方向只采2个垂直方向不降。色度数据减半平均每像素2字节8bit时。4:2:0每4个亮度像素色度水平采2个垂直方向每两行共享一行色度。实际效果就是每个2×2像素块里4个亮度样本共享一个Cb和一个Cr。平均每像素只有1.5字节8bit时。下面这个表可以直观看出三者的数据量和用途差异格式样本数Y:Cb:Cr8bit下平均字节/像素常见用途4:4:44:4:43专业影视制作、色度抠像、字幕合成4:2:24:2:22广电级摄像机、直播导播、视频编辑4:2:04:2:01.5流媒体、蓝光、视频会议、手机录像4:2:0能成为主流不是因为大家懒而是人眼确实分辨不出那么细的颜色差异。同样是黑底白字亮度是绝对的主角但如果是红底黄字边缘处的颜色渗出就比较明显。所以绿幕抠像这类场景必须用4:4:4因为色度信息一旦降采样人物边缘会多出一圈难看的绿边后期抠像极其痛苦。3. 存储形态详解位深、字节排列与文件布局采样决定的是取哪些值存储决定的是这些值怎么摆。同一份YUV数据按I420摆和按NV12摆内存大小相同但数据完全错位读出来就是花屏。这一节把三种格式的存储细节和最容易踩的内存布局问题说清楚。3.1 RAW存储位深、黑电平与DNG元数据RAW文件的数据量取决于像素数和位深。1200万像素、12bit位深理论数据量是1200万×12÷8约18MB但实际相机文件可能更大或更小因为压缩算法和元数据都会影响体积。很多相机出于字节对齐和硬件处理的考虑会把12bit数据放入16bit容器文件就更大了。存储12bit数据时有两种常见做法packed和unpacked。packed是把每个像素的12bit紧挨着排列三个12bit拼成四个字节unpacked则直接给每个像素分配两个字节高位补零。前者省空间但解码麻烦后者省效率但浪费内存。写采集驱动时一定要搞清楚硬件输出的是哪一种否则读出来的数据全是乱的。RAW文件真正值钱的地方不只是图像数据还有元数据。DNG作为通用RAW容器会保存黑电平、CFA Pattern方向、白平衡增益、相机色彩矩阵、ISO和快门等一系列参数。没有这些元数据RAW就是一串失去索引的数字。我自己遇到过解码其他型号相机RAW时忘记读取CFA Pattern结果解出来的图像整个颜色错位看起来像抽象画。CFA Pattern的RGGB、BGGR方向问题解RAW时排第一位。3.2 RGB存储交错排列与字节对齐RGB在内存里的排列方式多种多样最常见的几种RGB888/BGR888每像素3字节按通道顺序交错排列。RGBA8888/BGRA8888每像素4字节多一个Alpha通道便于透明处理和32位对齐。RGB565每像素2字节R占5bit、G占6bit、B占5bit常用于低端LCD屏。遇到RGB565时要特别小心位域顺序。同样是0xFFFF大端和小端读出来可能是白色也可能是别的颜色具体要看屏的规格书。嵌入式LCD驱动里这种坑太多了我见过有人折腾了两天才发现是RGB通道位置和内存字节序不一致。行对齐问题也值得单独说。很多硬件要求每行像素数据按4字节、16字节甚至64字节对齐所以图像行尾会有填充字节。BMP文件每行必须4字节对齐如果图像宽度不是4的倍数实际读文件时必须把填充字节跳过否则画面会有斜向的彩色条纹。这种问题用OpenCV的imread不明显因为库内部处理了但一旦你直接mmap一份BMP到内存自己解析立刻翻车。3.3 YUV存储平面、半平面与strideYUV存储的分支比RGB多很多最容易搞混。按排列方式可以分为平面格式和半平面格式。I420是典型的平面格式内存里先放一整块Y平面尺寸是W×H然后是U平面尺寸是(W/2)×(H/2)最后是V平面同样尺寸。总内存大小是W×H W/2×H/2 W/2×H/2也就是1.5×W×H。YV12只是U和V的顺序反过来不仔细看很容易搞错。NV12是半平面格式内存里先放Y平面然后是一块交错的UV平面——U和V交替排列。NV21把UV顺序反过来也就是VU交替。Android摄像头、多数视频编码器和DMA控制器都喜欢NV12因为UV交错后只需要两条DMA通道就能搬运完数据而且对缓存预取更友好。I420则需要三条通道硬件设计复杂一些。无论哪种格式stride都是绕不开的词。视频硬件经常要求每一行数据按16字节或64字节对齐所以当图像宽度是1920时没有问题但如果你裁剪出一个宽度50的小图每行实际stride很可能是64而不是50。UV平面的起始地址要用stride计算不能用简单的最简单W/2来推。我用ffmpeg和硬件编码器对接时就曾经因为stride没设置对视频画面出现了非常奇怪的重复横条纹调了一下午才发现内存布局问题。还有分辨率奇偶性4:2:0格式要求宽和高都是偶数否则凑不成完整的2×2像素块。一些编码库会自动填充边缘像素但填充部分不能当作真实图像数据否则会出现边缘偏色。4. 实战转换链路RAW→RGB→YUV的流程、坑位与验证前面追了采样和存储原理最终要落回到一行行代码上。这个章节我会把RAW到RGB、RGB到YUV的转换流程完整走一遍重点讲每一步为什么存在以及实际项目中容易忽略的细节。4.1 从RAW到RGB减黑电平、白平衡、颜色矩阵一个都不能少有人觉得RAW转RGB只是解码后直接映射三通道这是最大的误解。真正的RAW-to-RGB流程包含这几个步骤减黑电平把每个像素减去传感器黑电平偏置恢复真实信号零点。白平衡增益由于不同光源色温不同需要给R和B通道乘上增益系数让白色物体在图像里看起来是白的。G通道通常不动或微调。去马赛克根据Bayer排列补出每个像素缺失的两个颜色通道。颜色矩阵把相机传感器的色彩响应矩阵转换到目标色域空间比如sRGB或Adobe RGB。Gamma/色调映射把线性域的亮度压缩到显示设备可接受的范围。每一步都有对应的坑。白平衡增益尤其危险在暖黄路灯下B通道增益可能会非常大本来就接近饱和的高光区域会直接溢出变紫需要做高光恢复处理。颜色矩阵如果把某个负系数处理不当画面会出现明显的色偏甚至变成负值所以在整数实现里要做饱和处理。实际开发中很多人图省事直接用OpenCV的cvtColor处理RAW数据。但cvtColor要求输入是RGB三通道图你硬把单通道Bayer图丢进去它只会当成普通灰度图处理出来的东西当然不对。正确做法是先用专门的demosaic函数或者库处理Bayer数据再进cvtColor流程。4.2 从RGB到YUV矩阵系数与有限/全范围RGB到YUV的转换公式并不复杂核心是把RGB三通道通过线性变换合成一个亮度和两个色差信号。业界有多个标准最常用的是BT.601标清和BT.709高清。BT.601全范围下RGB到YUV的近似公式如下Y 0.299R 0.587G 0.114B Cb -0.1687R - 0.3313G 0.5B 128 Cr 0.5R - 0.4187G - 0.0813B 128BT.709的分量系数略有不同亮度系数变成0.2126、0.7152、0.0722。如果视频是高清内容却用了BT.601矩阵画面会整体偏色肤色尤其明显。另一个容易踩爆的坑是有限范围Limited Range和全范围Full Range。全范围Y取值0~255有限范围Y取值16~235Cb/Cr在16~240之间。电视广播标准习惯用有限范围电脑图形默认全范围。如果编码器输出有限范围的YUV播放器却按全范围解释画面会发灰、失去对比度反过来则会死黑死白。几乎所有视频项目都会遇到这个问题转换时必须明确范围并做对应缩放。顺便说一句很多库内部的YUV转换已经内置了BT.601或BT.709选项但默认参数未必符合你的数据来源一定要手动指定。写代码时别贪图默认值把标准写清楚日后排查问题能省一大半时间。4.3 用Python手工验证一条转换链路理论讲再多不如亲手算一遍。这里我用NumPy自己实现一个BT.601全范围RGB转YUV函数然后跟OpenCV的结果做对比验证。import numpy as np import cv2 def rgb2yuv_bt601_full(rgb): rgb rgb.astype(np.float32) r, g, b rgb[..., 0], rgb[..., 1], rgb[..., 2] y 0.299 * r 0.587 * g 0.114 * b cb -0.1687 * r - 0.3313 * g 0.5 * b 128 cr 0.5 * r - 0.4187 * g - 0.0813 * b 128 return np.dstack([y, cb, cr]) # 构造一张纯红色8x8图 img_rgb np.zeros((8, 8, 3), dtypenp.float32) img_rgb[..., 0] 255 # R通道 yuv_mine rgb2yuv_bt601_full(img_rgb) print(手工计算 YUV[0,0]:, yuv_mine[0, 0]) # OpenCV默认输入是BGR这里把RGB倒过来作为BGR输入 img_bgr img_rgb[..., ::-1].astype(np.uint8) yuv_cv cv2.cvtColor(img_bgr, cv2.COLOR_BGR2YUV) print(OpenCV结果 YUV[0,0]:, yuv_cv[0, 0])纯红色RGB(255,0,0)按BT.601计算Y约等于76.2Cb约等于85Cr约等于255.5溢出后被Clamp到255。你看结果会发现自己的手工实现和OpenCV结果几乎一致这既是公式正确性的佐证也是一种排查手段。如果在自己的工程里发现转换后的图像偏色用这个方法去查目标YUV值很快就能定位是矩阵用错还是范围没对齐。在读取YUV文件验证时也要注意平面格式和半平面格式的读取方式完全不同。I420先读W×H个字节的Y再分别读(W/2)×(H/2)的U和VNV12则是读完Y平面后直接连续读W×H/2字节的交错UV。如果文件是NV12却按I420解析画面会呈现非常明显的彩色噪点。4.4 实际工程中的选型与错误清单各种格式各有适用场景做技术选型时不要只看格式名称好不好听要看整个系统的数据流。下面按常见场景给一份直接可用的建议使用场景推荐格式理由相机拍照、后期调色RAWDNG最大后期空间白平衡可重设屏幕显示、图像处理算法RGB888/RGBA8888直接对应显示像素处理直观视频存储、网络传输YUV420NV12/I420带宽小编码器天然支持绿幕抠像、字幕合成YUV444或RGB避免色度降采样导致的边缘渗色嵌入式实时预览YUV422/NV12平衡带宽与效果硬件友好最后把我在实践中遇到的高频错误整理成清单你可以拿它当排查手册把RAW当灰度图直接处理忽略Bayer排列导致结果错乱。解RAW时忘记减黑电平画面发雾、暗部偏色。CFA Pattern方向读错RGGB和BGGR混淆图像颜色整体错位。RGB通道顺序没确认BGR和RGB混用画面像中毒。4:2:0宽高是奇数没做填充编码器直接报错。按width×height计算行大小没考虑stride对齐画面出现重复条纹。BT.601和BT.709矩阵混用整体偏色。有限范围和全范围对接错误画面发灰或死黑。图像格式这块知识不算深奥但每一个小细节都可能让人折腾很久。我自己是从踩坑里一点点摸清楚的写这篇文章也是希望你在处理RAW、RGB、YUV转换时少走这些弯路。遇到格式问题先不要怀疑硬件坏了拿一组已知颜色数据验证一遍往往几分钟就能定位问题所在。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询