【OPENCV】颜色通道YUV420与RGB的转换

1. YUV420p

这里不详细介绍YUV420, 简单的介绍一下,比如有一个 HxW 大小的图,如果是RGB颜色分量,那么每个通道都是HxW ,对于一个3通道的RGB来说,在传输的时候,所消耗的带宽是HxWx3。为了节省带宽,在视频传输,经常用的颜色通道是YUV420P, 这就意味着每4个Y共享1个U和V,这也相当于HxW 大小的Y通道,H x W x (1/4) 大小的U和 H x W x (1/4) 大小的V。这样即可节省一半的带宽。

假设有一个YUV视频(*.yuv),从yuv视频中读取帧的代码如下:

    fp = open(videofile, 'rb')
    filename = videofile.split('/')[-1][:-4] # for save
    # fp_out = open(savepath+filename+"_out.yuv", 'wb')

    framesize = height * width * 3 // 2  
    h_h = height // 2
    h_w = width // 2
    fp.seek(0, 2)  
    ps = fp.tell() 
    numfrm = ps // framesize  
    fp.seek(0, 0)
    for i in range(numfrm):
        print("%d/ %d"%(i, numfrm))
        Yt = np.zeros(shape=(height, width), dtype='uint8')
        Ut = np.zeros(shape=(h_h, h_w), dtype='uint8')
        Vt = np.zeros(shape=(h_h, h_w), dtype='uint8')

        for m in range(height):
            for n in range(width):
                Yt[m, n] = ord(fp.read(1))
        for m in range(h_h):
            for n in range(h_w):
                Ut[m, n] = ord(fp.read(1))
        for m in range(h_h):
            for n in range(h_w):
                Vt[m, n] = ord(fp.read(1))

        img = np.concatenate((Yt.reshape(-1), Ut.reshape(-1), Vt.reshape(-1))) 
        img = img.reshape((height*3 // 2, width)).astype('uint8') 
        bgr_img = cv2.cvtColor(img, cv2.COLOR_YUV2BGR_I420) 

2. 关于opencv 的 COLOR_YUV2BGR_I420

在查阅opencv的手册 https://docs.opencv.org/3.4/de/d25/imgproc_color_conversions.html

发现:
【OPENCV】颜色通道YUV420与RGB的转换_第1张图片
但是这在YUV420上并不试用,经过实验,在COLOR_YUV2BGR_I420这个通道,用的是量化的转换公式
【OPENCV】颜色通道YUV420与RGB的转换_第2张图片注意,此处尽管YUV的范围是0-255,但是依然按Y去减16去实现
【OPENCV】颜色通道YUV420与RGB的转换_第3张图片

参考链接:
[1] https://docs.opencv.org/3.4/de/d25/imgproc_color_conversions.html
[2] https://www.xuejiayuan.net/blog/648c43f3b53d415eb8061c181119e015
[3] https://github.com/jselbie/yuv420_to_rgb888/blob/master/yuv.py

你可能感兴趣的:(图像处理)