yuv转bmp说明

一 YUV起源

RGB是R(red)、G(green)、B(blue)的缩写,但同样是表示图像格式的YUV却不是缩写,而是一种颜色空间的表示方法,颜色空间的表示方法有很多种,常见的有RGB/CMYK/YIQ/YUV/HSI,而YUV是其中一种,可以把颜色空间表示方法看着为不同的坐标系表示方法,YUV中的Y是取自xyz坐标系中的y,而UV则是取自其他坐标系的名称,很多标准都是非常老的东西(半个世纪以上的历史 ),YUV不是凭空产生的,而是结合了多种颜色空间描述方法的特点而构建出来的,名称也是这么产生的,所以以YVU就是一种历史悠久的符号,现在应用也非常广泛。


二 YUV含义

YUV,分为三个分量,Y表示明亮度(Luminance或Luma),也就是灰度值;而U和V表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色,

三 YUV格式

yuv格式包含两个概念:
  • 采样格式
  • 封帧格式
如yuv420sp、yuv420p中的420指的是采样格式,sp与p是封帧格式(封帧这个说法不一定准确,原本用打包格式,但YUV又存在打包格式和平面格式的区别,后面介绍)。这就像h264与avi、mkv、flv等格式的关系,一个是编码格式,一个是封装格式,把数据生产与数据应用分开处理,这是各个领域的通用做法。

1.采样目的

YUV的采样主要是为了减少数据量,如同模拟时代的隔行扫描,在效果降低不太明显的情况下,节省带宽。

U指定蓝色色度分量,V指红色色度分量,由于人的眼睛对视频的亮度更敏感,所以采样的时候减少蓝色和红色分量的采样精度,降低带宽的同时,肉眼也不会感觉到图像质量的明显的变化。

2.采样格式

YUV采样格式包括YUV 4:4:4  YUV 4:2:2 YUV 4:1:1 YUV4:2:0这几种格式,YUV4:2:0应该是视频图像处理最常用的格式,这里就以YUV4:2:0为例简单介绍一下。
4:2:0并不意味着只有Y,Cb而没有Cr分量。它指得是对每行扫描线来说,只有一种色度分量以2:1的抽样率存储。相邻的扫描行存储不同的色度分量, 也就是说,如果一行是4:2:0的话,下一行就是4:0:2,再下一行是4:2:0...以此类推。对每个色度分量来说,水平方向和竖直方向的抽样率都是 2:1,所以可以说色度的抽样率是4:1。对非压缩的8比特量化的视频来说,每个由2x2个2行2列相邻的像素组成的宏像素需要占用6字节内存(亮度4个字节,两个色度各1个字节)。
注意与YUV 4:1:1的区别,yuv420与yuv411的采样率是一样的,但采样方式有一些不同。

3.封帧格式分类

YUV 封帧格式又分为两种类型:打包(packed)格式平面(planar)格式
planar: Planar与 Semi-Planar  使用三个数组分开存放 YUV 三个分量,就像是一个三维平面一样。
这种打包格式比较常用,存储时,YUV分块存放,Planar与 Semi-Planar都存在U前V后与V前U后两种情况,用的较多的还是U前V后的格式。做YUV格式转换时,如果生成的图像轮廓都都正常的,但颜色不正常,一般都是分量对应关系没搞对。
packed : Interleaved(交错)将 YUV 分量存放在同一个数组中,通常是几个相邻的像素组成一个宏像素(macro-pixel)。

4.常见封装格式

  • YUV420 Planar
这种格式UV的顺序也有两种格式,U前V后如下图叫I420,yuv420p就是这种,V前U后叫YV12(Y后紧跟V,1像素12位),YV12格式是常用的CODEC格式。

  • YUV420 Semi-Planar
这个格式的数据量跟YUV420 Planar的一样,但是U、V是交叉存放的。

U前V后叫NV12,也称为YUV420SP,NV12是英特尔定义的视频格式, 它在英特尔硬件平台上是原生态支持。


YUV的封装格式大的分两种类型,但细分的话有非常多种,除上面常见的I420,NV12,还有大量的如IMC1~IMC4,UYUV等,但基本上都很类似,只需要搞清楚YUV的排布顺序,转换起来都没有太大难度。可以参加msdn的文档:

https://msdn.microsoft.com/zh-cn/library/ms867704.aspx (使用 8 位 YUV 格式的视频呈现)


上面的图展示了YUV420图片在文件中的存放方式,1080P的YUV图片,Y在前面,UV跟在后面,总大小为高*宽的1.5倍。了解了打包格式与封装格式后,我们可以根据YUV图片大小来猜测图片的高宽,如我这里有一张YUV图片大小为3,110,400字节,除以1.5为2073600,这个分辨率大概200万左右,200万通常指的是1080P,实际上2073600/1920=1080,由于YUV图片没有控制信息,YUV转换为其他格式时,必须知道高宽、采样方式及打包格式,在做YUV转其他格式工具时,可以根据这一点来猜测YUV的高宽(单帧的YUV图片可以猜测高宽,但多帧的就没法猜),虽然分辨率非常乱,但常见的几种还是占主流。


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是将YUV换为灰度BMP的C++代码示例: ```c++ #include <iostream> #include <fstream> #include <cstdlib> #include <cstring> #include <cmath> using namespace std; int main(int argc, char *argv[]) { if (argc != 4) { cerr << "Usage: " << argv[0] << " input.yuv output.bmp width*height" << endl; return 1; } int width = atoi(argv[3]); int height = atoi(strchr(argv[3], '*') + 1); ifstream fin(argv[1], ios::binary); ofstream fout(argv[2], ios::binary); if (!fin) { cerr << "Failed to open input file: " << argv[1] << endl; return 1; } if (!fout) { cerr << "Failed to open output file: " << argv[2] << endl; return 1; } int y_size = width * height; int uv_size = y_size / 4; unsigned char *yuv = new unsigned char[y_size + uv_size * 2]; unsigned char *rgb = new unsigned char[y_size * 3]; fin.read((char *)yuv, y_size + uv_size * 2); for (int i = 0; i < y_size; i++) { int y = yuv[i]; rgb[i * 3] = rgb[i * 3 + 1] = rgb[i * 3 + 2] = y; } fout << "BM"; int bmp_size = y_size * 3 + height * ((4 - (width * 3) % 4) % 4); fout.write((char *)&bmp_size, 4); fout.write("\0\0\0\0", 4); fout.write("\x36\0\0\0", 4); int header_size = 40; fout.write((char *)&header_size, 4); fout.write((char *)&width, 4); fout.write((char *)&height, 4); short planes = 1; fout.write((char *)&planes, 2); short bpp = 24; fout.write((char *)&bpp, 2); fout.write("\0\0\0\0", 4); fout.write("\0\0\0\0", 4); fout.write("\0\0\0\0", 4); fout.write("\0\0\0\0", 4); fout.write((char *)rgb, y_size * 3); delete[] yuv; delete[] rgb; return 0; } ``` 该代码将YUV数据换为灰度BMP图像。它需要3个参数:输入YUV文件名,输出BMP文件名和图像的宽度和高度(格式为“width*height”)。该代码使用C++编写,可以在Linux和Windows上编译和运行。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值