这是什么YUV格式?真的是YUV420SP吗?
Which YUV format is this? Really YUV420SP?
下面是假定的 YUV420SP 缓冲区的 RGB 输出。没有转换,我只是像显示 RGB 一样显示 YUV420SP,只是为了查看一些模式。
图像位于大小为 width*height*3
的单个 unsigned char*
缓冲区中。所以如果这确实是 YUV420SP,那么我应该将 Y 作为黑白图像,然后进行 UV 交错处理。我想我应该将 Y 视为黑白图像,但为什么它在我的图像中重复了 3 次?我应该在紫外线部分看到什么吗?
当然,我尝试将此缓冲区转换为 RGB。我使用 https://github.com/andrechen/yuv2rgb/blob/master/yuv2rgb.h#L70 但我只得到一个全黑的图像。
之前做过几个YUV渲染器
YUV 420 缓冲区应包含 Y 的 width*height
字节,然后是 U 的 (width*height)/4)
字节。还有另一个 (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 整除。根据您的图形库和平台,您的渲染器可能会颠倒绘制此图像。
格式类似于 I420 format(也称为 YV12)。
I420 是具有完全平面有序格式的 YUV 4:2:0 格式。
在YUV420中,Y颜色通道就是每个像素的Luma(亮度)。
U 和 V 是 Chroma(颜色)通道。
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);
下面是假定的 YUV420SP 缓冲区的 RGB 输出。没有转换,我只是像显示 RGB 一样显示 YUV420SP,只是为了查看一些模式。
图像位于大小为 width*height*3
的单个 unsigned char*
缓冲区中。所以如果这确实是 YUV420SP,那么我应该将 Y 作为黑白图像,然后进行 UV 交错处理。我想我应该将 Y 视为黑白图像,但为什么它在我的图像中重复了 3 次?我应该在紫外线部分看到什么吗?
当然,我尝试将此缓冲区转换为 RGB。我使用 https://github.com/andrechen/yuv2rgb/blob/master/yuv2rgb.h#L70 但我只得到一个全黑的图像。
之前做过几个YUV渲染器
YUV 420 缓冲区应包含 Y 的 width*height
字节,然后是 U 的 (width*height)/4)
字节。还有另一个 (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 整除。根据您的图形库和平台,您的渲染器可能会颠倒绘制此图像。
格式类似于 I420 format(也称为 YV12)。
I420 是具有完全平面有序格式的 YUV 4:2:0 格式。
在YUV420中,Y颜色通道就是每个像素的Luma(亮度)。
U 和 V 是 Chroma(颜色)通道。
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);