基于Python實(shí)現(xiàn)圖片主題色的提取
前言
在 Groove 音樂中,當(dāng)我們改變歌曲時(shí),底部播放欄的顏色會(huì)隨專輯封面而變,比如下圖中播放欄的顏色變成了 aiko 衣服的顏色。下面我們會(huì)在 python 中實(shí)現(xiàn)相同的效果,也就是提取出圖片中的主題色。
實(shí)現(xiàn)流程
安裝依賴
提取主題色有很多方法,比如使用 k-means 聚類,選出 k 個(gè) RGB 坐標(biāo)的聚類中心,但是速度會(huì)差一些,我們這里換成中位切分法。已經(jīng)有人為我們實(shí)現(xiàn)好這個(gè)算法了,我們可以拿來就用。
pip install color-thief
提取主題色
color-thief 雖然可以很好地提取出候選的主題色,但還是需要我們親自挑選出合適的主題色,甚至對(duì)主題色做出一些微調(diào)。比如上圖中的文字是淺色的,如果提取到的主題色也是淺色的,效果就很差了。下面是代碼:
# 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 主題色各個(gè)通道的灰度值 """ colorThief = ColorThief(imagePath) # 調(diào)整圖像大小,加快運(yùn)算速度 if max(colorThief.image.size) > 400: colorThief.image = colorThief.image.resize((400, 400)) palette = colorThief.get_palette(quality=9) # 調(diào)整調(diào)色板明度 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): """ 調(diào)整調(diào)色板的明度 """ 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
測(cè)試
下面是一些圖片的測(cè)試結(jié)果,感覺效果還是挺不錯(cuò)的:
到此這篇關(guān)于基于Python實(shí)現(xiàn)圖片主題色的提取的文章就介紹到這了,更多相關(guān)Python主題色提取內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python制作爬蟲并將抓取結(jié)果保存到excel中
本文給大家記錄的是使用Python制作爬蟲爬取拉勾網(wǎng)信息并將結(jié)果保存到Excel中的實(shí)現(xiàn)思路及方法,并附上最終源碼,有需要的小伙伴可以參考下2016-04-04pyinstaller打包單個(gè)exe后無法執(zhí)行錯(cuò)誤的解決方法
今天小編就為大家分享一篇pyinstaller打包單個(gè)exe后無法執(zhí)行錯(cuò)誤的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06基于YUV 數(shù)據(jù)格式詳解及python實(shí)現(xiàn)方式
今天小編就為大家分享一篇基于YUV 數(shù)據(jù)格式詳解及python實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12Python時(shí)間戳與時(shí)間字符串互相轉(zhuǎn)換實(shí)例代碼
這篇文章主要介紹了Python時(shí)間戳與時(shí)間字符串互相轉(zhuǎn)換實(shí)例代碼,大家參考使用2013-11-11Python守護(hù)進(jìn)程(daemon)代碼實(shí)例
這篇文章主要介紹了Python守護(hù)進(jìn)程(daemon)代碼實(shí)例,本文直接給出實(shí)現(xiàn)代碼,代碼中包含詳細(xì)注釋,需要的朋友可以參考下2015-03-03Python實(shí)現(xiàn)讀取excel中的圖片功能
這篇文章主要介紹了如何利用Python實(shí)現(xiàn)讀取Excel中的圖片的功能,文中的實(shí)現(xiàn)步驟講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定幫助,需要的可以參考一下2022-01-01