具有多个条件的Python numpy数组迭代图像

时间:2016-05-05 21:43:11

标签: python arrays opencv numpy

我正在过滤一些图像以删除不必要的背景,到目前为止,在检查像素BGR(使用openCV)值方面取得了最大的成功。问题是用2个嵌套循环迭代图像太慢了:

h, w, channels = img.shape
    for x in xrange(0,h):
        for y in xrange (0,w):
            pixel = img[x,y]
            blue = pixel[0]
            green = pixel[1]
            red = pixel[2]

            if green > 110:
                img[x,y] = [0,0,0]
                continue

            if blue < 100 and red < 50 and green > 80:
                img[x,y] = [0,0,0]
                continue

还有一些类似的if语句,但你明白了。问题是在i7上的672x1250上大约需要10秒钟。

现在,我可以轻松地执行第一个if语句:

img[np.where((img > [0,110,0]).all(axis=2))] = [0,0,0]

而且速度要快得多,但我似乎无法使用np.where在其中使用多个条件执行其他if语句。

以下是我尝试的内容:

img[np.where((img < [100,0,0]).all(axis=2)) & ((img < [0,0,50]).all(axis=2)) & ((img > [0,80,0]).all(axis=2))] = [0,0,0]

但是引发了一个错误:

ValueError: operands could not be broadcast together with shapes (2,0) (1250,672)

如何使用np.where(或任何比2嵌套循环快的速度)正确迭代图像的任何想法都会有很大帮助!

1 个答案:

答案 0 :(得分:5)

你可以像这样表达条件(没有np.where):

import numpy as np
img = np.random.randint(255, size=(4,4,3))
blue, green, red = img[..., 0], img[..., 1], img[..., 2]
img[(green > 110) | ((blue < 100) & (red < 50) & (green > 80))] = [0,0,0]
In [229]: %%timeit img = np.random.randint(255, size=(672,1250,3))
   .....: blue, green, red = img[..., 0], img[..., 1], img[..., 2]
   .....: img[(green > 110) | ((blue < 100) & (red < 50) & (green > 80))] = [0,0,0]
   .....: 
100 loops, best of 3: 14.9 ms per loop

In [240]: %%timeit img = np.random.randint(255, size=(672,1250,3))
   .....: using_loop(img)
   .....: 
1 loop, best of 3: 1.39 s per loop

其中using_loop(img)执行问题中发布的双循环。