2012-01-19 56 views
3

私は、温度の視覚的表現を作成するプログラムを書いています。グリッド内に200ポイントのデータが配置されており、これらのポイント間のピクセルを補間するために補間を使用しています。以下に示すような画像を与える私は逆距離加重(ここで修飾Shepards法)を使用したいデータを出すプログラムを書いた効率的なヒートマップの補間方法

、:で

heatmap http://img688.imageshack.us/img688/1069/stackoverflowimage.png

を全て

最初に、各点から各管までの距離と合計距離が計算されます(これは不変であるためです)。これは、画像ライブラリのようなものではありません。このビットでは、一度だけ実行されるため時間がかかりませんが、コードを含めて値の格納方法を確認できます。

#set_tubes creates an array of tubes (which is the data I'm working on) 
#each tube has an x position in pixels, a y position in pixels and a temperature 

self.set_tubes() 
self.dists = [] 
for x in range(1,BASE_WIDTH-1): 
    self.summed_dists.append([]) 
    self.dists.append([]) 
    for y in range(1,BASE_HEIGHT-1): 
     self.summed_dists[x-1].append([]) 
     self.dists[x-1].append([]) 
     self.summed_dists[x-1][y-1]=0 
     for row in range(10): 
      self.dists[x-1][y-1].append([]) 
      for tube in range(20): 
       dist = np.sqrt((x-self.tubes[row][tube].xPos)**2+(y-self.tubes[row][tube].yPos)**2)+0.1 
       #The -3 in the next two lines is simply a weighting factor 
       self.dists[x-1][y-1][row].append(dist**(-3)) 
       self.summed_dists[x-1][y-1] = self.summed_dists[x-1][y-1] + dist**(-3) 

次に補間が行われます(これは温度が変化すると繰り返し行われます)。これは時間が重要な部分です。

def other_proc_calc_temp(ret_queue, dists, tubes,summed_dists): 
    heat_values = list() 
    for x in range (BASE_WIDTH): 
     heat_values.append([]) 
     for y in range(BASE_HEIGHT): 
      summed = 0 
      for row in range(10): 
       for tube in range(20): 
        dist = dists[x][y][row][tube] 
        temp = tubes[row][tube].temp 
        summed = summed + temp* dist/summed_dists[x-1][y-1] 
      heat_values[x].append(summed) 

私の問題は、200×200ピクセルの画像では、コンピュータのコードの2番目の部分を実行するのに約30秒かかります。同じまたは類似の効果を得るためのより速い方法、または私のコードで何らかのぎこちない非効率性を得る方法がありますか?

私は双線形補間と2次補間補間を試みましたが、私が取り出した画像には特に満足していませんでした。

私はまた、個々のピクセルに影響を与えて高速化しようとするデータポイントの近傍を制限していますが、これは助けになりましたが、イメージに明白な線を引かない限り、 。

ご協力いただきありがとうございます。

+1

これにnumpyを使用できるかどうかを確認してください。それ以外の場合は –

答えて

1

改善かもしれないことを1つの変更があります:

最も内側のループのdists[x][y]tubes[row]外を移動してみてください。 この内部反復ごとに複数の配列のインデックス検索を取るかもしれない(それ は、Pythonインタプリタがどのように巧妙に依存):

def other_proc_calc_temp(ret_queue, dists, tubes,summed_dists): 
    heat_values = list() 
    for x in range (BASE_WIDTH): 
     heat_values.append([]) 
     for y in range(BASE_HEIGHT): 
      outer_dist = dists[x][y] 
      summed = 0 
      for row in range(10): 
       inner_dist = outer_dist[row] 
       inner_tube = tubes[row] 
       for tube in range(20): 
        dist = inner_dist[tube] 
        temp = inner_tubes[tube].temp 
        summed = summed + temp* dist/summed_dists[x-1][y-1] 
      heat_values[x].append(summed) 

をPythonインタプリタは値が を持っていないことを知ってくれている場合変更しましたが、これは読みにくいです。しかし、Pythonインタプリタ がこれらの配列インデックスを何度も何度も再計算すると、それが足りる可能性があります。

ここでは、アレイのサイズを.append()ではなくむしろ前もって設定するという段落がありました。 gnibbler says .append() is an O(1) amortized operationこれはおそらくここではほとんど最適化が利用できないことを意味します。あなたが私が書いたものが好奇心なら、編集履歴を見てください。

+0

を参照してください。 'list.append()'は償却されたO(1)操作です –

+0

@gnibbler:ありがとうございます。より多くの言語のAPIドキュメントがこの情報を簡単に利用できるようにしたいと考えています。長いと明らかに無意味な段落が削除されました。 :) – sarnold