Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.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
C# 缩小YUV 4:2:2的算法_C#_Algorithm_Video - Fatal编程技术网

C# 缩小YUV 4:2:2的算法

C# 缩小YUV 4:2:2的算法,c#,algorithm,video,C#,Algorithm,Video,尝试编写一个有效的算法,将YUV4:2:2缩小2倍,并且不需要转换为RGB(这是CPU密集型的) 我已经看到了很多关于YUV到RGB转换的堆栈溢出的代码,但是这里只有一个YUV 4:2:0缩放的示例,我是基于这个示例开始我的代码的。但是,这会产生一个图像,该图像实际上是同一图像的3列,颜色已损坏,因此,当应用于4:2:2时,algo有问题 有人能看出这个代码有什么问题吗 public static byte[] HalveYuv(byte[] data, int imageWidth, int

尝试编写一个有效的算法,将YUV4:2:2缩小2倍,并且不需要转换为RGB(这是CPU密集型的)

我已经看到了很多关于YUV到RGB转换的堆栈溢出的代码,但是这里只有一个YUV 4:2:0缩放的示例,我是基于这个示例开始我的代码的。但是,这会产生一个图像,该图像实际上是同一图像的3列,颜色已损坏,因此,当应用于4:2:2时,algo有问题

有人能看出这个代码有什么问题吗

public static byte[] HalveYuv(byte[] data, int imageWidth, int imageHeight)
{
    byte[] yuv = new byte[imageWidth / 2 * imageHeight / 2 * 3 / 2];

    int i = 0;
    for (int y = 0; y < imageHeight; y += 2)
    {
        for (int x = 0; x < imageWidth; x += 2)
        {
            yuv[i] = data[y * imageWidth + x];
            i++;
        }
    }

    for (int y = 0; y < imageHeight / 2; y += 2)
    {
        for (int x = 0; x < imageWidth; x += 4)
        {
            yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];
            i++;
            yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x + 1)];
            i++;
        }
    }
    return yuv;
}
公共静态字节[]HalveYuv(字节[]数据,int-imageWidth,int-imageHeight)
{
字节[]yuv=新字节[imageWidth/2*imageHeight/2*3/2];
int i=0;
对于(int y=0;y
生成低质量缩略图的快速方法是丢弃每个维度中的一半数据

我们将图像分成4x2像素网格-网格中的每对像素由4个字节表示。在缩小的图像中,我们通过复制前4个字节来获取网格中前2个像素的颜色值,同时丢弃其他12个字节的数据

这种缩放可以推广到2的任意幂(1/2,1/4,1/8…)-这种方法很快,因为它不使用任何插值。这将给出一个质量较低的图像,它看起来块状,但是为了更好的结果,考虑一些采样方法。
public static byte[] FastResize(
    byte[] data, 
    int imageWidth, 
    int imageHeight, 
    int scaleDownExponent)
{
    var scaleDownFactor = (uint)Math.Pow(2, scaleDownExponent);

    var outputImageWidth = imageWidth / scaleDownFactor;
    var outputImageHeight = imageHeight / scaleDownFactor;
    // 2 bytes per pixel.
    byte[] yuv = new byte[outputImageWidth * outputImageHeight * 2];

    var pos = 0;
    // Process every other line.
    for (uint pixelY = 0; pixelY < imageHeight; pixelY += scaleDownFactor)
    { 
        // Work in blocks of 2 pixels, we discard the second.
        for (uint pixelX = 0; pixelX < imageWidth; pixelX += 2*scaleDownFactor)
        {
            // Position of pixel bytes.
            var start = ((pixelY * imageWidth) + pixelX) * 2;

            yuv[pos] = data[start];
            yuv[pos + 1] = data[start + 1];
            yuv[pos + 2] = data[start + 2];
            yuv[pos + 3] = data[start + 3];

            pos += 4;
        }
    }

    return yuv;
}
公共静态字节[]快速调整大小(
字节[]数据,
int imageWidth,
int图像高度,
int scaleDownExponent)
{
var scaleDownFactor=(uint)Math.Pow(2,scaleDownExponent);
var outputImageWidth=imageWidth/scaleDownFactor;
var outputImageHeight=图像高度/缩放下降因子;
//每像素2字节。
字节[]yuv=新字节[outputImageWidth*outputImageHeight*2];
var-pos=0;
//每隔一行处理一次。
对于(uint pixelY=0;pixelY
我假设原始数据的顺序如下(从示例代码中可以看出):首先是图像像素的亮度(Y)值(
size=imageWidth*imageHeight
字节)。在存在色度分量UV、s.t之后,单个像素的值依次给出。这意味着原始图像的总大小为
3*size

现在对于4:2:2,子采样意味着水平色度分量的每一个其他值都被丢弃。这将数据减少到大小
大小+0.5*大小+0.5*大小=2*大小
,即亮度完全保持,两个色度分量被分成一半。因此,结果图像应分配为:

byte[] yuv = new byte[2*imageWidth*imageHeight];
当完整复制图像的第一部分时,第一个循环变为:

int i = 0;
for (int y = 0; y < imageHeight; y++)
{
    for (int x = 0; x < imageWidth; x++)
    {
        yuv[i] = data[y * imageWidth + x];
        i++;
    }
}
inti=0;
对于(int y=0;y
因为这只是复制数据的开头,所以可以简化为

int size = imageHeight*imageWidth;
int i = 0;
for (; i < size; i++)
{
    yuv[i] = data[i];
}
int size=imageHeight*imageWidth;
int i=0;
对于(;i
现在要复制其余的,我们需要跳过其他水平坐标

for (int y = 0; y < imageHeight; y++)
{
    for (int x = 0; x < imageWidth; x += 2) // +2 skip each other horizontal component
    {
        yuv[i] = data[size + y*2*imageWidth + 2*x]; 
        i++;
        yuv[i] = data[size + y*2*imageWidth + 2*x + 1];
        i++;
    }
}
for(int y=0;y
需要
数据
-数组索引中的因子2,因为每个像素有2个字节(两个色度分量),因此每个“行”都有
2*imageWidth
字节的数据