2013-01-21 25 views
17

Elde ettiğim dizimde birkaç piksele sahip bir görüntüyü numpy olarak okudum.Numune'de büyük bir diziye bir arama tablosu uygulamak için uygun bir yol var mı?

256 değer içeren bir arama tablosu hesapladım. Şimdi aşağıdakileri yapmak istiyorum:

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

Evet, bu temelde bir lut böyle yapar.
Tek sorun şu ki: Verimli bir şekilde yapmak istiyorum ve python'da bu döngüyü çağırmak, bitirmesi için birkaç saniye beklememi bekliyor.

numpy.vectorize()'u biliyorum, yalnızca aynı python kodunu çağıran bir kolaylık işlevi.

cevap

25

sadece 1D olup lutlut eğer içine indeksine image kullanabilirsiniz.
İşte numpy indeksleme bir marş var:
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]]) 

Zihin da indeksleme doğru içinde 0

+3

* face desk * Bu çok basit, çığlık atabilirdim. Diğer yönde tüm zaman boyunca düşündüm ve işe yaramaz. Ama elbette, uyuşmaz şeyleri elementen yapar, bu yüzden bu açık çözümdür. Belki dün çok yorgundum. ;) – Profpatsch

+0

Aslında, çok boyutlu AÜSS için de işe yarayacak gibi görünüyor, en azından uyuşmuş 1.9.2 – Claude

+0

Çok şık bir çözüm, teşekkürler! – gcucurull

13

TheodrosZelleke cevabı başlar, ama sadece ona biraz belgesiz bilgelik eklemek istedim. Numpy, belgesine göre "fantezi indeksleme ile aynı şeyi yapar" işlevini sağlayan np.take işlevini sağlar.

Yani, hemen hemen, ama oldukça aynı değildir:

>>> 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 yaklaşık 3x hızlıdır! Deneyimlerime göre, görüntüleri RGB'den diğer renk alanlarına dönüştürmek için 3B luts kullanırken, 3D görünümünü 1B düzleştirilmiş bir görüntülemeye dönüştürmek için mantık eklemek, x10 hızını artırır.

+1

Oh, vay, bir süredir np.put'a daha derinden baktım çünkü bunun işe yarayacağını düşündüm. Ne zaman diğer işlevleri kontrol etmedim. -.- – Profpatsch

+6

Bu zamanlamalar iki yaşında şimdi: 1.9 ile başlayan yeni NumPy sürümleri, artık 'take' kullanımı kadar hızlı bir şekilde geliştirilmiş bir fantezi indeksleme makinesine sahip. – Jaime