双三次插值结果不同于 FFMPEG
Bicubic interpolation results different from FFMPEG
我刚刚实现了用于调整图像大小的双三次插值。
我有一个 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));
}
}
我忘记设置插值矩阵的二次变量值。它们被设置为 0,因此生成的插值类似于双线性插值。
我刚刚实现了用于调整图像大小的双三次插值。 我有一个 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));
}
}
我忘记设置插值矩阵的二次变量值。它们被设置为 0,因此生成的插值类似于双线性插值。