使用Python實現(xiàn)圖像顏色量化的方法
一、選擇圖片
從選擇圖像開始。 例如,我將使用下面的海水和椰子樹的照片。

二、創(chuàng)建腳本
1、導(dǎo)入相關(guān)庫
接下來,讓我們導(dǎo)入 extcolors 和 rgb2hex 庫。 extcolors 庫返回 RGB 值,將使用 rgb2hex 庫將其轉(zhuǎn)換為 HEX 顏色代碼。
import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.patches as patches import matplotlib.image as mpimg from PIL import Image from matplotlib.offsetbox import OffsetImage, AnnotationBbox
如果在導(dǎo)入這兩個庫時出現(xiàn)一些錯誤,您可以嘗試安裝一些必備庫以使其工作。 這些庫在下面的代碼中。 刪除 !pip 前面的 # 符號并運行以安裝它們。 請不要刪除版本號前的#符號。 它們只是筆記。
#!pip install easydev #version 0.12.0 #!pip install colormap #version 1.0.4 #!pip install opencv-python #version 4.5.5.64 #!pip install colorgram.py #version 1.2.0 #!pip install extcolors #version 1.0.0 import cv2 import extcolors from colormap import rgb2hex
2、創(chuàng)建方法
接下來,我將逐步解釋如何創(chuàng)建用于顏色提取的函數(shù)。 如果你想直接得到函數(shù),請給定義一個函數(shù)打分。
調(diào)整圖像大小
從準(zhǔn)備輸入圖像開始。 用現(xiàn)代相機和手機拍攝的照片太大了。 有些人可以拍攝超過 50 兆像素的照片(4K 顯示器只能顯示大約 8.3 兆像素)。 如果我們直接使用一個巨大的圖像,處理可能需要一些時間。
因此,首先要做的是調(diào)整大小。 下面的代碼顯示了如何將圖片的大小調(diào)整為 900 像素的寬度。 如果圖像不是很大或者你的 CPU 速度很快,這一步可以省略,或者可以增加輸出分辨率數(shù)。 請注意,調(diào)整照片大小后,新照片將保存在您的計算機上以供下一步閱讀。
input_name = '<photo location/name>'
output_width = 900 #set the output size
img = Image.open(input_name)
wpercent = (output_width/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((output_width,hsize), Image.ANTIALIAS)
#save
resize_name = 'resize_' + input_name #the resized image name
img.save(resize_name) #output location can be specified before resize_name
#read
plt.figure(figsize=(9, 9))
img_url = resize_name
img = plt.imread(img_url)
plt.imshow(img)
plt.axis('off')
plt.show()顏色提取
使用 extcolors 庫提取顏色。 我們必須設(shè)置的參數(shù):
容差:對顏色進行分組以限制輸出并提供更好的視覺表示。 基于從 0 到 100 的比例。其中 0 不會對任何顏色進行分組,而 100 會將所有顏色歸為一個。
限制:輸出中呈現(xiàn)的提取顏色數(shù)量的上限。
在下面的代碼中,我將公差值設(shè)置為 12,并將顏色代碼輸出的數(shù)量限制為 11 種顏色(limit=12)。 可以根據(jù)需要更改數(shù)字。 獲得的結(jié)果將是 RGB 顏色代碼及其出現(xiàn)。
colors_x = extcolors.extract_from_path(img_url, tolerance = 12, limit = 12) colors_x
使用 rgb2hex 庫定義一個函數(shù)以將 RGB 代碼轉(zhuǎn)換為 HEX 顏色代碼并創(chuàng)建一個 DataFrame。
def color_to_df(input):
colors_pre_list = str(input).replace('([(','').split(', (')[0:-1]
df_rgb = [i.split('), ')[0] + ')' for i in colors_pre_list]
df_percent = [i.split('), ')[1].replace(')','') for i in colors_pre_list]
#convert RGB to HEX code
df_color_up = [rgb2hex(int(i.split(", ")[0].replace("(","")),
int(i.split(", ")[1]),
int(i.split(", ")[2].replace(")",""))) for i in df_rgb]
df = pd.DataFrame(zip(df_color_up, df_percent), columns = ['c_code','occurence'])
return df
df_color = color_to_df(colors_x)
df_color繪制圖標(biāo)
list_color = list(df_color['c_code'])
list_precent = [int(i) for i in list(df_color['occurence'])]
text_c = [c + ' ' + str(round(p*100/sum(list_precent),1)) +'%' for c, p in zip(list_color,
list_precent)]
fig, ax = plt.subplots(figsize=(90,90),dpi=10)
wedges, text = ax.pie(list_precent,
labels= text_c,
labeldistance= 1.05,
colors = list_color,
textprops={'fontsize': 120, 'color':'black'}
)
plt.setp(wedges, width=0.3)
#create space in the center
plt.setp(wedges, width=0.36)
ax.set_aspect("equal")
fig.set_facecolor('white')
plt.show()
#create background color
fig, ax = plt.subplots(figsize=(192,108),dpi=10)
fig.set_facecolor('white')
plt.savefig('bg.png')
plt.close(fig)
#create color palette
bg = plt.imread('bg.png')
fig = plt.figure(figsize=(90, 90), dpi = 10)
ax = fig.add_subplot(1,1,1)
x_posi, y_posi, y_posi2 = 320, 25, 25
for c in list_color:
if list_color.index(c) <= 5:
y_posi += 125
rect = patches.Rectangle((x_posi, y_posi), 290, 115, facecolor = c)
ax.add_patch(rect)
ax.text(x = x_posi+360, y = y_posi+80, s = c, fontdict={'fontsize': 150})
else:
y_posi2 += 125
rect = patches.Rectangle((x_posi + 800, y_posi2), 290, 115, facecolor = c)
ax.add_artist(rect)
ax.text(x = x_posi+1160, y = y_posi2+80, s = c, fontdict={'fontsize': 150})
ax.axis('off')
plt.imshow(bg)
plt.tight_layout()
三、完整代碼
我為了省事,resize路徑被寫在程序了,請注意根據(jù)自己的情況修改。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.image as mpimg
from PIL import Image
from matplotlib.offsetbox import OffsetImage, AnnotationBbox
import cv2
import extcolors
from colormap import rgb2hex
def color_to_df(input):
colors_pre_list = str(input).replace('([(', '').split(', (')[0:-1]
df_rgb = [i.split('), ')[0] + ')' for i in colors_pre_list]
df_percent = [i.split('), ')[1].replace(')', '') for i in colors_pre_list]
# convert RGB to HEX code
df_color_up = [rgb2hex(int(i.split(", ")[0].replace("(", "")),
int(i.split(", ")[1]),
int(i.split(", ")[2].replace(")", ""))) for i in df_rgb]
df = pd.DataFrame(zip(df_color_up, df_percent), columns=['c_code', 'occurence'])
return df
def exact_color(input_image, resize, tolerance, zoom):
# background
bg = 'bg.png'
fig, ax = plt.subplots(figsize=(192, 108), dpi=10)
fig.set_facecolor('white')
plt.savefig(bg)
plt.close(fig)
# resize
output_width = resize
img = Image.open(input_image)
if img.size[0] >= resize:
wpercent = (output_width / float(img.size[0]))
hsize = int((float(img.size[1]) * float(wpercent)))
img = img.resize((output_width, hsize), Image.ANTIALIAS)
resize_name = 'C:/Users/zyh/Desktop/resize_456.jpg'
img.save(resize_name)
else:
resize_name = input_image
# crate dataframe
img_url = resize_name
colors_x = extcolors.extract_from_path(img_url, tolerance=tolerance, limit=13)
df_color = color_to_df(colors_x)
# annotate text
list_color = list(df_color['c_code'])
list_precent = [int(i) for i in list(df_color['occurence'])]
text_c = [c + ' ' + str(round(p * 100 / sum(list_precent), 1)) + '%' for c, p in zip(list_color, list_precent)]
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(160, 120), dpi=10)
# donut plot
wedges, text = ax1.pie(list_precent,
labels=text_c,
labeldistance=1.05,
colors=list_color,
textprops={'fontsize': 150, 'color': 'black'})
plt.setp(wedges, width=0.3)
# add image in the center of donut plot
img = mpimg.imread(resize_name)
imagebox = OffsetImage(img, zoom=zoom)
ab = AnnotationBbox(imagebox, (0, 0))
ax1.add_artist(ab)
# color palette
x_posi, y_posi, y_posi2 = 160, -170, -170
for c in list_color:
if list_color.index(c) <= 5:
y_posi += 180
rect = patches.Rectangle((x_posi, y_posi), 360, 160, facecolor=c)
ax2.add_patch(rect)
ax2.text(x=x_posi + 400, y=y_posi + 100, s=c, fontdict={'fontsize': 190})
else:
y_posi2 += 180
rect = patches.Rectangle((x_posi + 1000, y_posi2), 360, 160, facecolor=c)
ax2.add_artist(rect)
ax2.text(x=x_posi + 1400, y=y_posi2 + 100, s=c, fontdict={'fontsize': 190})
fig.set_facecolor('white')
ax2.axis('off')
bg = plt.imread('bg.png')
plt.imshow(bg)
plt.tight_layout()
return plt.show()
exact_color('C:/Users/zyh/Desktop/456.jpg', 900, 12, 2.5)運行結(jié)果如下

到此這篇關(guān)于使用Python進行圖像顏色量化的文章就介紹到這了,更多相關(guān)Python圖像顏色量化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
對numpy中的transpose和swapaxes函數(shù)詳解
今天小編就為大家分享一篇對numpy中的transpose和swapaxes函數(shù)詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
python實現(xiàn)數(shù)據(jù)導(dǎo)出到excel的示例--普通格式
今天小編就為大家分享一篇python實現(xiàn)數(shù)據(jù)導(dǎo)出到excel的示例--普通格式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-05-05
基于python2.7實現(xiàn)圖形密碼生成器的實例代碼
本文通過實例代碼給大家介紹了python2.7實現(xiàn)圖形密碼生成器,代碼簡單易懂,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧2019-11-11

