将YUY2转换为YV12

时间:2012-09-12 21:02:29

标签: c++ image-processing yuv

我几乎可以肯定这比我想象的要简单得多,但是我在互联网上搜索的时间比我想要试图找出如何转换这两种格式的费用要长得多。我能够从无符号字节流(unsigned char)中提取Y0,Cb,Y1,Cr数据,但我不知道这些字节是如何在YV12中排列的 - 这个文件是否意味着各种值实际上包含在不同的行中?

我一直在寻找像“c ++转换YUY2到YV12”之类的东西,并且完全没有找到教程或代码示例。我认为这会有一些我可以使用的文档形式,但这个特定主题的信息似乎很少。

2 个答案:

答案 0 :(得分:4)

linked entry on YUY2Wikipedia article on YV12一起看起来非常清楚:

  • YUY2将每两个相邻的水平像素存储为四个字节[Y1, U, Y2, V]

  • YV12将整个 M × N 帧存储在M*N + 2 * (M/2 * N/2)个字节的连续数组中。我们调用数组byte frame[M * N * 3 / 2]。我们有:

      {li> frame[i] i [0, M * N)中的 Y - 像素值。 {li> frame[j] j [M * N, M * N * 5/4)中每个2×2像素图块的 V 值。 {li> frame[j] k [M * N * 5/4, M * N * 6/4)是每个2×2像素磁贴的 U 值。

因此,当您从YUY2转换为YV12时,您必须将 U - 和 V - 数据的数量减半,可能需要取两个相邻行的平均值。

示例:

byte YUY2Source[M * N * 2] = /* source frame */;
byte YV12Dest[M * N * 3/2];

for (unsigned int i = 0; i != M * N; ++i)
{
    YV12Dest[i] = YUY2Source[2 * i];
}

for (unsigned int j = 0; j != M * N / 4; ++j)
{
    YV12Dest[M * N + j]       = ( YUY2Source[N*(j / N/2    ) + 4 * j + 3]
                                + YUY2Source[N*(j / N/2 + 1) + 4 * j + 3] ) / 2;

    YV12Dest[M * N * 5/4 + j] = ( YUY2Source[N*(j / N/2    ) + 4 * j + 1]
                                + YUY2Source[N*(j / N/2 + 1) + 4 * j + 1] ) / 2;
}

答案 1 :(得分:3)

  1. 将Y,U和V值分隔为单独的数组。
  2. 将U和V阵列的偶数行和奇数行的值平均在一起,将两行合并为一行。这会将这些阵列的高度减半。 Y数组为w * h,U和V数组现为w/2 * h/2
  3. 连接Y,V和U阵列。