一定要用Photoshop?no!動手用Python做一個顏色提取器! ⛵

ShowMeAI發表於2022-12-06
一定要用Photoshop?no!動手用Python做一個顏色提取器! ⛵

? 作者:韓信子@ShowMeAI
? Python3◉技能提升系列https://www.showmeai.tech/tutorials/56
? 計算機視覺實戰系列https://www.showmeai.tech/tutorials/46
? 本文地址https://www.showmeai.tech/article-detail/404
? 宣告:版權所有,轉載請聯絡平臺與作者並註明出處
? 收藏ShowMeAI檢視更多精彩內容

? 引言

一定要用Photoshop?no!動手用Python做一個顏色提取器! ⛵

我們本次用到的資料集是 ?Kaggle 100 種鳥資料集,大家可以透過 ShowMeAI 的百度網盤地址下載。

? 實戰資料集下載(百度網盤):公眾號『ShowMeAI研究中心』回覆『實戰』,或者點選 這裡 獲取本文 [39]使用Python構建圖片顏色提取器Bird 450 Species資料集

ShowMeAI官方GitHubhttps://github.com/ShowMeAI-Hub

大家在做影像處理或者製作PPT時,一個非常常用的功能是顏色提取,我們可以透過提取器從已有影像的某個位置提取顏色,而不用自己肉眼比對和選擇。今天ShowMeAI就帶大家用python來實現這個功能。

我們會構建如下2個顏色提取器:

  • 簡單提取器——從單個影像中選擇顏色
  • 複雜提取器——從多個影像中選擇顏色列表並顯示顏色
一定要用Photoshop?no!動手用Python做一個顏色提取器! ⛵

本文的實現涉及python程式設計知識與部分資料視覺化知識,大家可以透過ShowMeAI的以下教程和文章進行系統學習:

?圖解Python程式設計:從入門到精通系列教程

? 資料科學工具庫速查表 | Matplotlib 速查表

? 顏色提取器實現

? 匯入工具庫

首先我們需要匯入本次所需的工具庫,matplotlib.image用於顯示影像,pyperclip用於將字串儲存到剪貼簿,glob用於處理檔案路徑。

#Imports
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

import pyperclip

import random
import glob

我們將從不同的鳥類影像中提取顏色(即大家在第1節看到的影像)。我們讀取路徑下所有的jpg格式影像,程式碼如下:

#Dataset
read_path = "../../data/birds/"
img_path = glob.glob(read_path + "*.jpg")

? 簡單顏色提取器實現

我們先實現一個簡單顏色提取器。它的功能是,每次我們單擊影像中的某個位置,該畫素的 RGB 通道會儲存到我們的剪貼簿中,然後我們可以將該值貼上到筆記本中。

一定要用Photoshop?no!動手用Python做一個顏色提取器! ⛵

我們先構建一個onclick函式,每次單擊影像時都會執行此程式。我們獲取點選的 x 和 y 座標,然後得到該座標處畫素的 RGB 通道值,並將其作為字串儲存到剪貼簿。完整的程式碼如下:

def onclick(event):
    global img
    
    # get x,y of click
    x = round(event.xdata)
    y = round(event.ydata)
    
    # get RGB values
    rgb = img[y][x]
    
    # save to clip board
    pyperclip.copy(str(rgb))

我們要使用上面這個函式,我們首先使用 matplotlib 建立一個圖形,然後設定該圖的互動功能,將onclick函式作為引數傳入,這樣我們每次點選就會呼叫上述函式進行顏色提取。

%matplotlib notebook
global img

fig = plt.figure(figsize=(5,5))

#Add an interactive widget to figure 
cid = fig.canvas.mpl_connect('button_press_event', onclick)

#Load image and add count
path = img_path[0]
img = mpimg.imread(path)

plt.imshow(img)
plt.show()

注意:上述程式碼的第2行使用了全域性變數,這樣就可以在onclick函式中更新這些變數。

? 複雜顏色提取器實現

下面我們來構建一個複雜顏色提取器,它實現的功能如下圖所示:我們多次點選不同影像的多個位置,我們會按照順序編號和記錄顏色(注意顏色框左上角的紅色數字),並把顏色儲存到列表中。

一定要用Photoshop?no!動手用Python做一個顏色提取器! ⛵

我們還是需要構建onclick函式,和之前的簡單顏色提取器有點類似,這裡的主要區別在於我們不直接儲存 RGB 通道值,而是呼叫change_choice來調整右側顯示的提取顏色。

def onclick(event):
    global img
    global rgb
    
    # get x,y of click
    x = round(event.xdata)
    y = round(event.ydata)
    
    # get RGB values
    rgb = img[y][x]
    
    #Update second plot with colour
    change_choice()

我們再定義一個函式onpress,它會在按下鍵盤時執行。這個函式在按下了不同鍵的情況下做不同的處理:(change_imagechange_choice會分別用於更新圖片和更新顯示顏色框,在後續會定義)

  • n:執行change_image函式。
  • c:我們將 RGB 通道值儲存到剪貼簿和顏色列表中,接著執行change_choice函式。

具體程式碼實現如下:

def onpress(event):
    global rgb
    global colours
    
    #Get key 
    key = event.key

    if key == 'n':
        change_image()
        
    elif key == 'c':
         # save to clip board
        pyperclip.copy(str(rgb))
        
        # add to list of colours
        colours.append(rgb)
        
        change_choice()

change_choice函式用於更新右側顏色框。右側的顏色框有與影像框相同的尺寸,並且根據當前全域性 rgb 值進行顏色顯示。

def change_choice():
    global img
    global ax
    global colours
    global rgb
    
    # remove previous count
    for txt in ax[1].texts:
        txt.set_visible(False)
    
    # create array of colour choice
    dims = np.shape(img)
    col = np.array([[rgb]*dims[0]]*dims[1])
    ax[1].imshow(col)
    
    # update colour count
    ax[1].text(0, 15, len(colours),color='r',size=20)
    
    plt.show()

change_choice函式在2處呼叫和執行:

  • 點選圖片時呼叫的onclick函式中,它完成 全域性 rgb 更新並調整框中的顏色。
  • 呼叫onpress函式並按下“c”時,這裡顏色列表的長度+1,顏色計數也會改變。

接下來我們定義change_image函式。我們在按下“n”時會呼叫它更新影像框。程式碼如下:

def change_image():
    global img_path
    global img
    global ax
    global rgb
    
    # close all open plots
    plt.close('all')
    
    fig,ax = plt.subplots(1,2,figsize=(10,5))
    
    # add an interactive widget to figure 
    cid = fig.canvas.mpl_connect('button_press_event', onclick)
    cid2 = fig.canvas.mpl_connect('key_press_event', onpress)

    # load random image
    path = random.choice(img_path)
    img = mpimg.imread(path)
    
    ax[0].imshow(img)
    
    # reset the colour window
    rgb = [255,255,255]
    change_choice()

我們可以透過執行change_image函式來啟動顏色選擇器,如下:

%matplotlib tk
global img_path
global colours
colours = []

# load image paths
read_path = "../../data/birds/"
img_path = glob.glob(read_path + "*.jpg")

# start widget
change_image()

接下來當你就可以使用這個複雜顏色提取器啦,在您遍歷影像並儲存顏色時,顏色列表隨之更更新,我們在下圖的 colours 裡可以看到提取的顏色構建的rgb值序列。

一定要用Photoshop?no!動手用Python做一個顏色提取器! ⛵

參考資料

推薦閱讀

一定要用Photoshop?no!動手用Python做一個顏色提取器! ⛵

相關文章