Merge similar color codes/names to parent color code/names using python

79 Views Asked by At

I have a list of color names like this

['dodgerblue', 'lavender', 'powderblue', 'skyblue', 'snow', 'aliceblue', 'gainsboro', 'darkgray', black, white]

I want the output to be like

['blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'gainsboro', 'darkgray', black, white]

I want to group similar color names/codes into standard color code like the below: enter image description here

Here is the code I used to get color used in the image

import scipy.cluster
import sklearn.cluster
import numpy
from PIL import Image
import webcolors

def closest_colour(requested_colour):
    min_colours = {}
    for key, name in webcolors.CSS3_HEX_TO_NAMES.items():
        r_c, g_c, b_c = webcolors.hex_to_rgb(key)
        rd = (r_c - requested_colour[0]) ** 2
        gd = (g_c - requested_colour[1]) ** 2
        bd = (b_c - requested_colour[2]) ** 2
        min_colours[(rd + gd + bd)] = name
    return min_colours[min(min_colours.keys())]

def get_colour_name(requested_colour):
    try:
        closest_name = actual_name = webcolors.rgb_to_name(requested_colour)
    except ValueError:
        closest_name = closest_colour(requested_colour)
        actual_name = None
    return actual_name, closest_name
    
def get_dominant_color(pil_img, palette_size=16):
    # Resize image to speed up processing
    img = pil_img.copy()
    img.thumbnail((100, 100))

    # Reduce colors (uses k-means internally)
    paletted = img.convert('P', palette=Image.ADAPTIVE, colors=palette_size)

    # Find the color that occurs most often
    palette = paletted.getpalette()
    color_counts = sorted(paletted.getcolors(), reverse=True)
    palette_index = color_counts[0][1]
    dominant_color = palette[palette_index*3:palette_index*3+3]

    color_names = []
    for idx, val in enumerate(color_counts):
        color_cnt = color_counts[idx][0]
        if color_cnt > 100: # min number of color pixels
            palette_index = color_counts[idx][1]
            dominant_color = palette[palette_index*3:palette_index*3+3]
            actual_name, closest_name = get_colour_name(dominant_color)
            if closest_name not in color_names and closest_name != "white" and closest_name != "black":
                color_names.append(closest_name)
    return dominant_color, color_names

image = Image.open(save_png_name)
dominant_color, color_names = get_dominant_color(image,16)
print("color_names: ",color_names)
0

There are 0 best solutions below