2013-01-21 47 views
17

我已經有一個圖像在我的結果數組中有相當多的像素讀取numpy。有沒有一種方便的方法將查找表應用於numpy中的大型數組?

我計算了一個256值的查找表。現在,我要做到以下幾點:

for i in image.rows: 
    for j in image.cols: 
     mapped_image[i,j] = lut[image[i,j]] 

是的,這基本上是一個LUT做什麼。
唯一的問題是:我想要高效地執行它,並調用Python中的循環將讓我等待幾秒鐘完成。

我知道numpy.vectorize(),它只是一個簡便的函數,它調用相同的python代碼。

回答

25

如果lut1D,您可以使用image索引lut
下面是與NumPy上索引首發:
http://www.scipy.org/Tentative_NumPy_Tutorial#head-864862d3f2bb4c32f04260fac61eb4ef34788c4c

In [54]: lut = np.arange(10) * 10 

In [55]: img = np.random.randint(0,9,size=(3,3)) 

In [56]: lut 
Out[56]: array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90]) 

In [57]: img 
Out[57]: 
array([[2, 2, 4], 
     [1, 3, 0], 
     [4, 3, 1]]) 

In [58]: lut[img] 
Out[58]: 
array([[20, 20, 40], 
     [10, 30, 0], 
     [40, 30, 10]]) 

心裏也索引開始於0

+3

* face-desk * 這很簡單,我可以尖叫。我一直認爲在另一個方向,這是行不通的。但是,當然,numpy會按照元素來做事情,所以這是一個明顯的解決方案。 也許我昨天太累了。 ;) – Profpatsch

+0

實際上,它似乎也適用於多維LUTS,至少與numpy 1.9.2 – Claude

+0

非常優雅的解決方案,謝謝! – gcucurull

13

TheodrosZelleke在正確的答案,但我只是想一點點無證智慧添加到它。 Numpy提供了一個功能np.take,它根據文檔「與花式索引做同樣的事情」。

嗯,差不多,但不太一樣:

>>> import numpy as np 
>>> lut = np.arange(256) 
>>> image = np.random.randint(256, size=(5000, 5000)) 
>>> np.all(lut[image] == np.take(lut, image)) 
True 
>>> import timeit 
>>> timeit.timeit('lut[image]', 
...    'from __main__ import lut, image', number=10) 
4.369504285407089 
>>> timeit.timeit('np.take(lut, image)', 
...    'from __main__ import np, lut, image', number=10) 
1.3678052776554637 

np.take大約是3倍速度更快!根據我的經驗,當使用3D luts將圖像從RGB轉換爲其他色彩空間時,添加邏輯將3D查找轉換爲1D展平查找可以實現x10加速。

+1

哦,哇,我深入研究了'np.put'一段時間,因爲我認爲這可能會起作用。當它不是我沒有檢查其他功能。 -.- – Profpatsch

+6

這些時機現在已經兩年了:NumPy的新版本,從1.9開始,有一個大大改進的花式索引機器,現在使用'take'的速度相當快。 – Jaime

相關問題