在图像中查找颜色:如何减少CPU使用率?

时间:2018-10-29 23:25:42

标签: python python-imaging-library

我有这段代码:

im = Image.open( 'image.png' )

eachPixel = im.load( )
width, height = im.size

for x in range( 0, width ):
    for y in range( 0, height ):
        if eachPixel[ x, y ] == ( 255, 0, 0 ):
            return = True

工程,我只需要使用这种颜色的第一个像素的位置,有什么办法可以减少CPU使用率?图像为800x600,睡眠不起作用,因为这是实时的while循环。 替换颜色,删除,裁剪或使用其他库,任何东西。谢谢! 对不起,我的英语不好。

1 个答案:

答案 0 :(得分:2)

您可以使用numpy来做到这一点。我使用此图像进行测试:

enter image description here

代码是:

#!/usr/bin/env python3
import numpy as np                                                                          
from PIL import Image                                                                       

# Load image and make into NumPy array
im=np.array(Image.open('image.png').convert('RGB'),dtype=np.uint8)                          

# Colour we are looking for
red=np.array([255,0,0],dtype=np.uint8)                                                      

# Find the red pixels
np.where(np.all(im==red,axis=-1))                                                          

结果是:

(array([10, 10, 10, 11, 11, 11]), array([10, 11, 12, 10, 11, 12]))

这意味着第一个红色像素位于10,10,第二个红色像素位于10,11,依此类推。

在我的Mac上,一张800x600的图像需要7.03毫秒的时间。


只需检查一下,我们就可以像这样使用 ImageMagick 转储图像并检查红色像素在哪里:

convert image.png txt:

输出

# ImageMagick pixel enumeration: 23,22,65535,srgb
0,0: (0,65535,0)  #00FF00  lime
1,0: (0,65535,0)  #00FF00  lime
2,0: (0,65535,0)  #00FF00  lime
...
...
7,10: (0,65535,0)  #00FF00  lime
8,10: (0,65535,0)  #00FF00  lime
9,10: (0,65535,0)  #00FF00  lime
10,10: (65535,0,0)  #FF0000  red    <--- red
11,10: (65535,0,0)  #FF0000  red    <--- red
12,10: (65535,0,0)  #FF0000  red    <--- red
13,10: (0,65535,0)  #00FF00  lime
14,10: (0,65535,0)  #00FF00  lime
...
...
8,11: (0,65535,0)  #00FF00  lime
9,11: (0,65535,0)  #00FF00  lime
10,11: (65535,0,0)  #FF0000  red   <--- red
11,11: (65535,0,0)  #FF0000  red   <--- red
12,11: (65535,0,0)  #FF0000  red   <--- red
13,11: (0,65535,0)  #00FF00  lime
14,11: (0,65535,0)  #00FF00  lime
15,11: (0,65535,0)  #00FF00  lime
...
...

如果红色像素通常位于图像的顶部附近,那么您一次可以处理图像的1/4,或者如果您有4个CPU内核,则可以在每个内核上处理图像的1/4:

np.where(np.all(im[0:height//4,:,:]==red,axis=-1)) 

这需要1.7ms而不是7ms。