Вот код, использующий Подушка и Кластерный пакет Сципи .
Для простоты я жестко закодировал имя файла как «image.jpg».Изменение размера изображения для скорости: если вы не возражаете против ожидания, закомментируйте вызов изменения размера.При работе с этим образцом изображения синих перцев обычно говорится, что доминирующим цветом является # d8c865, что примерно соответствует яркой желтоватой области в левом нижнем углу двух перцев.Я говорю «обычно», потому что используемый алгоритм кластеризации имеет некоторую степень случайности.Есть несколько способов изменить это, но для ваших целей это может хорошо подойти.(Проверьте параметры варианта kmeans2 (), если вам нужны детерминированные результаты.)
from __future__ import print_function
import binascii
import struct
from PIL import Image
import numpy as np
import scipy
import scipy.misc
import scipy.cluster
NUM_CLUSTERS = 5
print('reading image')
im = Image.open('image.jpg')
im = im.resize((150, 150)) # optional, to reduce time
ar = np.asarray(im)
shape = ar.shape
ar = ar.reshape(scipy.product(shape[:2]), shape[2]).astype(float)
print('finding clusters')
codes, dist = scipy.cluster.vq.kmeans(ar, NUM_CLUSTERS)
print('cluster centres:\n', codes)
vecs, dist = scipy.cluster.vq.vq(ar, codes) # assign codes
counts, bins = scipy.histogram(vecs, len(codes)) # count occurrences
index_max = scipy.argmax(counts) # find most frequent
peak = codes[index_max]
colour = binascii.hexlify(bytearray(int(c) for c in peak)).decode('ascii')
print('most frequent is %s (#%s)' % (peak, colour))
Примечание: когда я увеличиваю количество кластеров, чтобы найти от 5 до 10 или 15, он часто дает результаты, которыебыли зеленоватыми или голубоватыми.Учитывая исходное изображение, это тоже приемлемые результаты ... Я не могу сказать, какой цвет действительно доминирует в этом изображении, поэтому я не ошибаюсь в алгоритме!
Также небольшой бонус: сохранитеуменьшенное изображение только с N наиболее часто встречающимися цветами:
# bonus: save image using only the N most common colours
import imageio
c = ar.copy()
for i, code in enumerate(codes):
c[scipy.r_[scipy.where(vecs==i)],:] = code
imageio.imwrite('clusters.png', c.reshape(*shape).astype(np.uint8))
print('saved clustered image')