一张图片主要是什么颜色?用 OpenCV 做图片主色提取工具

前面连续做了图片清晰度检测和图像差异检测,这次继续做一个比较轻量的 OpenCV 小工具:

图片主色提取工具。

有时候我们看到一张图片,会很自然地觉得它"偏蓝""偏绿"或者"整体是暖色调"。

但如果想让程序自动回答:

这张图片主要由哪些颜色组成?每种颜色大概占多少?

就需要把图片里的大量像素颜色进行归类。

这次我使用 OpenCV + K-Means,实现了一个简单的:

Image Color Palette

上传一张图片后,自动提取 Top 5 主色,并显示:

  • 颜色块
  • RGB
  • HEX
  • 颜色占比
  • 完整 Color Palette

一、为什么要提取图片主色?

一张普通图片可能包含几十万甚至上百万个像素。

每个像素都有自己的 RGB 值。

如果直接统计所有颜色,会得到非常多结果,而且很多颜色之间只差一点点。

比如天空区域可能同时包含:

浅蓝

蓝灰

亮蓝

偏白蓝

但从人的视觉角度看,它们其实都属于:

"天空这一组蓝色"

所以更合理的做法,是把相近的颜色聚在一起。

这就是这次使用 K-Means 的原因。


二、K-Means 在这里怎么用?

K-Means 本质上是一种聚类算法。

这次可以把每一个像素理解成一个三维数据点:

R

G

B

也就是:

(R, G, B)

然后让 K-Means 把所有像素分成 5 类。

这里设置:

K = 5

最终每一类都会得到一个聚类中心。

这个中心就可以看成:

这一组像素的代表颜色。

整体流程:

读取图片

↓

转换像素数据

↓

K-Means 聚类

↓

得到 5 个颜色中心

↓

统计每一类像素数量

↓

计算颜色占比

↓

按照占比排序

最后就能得到:

Top 5 Dominant Colors


三、这个工具做了哪些功能?

这次功能依然保持简单。

上传一张 JPG 或 PNG 图片以后,页面会自动显示:

原图预览

Top 5 Color Palette

RGB

HEX

颜色占比

同时 5 个主色会按照占比从高到低排列。

这样就能非常直观地看到:

一张图片整体上是什么颜色风格。


四、真实测试:公园里的狗狗图片

这次继续使用前面一直测试的狗狗图片。

图片里主要包含:

蓝天

绿色草地

树木

湖面

金黄色狗狗

从肉眼上看,本身就是一张颜色比较丰富的图片。

程序最终提取到了 5 个主色。

结果如下:

排名 HEX RGB 占比
1 #A1C8F0 (161, 200, 240) 25.78%
2 #B2A564 (178, 165, 100) 22.65%
3 #7F7D42 (127, 125, 66) 21.96%
4 #DAC59B (218, 197, 155) 15.29%
5 #4B4D1F (75, 77, 31) 14.32%

五种颜色占比相加刚好为:

100%


五、这些颜色和原图对得上吗?

其实从结果就能看出比较明显的对应关系。

第一种颜色:

#A1C8F0

是比较明显的浅蓝色。

它主要对应:

天空

湖面

部分高亮区域

占比:

25.78%

也是整张图片中占比最高的一类颜色。


第二种:

#B2A564

偏黄绿色。

它主要来自:

草地

树木

部分狗狗毛发和地面区域

占比:

22.65%


第三种:

#7F7D42

属于更深一点的橄榄绿色。

主要对应:

树叶

阴影草地

远处植被

占比:

21.96%


第四种:

#DAC59B

属于浅米黄色。

这类颜色主要来自:

狗狗毛发

亮部草地

部分建筑和地面

占比:

15.29%


第五种:

#4B4D1F

是比较深的绿色。

主要来自:

树木阴影

深色植被区域

占比:

14.32%

所以虽然 K-Means 并不知道什么叫:

天空

草地

狗狗

但通过颜色聚类,最终结果和人眼对这张图片的整体感受是比较一致的。


六、为什么不是直接统计"出现最多的 RGB"?

如果直接统计 RGB 出现次数,结果往往并不好用。

因为真实图片里存在:

光照变化

压缩

阴影

渐变

噪声

同一个蓝色天空区域,可能包含很多不同的 RGB 值。

这些颜色看起来很接近,但数值并不完全一样。

如果逐个统计,就会把它们拆成很多小颜色。

