
| 圖源1、圖源2
無論繪制什么圖表,配色方案都是非常重要的,配的好,整幅圖看起來會自然美觀,反之就可能很別扭,所謂的配色,筆者覺得就是一幅圖表的幾種主要顏色,一般繪圖的工具都會提供一些調色板,供我們配色,但是工具提供的顏色色終究是比較有限的,有時我們可能需要自己配色,如果沒有美識訓礎,自己配起來會比較難,這時我們可能需要借鑒其他的好看的圖表的配色,用取色器一個一個的取色顯得有些繁瑣,不過最近筆者發現了一個小工具haishoku,它借助pillow獲取色彩串列,可自動獲取一幅圖的主色調和配色方案,最多可以提取8種配色,haishoku只有300多行代碼,體量很小,也是一個學習CV的小案例,以下將用haishoku提取配色方案,并用seaborn繪圖,一起來看看吧,
copyright ? 意疏:https://blog.csdn.net/sinat_35907936/article/details/120589389
Haishoku簡介
-
haishoku原始碼簡介
haishoku代碼的核心是用pillow來獲取一幅影像的顏色串列,使用Image模塊的getcolors方法,該方法回傳某RGB出現的頻次和RGB值組成的元組,如下所示,注:maxcolors默認為256,即默認的最大顏色數只有256,如果輸入影像中的顏色數大于256,需要修改默認值,否則getcolors回傳會為空值,
from PIL import Image
img = Image.open('palette.png').convert('RGB')
# 縮小圖片,以減少計算量和限制最大色彩數
img = img.resize((256, 256),Image.ANTIALIAS)
colors = img.getcolors(maxcolors=256*256)
colors_sorted_freq = sorted(colors, key=lambda x:x[0], reverse=True)
print(colors_sorted_freq)
顏色串列:下圖左與下圖右的顏色串列
[(21025, (255, 255, 255)),
(5544, (64, 101, 156)),
(4992, (162, 212, 37)),
(4626, (141, 232, 235)),
(4394, (207, 177, 45)),
(4077, (147, 174, 243)),
(3196, (206, 59, 103)),
(3083, (98, 67, 82)),
(2624, (115, 217, 143)),
(365, (208, 178, 48)),
...,
]
[(101, (43, 46, 89)),
(100, (42, 45, 88)),
(91, (46, 49, 92)),
(89, (41, 44, 87)),
(85, (44, 47, 90)),
(83, (66, 97, 117)),
(83, (45, 48, 91)),
(80, (81, 124, 133)),
(79, (39, 42, 87)),
(77, (82, 125, 134)),
...,
]
主色調與配色:注意到,上面的顏色串列是按照顏色出現頻次降序排列的,如果把第一個作為主色調,然后把前若干個作為配色方案,這對于下圖左圖來說是一個比較不錯的方法,因為它顏色分明,而且各顏色集中,截取的前若干個顏色恰好是影像的配色方案的子集,但對于下圖右圖來講,就不理想了,因為它雖然顏色分明,但是顏色不集中,RGB值是漸變的,分散的,同樣是取前若干個顏色,得到的卻只是主色調的子集,而不是影像中我們肉眼可見的幾種主要顏色,

代碼:包括生成RGB串列、十六進制RGB編碼和顯示色帶,生成編碼的目的是方便在繪圖工具中直接使用,
from PIL import Image
img = Image.open('palette.png').convert('RGB')
# 縮小圖片,以減少計算量和限制最大色彩數
img = img.resize((256, 256),Image.ANTIALIAS)
colors = img.getcolors(maxcolors=256*256)
colors_sorted_freq = sorted(colors, key=lambda x:x[0], reverse=True)
# 提取顏色數
color_num = 9
# 獲取主要色彩RGB串列
main_RGB_list = [list(color[1]) for color in colors_sorted_freq[:color_num]]
print(main_RGB_list)
# 獲取主要色彩16進制編碼串列,hex函式輸出字符前兩個是0x
main_hex_list = ['#' + hex(color[1][0])[2:4] + hex(color[1][1])[2:4] + hex(color[1][2])[2:4] for color in colors_sorted_freq[:color_num]]
print(main_hex_list)
# 創建空圖用于存放配色帶
box_w, box_h = 1000,100
palette = Image.new('RGB', (box_w, box_h))
# 用于下面計算每種顏色占比
color_count_sum = sum([color[0] for color in colors_sorted_freq[:color_num]])
# 生成色帶圖
init_ul = 0
for color in colors_sorted_freq[:color_num]:
img_w = math.ceil(box_w*color[0]/color_count_sum)
new_image = Image.new('RGB', (img_w, box_h), color[1])
palette.paste(new_image, (init_ul, 0))
init_ul += img_w
palette.show()
RGB串列與十六進制RGB編碼
[[255, 255, 255], [64, 101, 156], [162, 212, 37], [141, 232, 235], [207, 177, 45], [147, 174, 243], [206, 59, 103], [98, 67, 82], [115, 217, 143]]
['#ffffff', '#40659c', '#a2d425', '#8de8eb', '#cfb12d', '#93aef3', '#ce3b67', '#624352', '#73d98f']
現實中大多數圖片中的RGB值都是漸變的,分散的,先把類似的顏色分組,再選主色調和配色方案才是合理的,這樣保證了選出來的顏色是影像中的主要顏色,haishoku作者采用RGB值分別分為三組的形式,將一幅圖片的RGB值拆分成了九個大組,再用每個大組里的RGB值的加權平均表示該組的顏色,其中權值是該RGB值在該組中出現的頻次的占比,最后輸出前8種顏色作為配色方案,詳見原始碼,其實除了這種手動分組的形式,還可以通過聚類演算法來自動分組,用聚類中心的RGB值作為該組的顏色代表,
copyright ? 意疏:https://blog.csdn.net/sinat_35907936/article/details/120589389
-
安裝與介面
安裝:
pip install haishoku
介面:
showPalette # 顯示配色方案
showDominant # 顯示主色調
getDominant # 獲取主色調
getPalette # 獲取配色方案
Haishoku基本使用
Haishoku只為我們提供了最多8種顏色的配色方案,如果想要更多這需要修改其原始碼,這并不復雜,實際上,我們在繪圖的時候,用到的顏色是不會太多的,所以8種應該也夠,通過上述介面,我們可以很容易的獲得配色方案并顯示配色方案,

