2017-02-14 11 views
1

RGB符号化された標高データを含む1024x1024の寸法のPNG画像があります。 Iはnumpyからasarrayを用いて画像に読み取る:PythonでRGB画像を短時間でデコードする方法

寸法 (1024, 1024, 4)有する3Dアレイをもたらす
rgb_data = np.asarray(image) 

を(私はRGBAを使用しています)私は、そのデータの上にいくつかのフィルタ(ガウス、中央値)を実行する必要がありますが、私は、デコードされた標高データ上でそれを実行する必要があります。 I復号標高データを含む寸法(1024, 1024)た2Dアレイを有することになる復号後

def decodeRGB(pixel): 
    return (pixel[0] * 256 + pixel[1] + pixel[2]/256) - 32768 

標高データは、以下の機能を復号することができます。 (海抜実際の高さ)

私はこれまで持っていることはこれです:

rgb_data = np.asarray(image) 
decoded_data = np.zeros(tile.size) 

for rownum in range(width): 
    for colnum in range(height): 
     decoded_data[rownum][colnum] = decodeRGB(rgb_data[rownum][colnum]) 

残念ながら、このソリューションは非常に遅いです。それはおよそかかります。 1024×1024の画像の場合は10秒です。

これを実装するためのより効果的な方法がありますか?

私の主な問題は、アレイの寸法が変化することです。 私は(1024, 1024, 4)の配列から(1024, 1024)の配列に行きます。

私は基本的にアレイサイズの縮小を可能にする画像内のすべてのRGB画素に関数を適用する高速/効率的な方法を探しています。

おかげであなたの助けのためにたくさん!

+0

Pythonは、画像ピクセルデータの読み込み、計算には適していません。 'LOW_LEVEL'言語を取得してください! – dsgdfg

+1

@dsgdfg確かに、純粋なPythonはそのスピードで知られていませんが、Numpyが普及しています。コンパイルされたコードを使用してマシンネイティブデータの多次元配列を操作できるため、算術とループはコンパイルされた速度仮想マシン上のPythonオブジェクトを操作するPythonバイトコードの速度がやや遅くなります。 –

+0

'64ビットマシンのラムアドレス+バーチャルラムアドレス+メインスレッドのラムアドレス+サブスレッドのラムアドレス' @Sandroプロジェクトではおそらく動作しますが、すべての時間ではないでしょう。 '? – dsgdfg

答えて

4

ベクトル化を利用してください:

r = rgb_data[..., 0] 
g = rgb_data[..., 1] 
b = rgb_data[..., 2] 
decoded_data = (256*r + g + b/256) - 32768 

rgb_data[..., 0]については256*rは等々一度256でそれらのすべてを乗算し、一度にすべての1024x1024赤の値を選択します。あなたのコード内で解釈されたforループはかなりのオーバーヘッドがあるので、それらを避けて変換を大幅に高速化する必要があります。

それとも、ワンライナーを使用することができます。

decoded_data = (rgb_data[..., :3] * (256, 1, 1/256)).sum(axis=-1) - 32768 

は精神で同様のより多くの方法がまだあります。この記事のコメントを見て、ワンライナーの素敵なコレクションを探してください。

+1

さらには 'rgb_data @ [256,1,1/256,6] - 32768' – Eric

+0

@Eric :-)でも、これらのゼロを掛け合わせて加算するのはそんなに無駄です。それでも、とてもかわいい! –

+0

その後、 'rgb_data [...、:3] @ [256,1、1/256] - 32768'と進みます。全体を構築して合計するよりも少ないメモリを使用する必要があります。 – Eric

3

あなたは非常に強力なnp.einsumを使用してプロセスをベクトル化することができます。あなたの係数から変換ベクトルを作成するだけです。

def decodeRGBArray(rgb_data): 
    transf = np.array([256., 1., 1./256., 0.]) 
    return np.einsum('ijk,k->ij', rgb_data, transf) - 32768 
関連する問題