Какой это формат YUV? Неужели ЮВ420СП?

Ниже приведен вывод RGB предполагаемого буфера YUV420SP. Никакого преобразования, я просто показываю YUV420SP, как будто это RGB, просто чтобы увидеть некоторые закономерности.

Изображение находится в одном буфере unsigned char* размером width*height*3. Так что, если это действительно YUV420SP, то у меня должно быть Y как черно-белое изображение, а затем UV с чередованием. Я думаю, что я должен видеть Y как черно-белое изображение, но почему оно повторяется 3 раза в моем изображении? И должен ли я видеть что-нибудь в УФ части?

Конечно, я попытался преобразовать этот буфер в RGB. Я использовал https://github.com/andrechen/yuv2rgb/blob/master/yuv2rgb.h#L70 но я получаю только полностью черное изображение.

введите здесь описание изображения


person Lucas Zanella    schedule 22.02.2020    source источник
comment
Можете ли вы показать свой код, который преобразует буфер в RGB? Какой формат вы выделили RGB экрану? И как вы сбрасываете байты YUV в буфер RGB?   -  person selbie    schedule 22.02.2020
comment
Не могли бы вы опубликовать буфер как изображение в градациях серого (а не как снимок экрана)? Я предполагаю, что размеры оттенков серого должны быть шириной x высота * 1,5.   -  person Rotem    schedule 22.02.2020
comment
По крайней мере опубликуйте ожидаемое разрешение изображения...   -  person Rotem    schedule 22.02.2020
comment
@selbie вот код: github.com/andrechen/yuv2rgb/ blob/master/yuv2rgb.cpp#L111, я предоставлю буфер   -  person Lucas Zanella    schedule 23.02.2020
comment
@LucasZanella - я имел в виду код, в котором вы выгружаете байты YUV непосредственно в средство визуализации. Или, по крайней мере, поделитесь исходным файлом YUV.   -  person selbie    schedule 23.02.2020


Ответы (2)


Формат выглядит как I420 формат (также называемый YV12).

I420 — это формат YUV 4:2:0 с полностью плоским упорядоченным форматом.
В YUV420 цветовой канал Y — это яркость (яркость) каждого пикселя.
U и V — это каналы цветности (цвета).< br> Разрешение 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 из опубликованного вами изображения.

Вот результат:
введите здесь описание изображения


Код 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);
person Rotem    schedule 22.02.2020

Я сделал несколько рендереров YUV раньше.

Буфер YUV 420 должен содержать width*height байт для Y, за которым следуют (width*height)/4) байта для U. И еще (width*height)/4) байта для V. Следовательно, если ваш байтовый буфер 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;
    }
}

Я думаю, что также существует неявное предположение о том, что ширина и высота изображений YUV всегда делятся на 4. Ваш рендерер может рисовать это изображение вверх ногами в зависимости от вашей графической библиотеки и платформы.

person selbie    schedule 22.02.2020