самый быстрый способ найти количество цветов изображения RGB пикселей - PullRequest
1 голос
/ 09 января 2020

У меня есть сценарий использования, в котором я должен найти последовательный счетчик цветов rgb каждого кадра живого видео после поиска. Я нашел фрагмент кода, который делает то же самое, но с точки зрения производительности, он занимает около 3 сек c чтобы дать мне вывод, но в моем случае я должен сделать этот расчет как можно быстрее, может быть 25 кадров в 1 секунду. Может ли кто-нибудь помочь мне выяснить, как это сделать, путем рефакторинга приведенного ниже кода

from PIL import Image
import timeit

starttime = timeit.default_timer()
with Image.open("netflix.png") as image:
    color_count = {}
    width, height = image.size
    print(width,height)
    rgb_image = image.convert('RGB')
    for x in range(width):
        for y in range(height):
            rgb = rgb_image.getpixel((x, y))
            if rgb in color_count:
                color_count[rgb] += 1
            else:
                color_count[rgb] = 1

    print('Pixel Count per Unique Color:')
    print('-' * 30)
    print(len(color_count.items()))
print("The time difference is :", timeit.default_timer() - starttime)

output:

Количество пикселей на уникальный цвет: 130869

Разница во времени : 3.9660612

1 Ответ

4 голосов
/ 09 января 2020

Вам необходимо использовать Numpy или OpenCV для быстрой обработки изображений в Python. Я сделал 9-цветную версию Паддингтона:

enter image description here

from PIL import Image
import numpy as np

# Open Paddington and make sure he is RGB - not palette
im = Image.open('paddington.png').convert('RGB')

# Make into Numpy array
na = np.array(im)

# Arrange all pixels into a tall column of 3 RGB values and find unique rows (colours)
colours, counts = np.unique(na.reshape(-1,3), axis=0, return_counts=1)

print(colours)
print(counts)

Результаты

[[ 14  48  84]
 [ 19  21  30]
 [ 33 108 163]
 [ 33 152 190]
 [ 72  58  58]
 [ 96 154 210]
 [180  89  64]
 [205 210 200]
 [208 151  99]]

[20389 40269 12820  1488 17185 25371 17050 16396  9032]

Это означает, что RGB (14,48,84) - 20,389 пикселей и т. Д.

Для моего изображения Ma c требуется 125 мс для изображения 400x400, что даст вам 8 кадров в секунду, так что вам лучше иметь как минимум 4 ядра ЦП и использовать их все для получения 25+ кадров в секунду.


Обновление

Я думаю, что на самом деле go значительно быстрее, чем это. Если вы возьмете скалярное произведение каждого из пикселей с [1,256,65536], вы получите одно 24-битное число для каждого пикселя, а не 3 8-битные числа. Тогда намного быстрее найти уникальные значения. Это выглядит так:

# Open Paddington and make sure he is RGB - not palette
im = Image.open('paddington.png').convert('RGB')

# Make into Numpy array
na = np.array(im)

# Make a single 24-bit number for each pixel
f = np.dot(na.astype(np.uint32),[1,256,65536]) 

nColours = len(np.unique(f))     # prints 9

Это занимает 4 мс, а не 125 мс на моей маме c: -)


Ключевые слова : Python, Numpy, PIL / Pillow, обработка изображений, подсчет уникальных цветов, подсчет цветов.

...