我正在过滤一些图像以删除不必要的背景,到目前为止,在检查像素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嵌套循环快的速度)正确迭代图像的任何想法都会有很大帮助!
答案 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)
执行问题中发布的双循环。