K-Means 的作用,就是把这些:

相近的颜色聚成一组。

最终只保留几个代表色。

所以相比直接做像素频次统计,K-Means 更适合做:

图片主色提取。


七、RGB 和 HEX 为什么都显示?

这次页面里同时显示了:

RGB

和:

HEX

例如第一种颜色:

RGB:

(161, 200, 240)

HEX:

#A1C8F0

RGB 更适合程序和图像处理。

HEX 则在:

网页设计

UI 配色

CSS

平面设计

中更加常见。

所以把两种格式都显示出来,后面直接复制颜色会方便很多。


八、这个工具有什么实际用途?

虽然功能比较简单,但实际使用场景还挺多。

图片配色分析

例如看到一张自己喜欢的照片,可以快速提取它的主要颜色。

然后作为:

PPT

海报

网页

UI

的配色参考。


封面设计

如果想让文字、按钮或者装饰元素和原图风格统一,就可以先提取主色。

然后直接使用对应的 HEX。


数据集分析

做计算机视觉任务时,也可以用主色分布简单观察不同图片之间的色彩差异。


图片自动分类

后面如果继续扩展,还可以根据颜色分布把图片简单分成:

偏蓝

偏绿

偏暖

偏暗

等类别。


九、K-Means 也有局限

主色提取并不是说:

这 5 个颜色就是图片中唯一存在的颜色。

实际上,原图里仍然包含大量不同 RGB。

K-Means 只是把这些像素压缩成:

5 个代表颜色。

另外,K 值也会直接影响结果。

如果:

K = 3

得到的是更加概括的主色。

如果:

K = 10

结果会更加细致。

这次选择:

K = 5

主要是因为既不会过于粗略,也不会让页面出现太多颜色。

比较适合做一个简单的 Palette。


十、这次项目依然保持"小而完整"

最近几篇我没有继续做特别复杂的大系统,而是想尝试这种:

一个文章解决一个具体问题。

这次技术也很简单:

Python

OpenCV

FastAPI

原生 HTML / CSS / JavaScript

不需要:

深度学习模型

数据库

登录系统

复杂前端框架

上传一张图片以后,几秒内就能直接得到颜色分析结果。

对于这种小工具来说已经足够了。


总结

这次完成了一个基于 OpenCV K-Means 的图片主色提取工具。

核心流程:

图片

↓

像素 RGB

↓

K-Means

↓

5 个 Cluster

↓

Color Center

↓

颜色占比

↓

Top 5 Palette

真实测试中,这张狗狗图片最终提取出的主色分别为:

#A1C8F0 --- 25.78%

#B2A564 --- 22.65%

#7F7D42 --- 21.96%

#DAC59B --- 15.29%

#4B4D1F --- 14.32%

结果基本对应:

蓝天

草地

植被

狗狗毛发

阴影区域

也说明 K-Means 用来做简单的图片主色分析还是非常直观的。

前面几篇分别解决了:

图片糊不糊?

两张图片哪里不一样?

这一篇则回答:

这张图片主要是什么颜色?

下一篇可以继续做一个同样简单的 OpenCV 小工具:

图片拍歪了怎么办?用 OpenCV 做自动倾斜检测与纠偏。

相关推荐
xsd202411181 小时前
把整套 AI 工作台装进 U 盘:开箱即用的本地短视频生产方案
人工智能
kaixin_啊啊1 小时前
【零基础学AI】第 10 章课后练习与答案
人工智能
智能相对论1 小时前
STEPX Neo:AI终端的“初代iPhone时刻”
人工智能·ios·iphone
xier_ran1 小时前
【infra之路】AI 编译器学习笔记(七):Linalg 与 Tiling——把迭代空间切成块
人工智能·笔记·学习
高洁011 小时前
世界模型环境预测与内在表征基础原理
人工智能·深度学习·机器学习·transformer·tornado
沪上企服通1 小时前
税制变更前的影子账套回归:代账 pipeline 怎么在规则上线前先跑一遍
人工智能·数据挖掘·回归
赶路人儿1 小时前
简述LLM 中的GCG 攻击
人工智能
m0_587383001 小时前
碰碰好评卡功能落地实战 从需求梳理到上线部署全流程实操指南
java·linux·服务器·前端·javascript·vue.js·人工智能
半吊子全栈工匠1 小时前
构建企业级 Agentic AI的语义层
人工智能·语义层·本体驱动的ai大模型