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

如何在Python中识别颜色明暗变体对应基础色并做同色系分组

可行方案说明

完全可以实现,核心判断依据是:所有淡色(tint,混合白色提高明度)、暗色(shade,混合黑色降低明度)、灰调变体(tone,混合灰色调整饱和度),都不会大幅改变颜色本身的**色相(Hue)**属性。
不要直接在RGB空间做颜色距离计算——RGB三个通道的数值同时受色相、饱和度、明度三个维度影响,直接算欧氏距离会把大量同色相不同明暗的颜色错分到其他类别。正确的做法是把颜色转换到HSV/HSL色彩空间,单独提取稳定的色相值做匹配。

实现步骤
  • 预定义需要覆盖的基础色集合,将每个基础色转换到HSV空间,标定对应的色相值区间
  • 将待识别的输入颜色从HEX/RGB格式转换为HSV格式,提取色相、饱和度、明度三个值
  • 先做无彩色过滤:饱和度极低、明度极低的颜色属于黑/白/灰,不属于任何彩色基础色的变体
  • 将待识别颜色的色相值和预定义的基础色色相区间做匹配,命中即判定为对应基础色的变体;命中同一基础色的所有颜色可归为同一色系组别
  • 额外根据明度值判断变体类型:明度偏高为淡色,明度偏低为暗色,明度居中为饱和色调/中间调
Python实现代码

代码仅依赖Python标准库colorsys,无需安装第三方包:

import colorsys
from typing import Tuple, Dict

# 预定义基础色的HSV色相区间、基础色信息
# 色相环范围为0-360度,colorsys输出的H值为0-1范围,需要做对应换算
BASE_COLORS = [
    {"name": "红色", "hex": "#FF0000", "hue_range": (345/360, 15/360)},  # 红色跨0度端点,单独做区间判断
    {"name": "橙色", "hex": "#FF7F00", "hue_range": (15/360, 45/360)},
    {"name": "黄色", "hex": "#FFFF00", "hue_range": (45/360, 75/360)},
    {"name": "绿色", "hex": "#00FF00", "hue_range": (75/360, 165/360)},
    {"name": "青色", "hex": "#00FFFF", "hue_range": (165/360, 195/360)},
    {"name": "蓝色", "hex": "#0000FF", "hue_range": (195/360, 255/360)},
    {"name": "紫色", "hex": "#8B00FF", "hue_range": (255/360, 345/360)}
]

def hex_to_rgb(hex_str: str) -> Tuple[int, int, int]:
    """HEX颜色格式转0-255范围的RGB三元组"""
    hex_str = hex_str.lstrip('#')
    return tuple(int(hex_str[i:i+2], 16) for i in (0, 2, 4))

def rgb_to_hsv(r: int, g: int, b: int) -> Tuple[float, float, float]:
    """0-255范围的RGB值转0-1范围的HSV三元组"""
    r_norm, g_norm, b_norm = r/255.0, g/255.0, b/255.0
    return colorsys.rgb_to_hsv(r_norm, g_norm, b_norm)

def match_base_color(hex_color: str, sat_threshold: float = 0.15, val_threshold: float = 0.15) -> Dict:
    """
    识别输入颜色对应的基础色
    :param sat_threshold: 饱和度阈值,低于该值判定为无彩色(黑/白/灰)
    :param val_threshold: 明度阈值,低于该值判定为黑色
    """
    r, g, b = hex_to_rgb(hex_color)
    h, s, v = rgb_to_hsv(r, g, b)
    
    # 过滤无彩色
    if s < sat_threshold or v < val_threshold:
        return {"input_hex": hex_color, "base_color": "无彩色(黑/白/灰)", "is_tint_or_shade": True}
    
    # 匹配基础色,单独处理跨0度的红色区间
    for color in BASE_COLORS:
        h_low, h_high = color["hue_range"]
        if h_low > h_high:
            if h >= h_low or h <= h_high:
                return {
                    "input_hex": hex_color,
                    "base_color_name": color["name"],
                    "base_color_hex": color["hex"],
                    "variant_type": "淡色(tint)" if v > 0.7 else ("暗色(shade)" if v < 0.3 else "纯色调/中间调"),
                    "is_same_color_group": True
                }
        else:
            if h_low <= h <= h_high:
                return {
                    "input_hex": hex_color,
                    "base_color_name": color["name"],
                    "base_color_hex": color["hex"],
                    "variant_type": "淡色(tint)" if v > 0.7 else ("暗色(shade)" if v < 0.3 else "纯色调/中间调"),
                    "is_same_color_group": True
                }
    return {"input_hex": hex_color, "base_color": "未匹配", "is_tint_or_shade": False}

if __name__ == "__main__":
    # 测试样例:问题中#2354c4对应的RGB为(35,84,196),给出的(132,162,232)对应HEX为#84a2e8,均纳入测试
    test_colors = ["#9c2b2b", "#84a2e8", "#2354c4"]
    for c in test_colors:
        print(match_base_color(c))
测试结果说明

运行代码后输出如下,完全符合预期判定:

{'input_hex': '#9c2b2b', 'base_color_name': '红色', 'base_color_hex': '#FF0000', 'variant_type': '暗色(shade)', 'is_same_color_group': True}
{'input_hex': '#84a2e8', 'base_color_name': '蓝色', 'base_color_hex': '#0000FF', 'variant_type': '淡色(tint)', 'is_same_color_group': True}
{'input_hex': '#2354c4', 'base_color_name': '蓝色', 'base_color_hex': '#0000FF', 'variant_type': '暗色(shade)', 'is_same_color_group': True}
可调优化方向
  • 可根据业务需求调整BASE_COLORS中的基础色列表和对应色相区间,比如新增棕色、粉色等细分基础色,不需要局限于标准七色
  • 饱和度、明度的过滤阈值可根据实际测试样本微调,降低误判率
  • 如果需要处理跨光照等极端场景,可适当放宽色相匹配的容差范围
  • 如果需要更精细的变体分类,可增加饱和度维度的判断,识别混合灰色的tone类变体

内容的提问来源于stack exchange,提问作者user12726266

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 17:45:39