Найти цвет на изображении: как можно уменьшить использование процессора? - PullRequest
0 голосов
/ 30 октября 2018

У меня есть этот кусок кода:

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

Работает, мне нужно только положение первого пикселя с этим цветом, любой способ уменьшить использование процессора? изображение 800x600, сон не работает, потому что это в то время как цикл в реальном времени. Замена цветов, удаление, обрезка или использование другой библиотеки, что угодно. Спасибо! Извините, мой плохой английский.

1 Ответ

0 голосов
/ 30 октября 2018

Вы можете сделать это с помощью 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 требуется 7,03 мс для изображения 800x600.


Просто чтобы проверить, мы можем вывести изображение, используя 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 ядра ЦП, вы можете сделать 1/4 изображения на каждом ядре:

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

Это займет 1,7 мс вместо 7 мс.

...