File size: 3,551 Bytes
52cbb9c
 
 
 
 
 
 
 
3d3b567
 
52cbb9c
 
 
 
 
3d3b567
 
 
 
 
 
 
 
 
52cbb9c
3d3b567
 
 
 
 
 
 
 
 
 
 
 
 
52cbb9c
3d3b567
52cbb9c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3d3b567
52cbb9c
3d3b567
52cbb9c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#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']