如何在 python 中提取图片主题色
前言
在 Groove 音乐中,当我们改变歌曲时,底部播放栏的颜色会随专辑封面而变,比如下图中播放栏的颜色变成了 aiko 衣服的颜色。下面我们会在 python 中实现相同的效果,也就是提取出图片中的主题色。
实现流程
安装依赖
提取主题色有很多方法,比如使用 k-means 聚类,选出 k 个 RGB 坐标的聚类中心,但是速度会差一些,我们这里换成中位切分法。已经有人为我们实现好这个算法了,我们可以拿来就用。
pip install color-thief
提取主题色
color-thief 虽然可以很好地提取出候选的主题色,但还是需要我们亲自挑选出合适的主题色,甚至对主题色做出一些微调。比如上图中的文字是浅色的,如果提取到的主题色也是浅色的,效果就很差了。下面是代码:
# coding: utf-8
from math import floor
import numpy as np
from colorthief import ColorThief
class DominantColor:
""" 图像主题色类 """
@classmethod
def getDominantColor(cls, imagePath: str):
""" 获取指定图片的主题色
Parameters
----------
imagePath: str
图片路径
Returns
-------
r, g, b: int
主题色各个通道的灰度值
"""
colorThief = ColorThief(imagePath)
# 调整图像大小,加快运算速度
if max(colorThief.image.size) > 400:
colorThief.image = colorThief.image.resize((400, 400))
palette = colorThief.get_palette(quality=9)
# 调整调色板明度
palette = cls.__adjustPaletteValue(palette)
for rgb in palette[:]:
h, s, v = cls.rgb2hsv(rgb)
if h < 0.02:
palette.remove(rgb)
if len(palette) <= 2:
break
# 挑选主题色
palette = palette[:5]
palette.sort(key=lambda rgb: cls.colorfulness(*rgb), reverse=True)
return palette[0]
@classmethod
def __adjustPaletteValue(cls, palette: list):
""" 调整调色板的明度 """
newPalette = []
for rgb in palette:
h, s, v = cls.rgb2hsv(rgb)
if v > 0.9:
factor = 0.8
elif 0.8 < v <= 0.9:
factor = 0.9
elif 0.7 < v <= 0.8:
factor = 0.95
else:
factor = 1
v *= factor
newPalette.append(cls.hsv2rgb(h, s, v))
return newPalette
@staticmethod
def rgb2hsv(rgb: tuple) -> tuple:
""" rgb空间变换到hsv空间 """
r, g, b = [i / 255 for i in rgb]
mx = max(r, g, b)
mn = min(r, g, b)
df = mx - mn
if mx == mn:
h = 0
elif mx == r:
h = (60 * ((g - b) / df) + 360) % 360
elif mx == g:
h = (60 * ((b - r) / df) + 120) % 360
elif mx == b:
h = (60 * ((r - g) / df) + 240) % 360
s = 0 if mx == 0 else df / mx
v = mx
return h, s, v
@staticmethod
def hsv2rgb(h, s, v) -> tuple:
""" hsv空间变换到rgb空间 """
h60 = h / 60.0
h60f = floor(h60)
hi = int(h60f) % 6
f = h60 - h60f
p = v * (1 - s)
q = v * (1 - f * s)
t = v * (1 - (1 - f) * s)
r, g, b = 0, 0, 0
if hi == 0:
r, g, b = v, t, p
elif hi == 1:
r, g, b = q, v, p
elif hi == 2:
r, g, b = p, v, t
elif hi == 3:
r, g, b = p, q, v
elif hi == 4:
r, g, b = t, p, v
elif hi == 5:
r, g, b = v, p, q
r, g, b = int(r * 255), int(g * 255), int(b * 255)
return r, g, b
@staticmethod
def colorfulness(r: int, g: int, b: int):
rg = np.absolute(r - g)
yb = np.absolute(0.5 * (r + g) - b)
rg_mean, rg_std = np.mean(rg), np.std(rg)
yb_mean, yb_std = np.mean(yb), np.std(yb)
std_root = np.sqrt(rg_std ** 2 + yb_std ** 2)
mean_root = np.sqrt(rg_mean ** 2 + yb_mean ** 2)
return std_root + 0.3 * mean_root
测试
下面是一些图片的测试结果,感觉效果还是挺不错的:
如何在 python 中提取图片主题色的更多相关文章
- 小技巧!CSS 提取图片主题色功能探索
本文将介绍一种利用 CSS 获取图片主题色的小技巧.一起看看~ 背景 起因是微信技术群里有个同学发问,有什么方法能够获取图片的主色呢?有一张图片,获取他的主色调: 利用获取到的这个颜色值,来实现类似这 ...
- 利用ROS工具从bag文件中提取图片
bag文件是ROS常用的数据存储格式,因此要从bag文件中提取数据就需要了解一点ROS的背景知识. 1. 什么是ROS及其优势 ROS全称Robot Operating System,是BSD-lic ...
- 如何在Python中从零开始实现随机森林
欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 决策树可能会受到高度变异的影响,使得结果对所使用的特定测试数据而言变得脆弱. 根据您的测试数据样本构建多个模型(称为套袋)可以减少这种差异,但是 ...
- 如何在Python 中使用UTF-8 编码 && Python 使用 注释,Python ,UTF-8 编码 , Python 注释
如何在Python 中使用UTF-8 编码 && Python 使用 注释,Python ,UTF-8 编码 , Python 注释 PIP $ pip install beauti ...
- 面试官问我:如何在 Python 中解析和修改 XML
摘要:我们经常需要解析用不同语言编写的数据.Python提供了许多库来解析或拆分用其他语言编写的数据.在此 Python XML 解析器教程中,您将学习如何使用 Python 解析 XML. 本文分享 ...
- 如何在Python中加速信号处理
如何在Python中加速信号处理 This post is the eighth installment of the series of articles on the RAPIDS ecosyst ...
- c# HTML中提取图片地址
public class HtmlHelper { /// <summary> /// HTML中提取图片地址 /// </summa ...
- [Linux] 如何在 Linux 中提取随机数
如何在 Linux 中提取随机数 一.设备文件 /dev/random & /dev/urandom 字符特殊文件 /dev/random 和 /dev/urandom (存在于Linux 1 ...
- C#从Gif中提取图片
C#从Gif中提取图片的代码片段 private void btn_extract_Click(object sender, EventArgs e) { Image imgGif = Image.F ...
随机推荐
- 第二十一个知识点:CRT算法如何提高RSA的性能?
第二十一个知识点:CRT算法如何提高RSA的性能? 中国剩余定理(The Chinese Remainder Theorem,CRT)表明,如果我们有两个等式\(x = a \mod N\) 和\(x ...
- Adversarial Examples Are Not Bugs, They Are Features
目录 概 主要内容 符号说明及部分定义 可用特征 稳定可用特征 可用不稳定特征 标准(standard)训练 稳定(robust)训练 分离出稳定数据 分离出不稳定数据 随机选取 选取依赖于 比较重要 ...
- CH7511|LT7211|PS8625替代方案 CS5211 设计EDP转LVDS优势方案原理图+PCB板设计
CH7511|LT7211|PS8625这三款都是专门用于设计EDP转LVDS转接板或者屏转换方案板,CH7511.LT7211.PS8625目前这几款都是出于缺货状态,台湾瑞奇达Capstone 新 ...
- 前后端java+vue 实现rsa 加解密与摘要签名算法
RSA 加密.解密.签名.验签.摘要,前后端java+vue联调测试通过 直接上代码 // 注意:加密密文与签名都是唯一的,不会变化.// 注意:vue 端密钥都要带pem格式.java 不要带pem ...
- 使用 jQuery 实现页面背景色的更换,通过下拉框选择对应的颜色,页面背景会随着选中的颜色进行更换
查看本章节 查看作业目录 需求说明: 使用 jQuery 实现页面背景色的更换,通过下拉框选择对应的颜色,页面背景会随着选中的颜色进行更换 实现思路: 在页面中添加 <select> 标签 ...
- 使用 JavaScript 中的 document 对象的属性,根据下拉框中选择的属性,更改页面中的字体颜色和背景颜色
查看本章节 查看作业目录 需求说明: 使用 JavaScript 中的 document 对象的属性,根据下拉框中选择的属性,更改页面中的字体颜色和背景颜色 实现思路: 在页面的 <body&g ...
- Linux查找class类所在jar包
1.说明 写代码或者定位问题的时候, 经常发生只知道类名不知道其所在jar包的问题, 在Eclipse中可以使用Ctrl+Shift+T查找类, 但是如果类所在的jar包不在Build Path中, ...
- Python_对excel表格读写-openpyxl、xlrd&xlwt
openpyxl 和 xlrd&xlwt 都能对excel进行读写,但是它们读写的格式不同,openpyxl 只能读写 xlsx格式的excel,xlrd&xlwt 只能读写 xls格 ...
- 详解nginx的请求限制(连接限制和请求限制)
https://www.jb51.net/article/143682.htm 一,背景 我们经常会遇到这种情况,服务器流量异常,负载过大等等.对于大流量恶意的攻击访问,会带来带宽的浪费,服务器压力, ...
- spring security 登出操作 详细说明
1.前言 这里专门 做 spring security 登出操作 的 详细记录 2.操作 (1)目录结构 (2)在security 拦截规则配置文件添加退出登录支持 源码 package com.e ...