K-Means颜色变卦和渐变色

一、理论深度提升:补充算法细节与数学基础

1. K-Means 算法核心公式(增强专业性)

在 “原理步骤” 中加入数学表达式,说明聚类目标:
K-Means 的目标是最小化簇内平方和(Within-Cluster Sum of Squares, WCSS):J=∑i=1K​∑x∈Ci​​∥x−μi​∥2
其中,Ci​ 是第 i 个簇,μi​ 是簇中心。算法通过迭代更新簇中心 μi​ 和分配样本到最近中心,逐步优化 J。

2. 颜色空间选择(扩展知识边界)

新增小节说明 RGB 颜色空间的局限性,推荐更适合聚类的颜色空间(如 Lab):

  • RGB:各通道高度相关,欧氏距离不能准确反映视觉差异。
  • Lab:基于人眼感知,通道独立,聚类效果更符合视觉预期(可补充代码示例,需安装colorama库)。

 

二、K-Means 颜色聚类(K-Means Color Clustering)

1.概念与作用

K-Means 颜色聚类是借助 K-Means 聚类算法 对图像(或颜色集合)中的颜色进行分组,目的是提取出最具代表性的若干种颜色(聚类中心),实现颜色简化或风格化。比如:

1)简化图像色彩:把照片的上百种颜色压缩为 5 - 10 种主色,生成类似插画、低多边形艺术的效果。

2)色彩分析:快速找出图像里占比高的颜色,用于设计配色参考、图像分类(如区分风景照的 “暖色调”“冷色调” )。

2.原理步骤

1)数据准备:把图像的每个像素(RGB 形式,如 (r, g, b) )视为高维空间(3 维,对应 RGB 通道)中的点。

2)聚类分组:用 K-Means 算法将这些点聚成 K 类(K 是你设定的聚类数,比如 5 类就提取 5 种主色 )。算法随机选 K 个初始中心,不断迭代调整,让同类点尽可能靠近自己的中心,不同类中心尽可能远离。

3)颜色替换:用每个聚类的中心颜色,替换该类所有像素的颜色。最终图像就只剩 K 种主色,实现色彩简化。

代码:(使用的时候记得修改图片路径)

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from matplotlib.image import imreaddef set_chinese_font():"""设置 Matplotlib 支持中文显示的字体"""import matplotlib.font_manager as fmchinese_fonts = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC", "Microsoft YaHei"]available_fonts = [f.name for f in fm.fontManager.ttflist]for font in chinese_fonts:if font in available_fonts:plt.rcParams["font.family"] = fontprint(f"已设置中文字体: {font}")return Trueprint("警告: 未找到可用的中文字体,图表中的中文可能显示为方块")return False# 设置中文字体
set_chinese_font()
image_path = r"D:\keshihua\biancheng\PythonProject1\haimianbaobao.jpg"  
try:image = imread(image_path)if image.shape[-1] == 4:image = image[..., :3]print(f"图像加载成功,尺寸: {image.shape}")
except FileNotFoundError:print("错误:图片路径不存在,请检查路径!")exit(1)
except Exception as e:print(f"加载图片失败: {e}")exit(1)n_clusters = 5  
pixels = image.reshape(-1, 3)  kmeans = KMeans(n_clusters=n_clusters, random_state=42, n_init='auto')
kmeans.fit(pixels)if image.dtype == np.uint8:main_colors = kmeans.cluster_centers_.astype(np.uint8)
else:main_colors = kmeans.cluster_centers_
main_colors = main_colors.reshape(-1, 3)plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(image)
plt.title("原始图像")
plt.axis('off')plt.subplot(1, 2, 2)
color_width = 1 / n_clusters  
for i in range(n_clusters):plt.fill_between(x=[i * color_width, (i + 1) * color_width],y1=0, y2=1,color=main_colors[i] / 255.0 if image.dtype == np.uint8 else main_colors[i],edgecolor='white')
plt.axis('off')
plt.title(f"提取的 {n_clusters} 种主色")plt.tight_layout()
plt.show()print("提取的主色 (RGB 数值):")
for i, color in enumerate(main_colors):if image.dtype == np.uint8:print(f"主色 {i+1}: {color}")else:print(f"主色 {i+1}: {color.round(3)}")

运行结果:

三、渐变色(Gradient Color)

1.概念与作用

渐变色是指 两种或多种颜色之间平滑过渡的色彩效果 ,能营造柔和、连贯的视觉感受。结合 K-Means 颜色聚类,常用来:

1)可视化聚类结果:用聚类得到的主色,生成从一种主色平滑过渡到另一种主色的色带,直观展示 “提取了哪些主色” 。

2)设计配色方案:基于图像主色,快速生成协调的渐变色,用于 UI 设计、海报背景等。

2.实现方式:

1)提取主色:先用 K-Means 聚类得到 K 个主色(聚类中心)。

2)创建渐变映射:用 LinearSegmentedColormap(Matplotlib 工具),把主色按顺序排列,让颜色在色带中平滑过渡。

