Вот подход, использующий KDTree для эффективного поиска ближайшего цвета.Обратите внимание, что хотя KDTrees могут быть довольно продвинутыми, использовать их на самом деле довольно просто.
import numpy as np
from matplotlib import colors
from scipy.spatial import cKDTree as KDTree
from scipy.misc import face
REDUCED_COLOR_SPACE = True
# borrow a list of named colors from matplotlib
if REDUCED_COLOR_SPACE:
use_colors = {k: colors.cnames[k] for k in ['red', 'green', 'blue', 'black', 'yellow', 'purple']}
else:
use_colors = colors.cnames
# translate hexstring to RGB tuple
named_colors = {k: tuple(map(int, (v[1:3], v[3:5], v[5:7]), 3*(16,)))
for k, v in use_colors.items()}
ncol = len(named_colors)
if REDUCED_COLOR_SPACE:
ncol -= 1
no_match = named_colors.pop('purple')
else:
no_match = named_colors['purple']
# make an array containing the RGB values
color_tuples = list(named_colors.values())
color_tuples.append(no_match)
color_tuples = np.array(color_tuples)
color_names = list(named_colors)
color_names.append('no match')
# get example picture
img = face()
# build tree
tree = KDTree(color_tuples[:-1])
# tolerance for color match `inf` means use best match no matter how
# bad it may be
tolerance = np.inf
# find closest color in tree for each pixel in picture
dist, idx = tree.query(img, distance_upper_bound=tolerance)
# count and reattach names
counts = dict(zip(color_names, np.bincount(idx.ravel(), None, ncol+1)))
print(counts)
import pylab
pylab.imshow(img)
pylab.savefig('orig.png')
pylab.clf()
pylab.imshow(color_tuples[idx])
pylab.savefig('minimal.png' if REDUCED_COLOR_SPACE else 'reduced.png')
Вывод с полным цветовым пространством matplotlib:
{'aliceblue': 315, 'antiquewhite':0, «Аква»: 0, «Аквамарин»: 0, «Лазурный»: 0, «Бежевый»: 27, «Бисквит»: 0, «Черный»: 88584, «Бланчедальмонд»: 0, «Синий»: 0,'blueviolet': 0, 'brown': 0, 'burlywood': 76, 'cadetblue': 0, 'chartreuse': 0, 'chocolate': 0, 'коралл': 0, 'cornflowerblue': 0, 'cornsilk': 0,' малиновый ': 0,' голубой ': 0,' darkblue ': 0,' darkcyan ': 0,' darkgoldenrod ': 0,' darkgray ': 0,' darkgreen ': 4148,' darkgrey ':71985, 'darkkhaki': 32907, 'darkmagenta': 0, 'darkolivegreen': 90899, 'darkorange': 0, 'darkorchid': 0, 'darkred': 0, 'darksalmon': 0, 'darkseagreen': 30171,'darkslateblue': 134, 'darkslategray': 108608, 'darkslategrey': 0, 'darkturquoise': 0, 'darkviolet': 0, 'deeppink': 0, 'deepskyblue': 0, 'dimgray': 0, 'dimgrey': 108318,' dodgerblue ': 0,' firebrick ': 0,' floralwhite ': 0,' forestgreen ': 1,' fuchsia ': 0,' gainsboro': 10438, «призрачный белый»: 736, «золотой»: 0, «золотой стержень»: 0, «серый»: 0, «зеленый»: 0, «зеленый желто»: 0, «серый»: 79835, «медовая роса»:0, «hotpink»: 0, «indianred»: 0, «индиго»: 0, «слоновая кость»: 0, «хаки»: 1056, «лаванда»: 4650, «lavenderblush»: 46, «lawngreen»: 0,«лимончифон»: 0, «голубой»: 3, «светлый»: 0, «светлый»: 0, «светло-золотой»: 0, «светло-серый»: 11905, «светло-зеленый»: 2323, «светло-серый»: 0, «лайтпинк»': 0,' lightsalmon ': 0,' lightseagreen ': 0,' lightskyblue ': 0,' lightslategray ': 0,' lightslategrey ': 31920,' lightsteelblue ': 3590,' lightyellow ': 0,' lime ':0, «салатовый»: 0, «льняной»: 46, «пурпурный»: 0, «темно-бордовый»: 0, «медиумаквамарин»: 0, «медиумблю»: 0, «средний орхидея»: 0, «медиумурпуль»: 15,'mediumseagreen': 0, 'mediumslateblue': 0, 'mediumspringgreen': 0, 'mediumturquoise': 0, 'mediumvioletred': 0, 'midnightblue': 54, 'mintcream': 0, 'mistyrose': 19, 'moccasin': 0,' navajowhite ': 0,' navy ': 0,' oldlace ': 0,' olive ': 0,' olivedrab ': 30828,' orange ': 0,' orangered ': 0,' orchid': 0,' palegoldenrod ': 1499,' palegreen ': 285,' paleturquoise ': 0,' palevioletred ': 0,' papayawhip ': 0,' peachpuff ': 0,' peru ': 21,' pink ':0, «слива»: 0, «пудрово-голубой»: 0, «фиолетовый»: 0, «rebeccapurple»: 0, «красный»: 0, «rosybrown»: 2831, «royalblue»: 0, «saddlebrown»: 0,'salmon': 0, 'sandybrown': 0, 'seagreen': 0, 'seashell': 0, 'sienna': 5, 'silver': 35951, 'skyblue': 0, 'slateblue': 0, 'slategray': 7836,' slategrey ': 0,' snow ': 18,' springgreen ': 0,' steelblue ': 0,' tan ': 3925,' teal ': 0,' thistle ': 10274,' tomato ':0, «бирюзовый»: 0, «фиолетовый»: 0, «пшеница»: 21, «белый»: 3, «белый дым»: 834, «желтый»: 0, «желто-зеленый»: 9292, «нет совпадения»: 0}
Вывод только с основными цветами:
{'red': 0, 'green': 403561, 'blue': 3262, 'black': 153782, 'yellow': 225827,'no match': 0}
Исходное изображение:
Версия с уменьшенным цветом:
Версия базового цвета: