2016-07-08 7 views
2

私は、画像を繰り返し処理し、そのプロパティをしきい値で分割するより効率的な方法を探していました。オンラインで検索し、プログラミングの友人と話し合う際、彼らは私にベクトル化(特にnumpyを使用)という概念を導入しました。多くの検索と試行錯誤の後、私はそれを掛けるように見えません。ある人が私にリンクを与えたり、次のコードをより効率的にする方法を提案できますか?Python/NumPyによる画像の閾値処理のベクトル化

Im = plt.imread(img) 
Imarray = np.array(Im) 
for line in Imarray: 
    for pixel in line: 
     if pixel <= 20000: 
      dim_sum += pixel 
      dim_counter += 1 
     if pixel > 20000: 
      bright_sum += pixel 
      bright_counter += 1 
bright_mean = bright_sum/bright_counter 
dim_mean = dim_sum/dim_counter 

基本的に、各ピクセルは0と30000の間で輝度量を保持し、Iは、それぞれ、20000以下と20000以上のすべてのピクセルを平均化しようとしています。私がこれを行う方法を知っている最良の方法は、forループ(Pythonで遅い)を使用し、if文で各ピクセルを検索することです。

+2

あなたのインデントは正しくありません –

+0

私は投稿後に気づ​​きました。私はちょうどC + +でコードを入力し終わって、それを二重チェックするのを忘れました。 –

答えて

6

NumPyは、arraysufuncsでベクトル化をサポートしています。あなたの場合、入力画像としてNumPy配列があります。したがって、それらの比較は、入力配列と同じ形状のブール値の配列を与えるために、単方向/ベクトル化の方法で行うことができます。これらのブール型配列は、入力配列へのインデックス付けに使用されると、そこから有効な要素が選択されます。これはboolean-indexingと呼ばれ、このようなベクター化された選択に重要な機能を形成します。

最後に、NumPy ufunc ndarray.meanを使用して、ベクトル化された形で再び動作し、選択された要素の平均値を示します。

このように、コードにすべてのそれらを置くために、私たちは持っているだろう -

bright_mean, dim_mean = Im[Im > 20000].mean(), Im[Im <= 20000].mean() 

を、この特定の問題については、ビューのコード効率の観点から、それはかつての比較を行うために、より理にかなって。この比較によってブール値の配列が得られます。これは後で2回使用することができます。したがって、代わりに私たちは持っているでしょう -

mask = Im > 20000 
bright_mean, dim_mean = Im[mask].mean(), Im[~mask].mean() 
+0

Divakarありがとう、私はブール配列が適切にどのように働いたのか不思議でした。それは多くの意味があります。 –