- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想用 C++ 实现上述两种图像重采样算法(双三次和 Lanczos)。我知道那里有许多现有的实现,但我仍然想制作自己的。我想实现它,部分原因是我想了解它们的工作原理,部分原因是我想为它们提供一些主流实现中没有的功能(例如可配置的多 CPU 支持和进度报告)。
我尝试阅读维基百科,但内容对我来说有点太枯燥了。也许对这些算法有更好的解释?我在 SO 或 Google 上都找不到任何东西。
已添加: 似乎没有人能给我关于这些主题的良好链接。至少有人可以在这里解释一下吗?
最佳答案
这两种算法的基本操作原理都非常简单。它们都是卷积滤波器。一个卷积滤波器,它针对每个输出值将卷积函数的原点移动到输出的中心,然后将输入中的所有值与该位置处的卷积函数的值相乘,并将它们相加。
卷积的一个属性是输出的积分是两个输入函数积分的乘积。如果您考虑输入和输出图像,那么积分意味着平均亮度,如果您希望亮度保持不变,则卷积函数的积分需要加起来为 1。
理解它们的一种方法是将卷积函数视为显示输入像素对输出像素的影响程度取决于它们的距离的东西。
卷积函数通常被定义为当距离大于某个值时它们为零,这样您就不必为每个输出值考虑每个输入值。
对于 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 函数具有可分离性属性,并且如果调整大小,网格是规则的,您可以通过分别进行水平和垂直卷积并预先计算每行的垂直过滤器和每列的水平过滤器来优化这一点。
双三次卷积基本相同,只是滤波器核函数不同。
要了解更多详细信息,在书Digital Image Processing 中有一个非常好的和透彻的解释。 , 第 16.3 节。
此外,image_operations.cc和 convolver.cc在 skia 中有一个评论很好的 lanczos 插值实现。
关于algorithm - 我在哪里可以找到有关双三次插值和 Lanczos 重采样的好读物?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/943781/
我是一名优秀的程序员,十分优秀!