原始碼:
from haishoku.haishoku import Haishoku
path = 'palette.png'
# 可以用網頁鏈接
# path = "http://wx2.sinaimg.cn/large/89243dfbly1ffoekfainzj20dw05k0u7.jpg"
# Haishoku是一個物件
h = Haishoku.loadHaishoku(path)
print(h.palette)
print(h.dominant)
palette = Haishoku.getPalette(path)
dominant = Haishoku.getDominant(path)
# 顯示色帶
Haishoku.showPalette(path)
# Haishoku.showDominant(path)
主色調與配色:輸出了上圖左圖的主色調和配色,可以觀察到主色調并不是(255,255,255),這也就間接說明了主色調與配色方案中的每一種顏色都是是求平均而來的,由于haishoku介面輸出的依舊是元組,我們需要處理一下才方便使用,至于如何處理,請往下看,
[(0.4, (252, 253, 252)), (0.11, (63, 100, 155)), (0.1, (162, 212, 38)), (0.1, (142, 232, 235)), (0.09, (206, 176, 44)), (0.08, (146, 172, 239)), (0.06, (97, 66, 81)), (0.06, (206, 61, 104))]
(252, 253, 252)
配色方案應用——seaborn繪圖
-
第一幅圖配色應用
第一幅圖配色方案的應用,由于已經用RGB_encode函式把Haishoku輸出轉換成了十六進制編碼,所以直接把編碼中的若干個傳遞給繪圖函式就可以了,關鍵詞palette,意思就是配色,

import seaborn as sns
import matplotlib.pyplot as plt
from haishoku.haishoku import Haishoku
def RGB_encode(color_list):
# 獲取主要色彩RGB串列
main_RGB_list = [list(color[1]) for color in color_list]
# 獲取主要色彩16進制編碼串列
main_hex_list = ['#' + hex(color[1][0])[2:4] + hex(color[1][1])[2:4] + hex(color[1][2])[2:4] for color in color_list]
return main_RGB_list, main_hex_list
# 獲取配色方案
path = 'palette.png'
palette = Haishoku.getPalette(path)
main_RGB_list, main_hex_list = RGB_encode(palette)
print(main_RGB_list)
print(main_hex_list)
# 繪圖
sns.set_style("whitegrid")
tips = sns.load_dataset("tips")
plt.figure(figsize=(10, 8))
ax = sns.boxplot(x="day", y="total_bill",
data=tips,whis=[0, 100], palette=main_hex_list[1:])
sns.stripplot(x="day", y="total_bill", data=tips,
size=4, color=".3", linewidth=0)
plt.show()
如果出現以下錯誤,表明本地沒有seaborn的內置資料,在github上面下載下來,然后放在C:\Users\YourName\seaborn-data目錄下面即可,
URLError: <urlopen error [Errno 11004] getaddrinfo failed>
-
第二幅圖配色應用
第二幅圖也是類似的操作,代碼修改很小,

import seaborn as sns
import matplotlib.pyplot as plt
from haishoku.haishoku import Haishoku
def RGB_encode(color_list):
# 獲取主要色彩RGB串列
main_RGB_list = [list(color[1]) for color in color_list]
# 獲取主要色彩16進制編碼串列
main_hex_list = ['#' + hex(color[1][0])[2:4] + hex(color[1][1])[2:4] + hex(color[1][2])[2:4] for color in color_list]
return main_RGB_list, main_hex_list
# 獲取配色方案
path = 'rose.jpg'
palette = Haishoku.getPalette(path)
main_RGB_list, main_hex_list = RGB_encode(palette)
print(main_RGB_list)
print(main_hex_list)
# 繪圖
sns.set_style("whitegrid")
titanic = sns.load_dataset("titanic")
plt.figure(figsize=(10, 8))
ax = sns.catplot(x="sex", y="survived", hue="class", kind="bar", data=titanic,palette=main_hex_list[3:])
plt.show()
注意到Haishoku這種手動分組的組數,即最大配色方案顏色數是不易更改的,牽一發而動全身,所以用聚類來進行顏色分組或許能取得更具有彈性的配色方案,后面筆者將嘗試用聚類方法來獲取一副圖中的配色方案,歡迎關注,
copyright ? 意疏:https://blog.csdn.net/sinat_35907936/article/details/120589389
參考
https://github.com/buptlihang/haishoku/blob/master/docs/document_zh.md
https://github.com/buptlihang/haishoku/blob/master/demo/demo.py
http://seaborn.pydata.org/examples/horizontal_boxplot.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/305208.html
標籤:python