3)生成渐变图像:用创建好的颜色映射,生成从左到右(或其他方向)的渐变色带。

代码:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from matplotlib.image import imread
from matplotlib.colors import LinearSegmentedColormap# 设置中文字体
def set_chinese_font():import matplotlib.font_manager as fmchinese_fonts = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC", "Microsoft YaHei"]available_fonts = [f.name for f in fm.fontManager.ttflist]for font in chinese_fonts:if font in available_fonts:plt.rcParams["font.family"] = fontprint(f"已设置中文字体: {font}")return Trueprint("警告: 未找到可用的中文字体,图表中的中文可能显示为方块")return Falseset_chinese_font()image_path = r"D:\keshihua\biancheng\PythonProject1\haimianbaobao.jpg"
try:image = imread(image_path)if image.shape[-1] == 4:image = image[..., :3]print(f"图像加载成功,尺寸: {image.shape}")
except Exception as e:print(f"加载图片失败: {e}")exit(1)n_clusters = 5  # 可调整聚类数量
pixels = image.reshape(-1, 3)kmeans = KMeans(n_clusters=n_clusters, random_state=42, n_init='auto')
kmeans.fit(pixels)if image.dtype == np.uint8:main_colors = kmeans.cluster_centers_.astype(np.uint8)
else:main_colors = kmeans.cluster_centers_
main_colors = main_colors.reshape(-1, 3)# 归一化颜色到 [0,1] 范围
main_colors_normalized = main_colors / 255.0 if image.dtype == np.uint8 else main_colors# 创建渐变色映射(按聚类中心顺序过渡)
cmap = LinearSegmentedColormap.from_list('custom_gradient', main_colors_normalized, N=200)# 生成水平渐变色条
gradient = np.linspace(0, 1, 500).reshape(1, -1)  # 500 个渐变点
gradient_image = cmap(gradient)[0, :, :3]  # 提取 RGB 值plt.figure(figsize=(14, 8))# 子图 1:原始图像
plt.subplot(2, 2, 1)
plt.imshow(image)
plt.title("原始图像")
plt.axis('off')# 子图 2:主色提取(色块形式)
plt.subplot(2, 2, 2)
color_width = 1 / n_clusters
for i in range(n_clusters):plt.fill_between(x=[i * color_width, (i + 1) * color_width],y1=0, y2=1,color=main_colors_normalized[i],edgecolor='white',linewidth=1)# 添加颜色标签plt.text((i * color_width + (i + 1) * color_width) / 2,0.5,f"#{i+1}",ha='center',va='center',color='white' if np.mean(main_colors_normalized[i]) < 0.5 else 'black',fontweight='bold')
plt.axis('off')
plt.title(f"提取的 {n_clusters} 种主色")# 子图 3:渐变色条(水平)
plt.subplot(2, 1, 2)
plt.imshow(gradient_image.reshape(1, -1, 3), aspect='auto')
plt.title("主色之间的平缓过渡")
plt.axis('off')# 添加主色标记点(修复颜色格式问题)
for i in range(n_clusters):pos = i / (n_clusters - 1) if n_clusters > 1 else 0.5  # 计算位置plt.plot([pos * 499], [0], 'wo', markersize=8, markeredgecolor='black')  # 白色圆点# 修复:使用 tuple 格式传递颜色,而不是字符串plt.plot([pos * 499], [0], 'o', color=tuple(main_colors_normalized[i]), markersize=5)plt.tight_layout()
plt.show()print("提取的主色 (RGB 数值):")
for i, color in enumerate(main_colors):rgb_str = f"RGB({color[0]:3d}, {color[1]:3d}, {color[2]:3d})"hex_str = '#{:02x}{:02x}{:02x}'.format(*color) if image.dtype == np.uint8 else ''print(f"主色 #{i+1}: {rgb_str} {hex_str if hex_str else ''}")

原图:

四、常见问题与优化策略(提升实用性)

1. 如何选择最优 K 值?

新增小节介绍肘部法则(Elbow Method),通过 WCSS 曲线确定最佳聚类数:

 

# 计算不同K值的WCSS
wcss = []
for k in range(2, 10):kmeans = KMeans(k, random_state=42).fit(pixels)wcss.append(kmeans.inertia_)# 绘制肘部曲线
plt.plot(range(2, 10), wcss, 'bo-')
plt.xlabel("聚类数 K")
plt.ylabel("WCSS")
plt.title("肘部法则确定最优K值")
2. 聚类结果不稳定怎么办?

建议:

  • 增加n_init参数(如n_init=10),重复初始化多次取最优。
  • 使用层次聚类(Hierarchical Clustering)作为预聚类,提供更稳定的初始中心。

 

3. 对比其他颜色聚类算法

新增表格对比 K-Means 与其他算法的优缺点:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/84346.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入解析C#表达式求值:优先级、结合性与括号的魔法

