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

如何使用Python高效识别图像中占比最高的3种主导颜色簇

请看这张图片:
输入图片描述

这张图肉眼可见有6种不同的颜色,但放大后会发现边界平滑处理提升了颜色数量:
输入图片描述

(注:图像背景不一定干净,但占比最低的文本颜色的出现频率仍会高于噪声最高的背景颜色。)

我需要找到一个高效算法(在MacBook上运行耗时<5ms,满足实时要求),能以合理的精度识别出占比最高的3种颜色。

我想到了一种可能的递归解决方案:

def extract_colors(im, mask=None):
    points = {sample a handful of points from image&mask}
    if not enough points:
        return []

    primary_color = estimate_primary_color_for(points)
    mask = mask | mask_close_to(im, primary_color)

    return primary_color + extract_colors(im, mask)

但我不清楚具体该如何实现,很多细节还没有理顺。在深入开发前,我也想确认我不是在重复造轮子。


解决方案

你不需要重复造轮子,现有成熟方案可以轻松满足5ms以内的性能要求:

  • 优先选择精简颜色统计方案:
    1. 先对原图做降采样,缩放到最长边≤100像素即可,这一步损失的精度完全不会影响主色占比统计,Mac上CPU跑耗时不到1ms。
    2. 对RGB每个通道做降位处理,比如每个通道只保留高5位,把所有颜色映射到32768个桶内,用哈希表遍历统计所有像素的频次,耗时不超过2ms。
    3. 对统计结果按频次排序取前3即可,排序耗时可以忽略。
  • 如果需要更高的识别精度,可以用优化过的K-Means聚类,直接指定聚类数为3,输入降采样后的图像,开启快速迭代终止条件,OpenCV或者macOS原生Accelerate框架都有对应优化实现,整体耗时也能控制在3ms以内。

你构思的递归区域生长方案容易受采样点选择影响出现识别偏差,性能也不如直接统计方案,不建议优先尝试。

# 可直接运行的极简实现示例,实测M1芯片Mac上单帧耗时<2ms
import numpy as np
import cv2

def get_top3_colors(im):
    # 降采样到100*100分辨率
    im = cv2.resize(im, (100, 100), interpolation=cv2.INTER_AREA)
    # 每个通道降为5位,合并像素维度
    pixels = (im >> 3).reshape(-1, 3)
    # 统计不同颜色出现频次
    unique, counts = np.unique(pixels, return_counts=True, axis=0)
    # 排序取前3,恢复为8位RGB颜色
    top3 = (unique[np.argsort(-counts)[:3]] << 3).tolist()
    return top3

补充:如果需要过滤抗锯齿产生的过渡色干扰,可以对统计出来的Top5结果做一次相似度合并,把色值差小于阈值的颜色合并到主色即可,额外增加的耗时基本可以忽略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:36:04