Python - Найдите доминирующий/наиболее распространенный цвет в изображении

Я ищу способ найти самый доминирующий цвет/тон в изображении с помощью Python. Или средний оттенок или наиболее распространенное из RGB сделают. Я посмотрел на библиотеку Python Imaging и не мог найти ничего касающегося, что я искал в их руководстве, и также кратко в VTK.

Я действительно однако находил Сценарий PHP, который делает то, в чем я нуждаюсь, здесь (вход в систему, требуемый загружать). Сценарий, кажется, изменяет размер изображения к 150*150, производит доминирующие цвета. Однако после этого я справедливо потерян. Я действительно рассматривал запись чего-то, что изменит размер изображения к небольшому размеру, затем проверяют любой пиксель или так поскольку это - изображение, хотя я предполагаю, что это было бы очень неэффективно (хотя реализовывая эту идею, поскольку модуль Python C мог бы быть идеей).

Однако после всего этого, я все еще озадачен. Таким образом, я обращаюсь к Вам, ТАКИМ ОБРАЗОМ. Есть ли легкий, эффективный способ найти доминирующий цвет в изображении.

54
задан Blue Peppers 13 July 2010 в 11:05
поделиться

3 ответа

Вот код, использующий Pillow и кластерный пакет Scipy .

Для простоты я жестко запрограммировал имя файла как «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')
56
ответ дан 7 November 2019 в 08:01
поделиться

Библиотека изображений Python имеет метод getcolors для объектов Image:

im.getcolors() => список (count, color) кортежей или None

Думаю, вы можете попробовать изменить размер изображения перед этим и посмотреть, будет ли результат лучше.

14
ответ дан 7 November 2019 в 08:01
поделиться

Вы можете использовать PIL для многократного уменьшения размера изображения с коэффициентом 2 в каждом измерении, пока оно не достигнет 1x1. Я не знаю, какой алгоритм использует PIL для масштабирования с большим коэффициентом, поэтому переход непосредственно к 1x1 при одном изменении размера может привести к потере информации. Возможно, это не самый эффективный вариант, но он даст вам «средний» цвет изображения.

5
ответ дан 7 November 2019 в 08:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: