双三次插值中的伪影

信息处理 插值
2022-01-14 10:21:27

我写了一个算法来对图像进行双三次插值。我使用了维基百科页面中描述的方法。在简单的图像上,结果看起来不错,但在更复杂的图像上,我在非平滑区域得到了奇怪的伪影。

这些文物的可能来源是什么,我可以尝试摆脱它们吗?

我的代码在github 上,但我检查了几次,所以我认为问题不是来自它,而是来自维基百科中建议的简单实现

我正在使用这个特定的方程(三阶 Hermite 多项式插值)进行插值(一维):

x(n+t)=12[1tt2t3][0200101025411331][x[n1]x[n]x[n+1]x[n+2]]

其中 , ... , .. 是周围像素的值(在一维中),是小数坐标(其中)相邻像素之间的插值像素。是一个整数,对于任何整数x[n1]x[n+2]t0t<1x[n]x[n+1]nx(n)=x[n]n

预期输出:

预期输出

我的结果,仔细看鸟头,出现了很多白色像素。

我的结果

---编辑---为了显示我的代码确实产生了连贯的结果,这里是我放大具有 16 个红色像素的简单图像的示例。

输入 4*4 像素

这是库的输出(也使用三阶 Hermite 多项式插值):

图书馆的输出 200x200

这是我的结果:

我的代码输出 200x200

在这种情况下,IMO 完全可以接受差异,但这表明我的插值确实是合法的。

2个回答

您所看到的是acutance,如关于双三次插值的维基百科文章中所述。

然而,对于图像的下采样,三次插值可能不是理想的选择,但对上采样更有意义。

请注意,如果您的下采样率超过 4,则原始图像中将有许多像素根本不会在下采样版本中使用。

解决这个问题的最简单方法是通过迭代取 4 个相邻像素的平均值来进行下采样,直到您处于所需图像大小的 2 倍以内。然后你可以通过三次插值来完成最后一部分。

如果您想要高质量的重采样,请尝试查看ImageMagik 文档以获取灵感。他们特别推荐使用窗口滤波器进行下采样,例如 Lanczos 或 Sinc。

我不确定问题是什么,但我的第一个猜测是代码从图像中提取的 16 个像素以错误的顺序被解释。

换句话说,也许当前的代码块

val b_1 = q(x1, x2, x3)(extracted(0), extracted(1), extracted(2), extracted(3))
val b0  = q(x1, x2, x3)(extracted(4), extracted(5), extracted(6), extracted(7))
val b1  = q(x1, x2, x3)(extracted(8), extracted(9), extracted(10), extracted(11))
val b2  = q(x1, x2, x3)(extracted(12), extracted(13), extracted(14), extracted(15))

需要是别的东西,也许像

val b_1 = q(x1, x2, x3)(extracted(0), extracted(4), extracted(8), extracted(12))
val b0  = q(x1, x2, x3)(extracted(1), extracted(5), extracted(9), extracted(13))
val b1  = q(x1, x2, x3)(extracted(2), extracted(6), extracted(10), extracted(14))
val b2  = q(x1, x2, x3)(extracted(3), extracted(7), extracted(11), extracted(15))

?

这种混洗像素会产生类似于您所看到的结果 - 输出在“平滑”区域看起来很好,但在非平滑区域中结果更明显是错误的。

这个“非缩放”测试(运行“插值”以生成完全相同大小的图像)是一个很好的第一个测试——它应该提供与输入图像完全相同的像素对像素的输出图像。(扩大或缩小图像的测试,不清楚输出图像应该是什么)。

我还会考虑在一个非常简单的图像上运行非缩放测试(甚至可能是缩放测试),它足够小,以至于人类可以单步遍历图像中的每个像素 - 可能类似于

0 0 0
0 5 6
0 8 9

一旦你让这个“非缩放”测试工作,我同意罗伯特的观点,要真正测试插值,你还需要运行一些扩展或缩小图像的测试。