我正在寻找如何重新采样一个numpy数组表示图像数据在一个新的大小,最好有一个选择的插值方法(最近,双线性等)。我知道有
scipy.misc.imresize
它通过 Package PIL的resize函数来实现这一点。唯一的问题是,由于它使用PIL,numpy数组必须符合图像格式,最多只能有4个“颜色”通道。
我希望能够调整任意图像的大小,与任何数量的“颜色”通道。我想知道在scipy/numpy中是否有一种简单的方法来做到这一点,或者我是否需要自己滚动。
我有两个想法如何炮制一个自己:
- 在每个通道上分别运行
scipy.misc.imresize
的函数 - 使用
scipy.ndimage.interpolation.affine_transform
创建自己的
第一个对于大数据可能会很慢,第二个似乎除了样条之外没有提供任何其他插值方法。
7条答案
按热度按时间lnvxswe21#
根据您的描述,您需要
scipy.ndimage.zoom
。双线性插值将是
order=1
,最近的是order=0
,三次是默认值(order=3
)。zoom
专门用于您想要重新采样到新分辨率的规则网格数据。举个简单的例子:
结果是:
缩放也适用于3D(和nD)阵列。但是,请注意,例如,如果缩放2倍,将沿沿着 * 所有 * 轴缩放。
这产生:
在多波段图像的情况下,通常不希望沿“z”轴沿着插值,从而创建新波段。
如果您想要缩放3波段RGB图像,则可以通过指定一系列元组作为缩放因子来实现:
这产生:
yks3o0rb2#
如果你想重新采样,那么你应该看看Scipy的cookbook for rebinning。特别是,最后定义的
congrid
函数将支持重新装箱或插值(相当于IDL中同名的函数)。如果你不想插值,这应该是最快的选择。您也可以直接使用
scipy.ndimage.map_coordinates
,它将为任何类型的重建(包括非结构化网格)进行样条插值。我发现map_coordinates对于大型数组(nx,ny > 200)来说很慢。对于结构化网格上的插值,我倾向于使用
scipy.interpolate.RectBivariateSpline
。您可以选择样条的顺序(线性,二次,三次等),甚至可以为每个轴独立选择。举个例子:在这个例子中,你正在做一个双线性插值
(kx = ky = 1)
。不支持“最近”类型的插值,因为这只是矩形网格上的样条插值。这也不是最快的方法。如果您在进行双线性或双三次插值,通常进行两次1D插值会快得多:
你也可以使用
kind='nearest'
,但在这种情况下,不要使用横向数组。zbq4xfa03#
你看过Scikit-image吗?它的
transform.pyramid_*
函数可能对你有用。ukqbszuj4#
我最近发现scipy.ndimage.interpolation.zoom有一个问题,我已经提交了一份bug报告:https://github.com/scipy/scipy/issues/3203
作为替代方案(或者至少对我来说),我发现scikit-image的skimage.transform.resize可以正确工作:http://scikit-image.org/docs/dev/api/skimage.transform.html#skimage.transform.resize
zoom -不是指定一个乘法器,而是指定你想要的输出形状。这适用于2D和3D图像。
对于2D图像,您可以使用transform.rescale并指定乘数或比例,就像使用interpolation. zoom一样。
91zkwejq5#
可以使用
interpolate.interp2d
。例如,考虑由numpy数组
arr
表示的图像,您可以将其调整为任意高度和宽度,如下所示:当然,如果你的图像有多个通道,你必须为每个通道执行插值。
lztngnrs6#
最近的插值可以通过numpy.repeat实现
对于RGB图像,我们还需要重复通道尺寸
e3bfsja27#
此解决方案缩放输入图像的X和Y,而不影响RGB通道:
希望这是有用的。