1

我很难理解scipy.ndimage.zoom()when的行为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()但我不太确定观察到的效果是否相同。

4

2 回答 2

2

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

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

斌解释

考虑数组[1 2 3],让我们将每个值分配给一个 bin。每个 bin 的边缘是:0and 1for 1, 1and 2for2等。

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)


注释

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


(感谢@Patol75 为我指明了正确的方向

于 2019-12-12T13:18:13.127 回答
1

我认为这是预期的行为。

考虑您的初始列表,[1, 2, 3]. 您要求 scipy 将其放大 4 倍,从而创建一个 4x3=12 元素列表。列表的第一个元素必须是 1,最后一个元素必须是 3。然后,对于 2,我们有偶数个元素,因此将 2 作为第 6 和第 7 个元素是有意义的。这给了[1, , , , , 2, 2, , , , , 3]. 从这里,您提供了 order=0 的缩放,这意味着缩放将使用 0 阶样条填充缺失值。第一种情况,缩放需要填写 1 到 2 之间的 4 个缺失值。这必须是[1, 1, 2, 2]. 第二种情况,2 到 3 之间有 4 个缺失值。同样的逻辑,[2, 2, 3, 3]. 最终结果[1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3]

现在考虑 5 倍缩放,它生成一个 15 元素数组。同样的故事,除了有一个“中间”元素,因此只有一个 2 最初放置在新列表中,位于第 8 位。在每对之间填充六个元素,我们得到相同的逻辑[1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3]

因此,您得到的 2 比 1 或 3 多,因为 2 涉及两个插值操作,而 1 和 3 都涉及一个。

于 2019-12-11T10:24:31.630 回答