2017-03-31 5 views
0

イメージを読み取り、各ピクセルで機能を実行してから新しいイメージとして保存する必要があります。最初と最後の部分(読み書き)にscikit-imageを使用しますが、2番目の操作(実際の変換)を高速で行うのに問題があります。scikit-imageピクセルごとの操作

scikit-imageでの読み取り操作の結果は、幅と高さがイメージのN_CHANNELSが3または4のシェイプ(WIDTH、HEIGHT、N_CHANNELS)のnumpy配列です。関数を適用する必要があります[R、G、B]から[R-B、G-B、B-R]にピクセルを個々に変換するものなど、

私はこれを実行しようと数日を費やしましたが、私が今まで持っている唯一の解決策は、各行と列をループして計算を実行することです。これには非常に時間がかかります。

私は配列をベクトル化しようとしましたが、結果は1次元配列であり、それを使用することはできません。これを行うための他の演奏方法はありますか?

def calculate_ndvi(nir, red): 
    if red == 0 and nir == 0: 
     return 0.5 
    else: 
     num = int(nir) - int(red) 
     den = int(nir) + int(red) 
     return num/den 


zero_uint = numpy.uint8(0) 


def process_color(clr): 
    ndvi = calculate_ndvi(clr[2], clr[0]) 
    return [-ndvi, ndvi, zero_uint] 


def save_ndvi_file(): 
    image = io.imread(input_path) 

    rows = image.shape[0] 
    cols = image.shape[1] 

    out = numpy.empty(shape=(rows, cols, 3)) 
    for i in range(rows): 
     for j in range(cols): 
      out[i][j] = process_color(image[i][j]) 

    io.imsave('output.jpg', out) 
+0

コードを見ることなく、私たちができることは推測です。 [mcve]を準備してください。 25MPファイルにその関数を適用するのに非常に時間がかかるべきではないので、おそらく何か間違っているでしょう。 –

答えて

2

操作の多次元ブロードキャストを使用してこれをベクトル化できます。あなたはオーバーループしていたすべてのものが、今ではなく、外部関数の呼び出しをループするよりも、放送numpyの操作を介して行われていることを

def save_ndvi_file(): 
    image = io.imread(input_path) 

    nir = image[:, :, 2] 
    red = image[:, :, 0] 
    ndvi = (nir - red)/(nir + red) 
    ndvi[(nir == 0) & (red == 0)] = 0.5 
    out = ndvi[:, :, np.newaxis] * np.array([[[-1, 1, 0]]]) 

    io.imsave('output.jpg', out) 

注意:ここではベクトル化の方法ですべてを行い、あなたの関数のバージョンがあります。このようにコードを書くには、アルゴリズムについて少し違った考え方が必要ですが、使い慣れた方が直感的です。

関連する問題