Relationship between YUV and RGB
可以参考维基百科的解释:https://zh.wikipedia.org/wiki/YUV
color depth: https://en.wikipedia.org/wiki/Color_depth
1. YUV格式
1.1 基本概念
YUV 的存储大小:8bit perpixel、10bit perpixel、12bit perpixel、16bit perpixel
不同的bit perpixel(bpp) 表示对应的像素点的占用的内存也不一样。
8 bit 的值 直接用int8 就可以了;
10、12、16bit的值根据情况来确定大小的读取,一般使用int16 来计算;如果不够10Bits,会将16bits的空余的值赋0。
通常,YUV的存储,是先存储Y值的数据,UV根据不同的格式来对应的存储。包含的格式有YCbCr 4:2:0、YCbCr 4:2:2、YCbCr 4:1:1和YCbCr 4:4:4
- 4:4:4表示完全取样。
占用的空间内存为:
s i z e = h e i g h t ∗ w i d t h ∗ 3 size = height * width * 3 size=height∗width∗3 - 4:2:2表示2:1的水平采样,垂直完全采样。
占用的空间内存为:
s i z e = h e i g h t ∗ w i d t h ∗ ( 1 + 1 ) size = height * width * (1+1) size=height∗width∗(1+1) - 4:2:0表示2:1的水平采样,垂直2:1采样。
占用的空间内存为:
s i z e = h e i g h t ∗ w i d t h ∗ ( 1 + 1 / 2 ) size = height * width * (1+ 1/2) size=height∗width∗(1+1/2) - 4:1:1表示4:1的水平采样,垂直完全采样。
占用的空间内存为:
s i z e = h e i g h t ∗ w i d t h ∗ ( 1 + 1 / 2 ) size = height * width * (1+ 1/2) size=height∗width∗(1+1/2)
1.2 YUV420
通常YUV420的存储格式为:
一般情况下,我们先读取Y值,后读取U值,最后读取V值;
YUV420的根式还包括YUV420P(planar 平面)和YUV420SP(semi-planar 半平面)
1.2.1 YUV420P
对于YUV420P,包括I420和YV12格式:
YU12(I420): YYYYYYYY UUVV
也就是先读取Y后读取U最后读取V
YV12: YYYYYYYY VVUU
先读取Y后读取V最后读取V
1.2.2 YUV420SP
YUV420SP格式的图像阵列,是先读取Y值,然后UV或者VU交替存储。NV12和NV21属于YUV420SP格式。是一种两平面的模式。
NV12:先存储Y后,UV交替存储,即YYYYUVUV
NV21:先存储Y后,VU交替存储,即 YYYYVUVU
2. YUV420sp to RGB
# -*- coding: utf-8 -*-
from PIL import Image
import time, shutil, sys
from time import perf_counter
import numpy as np
from matplotlib import pyplot as plt
from skimage import io
path = '10_0.yuv'
def readyuv(path, r, c, bits):
with open(path,'rb') as fp:
if bits == 8:
data_bytes = fp.read(r*c+int(r*c/2))
data_bytes = np.fromstring(data_bytes,'int8')
if bits == 10:
data_bytes = fp.read(2*(r*c+int(r*c/2)))
data_bytes = np.fromstring(data_bytes,'int16')
my = data_bytes[0 : r*c]
mu = data_bytes[r*c:r*c+int(r*c/2):2]
mv = data_bytes[r*c+1: r*c+int(r*c/2):2]
imy = np.reshape(my, (c, r))
imu = np.reshape(mu, (int(c/2), int(r/2)))
imv = np.reshape(mv, (int(c/2), int(r/2)))
if bits == 10:
imy1 = imy1 / 1023 * 255
imy = imy1.astype(int)
imu1 = imu1 / 1023 * 255
imu = imu1.astype(int)
imv1 = imv1 / 1023 * 255
imv = imv1.astype(int)
return imy, imu, imv
data = read_yuv1(path2, 4000, 3000, bits=10)
plt.figure()
plt.imshow(data)
data1 = data.astype(int)
plt.figure()
plt.imshow(data1)
将YUV转化为RGB,范围是[0, 255],需要进行计算
计算公式如下所示: