代码之家  ›  专栏  ›  技术社区  ›  PPP

这是哪种YUV格式?真的吗?

  •  0
  • PPP  · 技术社区  · 6 年前

    下面是假定的YUV420SP缓冲区的te RGB输出。没有转换,我只是显示YUV420SP,就像它是RGB一样,只是想看看一些模式。

    unsigned char* width*height*3

    当然我试着把这个缓冲区转换成RGB。我曾经 https://github.com/andrechen/yuv2rgb/blob/master/yuv2rgb.h#L70 但我只能得到一个完全黑色的图像。

    enter image description here

    0 回复  |  直到 6 年前
        1
  •  1
  •   Rotem    6 年前

    格式如下 I420 format (也称为 伊夫12 ).

    I420是YUV 4:2:0格式,具有全平面有序格式。
    在YUV420中,Y颜色通道是每个像素的亮度。
    U和V是色度(颜色)通道。
    U和V的分辨率在两个轴上都是Y的一半(在每个轴上以0.5的因子进行下采样)。

    I420插图:

    unsigned char* src 是指向帧缓冲区的指针,分辨率为640x480:

    src ->               YYYYYY  
                         YYYYYY  
                         YYYYYY  
                         YYYYYY  
    src + 640*480     -> UUU  
                         UUU  
    src + (320*240)*5 -> VVV  
                         VVV  
    

    我使用MATLAB代码从您发布的图像中恢复RGB图像。

    结果如下:
    enter image description here


    MATLAB代码(仅供参考):

    I = imread('Test.png');
    R = I(:,:,1);G = I(:,:,2);B = I(:,:,3);
    
    T = zeros(size(R,1), size(R,2)*3, 'uint8');
    T(:, 1:3:end) = R;T(:, 2:3:end) = G;T(:, 3:3:end) = B;
    T = T';T = T(:);
    
    Y = T(1:640*480);
    U = T(640*480+1:640*480+640*480/4);
    V = T(640*480+640*480/4+1:640*480+(640*480/4)*2);
    
    Y = (reshape(Y, [640, 480]))';
    U = (reshape(U, [320, 240]))';
    V = (reshape(V, [320, 240]))';
    
    U = imresize(U, 2);
    V = imresize(V, 2);
    YUV = cat(3, Y, U, V);
    RGB = ycbcr2rgb(YUV);
    
        2
  •  1
  •   selbie    6 年前

    我以前做过一些YUV渲染器。

    YUV 420缓冲区应包含 width*height 字节表示Y,后跟 (width*height)/4) (宽*高)/4) 因此,如果您的YUV字节缓冲区应该包含 (width*height*3)/2 字节大小。

    只需在描述时查看灰度模式,就需要将“Y”字节转换为24位RGB,如下所示:

    像这样:

    unsigned char* YUV_BYTES = < some buffer of size (width*height*3)/2 with bytes copied in>
    unsigned char* RGB_BYTES = < some buffer of size width*height*3 >
    
    const unsigned char* dst = RGB_BYTES;
    for (unsigned int r = 0; r < height; r++)
    {
        unsigned int row_offset = r*width;
        for (unsigned int c = 0; c < width; c++)
        {
            *dst[0] = YUV[row_offset + c];  // R
            *dst[1] = YUV[row_offset + c];  // G
            *dst[2] = YUV[row_offset + c];  // B
            dst += 3;
        }
    }