重新缩放numpy数组

ner*_*com 5 python arrays numpy

我有一个2D numpy数组,它表示来自CCD的单色图像,该CCD已经被装箱3x3(也就是说,数组中的每个值代表物理CCD上的9个像素(3x3)).

我想重新缩放它以匹配原始CCD布局(因此我可以使用来自同一CCD的非分箱图像轻松覆盖它).

我看到重新采样一个代表图像的numpy数组,但这似乎没有做我想要的.

假设我有一个数组g:

import numpy as np
import scipy.ndimage

 g = np.array([[0, 1, 2],
               [3, 4, 5],
               [6, 7, 8]])
Run Code Online (Sandbox Code Playgroud)

当我尝试将其缩放2倍时:

o = scipy.ndimage.zoom(g, 2, order=0)
Run Code Online (Sandbox Code Playgroud)

我得到了我所期望的 - 每个值现在是2x2相同的值:

array([[0, 0, 1, 1, 2, 2],
       [0, 0, 1, 1, 2, 2],
       [3, 3, 4, 4, 5, 5],
       [3, 3, 4, 4, 5, 5],
       [6, 6, 7, 7, 8, 8],
       [6, 6, 7, 7, 8, 8]])
Run Code Online (Sandbox Code Playgroud)

但是当我尝试按比例缩放3倍时,我得到了这个:

o = scipy.ndimage.zoom(g, 3, order=0)
Run Code Online (Sandbox Code Playgroud)

给我:

array([[0, 0, 1, 1, 1, 1, 2, 2, 2],
       [0, 0, 1, 1, 1, 1, 2, 2, 2],
       [3, 3, 4, 4, 4, 4, 5, 5, 5],
       [3, 3, 4, 4, 4, 4, 5, 5, 5],
       [3, 3, 4, 4, 4, 4, 5, 5, 5],
       [3, 3, 4, 4, 4, 4, 5, 5, 5],
       [6, 6, 7, 7, 7, 7, 8, 8, 8],
       [6, 6, 7, 7, 7, 7, 8, 8, 8],
       [6, 6, 7, 7, 7, 7, 8, 8, 8]])
Run Code Online (Sandbox Code Playgroud)

我希望原始数组中的每个值都成为一组3x3值......这不是我得到的.

我该怎么做?(为什么我会得到这个不直观的结果?)

War*_*ser 5

你可以使用np.kron:

In [16]: g
Out[16]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

In [17]: np.kron(g, np.ones((3,3), dtype=int))
Out[17]: 
array([[0, 0, 0, 1, 1, 1, 2, 2, 2],
       [0, 0, 0, 1, 1, 1, 2, 2, 2],
       [0, 0, 0, 1, 1, 1, 2, 2, 2],
       [3, 3, 3, 4, 4, 4, 5, 5, 5],
       [3, 3, 3, 4, 4, 4, 5, 5, 5],
       [3, 3, 3, 4, 4, 4, 5, 5, 5],
       [6, 6, 6, 7, 7, 7, 8, 8, 8],
       [6, 6, 6, 7, 7, 7, 8, 8, 8],
       [6, 6, 6, 7, 7, 7, 8, 8, 8]])
Run Code Online (Sandbox Code Playgroud)

输出zoom(g, 3, order=0)有点令人惊讶.考虑第一行:[0, 0, 1, 1, 1, 1, 2, 2, 2].为什么有四个1

order=0缩放(实际)计算时np.linspace(0, 2, 9),看起来像

In [80]: np.linspace(0, 2, 9)
Out[80]: array([ 0.  ,  0.25,  0.5 ,  0.75,  1.  ,  1.25,  1.5 ,  1.75,  2.  ])
Run Code Online (Sandbox Code Playgroud)

然后舍入值.如果你使用np.round(),你得到:

In [71]: np.round(np.linspace(0, 2, 9)).astype(int)
Out[71]: array([0, 0, 0, 1, 1, 1, 2, 2, 2])
Run Code Online (Sandbox Code Playgroud)

需要注意的是np.round(0.5)给予0,但np.round(1.5)给人2. np.round()使用"圆一半甚至"打破平局的规则.显然,在做的舍入zoom代码使用"圆半年下来"的规则:其四舍五入0.501.51,如下面的

In [81]: [int(round(x)) for x in np.linspace(0, 2, 9)]
Out[81]: [0, 0, 1, 1, 1, 1, 2, 2, 2]
Run Code Online (Sandbox Code Playgroud)

这就是为什么那里有四个1s.