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

tih*_*rbz 2 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
Run Code Online (Sandbox Code Playgroud)

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

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

img[np.where((img > [0,110,0]).all(axis=2))] = [0,0,0]
Run Code Online (Sandbox Code Playgroud)

并且速度要快得多,但我似乎无法使用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]
Run Code Online (Sandbox Code Playgroud)

但抛出一个错误:

ValueError: operands could not be broadcast together with shapes (2,0) (1250,672)
Run Code Online (Sandbox Code Playgroud)

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

unu*_*tbu 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]
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

where using_loop(img)执行问题中发布的双循环.