Voici un code qui utilise Oreiller et Le paquet cluster de Scipy .
Pour simplifier, j'ai codé en dur le nom de fichier "image.jpg". Le redimensionnement de l'image est une question de rapidité : si l'attente ne vous dérange pas, commentez l'appel au redimensionnement. Lorsqu'il est exécuté sur ce exemple d'image de poivrons bleus il est généralement dit que la couleur dominante est #d8c865, ce qui correspond à peu près à la zone jaunâtre brillante en bas à gauche des deux poivrons. Je dis "habituellement" parce que le algorithme de groupement utilisé a un certain degré d'aléatoire. Il y a plusieurs façons de modifier cela, mais pour vos besoins, cela peut convenir. (Consultez les options de la variante kmeans2() si vous avez besoin de résultats déterministes).
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))
Note : lorsque j'ai étendu le nombre de clusters à trouver de 5 à 10 ou 15, cela a fréquemment donné des résultats verdâtres ou bleutés. Compte tenu de l'image d'entrée, ces résultats sont également raisonnables... Je ne peux pas non plus dire quelle couleur est vraiment dominante dans cette image, donc je ne blâme pas l'algorithme !
Petit bonus également : sauvegarder l'image réduite avec seulement les N couleurs les plus fréquentes :
# 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')
0 votes
Je suppose qu'il redimensionne l'image pour permettre à l'algorithme de redimensionnement de faire une partie du calcul de la moyenne pour vous.