在Python中循环遍历图像的每个像素的更快方法?

din*_*elk 11 python time loops numpy image

我需要遍历2560x2160 2D numpy阵列(图像)的每个像素.我的问题的简化版本如下:

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
Run Code Online (Sandbox Code Playgroud)

这在我的电脑上完成了大约30秒的讨厌.(酷睿i7,8GB内存)有没有更快的方法来执行这个内部'if'语句循环?我只对超过一定限度的像素感兴趣,但我确实需要它们的(x,y)索引和值.

nne*_*neo 17

使用布尔矩阵:

x, y = (image > limit).nonzero()
vals = image[x, y]
Run Code Online (Sandbox Code Playgroud)

  • 哇!我的眼睛睁开了。花费 < 0.1 秒。 (2认同)
  • 你能详细说明这究竟是如何运作的吗? (2认同)

HYR*_*YRY 8

首先,尝试使用矢量化计算:

i, j = np.where(image > limit)
Run Code Online (Sandbox Code Playgroud)

如果矢量化计算无法解决您的问题,您可以将for循环加速为:

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

要么:

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

numpy.ndenumerate很慢,通过使用normal for循环并通过item方法从数组中获取值,可以将循环加速4倍.

如果你需要更高的速度,尝试使用Cython,它将使你的代码与C代码一样快.