2012-10-22 7 views
8

2560x2160 2D numpy 배열 (이미지)의 각 픽셀을 반복해야합니다. 다음과 같이 내 문제의 단순화 된 버전입니다 : 이것은 내 컴퓨터에 완료하는 불쾌한 ~ 30 초 걸리는파이썬에서 이미지의 모든 픽셀을 빠르게 루프 할 수 있습니까?

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 

. (Core i7, 8GB RAM) 내부 'if'문으로이 루프를 수행하는 더 빠른 방법이 있습니까? 나는 특정 한계 이상의 픽셀에만 관심이 있지만, (x, y) 인덱스와 값이 필요하다.

답변

13

부울 행렬을 사용

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

와우! 내 눈이 열린다. 0.1 초 미만입니다. – dinkelk

+0

여기서 x와 y는 무엇입니까? –

+1

@AndrewHundt :'x'와'y'는 각각 0이 아닌 점에 대한 x와 y- 인덱스의 배열입니다. – nneonneo

6

첫째, 사용하려고 벡터화 계산 : 문제 벡터화 계산에 의해 해결 될 수없는 경우

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

, 당신은 루프의 속도를 빠르게 할 수 있습니다 :

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

나 :

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

numpy.ndenumerate는 일반 for 루프를 사용하고 배열에서 값을 item 메서드로 가져 오는 속도가 느리므로 루프를 4 배 빠르게 할 수 있습니다.

속도가 더 필요하면 Cython을 사용해보십시오. 코드가 C 코드만큼 빠릅니다.

관련 문제