2015-04-23 90 views
1

我很想找到一種快速方法,用於從定義的查找表中查找線性插值顏色。基於給定的顏色映射,在運行時將顏色分配給大量項目的目的。顏色表查找表是包含值(升序),紅色,綠色,藍色,不透明度的元組列表。在Python中使用線性插值進行高效的顏色查找

下面是一個帶有標準python的簡單配方。 我也可以使用熊貓,因爲我用它來做其他事情。

# Interpolate colors from a lookup table 
import bisect 

def find_color(x, vlist, lut): 
    """Finds linearly interpolated color from specified lut and x 
     Returns RGBA tuple 
     Parameters 
     x: value to lookup 
     vlist: list of values in lut 
     lut: List of tuples Value, R, G, B, A 
    """ 
    last = len(lut) - 1 # last index for lut 

    if x <= vlist[0] : #clamp low end 
      return lut[0][1], lut[0][2], lut[0][3], lut[0][4] 
    elif x >= vlist[last]: #clamp high end 
      return lut[last][1], lut[last][2], lut[last][3], lut[last][4] 
    else: 
      # since vlist is sorted we can use bisect 
      hi = bisect.bisect_left(vlist, x) #hi index 
      lo = hi - 1 # lo index 

      # interpolation weight from left 
      w = (x - vlist[lo])/(vlist[hi] -vlist[lo]) 
      #print x, lo, hi, w 

      # use w to interpolate r,g,b,a from lo and hi bins 
      # interpolated_value = low_value + w * bin_size 
      r = lut[lo][1] + w * (lut[hi][1] - lut[lo][1]) 
      g = lut[lo][2] + w * (lut[hi][2] - lut[lo][2]) 
      b = lut[lo][3] + w * (lut[hi][3] - lut[lo][3]) 
      a = lut[lo][4] + w * (lut[hi][4] - lut[lo][4]) 
      return int(r), int(g), int(b), int(a) 


# Color lookup table 
lut = [ (0.0, 255, 0, 0, 64), 
    (0.5, 0, 255, 255,128), 
    (1.0, 0, 0, 255, 255) ] 

# Value list - extract first column from lut 
vlist = [ x[0] for x in lut] 

# Test find_color() for arbitrary value 
for i in xrange(-5, 12): 
    x = i/10.0 
    print find_color(x, vlist, lut) 
+0

有很多有效的方法可以在熊貓中查找,只需在這裏搜索熊貓進行「查找」,您就會發現很多東西。我問了一個關於n維查找的問題,並得到了很好的答案,並且可能與您正在嘗試執行的操作類似:http://stackoverflow.com/questions/25772977/n-dimensional-table-lookup-array-dataframe - 或字典 – JohnE

+0

我在發佈之前做過搜索,但我遇到的結果不適合用插值查找。我需要爲1000個值重複執行此操作,因此需要提高效率。此外,我不使用顛簸,但感謝您的想法 – user3043805

+0

如果您使用熊貓,你有點使用numpy,因爲熊貓建立在numpy之上;-)另外,你確實提到了效率和numpy會比標準python更有效率名單。至於查找+插值,我不認爲你會發現這個組合,但似乎你的問題可以通過兩步來完成 - 1.查找,2.插值。 FWIW。 – JohnE

回答

0

如果您可以提前預處理查找表,則可以用簡單的查找替換二分查找+插值。只要你願意接受不完全準確的輸出的可能性,這應該是顏色的情況 - 關閉一個錯誤是很難發現的。

取值並乘以某個常量,然後轉換爲整數,並將該整數用作列表的索引。

resolution = 1024 
multiplier = float(resolution)/(lut[-1][0] - lut[0][0]) 
lookup = [(0, 0, 0, 0)] * resolution 
for index in range(resolution): 
    r, g, b, a = find_color(lut[0][0] + i/multiplier, vlist, lut) 
    lookup[index] = (r, g, b, a) 

def find_color2(x): 
    return lookup[int((x - lut[0][0]) * multiplier)] 
+0

我的印象是,除非我的數據是雙精度浮點數,否則這將無法預測地工作。感謝您的想法,雖然 – user3043805

+0

@ user3043805繼續前進,然後決議,內存很便宜。數值的精確度與它們之間的距離差不多,如果你有兩個非常靠近,你需要高分辨率,但是如果它們全部展開,你可以使用更少的分辨率。嘗試測試並看看。 –

相關問題