You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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)

修改方案

  1. 定义颜色分组映射字典,根据规则将子颜色映射到父颜色
  2. 添加颜色合并逻辑,将提取到的颜色列表按映射规则替换

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:09:30