使用Python将相似颜色名称/代码合并至标准父颜色
颜色分组合并实现方案
现有颜色名称列表:
['dodgerblue', 'lavender', 'powderblue', 'skyblue', 'snow', 'aliceblue', 'gainsboro', 'darkgray', 'black', 'white']
需要按照颜色分组规则合并为:
['blue', 'blue', 'blue', 'blue', 'blue', 'blue', 'gainsboro', 'darkgray', 'black', 'white']
即把相似的子颜色归类到对应的标准父颜色中。以下是提取图像颜色的Python代码,需添加颜色合并功能:
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)
修改方案
- 定义颜色分组映射字典,根据规则将子颜色映射到父颜色
- 添加颜色合并逻辑,将提取到的颜色列表按映射规则替换
修改后的完整代码
import scipy.cluster import sklearn.cluster import numpy from PIL import Image import webcolors # 颜色分组映射字典,可根据实际规则扩展更多映射关系 COLOR_GROUP_MAP = { 'dodgerblue': 'blue', 'lavender': 'blue', 'powderblue': 'blue', 'skyblue': 'blue', 'snow': 'blue', 'aliceblue': 'blue', } 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 merge_colors(color_list): """将颜色列表中的子颜色替换为对应的父颜色""" merged_colors = [] for color in color_list: merged_colors.append(COLOR_GROUP_MAP.get(color, color)) return merged_colors 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) merged_color_names = merge_colors(color_names) print("original color_names: ", color_names) print("merged color_names: ", merged_color_names)
内容的提问来源于stack exchange,提问作者Naren Babu R
相关产品推荐
相关产品推荐

