1

バイリニアフィルタリングを使用して2Dnumpy配列(画像)のサイズを変更するための適切なnumpyソリューションがあるかどうかを確認していますか?

より具体的には、私の配列は(rgba画像のように)形状(幅、高さ、4)を持っています。ダウンスケーリングも「偶数」のステップでのみ実行されます。つまり、(w、h、4)から(w / 2、h / 2、4)、(w / 4、h / 4、4)などです。

私はかなり前からブラウジングしてきましたが、誰もがscipy/PILバージョンのimresizeを参照しているようです。

Pythonパッケージへの依存関係の数を最小限に抑えたいので、numpyのみの要件です。

代わりにC++で実装する前に、SOに確認したかっただけです。

4

1 に答える 1

3

numpyに特定の解決策はないと思いますが、Pythonの快適さを離れることなく、効率的に実装できるはずです。間違っている場合は訂正してください。ただし、画像のサイズが2で割り切れる場合、双一次フィルターは基本的に元の画像の4ピクセルを平均して、新しい画像の1ピクセルを取得するのと同じです。画像サイズが2の累乗である場合は、次のコードを使用します。

from __future__ import division
import numpy as np
from PIL import Image

def halve_image(image) :
    rows, cols, planes = image.shape
    image = image.astype('uint16')
    image = image.reshape(rows // 2, 2, cols // 2, 2, planes)
    image = image.sum(axis=3).sum(axis=1)
    return ((image + 2) >> 2).astype('uint8')

def mipmap(image) :
    img = image.copy()
    rows, cols, planes = image.shape
    mipmap = np.zeros((rows, cols * 3 // 2, planes), dtype='uint8')
    mipmap[:, :cols, :] = img
    row = 0
    while rows > 1:
        img = halve_image(img)
        rows = img.shape[0]
        mipmap[row:row + rows, cols:cols + img.shape[1], :] = img
        row += rows
    return mipmap

img = np.asarray(Image.open('lena.png'))
Image.fromarray(mipmap(img)).save('lena_mipmap.png')

この出力を生成します:

ここに画像の説明を入力してください

512x512の元のイメージで、次のシステムで実行されます。

In [3]: img.shape
Out[3]: (512, 512, 4)

In [4]: %timeit mipmap(img)
10 loops, best of 3: 154 ms per loop

これは、辺の長さが奇数になると機能しませんが、そのような場合のダウンサンプリングをどのように処理するかに応じて、ピクセルの完全な行(または列)を取り除き、形状を変更できるはずです。 image to (rows // 2, 2, cols // 2, 2, planes)、つまりimg[r, :, c, :, p]、新しいピクセル値を取得するために補間する値の2x2行列です。

于 2013-01-28T08:31:16.440 に答える