2012-10-22 58 views
8

我需要遍歷2560x2160 2D numpy陣列(圖像)的每個像素。我的問題的簡化版本如下:更快速地循環遍歷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 

這是一個令人討厭的~30秒完成在我的電腦上。 (酷睿i7,8GB RAM) 有更快的方式來執行這個循環與一個內部'如果'的聲明?我只對超過某個限制的像素感興趣,但我確實需要它們的(x,y)指數和值。

回答

13

使用布爾矩陣:

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

WOW!我的眼睛被打開了。取<0.1秒。 – dinkelk

+0

x和y這裏是什麼? –

+1

@AndrewHundt:'x'和'y'分別是非零點的x和y索引數組。 – nneonneo

6

首先,嘗試使用矢量化計算:

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

如果你的問題不能由矢量化計算解決,您可以加速比for循環:

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代碼一樣快。