Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing 将YUV4:4:4转换为YUV4:2:2图像_Image Processing_Yuv - Fatal编程技术网

Image processing 将YUV4:4:4转换为YUV4:2:2图像

Image processing 将YUV4:4:4转换为YUV4:2:2图像,image-processing,yuv,Image Processing,Yuv,互联网上有很多关于YUV4:4:4到YUV4:2:2格式之间差异的信息,但是,我找不到任何关于如何将YUV4:4:4转换为YUV4:2:2的信息。由于这种转换是使用软件执行的,所以我希望应该有一些开发人员已经完成了转换,并且可以向我介绍描述转换算法的源代码。当然,拥有软件代码会很好,但是拥有理论知识就足以编写我自己的软件了。具体来说,我想知道像素结构以及在转换期间如何管理字节 我发现了几个类似的问题,如和,但是,无法回答我的问题。另外,我在上发布了这个问题,他们认为这是一个软件问题。你找不到具体

互联网上有很多关于YUV4:4:4到YUV4:2:2格式之间差异的信息,但是,我找不到任何关于如何将YUV4:4:4转换为YUV4:2:2的信息。由于这种转换是使用软件执行的,所以我希望应该有一些开发人员已经完成了转换,并且可以向我介绍描述转换算法的源代码。当然,拥有软件代码会很好,但是拥有理论知识就足以编写我自己的软件了。具体来说,我想知道像素结构以及在转换期间如何管理字节


我发现了几个类似的问题,如和,但是,无法回答我的问题。另外,我在上发布了这个问题,他们认为这是一个软件问题。

你找不到具体描述的原因是有很多方法可以做到。
让我们从维基百科开始:

4:4:4:
三个Y'CbCr分量中的每一个都具有相同的采样率,因此没有色度子采样。该方案有时用于高端电影扫描仪和电影后期制作

4:2:2:
两个色度分量的采样率为luma的一半:水平色度分辨率减半。这会将未压缩视频信号的带宽减少三分之一,而视觉差异很小甚至没有

注:术语YCbCr和YUV可互换使用。

Y′CbCr经常与YUV颜色空间混淆,通常术语YCbCr和YUV互换使用,导致一些混淆;当提及视频或数字形式的信号时,“YUV”一词主要指“Y′CbCr”

数据内存排序:
还有不止一种格式。
英特尔文档定义了两大类:“像素级图像格式”和“平面图像格式”。
这里有一个很好的文档:
请参阅此处:了解YUV像素排列格式。
请参阅此处:了解下采样说明

让我们假设“像素顺序”格式:

YUV 4:4:4 data order: Y0 U0 V0  Y1 U1 V1  Y2 U2 V2  Y3 U3 V3  
YUV 4:2:2 data order: Y0  U0    Y1  V0    Y2  U1    Y3  V1  
每个元素都是一个字节,Y0是内存中较低的字节。
上述4:2:2数据顺序命名为UYVY或像素格式

转换算法:

  • “原始次抽样”:
    每秒“抛出”一次
    U
    /
    V
    组件:
    U0
    ,抛出
    U1
    ,取
    V0
    抛出
    V1

    来源:
    Y0
    U0
    V0
    Y1
    U1
    V1
    Y2
    U2
    V2

    目的地:
    Y0
    U0
    Y1
    V0
    Y2
    U2
    Y3
    V2

    我不能推荐它,因为它会导致伪影

  • 平均每个
    U
    /
    V
    对:
    取目的地
    U0
    等于源
    (U0+U1)/2
    ,与
    V0
    相同。…
    来源:
    Y0
    U0
    V0
    Y1
    U1
    V1
    Y2
    U2
    V2

    目的地:
    Y0
    (U0+U1)/2
    Y1
    (V0+V1)/2
    Y2
    (U2+U3)/2
    Y3
    (V2+V3)/2

  • 对下采样U和V使用其他插值方法(例如立方插值)。
    通常,与简单平均值相比,您将看不到任何差异


  • C实现:

    这个问题没有标记为C,但我认为下面的C实现可能会有所帮助。
    以下代码通过平均每个U/V对,将像素顺序的YUV 4:4:4转换为像素顺序的YUV 4:2:2:

    //将单行I0从像素顺序的YUV 4:4:4转换为像素顺序的YUV 4:2:2。
    //将结果保存在J0中。
    //I0大小(以字节为单位)是图像宽度*3
    //J0大小(字节)是图像宽度*2
    静态void convertRowYUV444到YUV422(常量无符号字符I0[],
    const int图像宽度,
    无符号字符J0[]
    {
    int x;
    //每次迭代处理两个Y、U、V三元组:
    对于(x=0;x>1;//目标U元素等于两个源U元素的平均值。
    无符号int v01=(v0+v1+1)>>1;//目标U元素等于两个源U元素的平均值。
    J0[x*2]=y0;//存储Y元素(未修改)。
    J0[x*2+1]=(无符号字符)u01;//存储目标U元素(并将uint32转换为uint8)。
    J0[x*2+2]=y1;//存储Y元素(未修改)。
    J0[x*2+3]=(无符号字符)v01;//存储目标V元素(并将uint32转换为uint8)。
    }
    }
    //将图像I从像素顺序的YUV 4:4:4转换为像素顺序的YUV 4:2:2。
    //I-以像素顺序数据YUV 4:4:4格式输入图像。
    //image_width-图像I的列数。
    //image_height-图像I的行数。
    //J-按像素顺序排列的目标“图像”