—— 为什么2/6*4不等于1/12&#xff1f; &#x1f50d; 一、表达式求值顺序为何重要&#xff1f; 表达式如精密仪器&#xff0c;子表达式求值顺序直接决定结果。例如&#xff1a; int result 3 * 5 2;若先算乘法&#xff1a;(3*5)2 17 ✅若先算加法&#xff1a;3*(52)21…

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…

Spring——Spring相关类原理与实战

摘要 本文深入探讨了 Spring 框架中 InitializingBean 接口的原理与实战应用&#xff0c;该接口是 Spring 提供的一个生命周期接口&#xff0c;用于在 Bean 属性注入完成后执行初始化逻辑。文章详细介绍了接口定义、作用、典型使用场景&#xff0c;并与其他相关概念如 PostCon…

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…

冯诺依曼架构是什么?

冯诺依曼架构是什么&#xff1f; 冯诺依曼架构&#xff08;Von Neumann Architecture&#xff09;是现代计算机的基础设计框架&#xff0c;由数学家约翰冯诺依曼&#xff08;John von Neumann&#xff09;及其团队在1945年提出。其核心思想是通过统一存储程序与数据&#xff0…

【持续更新】linux网络编程试题

问题1 请简要说明TCP/IP协议栈的四层结构&#xff0c;并分别举出每一层出现的典型协议或应用。 答案 应用层&#xff1a;ping,telnet,dns 传输层&#xff1a;tcp,udp 网络层&#xff1a;ip,icmp 数据链路层&#xff1a;arp,rarp 问题2 下列协议或应用分别属于TCP/IP协议…

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…

React 基础入门笔记

一、JSX语法规则 1. 定义虚拟DOM时&#xff0c;不要写引号 2.标签中混入JS表达式时要用 {} &#xff08;1&#xff09;.JS表达式与JS语句&#xff08;代码&#xff09;的区别 &#xff08;2&#xff09;.使用案例 3.样式的类名指定不要用class&#xff0c;要用className 4.内…

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…

SQL进阶之旅 Day 19:统计信息与优化器提示

【SQL进阶之旅 Day 19】统计信息与优化器提示 文章简述 在数据库性能调优中&#xff0c;统计信息和优化器提示是两个至关重要的工具。统计信息帮助数据库优化器评估查询成本并选择最佳执行计划&#xff0c;而优化器提示则允许开发人员对优化器的行为进行微调。本文深入探讨了…

安宝特方案丨船舶智造AR+AI+作业标准化管理系统解决方案(维保)

船舶维保管理现状&#xff1a;设备维保主要由维修人员负责&#xff0c;根据设备运行状况和维护计划进行定期保养和故障维修。维修人员凭借经验判断设备故障原因&#xff0c;制定维修方案。 一、痛点与需求 1 Arbigtec 人工经验限制维修效率&#xff1a; 复杂设备故障的诊断和…

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…

基于区块链的供应链溯源系统:构建与实践

前言 在当今全球化的经济环境中&#xff0c;供应链的复杂性不断增加&#xff0c;商品从原材料采购到最终交付给消费者的过程涉及多个环节和众多参与者。如何确保供应链的透明度、可追溯性和安全性&#xff0c;成为企业和消费者关注的焦点。区块链技术以其去中心化、不可篡改和透…

Web攻防-SQL注入数据格式参数类型JSONXML编码加密符号闭合

知识点&#xff1a; 1、Web攻防-SQL注入-参数类型&参数格式 2、Web攻防-SQL注入-XML&JSON&BASE64等 3、Web攻防-SQL注入-数字字符搜索等符号绕过 案例说明&#xff1a; 在应用中&#xff0c;存在参数值为数字&#xff0c;字符时&#xff0c;符号的介入&#xff0c…

探秘鸿蒙 HarmonyOS NEXT:实战用 CodeGenie 构建鸿蒙应用页面

在开发鸿蒙应用时&#xff0c;你是否也曾为一个页面的布局反复调整&#xff1f;是否还在为查 API、写模板代码而浪费大量时间&#xff1f;今天带大家实战体验一下鸿蒙官方的 AI 编程助手——CodeGenie&#xff08;代码精灵&#xff09; &#xff0c;如何从 0 到 1 快速构建一个…

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…

使用Whisper本地部署实现香港版粤语+英语混合语音转文字方案

今天要一个非常好的朋友有个工作&#xff0c;就是要把医院医生诊断的说话记录转成文字&#xff0c;之前都是她本人一句一句的听&#xff0c;然后记录下来的&#xff0c;我想通过ai 来解决这个问题。 她的需求如下&#xff1a; 不能把数据传到网上&#xff0c;隐私问题所以需要…

案例分享--汽车制动卡钳DIC测量

制动系统是汽车的主要组成部分&#xff0c;是汽车的主要安全部件之一。随着车辆性能的不断提高&#xff0c;车速不断提升&#xff0c;对车辆的制动系统也随之提出了更高要求&#xff0c;因此了解车辆制动系统中每个部件的动态行为成为了制动系统优化的主要途径&#xff0c;同时…