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

Python图像颜色统计时饼图不显示及自动统计频率问题求助

问题修复与自动颜色统计实现

嘿,我来帮你搞定这两个问题——首先解决图像和饼图不显示的bug,然后实现自动统计颜色数量的功能。

一、先修复图表不显示的问题

你的代码里有几个小问题导致图像和饼图没出来,我把修复后的完整代码列出来,再逐个解释:

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import numpy as np
import cv2
from collections import Counter
from skimage.color import rgb2lab, deltaE_cie76
import os
%matplotlib inline

def RGB2HEX(color):
    return "#{:02x}{:02x}{:02x}".format(int(color[0]), int(color[1]), int(color[2]))

def get_image(image_path):
    image = cv2.imread(image_path)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    return image

def get_colors(image, number_of_colors, show_chart):
    # 把图像调整尺寸并重塑,移到函数内部,避免全局变量问题
    modified_image = cv2.resize(image, (600, 400), interpolation=cv2.INTER_AREA)
    modified_image = modified_image.reshape(modified_image.shape[0] * modified_image.shape[1], 3)
    
    clf = KMeans(n_clusters=number_of_colors)
    labels = clf.fit_predict(modified_image)
    counts = Counter(labels)
    
    # 按出现次数排序颜色(可选,让饼图从多到少显示)
    counts = dict(sorted(counts.items(), key=lambda item: item[1], reverse=True))
    
    center_colors = clf.cluster_centers_
    ordered_colors = [center_colors[i]/255 for i in counts.keys()]
    hex_colors = [RGB2HEX(center_colors[i]) for i in counts.keys()]
    rgb_colors = [center_colors[i] for i in counts.keys()]
    
    if show_chart:
        plt.figure(figsize=(8, 6))
        plt.pie(counts.values(), labels=hex_colors, colors=ordered_colors)
        # 显式调用show()确保图表显示,即使是inline模式也保险
        plt.show()
    
    # 正确返回RGB颜色列表
    return rgb_colors

# 调用函数,参数顺序现在正确了:先传图像,再颜色数量,最后是否显示图表
image = get_image('C://Users/user/Desktop/g.jpg')
rgb_colors = get_colors(image, 5, True)

修复点说明:

  1. 参数顺序错误:你原来的get_colors定义是(number_of_colors, show_chart),但调用时却传了图像、数量、True,完全不匹配。我把函数改成第一个参数接收图像,这样调用逻辑就对了。
  2. 全局变量隐患:原来的modified_image是在函数外定义的,没有和图像绑定,现在移到get_colors内部,每次处理传入的图像,逻辑更清晰。
  3. 缺少plt.show():即使加了%matplotlib inline,有些环境还是需要显式调用plt.show()才能弹出图表,加上它更稳妥。
  4. 返回值问题:原来的return rgb_colors位置不对,现在放到函数末尾,确保能正确返回颜色列表。

二、实现自动统计颜色数量(无需手动指定k值)

这里用肘部法则来自动确定最优的聚类数(颜色数量)。原理是:随着聚类数k增加,样本到聚类中心的平方误差和(SSE)会逐渐减小,当k超过某个值后,SSE的下降速度会骤减,这个拐点就是肘部,对应的k就是最优值。

实现代码:

先添加一个计算肘部点的函数,然后用它来自动获取k值:

def find_optimal_k(image, max_k=10):
    modified_image = cv2.resize(image, (600, 400), interpolation=cv2.INTER_AREA)
    modified_image = modified_image.reshape(modified_image.shape[0] * modified_image.shape[1], 3)
    
    sse = []
    for k in range(1, max_k+1):
        kmeans = KMeans(n_clusters=k)
        kmeans.fit(modified_image)
        sse.append(kmeans.inertia_)
    
    # 绘制肘部曲线(可选,方便你直观看到拐点)
    plt.figure(figsize=(8, 4))
    plt.plot(range(1, max_k+1), sse, 'bo-')
    plt.xlabel('Number of Clusters (k)')
    plt.ylabel('SSE')
    plt.title('Elbow Method for Optimal k')
    plt.show()
    
    # 计算拐点:找SSE下降幅度最大的点,这里用简单的差值法
    deltas = np.diff(sse)
    # 找差值变化最大的位置,对应的k就是肘部点
    optimal_k = np.argmin(deltas[1:]) + 2  # 因为diff后索引偏移了1,所以加2
    return optimal_k

# 使用方法:
image = get_image('C://Users/user/Desktop/g.jpg')
optimal_k = find_optimal_k(image, max_k=10)
print(f"自动识别的最优颜色数量:{optimal_k}")
rgb_colors = get_colors(image, optimal_k, True)

说明:

  • max_k可以自己调整,比如设为10或15,一般图像的主要颜色不会太多。
  • 肘部法则是经验性的方法,如果你需要更精确的结果,也可以用轮廓系数法,但肘部法则在颜色统计场景下已经足够好用。
  • 运行find_optimal_k会先弹出肘部曲线,你可以直观看到哪个k是拐点,同时函数会自动返回最优k值。

这样修改后,你的程序不仅能正常显示图像统计的饼图,还能自动确定要统计的颜色数量啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:31:20