如何重构numpy数组来表示图像?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

我正在寻找如何重采样一个数字数组,表示图像数据在一个新的大小,最好有一个选择的插值方法(最近,双线性等)。

scipy.misc.imresize

它正是通过包装PIL的调整大小函数来做到这一点的。唯一的问题是,由于它使用PIL,numpy数组必须符合图像格式,给我最多4个“颜色”通道。

我希望能够调整任意大小的图像,与任意数量的“颜色”频道。我在想,是否有一种简单的方法可以在cipy/numpy中做到这一点,或者我是否需要使用自己的方法。

提问于
用户回答回答于

根据你的描述,你想scipy.ndimage.zoom

作为一个简单的例子:

import numpy as np
import scipy.ndimage

x = np.arange(9).reshape(3,3)

print 'Original array:'
print x

print 'Resampled by a factor of 2 with nearest interpolation:'
print scipy.ndimage.zoom(x, 2, order=0)


print 'Resampled by a factor of 2 with bilinear interpolation:'
print scipy.ndimage.zoom(x, 2, order=1)


print 'Resampled by a factor of 2 with cubic interpolation:'
print scipy.ndimage.zoom(x, 2, order=3)

其结果是:

Original array:
[[0 1 2]
 [3 4 5]
 [6 7 8]]
Resampled by a factor of 2 with nearest interpolation:
[[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]]
Resampled by a factor of 2 with bilinear interpolation:
[[0 0 1 1 2 2]
 [1 2 2 2 3 3]
 [2 3 3 4 4 4]
 [4 4 4 5 5 6]
 [5 5 6 6 6 7]
 [6 6 7 7 8 8]]
Resampled by a factor of 2 with cubic interpolation:
[[0 0 1 1 2 2]
 [1 1 1 2 2 3]
 [2 2 3 3 4 4]
 [4 4 5 5 6 6]
 [5 6 6 7 7 7]
 [6 6 7 7 8 8]]

data = np.arange(27).reshape(3,3,3)
print 'Original:\n', data
print 'Zoomed by 2x gives an array of shape:', ndimage.zoom(data, 2).shape

输出:

Original:
[[[ 0  1  2]
  [ 3  4  5]
  [ 6  7  8]]

 [[ 9 10 11]
  [12 13 14]
  [15 16 17]]

 [[18 19 20]
  [21 22 23]
  [24 25 26]]]
Zoomed by 2x gives an array of shape: (6, 6, 6)

您可以通过指定一个元组序列作为缩放因子来实现这一点:

print 'Zoomed by 2x along the last two axes:'
print ndimage.zoom(data, (1, 2, 2))

输出:

Zoomed by 2x along the last two axes:
[[[ 0  0  1  1  2  2]
  [ 1  1  1  2  2  3]
  [ 2  2  3  3  4  4]
  [ 4  4  5  5  6  6]
  [ 5  6  6  7  7  7]
  [ 6  6  7  7  8  8]]

 [[ 9  9 10 10 11 11]
  [10 10 10 11 11 12]
  [11 11 12 12 13 13]
  [13 13 14 14 15 15]
  [14 15 15 16 16 16]
  [15 15 16 16 17 17]]

 [[18 18 19 19 20 20]
  [19 19 19 20 20 21]
  [20 20 21 21 22 22]
  [22 22 23 23 24 24]
  [23 24 24 25 25 25]
  [24 24 25 25 26 26]]]
用户回答回答于

可以直接使用scipy.ndimage.map_coordinates,它将对任何类型的重采样(包括非结构化网格)进行样条插值。

对于结构化网格上的插值,我倾向于使用scipy.interpolate.RectBivariateSpline。您可以选择样条的顺序(线性,二次,三次等),甚至独立于每个轴。例如:

    import scipy.interpolate as interp
    f = interp.RectBivariateSpline(x, y, im, kx=1, ky=1)
    new_im = f(new_x, new_y)

在这种情况下,你在做双线性插值(kx = ky = 1)。“最近”类型的插值不受支持,因为所有这些都是矩形网格上的样条插值。这也不是最快的方法。

如果您是在进行双线性或双三次插值,那么进行两个一维插值通常要快得多:

    f = interp.interp1d(y, im, kind='linear')
    temp = f(new_y)
    f = interp.interp1d(x, temp.T, kind='linear')
    new_im = f(new_x).T

您也可以使用kind='nearest',但在这种情况下,去掉横向阵列。

扫码关注云+社区