【问题标题】:How to rotate yuv420 data?如何旋转yuv420数据?
【发布时间】:2012-04-04 12:03:52
【问题描述】:

我需要知道如何将 yuv420p 格式的图像旋转 90 度。将其转换为 rgb、旋转并再次转换为 yuv 的选项是不可行的。即使是算法也会有所帮助。

问候, 阿尼鲁德。

【问题讨论】:

标签: c++ algorithm image-processing yuv


【解决方案1】:

如果图像是 yuv420 平面图像,这就是图像数据的编码方式。 平面的意思是首先是y截面,然后是U截面,然后是V截面。

考虑图片的宽度w,图片的高度h。

  1. 图片总大小为w*h*3/2

  2. Y 部分也称为发光,占 w*h。

  3. Y 部分每 2x2 块有一个 U 像素和一个 V 像素。

  4. 接下来是 U 部分,占据 (w/2)*(h/2) 并放置在距图像开头 w*h 的偏移处。

  5. V 部分紧随其后,占据 (w/2)*(h/2) 并放置在 (w*h)+((w*h)/4) 的偏移处。

为了将图像旋转 90 度,您实际上是将这个 w*h 数组复制到一个 h*w 数组中

如上所述,您只需分别复制上面的 3 个 Y、U、V 块。

  1. 从 Y 部分开始。要复制的第一个像素位于源数组中的 (h-1)*w 处,将其复制到目标数组的 (0,0)。第二个像素在 (h-2)*w 等...

  2. 记住 U 和 V 部分只有 (w/2)*(h/2)

  3. 接下来复制 U 部分。要复制的第一个像素位于 Source Array 中的 (w*h)+(((h/2)-1)*(w/2)) 处,将其复制到 (h*w)+(0,0) 中目标数组。第二个像素位于 (w*h)+(((h/2)-2)*(w/2)) 等...

  4. 最后复制 V 部分。要复制的第一个像素位于 Source Array 中的 ((w*h)+(w*h/4))+(((h/2)-1)*(w/2)) 处,将其复制到 (h目标数组中的 *w)+(w*h/4)+(0,0)。第二个像素在 ((w*h)+(w*h/4))+(((h/2)-2)*(w/2)) 等等...

    李>

这样得到的Destination Array包含旋转90度的图像。

【讨论】:

    【解决方案2】:

    我想它不是planar YUV,如果它已经是它很容易(跳过第一步和最后一步)。你的意思是让 YUV 4:2:0 平面化,但是我不明白你为什么会遇到困难。

    1. 首先将其转换为平面:为平面分配空间并根据您拥有的packed YUV 格式将字节放在正确的位置。
    2. 分别旋转YUV 平面。每个块的“颜色”(UV)信息应保持不变。
    3. 重新组合飞机以重新获得你一开始拥有的权利packed YUV

    如果您的图像尺寸是 4 的倍数,这始终可以正常工作。如果不是,请小心...

    【讨论】:

    • 所以,如果 w * h(假设它是 4 的倍数)是图像的分辨率,我可以将数组的第一个 wh 元素视为 Y 平面,然后将下一个 w i>h/2 为 U,其余为 V?为了实现 90 度旋转,我可以单独转置这些值吗?那确实会使算法变得非常简单!
    • 这是正确的,但 4:2:0 的二次采样 U 平面大小为 wh/4 而不是 wh/2。如果格式不完全匹配,答案中的链接还应该为您提供更多详细信息,这些 YUV 格式有很多!
    • @jdehaan :如何指向 YUV 数据的地址。单个平面的开始和结束指针?
    【解决方案3】:

    我认为 YUV420p 确实是平面的。

    尝试查看 AviSynth 的源代码。 turn(旋转)函数在turn.cpp和turnfunc.cpp

    http://www.avisynth.org/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-27
      • 2019-11-14
      • 2011-06-24
      相关资源
      最近更新 更多