gpt4 book ai didi

python - scipy ndimage 使用哪种三次样条方法进行 affine_transform?

转载 作者:太空狗 更新时间:2023-10-30 00:18:20 27 4
gpt4 key购买 nike

背景/背景

我试图重现 scipyndimage.affine_transform 输出的值函数,但与 scipy 实现相比,我似乎使用了不同的“三次”插值方案。

例子

让我们来看一个非常简单的示例(不是您想要对其使用三次插值的数据,但很容易理解)。检查我实现的值 uniform Catmull-Rom splines .我的小实现示例:

import numpy as np
from scipy.ndimage import affine_transform


def catmull_rom_interp(p0, p1, p2, p3, x):
return (
(-0.5 * p0 + 1.5 * p1 - 1.5 * p2 + 0.5 * p3) * (x ** 3)
+ (p0 - 2.5 * p1 + 2 * p2 - 0.5 * p3) * (x ** 2)
+ (-0.5 * p0 + 0.5 * p2) * x
+ p1
)


image = np.zeros((9,))
image[3] = 13.3

scipy_result_filtered = affine_transform(
image, np.eye(1), offset=-1.7, order=3, prefilter=True
)
scipy_result = affine_transform(image, np.eye(1), offset=-1.7, order=3, prefilter=False)

image_padded = np.pad(image, 3, mode="constant", constant_values=0)
result_manual = np.zeros((9,))

for i in range(9):
result_manual[i] = catmull_rom_interp(*image_padded[i : i + 4], 0.3)

print(scipy_result)
print(scipy_result_filtered)
print(result_manual)

# yields
# [0. 0. 0. 0.05985 4.63061667 7.84921667 0.76031667 0. 0. ]
# [0. 0. 0.1675183 -1.06094923 4.43537861 11.10313479 -1.75261778 0.46923634 -0.12432758]
# [0. 0. 0. -0.41895 3.85035 10.84615 -0.97755 0. 0. ]


#
# PLOTTING
#

import matplotlib.pyplot as plt

plt.gca().grid()

plots = []
for i in range(9):
plots.append(lambda x: catmull_rom_interp(*image_padded[i : i + 4], x))

plt.plot(scipy_result, "--", label="scipy", alpha=0.5)
plt.plot(scipy_result, "o", color=plt.get_cmap("tab10")(0))

plt.plot(scipy_result_filtered, "--", label="scipy filtered", alpha=0.5)
plt.plot(scipy_result_filtered, "o", color=plt.get_cmap("tab10")(1))
plt.plot(result_manual, "o")
for i in range(9):
plt.plot(
np.linspace(i - 0.3, i + 1 - 0.3, 100),
plots[i](np.linspace(0, 1, 100)),
"--",
alpha=0.5,
color=plt.get_cmap("tab10")(2),
label="Catmull-Rom spline" if i == 0 else None,
)

plt.plot(
np.arange(-0.3, 8.8),
[0] * 2 + list(image[:-1]),
"o",
label="Data to interpolate",
color="k",
)


plt.legend(framealpha=1)
plt.show()

将产生以下图表(请注意,由于不知道 scipy 函数的真实插值函数,我只是绘制线性连接以更好地突出不同的数据点): enter image description here

观察:

  • scipy 方法不使用 Catmull-Rom 样条
  • scipy 方法(没有过滤)不会产生过冲,这通常与尖锐边缘的三次插值相关,但正如 scipy 文档中提到的那样,确实会导致一些模糊,这似乎与图像的特定偏移有关示例中使用
  • 预过滤 scipy 方法更接近 Catmull-Rom 样条但不相同(存在明显差异)

问题

  • scipy 使用哪种插值方案?
  • 在他们的文档和/或代码中实际可以在哪里找到它?
  • 奖励:一种在 Python 中实现它(用于检查目的)的简单方法

最佳答案

因为我还不能评论,该函数的源代码位于:https://github.com/scipy/scipy/blob/master/scipy/ndimage/interpolation.py#L355

它似乎做了一些基本的转换/错误检查,然后输入到 zoomShift 中。或 geometricTransform取决于参数。

不幸的是,我没有足够的洞察力来回答 1 或 3。

关于python - scipy ndimage 使用哪种三次样条方法进行 affine_transform?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57281432/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com