2012-10-22 11 views
8

Potrzebuję pętli przez każdy piksel z 2D numpy tablicy (obraz) 2560x2160. Uproszczona wersja mój problem jest następujący:Szybszy sposób przechodzenia przez każdy piksel obrazu w języku Python?

import time 
import numpy as np 

t = time.clock() 
limit = 9000 
for (x,y), pixel in np.ndenumerate(image): 
    if(pixel > limit) 
     pass 
tt = time.clock() 
print tt-t 

To trwa nieprzyjemny ~ 30 sekund, aby zakończyć na moim komputerze. (Core i7, 8GB RAM) Czy istnieje szybszy sposób na wykonanie tej pętli z wewnętrzną instrukcją "if"? Interesują mnie tylko piksele powyżej określonego limitu, ale potrzebuję ich (x, y) wskaźników i wartości.

Odpowiedz

13

Użyj matrycę logiczną:

x, y = (image > limit).nonzero() 
vals = image[x, y] 
+1

WOW! Moje oczy są otwarte. Zajęło <0,1 sekundy. – dinkelk

+0

co jest tutaj w x i y? –

+1

@AndrewHundt: 'x' i' y' są tablicami indeksów x i y dla niezerowych punktów, odpowiednio. – nneonneo

6

Najpierw spróbuj użyć obliczanie vectorize:

i, j = np.where(image > limit) 

Jeżeli problemu nie można rozwiązać za pomocą obliczeń wektoryzacji można przyspieszenie do pętli jako :

for i in xrange(image.shape[0]): 
    for j in xrange(image.shape[1]): 
     pixel = image.item(i, j) 
     if pixel > limit: 
      pass 

czyli

from itertools import product 
h, w = image.shape 
for pos in product(range(h), range(w)): 
    pixel = image.item(pos) 
    if pixel > limit: 
     pass 

Numer numpy.enumerate jest powolny, za pomocą normalnej pętli for i otrzymamy wartość z tablicy według metody item, którą można przyspieszyć przez 4x.

Jeśli potrzebujesz większej prędkości, spróbuj użyć Cythona, spowoduje to, że twój kod będzie tak szybki, jak kod C.

Powiązane problemy