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值......这不是我得到的.
我该怎么做?(为什么我会得到这个不直观的结果?)
你可以使用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.5到0并1.5到1,如下面的
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.