以下是假定的YUV420SP缓冲区的RGB输出。没有转换,我只是在显示YUV420SP就像是RGB一样,只是为了看到一些图案。
[图像位于大小为unsigned char*
的单个width*height*3
缓冲区中。因此,如果确实是YUV420SP,则应该将Y作为黑白图像,然后将UV插入。我认为应该将Y视为黑白图像,但是为什么它在我的图像中重复3次?我应该在紫外线部分看到什么吗?
当然,我尝试将该缓冲区转换为RGB。我使用了https://github.com/andrechen/yuv2rgb/blob/master/yuv2rgb.h#L70,但只得到了全黑的图像。
格式看起来像I420 format(也称为YV12)。
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图像。
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);
我之前做过一些YUV渲染器。
[YUV 420缓冲区应包含Y的width*height
个字节,然后是U的(width*height)/4)
个字节,而V包含另一个(width*height)/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; } }
我认为,YUV图像的宽度和高度始终可以被4整除,这是一个隐含的假设。根据您的图形库和平台,渲染器可能会颠倒绘制此图像。