#This file finds X dominant colors of a given image, using k-means and different channels of the image, #like RGB, and luminance. import colorsys import math import numpy as np from PIL import Image from sklearn.cluster import MiniBatchKMeans PALETTE_WIDTH = 800 PALETTE_HEIGHT = 200 MAX_SIZE = 500,500 def make_palette(file, n_clusters): im = Image.open(file) im.thumbnail(MAX_SIZE) pixels = np.array([im.getpixel((x,y)) for x in range(0, im.size[0]) for y in range(0, im.size[1])]) clt = MiniBatchKMeans(n_clusters = n_clusters, n_init = 1) clt.fit(pixels) return [[int(round(i)) for i in color] for color in clt.cluster_centers_] def perceived_brightness (r, g, b): """ Calculates perceived brightness for the given RGB values. code from Darel Rex Finley (http://alienryderflex.com/hsp.html) """ return math.sqrt((.299 * r * r) + (.587 * g * g) + (.114 * b * b)) def hsp_rank (r, g, b, mult=8): """ Combines hue, saturation, and perceived brightness info for a smoother sort. """ lum = perceived_brightness(r, g, b) h, s, v = colorsys.rgb_to_hsv(r, g, b) return (h * lum * mult, s * lum * mult, s * mult) def findDominantColors(imageFile, numberOfColors, showImage = True): src = imageFile n_clusters = numberOfColors cluster_centers = make_palette(src, n_clusters) cluster_centers.sort(key=lambda rgb: hsp_rank(*rgb)) pixels = [] dominantColors = [] for i in range(n_clusters): color = tuple(cluster_centers[i]) dominantColors.append(color) # print("Color #{}: {}".format(i+1, color)) for j in range(PALETTE_WIDTH//n_clusters * PALETTE_HEIGHT): pixels.append(color) if showImage: img = Image.new('RGB',(PALETTE_HEIGHT,PALETTE_WIDTH)) img.putdata(pixels) img.show() return dominantColors def rgb_to_hex(rgb): return '#{:02x}{:02x}{:02x}'.format(rgb[0], rgb[1], rgb[2]) def hex_to_rgb(hex): hex = hex.lstrip('#') return tuple(int(hex[i:i+2], 16) for i in (0, 2, 4)) def create_color_palette(colors, palette_width=800, palette_height=200): """ Receives a list of colors in hex format and creates a palette image """ pixels = [] n_colors = len(colors) for i in range(n_colors): color = hex_to_rgb(colors[i]) for j in range(palette_width//n_colors * palette_height): pixels.append(color) img = Image.new('RGB', (palette_height, palette_width)) img.putdata(pixels) img.show() ##############pipeline for testing # print("Dominant colors:") # dominantColors=findDominantColors('./estampa-test.png', 10, False) # dominantColorHex=[rgb_to_hex(color) for color in dominantColors] # print(dominantColorHex) # # ['#d54b18', '#555015', '#98680e', '#1f3919', '#da8007', '#a50637', '#b50406', '#d52350', '#e2090f', '#f8545c']