双立方插值结果与FFMPEG不同

时间:2018-03-06 11:58:26

标签: c++ ffmpeg interpolation image-resizing bicubic

我刚刚实现了双三次插值来调整图像大小。 我有一个测试图像6x6像素(灰度),它的列是黑色和白色(x3)。 我将我的代码结果与工具ffmpeg的结果进行比较,但它们并不正确。我无法理解为什么,我想我可能正在计算像素的邻域错误或者可能是调整大小的像素到原始像素的距离。 有人可以查看我的代码(我会简化它以便更好地阅读)并告诉我错误在哪里?

    // Iterate through each line
    for(int lin = 0; lin < dstHeight; lin++){
        // Original coordinates
        float linInOriginal = (lin - 0.5) / scaleHeightRatio;

        // Calculate original pixels coordinates to interpolate
        int linTopFurther = clamp(floor(linInOriginal) - 1, 0, srcHeight - 1);
        int linTop = clamp(floor(linInOriginal), 0, srcHeight - 1);
        int linBottom = clamp(ceil(linInOriginal), 0, srcHeight - 1);
        int linBottomFurther = clamp(ceil(linInOriginal) + 1, 0, srcHeight - 1);

        // Calculate distance to the top left pixel
        float linDist = linInOriginal - floor(linInOriginal);

        // Iterate through each column
        for(int col = 0; col < dstWidth; col++){
            // Original coordinates
            float colInOriginal = (col - 0.5) / scaleWidthRatio;

            // Calculate original pixels coordinates to interpolate
            int colLeftFurther = clamp(floor(colInOriginal) - 1, 0, srcWidth - 1);
            int colLeft = clamp(floor(colInOriginal), 0, srcWidth - 1);
            int colRight = clamp(ceil(colInOriginal), 0, srcWidth - 1);
            int colRightFurther = clamp(ceil(colInOriginal) + 1, 0, srcWidth - 1);

            // Calculate distance to the top left pixel
            float colDist = colInOriginal - floor(colInOriginal);

            // Gets the original pixels values
            // 1st row
            uint8_t p00 = srcSlice[0][linTopFurther * srcWidth + colLeftFurther];
            // ...

            // 2nd row
            uint8_t p01 = srcSlice[0][linTop * srcWidth + colLeftFurther];
            // ...

            // 3rd row
            // ...

            // 4th row
            // ...

            // Bilinear interpolation operation
            // Y
            float value = cubicInterpolate(
                cubicInterpolate(static_cast<float>(p00), static_cast<float>(p10), static_cast<float>(p20), static_cast<float>(p30), colDist),
                cubicInterpolate(static_cast<float>(p01), static_cast<float>(p11), static_cast<float>(p21), static_cast<float>(p31), colDist),
                cubicInterpolate(static_cast<float>(p02), static_cast<float>(p12), static_cast<float>(p22), static_cast<float>(p32), colDist),
                cubicInterpolate(static_cast<float>(p03), static_cast<float>(p13), static_cast<float>(p23), static_cast<float>(p33), colDist),
                linDist);

            dstSlice[0][lin * dstWidth + col] = double2uint8_t(clamp(value, 0.0f, 255.0f));
        }
    }

1 个答案:

答案 0 :(得分:0)

我忘记设置插值矩阵的二阶变量的值。它们设置为0,因此所得的插值将类似于双线性插值。