哪里可以找到关于双三次插值和Lanczos重采样的好读物?

时间:2009-06-03 09:08:53

标签: algorithm image-processing resampling

我想在C ++中实现上面提到的两个图像重采样算法(bicubic和Lanczos)。我知道有很多现有的实现,但我仍然想做自己的。我想部分原因是因为我想了解它们是如何工作的,部分是因为我想给它们一些主流实现中没有的功能(比如可配置的多CPU支持和进度报告)。

我试过读维基百科,但这些东西对我来说有点太干了。也许对这些算法有一些更好的解释?我在SO或谷歌上找不到任何东西。

已添加:似乎没人能给我一个关于这些主题的良好链接。任何人都可以至少尝试在这里解释一下吗?

3 个答案:

答案 0 :(得分:12)

两种算法的基本操作原理都非常简单。它们都是卷积滤波器。一个卷积滤波器,对于每个输出值,将卷积函数原点移动到输出的中心,然后将输入中的所有值与该位置的卷积函数的值相乘,并将它们相加。

卷积的一个属性是输出的积分是两个输入函数的积分的乘积。如果你考虑输入和输出图像,那么积分意味着平均亮度,如果你想要亮度保持不变,卷积函数的积分需要加起来。

如何理解它们的一种方法是将卷积函数视为显示输入像素根据距离影响输出像素的数量。

通常定义卷积函数,使得当距离大于某个值时它们为零,这样您就不必考虑每个输出值的每个输入值。

对于lanczos插值,卷积函数基于 sinc(x)= sin(x * pi)/ x 函数,但只采用前几个波瓣。通常3:

lanczos(x) = {
    0 if abs(x) > 3,
    1 if x == 0,
    else sin(x*pi)/x
}

此函数称为过滤器内核。

要使用lanczos进行重新取样,可以想象您将输出和输入叠加在一起,其中的点表示像素位置的位置。对于每个输出像素位置,您从该点获取一个+ - 3个输出像素的框。对于位于该框中的每个输入像素,计算该位置处的lanczos函数的值,其中输出像素坐标中的输出位置的距离作为参数。然后,您需要通过缩放它们来对计算值进行标准化,使它们加起来为1.然后将每个输入像素值与相应的缩放值相乘,并将结果相加以获得输出像素的值。

因为lanzos函数具有可分性属性,并且如果要调整大小,网格是常规的,您可以通过水平和垂直分别进行卷积并预先计算每列的垂直过滤器和每列的水平过滤器来优化它。 / p>

双立方卷积基本相同,具有不同的滤波器核函数。

为了获得更多细节,在Digital Image Processing一节第16.3节中有一个非常好的和彻底的解释。

此外,skia中的image_operations.ccconvolver.cc对lanczos插值有很好的评论。

答案 1 :(得分:12)

虽然Ants Aasma所说的大致描述了这种差异,但我认为你为什么要做这样的事情并不是特别有用。

就链接而言,您在图像处理中提出了一个非常基本的问题,任何关于该主题的体面入门教科书都将对此进行描述。如果我没记错的话,Gonzales and Woods就可以了,但是我远离书本而无法检查。

现在谈谈细节,从根本上考虑你在做什么应该是有帮助的。您有一个正方形的测量点,您想为其插入新值。在上采样的简单情况下,让我们想象你想要在你已经拥有的每一个之间进行新的测量(例如,分辨率提高一倍)。

现在您将无法获得“正确”值,因为通常您没有这些信息。所以你必须估计它。这该怎么做?一种非常简单的方法是线性插值。每个人都知道如何用两个点来做这个,你只需在它们之间画一条线,然后从线上读取新值(在这种情况下,在中间点)。

现在图像是二维的,所以你真的想要在左右和上下方向都这样做。使用结果进行估算,瞧你有“双线性”插值。

这个问题的主要问题在于它不是很准确,尽管它比“最近邻”方法更好(也更慢),而且最近邻方法也非常本地和快速。

要解决第一个问题,你想要的东西比两点的线性拟合更好,你想要适合更多数据点(像素),以及可以是非线性的东西。精度和计算成本的良好折衷是称为三次样条。因此,这将为您提供平滑的拟合线,并再次通过中间所需的值来近似您的新“测量”。在两个方向都这样做,你有“双三次”插值。

这样更准确,但仍然很重。解决速度问题的一种方法是使用卷积,它具有很好的属性,在傅里叶域中,它只是一个乘法,所以我们可以很快地实现它。但是您不必担心实现会理解卷积结果在任何时候都是一个函数(您的图像)被集成在另一个函数中,通常是更小的支持(非零部分)函数称为内核之后,内核已经在该特定点上居中。在离散的世界中,这些只是产品的总和。

事实证明,您可以设计一个卷积内核,它具有与三次样条相似的属性,并使用它来获得快速的“双三次”

Lancsoz重采样是类似的事情,内核中的属性略有不同,这主要意味着它们将具有不同的特征伪像。您可以轻松地查找这些内核函数的详细信息(我确定维基百科有它们,或任何介绍文本)。图形程序中使用的实现往往是高度优化的,有时会有专门的假设,使它们更有效但不那么通用。

答案 2 :(得分:5)

我想建议以下文章,以便基本了解不同的图像插值方法image interpolation via convolution。如果你想尝试更多插值方法,imageresampler是一个很好的开源项目。

在我看来,图像插值可以从两个方面来理解,一个是从函数拟合的角度来看,一个是从卷积的角度来看。例如,image interpolation via convolution中的函数拟合视角很好地解释了Cubic interpolation中解释的样条插值。

此外,图像插值始终与特定应用相关,例如图像缩放,图像旋转等。实际上,对于特定应用,可以以智能方式实现图像插值。例如,图像旋转可以通过three-shearing method实现,并且在每次剪切操作期间,可以实现不同的一维插值算法。