python - `scipy.ndimage.zoom()` 的意外行为 `order=0`

标签 python numpy scipy zooming ndimage

我很难理解 scipy.ndimage.zoom() 的行为当order=0 .

考虑以下代码:

import numpy as np
import scipy as sp
import scipy.ndimage

arr = np.arange(3) + 1
print(arr)
for order in range(5):
    zoomed = sp.ndimage.zoom(arr.astype(float), 4, order=order)
    print(order, np.round(zoomed, 3))

其输出是:

0 [1. 1. 1. 2. 2. 2. 2. 2. 2. 3. 3. 3.]
1 [1.    1.182 1.364 1.545 1.727 1.909 2.091 2.273 2.455 2.636 2.818 3.   ]
2 [1.    1.044 1.176 1.394 1.636 1.879 2.121 2.364 2.606 2.824 2.956 3.   ]
3 [1.    1.047 1.174 1.365 1.601 1.864 2.136 2.399 2.635 2.826 2.953 3.   ]
4 [1.    1.041 1.162 1.351 1.59  1.86  2.14  2.41  2.649 2.838 2.959 3.   ]

所以,当 order=0这些值(预期)不会被插值。 然而,我期待的是:

[1. 1. 1. 1. 2. 2. 2. 2. 3. 3. 3. 3.]

即每个值的元素数量完全相同,因为缩放是整数。 因此,我期望得到与 np.repeat() 相同的结果。 :

print(np.repeat(arr.astype(float), 4))
[1. 1. 1. 1. 2. 2. 2. 2. 3. 3. 3. 3.]

为什么每个元素重复的次数会有所不同?


请注意np.repeat()不直接使用多维数组,这就是为什么我想从 scipy.ndimage.zoom() 获得“正确”行为的原因.


我的 NumPy 和 SciPy 版本是:

print(np.__version__)
# 1.17.4
print(sp.__version__)
# 1.3.3

我发现了这个: `scipy.ndimage.zoom` vs `skimage.transform.rescale` with `order=0` 这表明 scipy.ndimage.zoom() 有一些意外的行为但我不太确定观察到的效果是否相同。

最佳答案

这是一个 bin/edge 数组解释问题。 scipy.ndimage.zoom()的行为基于数组值的边缘解释,而为整数缩放因子生成相同大小的 block (模仿 np.repeat() )的行为基于 bin 解释。

让我们用一些“图片”来说明。

Bin解释

考虑数组[1 2 3] ,让我们将每个值分配给一个容器。 每个垃圾箱的边缘为:01对于 1 , 12对于 2

0 1 2 3
|1|2|3|

现在,让我们将该数组缩放 4 倍:

                    1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2
|   1   |   2   |   3   |

因此,使用 Next-door Neighbor 方法分配给 bin 的值是:

                    1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2
|1 1 1 1|2 2 2 2|3 3 3 3|

边缘解释

考虑与之前相同的数组 [1 2 3] ,但现在让我们将每个值分配给一条边:

0 1 2
| | |
1 2 3

现在,让我们将该数组缩放 4 倍:

                    1 1
0 1 2 3 4 5 6 7 8 9 0 1
| | | | | | | | | | | |
1          2          3

因此,使用 Next-door Neighbor 方法分配给边的值是:

                    1 1
0 1 2 3 4 5 6 7 8 9 0 1
| | | | | | | | | | | |
1 1 1 2 2 2 2 2 2 3 3 3

和边缘3被分配给2因为2有位置5.51有位置0(5.5 - 3 = 2.5) < (3 - 0 = 3) 。 同样,边缘8被分配给2因为(8 - 5.5 = 2.5) < (11 - 8 = 3) .


评论

在物理学中,“箱阵列解释”通常更有用,因为测量通常是“在适当的域中对某个箱进行某种积分的结果”(特别是在以下位置收集的任何形式的信号 - 包括图像)给定的时间间隔),因此我期待 scipy.ndimage.zoom() 的“bin 解释”但我承认“边缘解释”同样有效(尽管我不确定哪些应用程序从中受益最多)。


(感谢@Patol75为我指出正确的方向direction)

关于python - `scipy.ndimage.zoom()` 的意外行为 `order=0`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59281884/

相关文章:

python - 递归:带有 `scipy.lfilter` 的 IIR 滤波器

python - 使用 skimage 替换 scipy.misc.imread

python - 将数据框中带有时间戳的多行事件转换为带有开始和结束日期时间的单行

python - 在python中存储大型对称稀疏矩阵的最有效方法

python - python的dict构造函数是如何处理Mappings的?

python - 被屏蔽的 RGB 图像不会出现被 imshow 屏蔽

python - 将零添加到长 Numpy 数组

python - 在另一个 1d/2d 向量之后重采样(缩小)2D 向量

python - 选择对象实例化的几种方法之一

python - 生成一个新的 2 阶 numpy 数组,用一定范围内的随机数填充每个元素