打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
RGB、YUV420、NV21、I420编码; raw转nv21转RGB代码
userphoto

2023.05.10 辽宁

关注
一、RGB与YUV
首先了解视频编码为什么使用YUV420而不是RGB。RGB 色彩空间更适合图像采集和显示, YUV 空间用于编码和存储则比较好。在存储和编码之前,RGB 图像要转换为 YUV 图像,而 YUV 图像在显示之前通常有必要转换回 RGB。这里显示的时候 YUV 转成 RGB 通常是硬件或者软件内部做了,我们写代码开发的时候YUV转 RGB显示到屏幕这个过程通常是透明的。
看图说话。
所以从内存的角度来说:yuv单位像素使用的内存更低,但是两者表示的效果是一致的;也可以认为rgb过度绘制了,把人眼无法分辨的区域也进行了绘制。下面看一下两者之间内存暂用对比,这里采用RGB24对比:RGB24使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。在一个2*2的像素区域,RGB暂用的字节数为2*2*3=12字节。那么用yuv表示,占用的字节数为4(Y)+1(u)+1(v)=6字节,其中Y占用4个字节,U和V各占用1字节,比例为4:1:1
所以在一个宽高为w*h的设备上,使用rgb表示编码占用的字节数为w*h*3,使用yuv表示暂用的内存为w*h*+w*h/4+w*h/4 = w*h*3/2. 显然可以计算得到此种格式下YUV所占用的数据量是RGB24的二分之一
二、YUV为什么可以
由于我们眼睛的视网膜杆细胞多于视网膜的锥细胞,而视网膜的杆细胞是识别亮度的,锥细胞是识别色度的,所以我们的眼睛对于明暗的分辨要比对颜色的分辨要精细,也就是我们眼睛对于亮度的敏感程度要大于色度的敏感程度。那么,我们在存储图像信息时,为了节约空间,就没有必要将所有的色度信息全部存储下来了。
因此在上色项目中,我们只是在较小尺寸上进行上色任务,然后结合上色小图片的颜色信息(UV)与超分后图片的纹理信息(Y)综合得到最终结果。
视觉心理学研究表明,人的视觉系统对光的感知程度可以用两个属性来描述:亮度(luminance)跟 色度(chrominance)。色度感知 包含两个维度:色调(Hue)和 色饱和度(saturation)。色调是由光波的峰值定义的,描述的是光的颜色。色饱和度是由光波的谱宽定义的,描述的是光的纯度。
因此 HVS 对色彩的感知主要有 3个属性:亮度(luminance),色调(Hue)和 色饱和度(saturation)。也就是 YUV 色彩空间,Y 代表 亮度,U代表色调,V代表色饱和度
三、YUV的不同格式
YUV 相比于 RGB 格式最大的好处是可以做到在保持图像质量降低不明显的前提下,减小文件大小。TUV 格式之所以能够做到,是因为进行了采样操作。
YUV 码流的存储格式与其采样方式密切相关,主流的采样方式有三种:YUV 4:4:4(YUV444),YUV 4:2:2(YUV422),YUV 4:2:0(YUV420)。
YUV 4:4:4 采样,每一个 Y 对应一组 UV 分量。
YUV 4:2:2 采样,每两个 Y 共用一组 UV 分量。
YUV 4:2:0 采样,每四个 Y 共用一组 UV 分量。
对于最常用的YUV420格式与422格式,仍然有不同的区分。
尤其要注意的是nv21虽然是yuv420的一种,但nv21是针对android设备的视频编码。因此一般的从安卓手机中拿到的raw数据都是nv21格式。
nv21编码格式:比如一张3000*4032的图片,经过nv21编码后,会变成前面3000*4032字节全是Y,从3000*4032字节长度开始,U和V会交替排列,uv的字节长度合起来为3000/2*4032。
I420也是YUV420编码格式的一种,由于android手机厂商的原因,摄像头采集到的数据永远都是经过NV21编码的数据,但是对于这种数据不能够显示在苹果或windows平台,那么需要对这个编码格式的数据需要重新编码,其中I420这种编码格式,所有的厂商都是适配的。
四、raw转nv21转RGB代码
def yuv420sp_to_rgb888(width, height, yuv): # function requires both width and height to be multiples of 4 if (width % 4) or (height % 4): raise Exception("width and height must be multiples of 4") rgb_bytes = bytearray(width*height*3) #yuv = np.array(yuv, dtype=np.uint8).reshape(height*3, width) array = np.frombuffer(yuv, dtype=np.uint8).reshape(4500, 4032) print(array.shape) RGBImage = cv2.cvtColor(array, cv2.COLOR_YUV2RGB_NV21) return RGBImagedef raw2jpg(source, dest): print("opening file") f = open(source, "rb") yuv = f.read() f.close() print("read file") img = yuv420sp_to_rgb888(4032, 3000, yuv) print("finished conversion. Creating image object") cv2.imwrite(dest, img) print("Save completed")1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
注意下opencv内部对于nv12等不同格式YUV与RGB转换都是非常到位的,合理使用opencv工具可以起到提升工作效率的效果
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【图像】一张图理清所有的RAW RGB YUV图像格式
图文详解YUV420数据格式
007. MIPI扫盲——CSI-2介绍(四)
博客聚合 - MSDK格式转化篇(九)从RGB24到NV12 : sokerspace.com
入门视频采集与处理(学会分析YUV数据)
常用图像像素格式 NV12、NV2、I420、YV12、YUYV
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服