82

画像データを表すnumpy配列を新しいサイズでリサンプリングする方法を探しています。できれば補間方法(最近接、双一次など)を選択できます。私はあることを知っています

scipy.misc.imresize

これは、PIL のサイズ変更関数をラップすることで、まさにこれを行います。唯一の問題は、PIL を使用しているため、numpy 配列が画像形式に準拠する必要があり、最大 4 つの「カラー」チャネルが得られることです。

任意の数の「カラー」チャネルを使用して、任意の画像のサイズを変更できるようにしたいと考えています。scipy/numpy でこれを行う簡単な方法があるかどうか、または自分でロールする必要があるかどうか疑問に思っていました。

自分で作成する方法について、2 つのアイデアがあります。

  • scipy.misc.imresizeすべてのチャネルで個別に実行される機能
  • を使用して自分で作成するscipy.ndimage.interpolation.affine_transform

最初のものはおそらく大きなデータに対して遅く、2番目のものはスプライン以外の補間方法を提供していないようです.

4

6 に答える 6

122

あなたの説明に基づいて、あなたはscipy.ndimage.zoom.

バイリニア補間はorder=1、ニアレストはorder=0、キュービックはデフォルト ( order=3) です。

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]]

編集: Matt S. が指摘したように、マルチバンド画像のズームにはいくつかの注意事項があります。以下の部分を、以前の回答の 1 つからほぼそのままコピーしています。

ズームは、3D (および nD) 配列でも機能します。ただし、たとえば 2 倍にズームすると、すべての軸に沿ってズームすることに注意してください。

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)

マルチバンド イメージの場合、通常、"z" 軸に沿って補間して新しいバンドを作成することは望ましくありません。

ズームしたい 3 バンドの RGB 画像のようなものがある場合は、一連のタプルをズーム係数として指定することでこれを行うことができます。

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]]]
于 2013-05-12T17:19:54.177 に答える
15

リサンプリングする場合は、Scipy のクックブック for rebinningを参照してください。特に、congrid最後に定義された関数は、リビニングまたは補間をサポートします (同じ名前の IDL の関数と同等)。補間が必要ない場合は、これが最速のオプションです。

scipy.ndimage.map_coordinatesまた、あらゆる種類のリサンプリング (構造化されていないグリッドを含む) に対してスプライン補間を行う direct を使用することもできます。大きな配列 (nx、ny > 200) では 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)。「最も近い」種類の補間はサポートされていません。これが行うのは、長方形のメッシュに対するスプライン補間だけだからです。また、最速の方法ではありません。

バイリニアまたはバイキュービック補間を使用している場合は、通常、2 つの 1D 補間を行う方がはるかに高速です。

    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'が、その場合は横配列を取り除きます。

于 2012-11-06T04:10:36.687 に答える
10

Scikit-imageを見たことがありますか?そのtransform.pyramid_*機能はあなたに役立つかもしれません。

于 2012-11-06T12:43:42.620 に答える