Spaces:
Runtime error
Runtime error
#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 | |
from collections import Counter | |
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 make_palette(file, n_clusters): | |
im = Image.open(file) | |
im.thumbnail(MAX_SIZE) | |
pixels = np.array([im.getpixel((x, y)) for x in range(im.size[0]) for y in range(im.size[1])]) | |
clt = MiniBatchKMeans(n_clusters=n_clusters, n_init=1) | |
clt.fit(pixels) | |
cluster_centers = [[int(round(i)) for i in color] for color in clt.cluster_centers_] | |
# sort cluster centers by number of pixels assigned to them | |
counts = Counter(clt.labels_) | |
sorted_counts = sorted(counts.items(), key=lambda x: -x[1]) | |
cluster_centers = [cluster_centers[i] for i, _ in sorted_counts] | |
return 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 | |
# palette is ordered by its presence in the image | |
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'] |