教你如何用python把玩守望先鋒新英雄

資料團學社發表於2018-11-29

本文約1500字,閱讀需要5分鐘

關鍵詞:Python P圖  OpenCV

本文講述了藉助Python語言和OpenCV工具庫完成一個簡單的P圖操作的過程~

作為一名視覺化工程師,如果只會使用PS,那麼你一定OUT了。在專注各種花式P圖多年,在學習PS,AI,PR,AE,XD……無數設計軟體之後,本人終於悟到了一門獨步江湖的絕技——“程式碼P圖”。

今天,我就把這門P圖界的無上秘籍,傳授給你!希望你在炫技(zuo si)的道路上越走越遠。

來看一下今天的素材:守望先鋒新上線的英雄——艾什的正面照:

教你如何用python把玩守望先鋒新英雄

然後這是一張背景圖:

教你如何用python把玩守望先鋒新英雄

今天的任務很簡單,我要對第一張圖中的人物進行摳圖,然後貼在背景圖上

這個操作用PS並不複雜,讓我們來看一下這一過程如何用程式碼來實現~

 素材處理 


首先,匯入一些工具包

opencv(cv2),用於影像處理

numpy,用於資料計算。

matplotlib用於出圖。

import cv2
import numpy as np
import matplotlib.pyplot as plt

 建立一個顯示圖片的函式,便於在P圖過程中,實時檢視效果

使用的是matplotlib的功能,和製作圖表的過程一致。

#建立顯示圖片的函式
def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()

 然後,匯入前景圖

因為opencv的圖片預設使用BGR影像格式,而我們通常使用的圖片是RGB(紅,綠,藍),所以,需要再轉換一下格式,否則檢視時顏色會失真。

最後列印圖片規格和圖片本身

#匯入前景圖
img=cv2.imread('img.png'#圖片匯入
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) #轉換顏色模型
print(img.shape) #列印圖片規格
show(img) #顯示圖片

 來看一下效果,高1054畫素,長703畫素,3通道。

教你如何用python把玩守望先鋒新英雄

 

同樣的方法,匯入背景圖

#匯入背景圖
back_img = cv2.imread('back_img.jpg'#圖片匯入
back_img = cv2.cvtColor(back_img,cv2.COLOR_BGR2RGB) #轉換顏色模型
print(back_img.shape) #列印圖片規格
show(back_img) #顯示圖片

 

效果如下,高1079,長1920,3通道。

教你如何用python把玩守望先鋒新英雄

我們發現人物圖高度和背景高度差不多,且我們只要中間的人像即可,那麼我們先來適當地裁剪一下圖片

#裁剪圖片
img = img[0:1000,150:550#裁剪圖片大小
show(img) #顯示圖片


透過切片,裁去了logo

教你如何用python把玩守望先鋒新英雄

 

再對圖片縮小10%,這樣大小最為合適

#縮放圖片
print(img.shape) #列印圖片規格
img=cv2.resize(img,None,fx=0.9,fy=0.9#圖片縮小10%
print(img.shape) #列印圖片規格

 列印一下圖片尺寸,發現裁剪成功

教你如何用python把玩守望先鋒新英雄

圖片在計算機中是用數字矩陣形式儲存的,紅、綠、藍三個顏色通道每種色各分為256階,分別由0-255這256個數表示。比如900*360的圖片,可以理解為900行360列的畫素矩陣,而每個畫素又是由R,G,B三個數字確認其顏色的。於是,我們先把圖片的行,列數記錄下來,稍後可以用諸如遍歷的方法讀取每個畫素,再對其進行矩陣計算。

#拆分圖片資訊
rows,cols,channels = img.shape #拆分圖片資訊

 摳圖:三種效果 


摳圖的方法雷同PS,我們要先建立個蒙版。在開始之前,我們先需要把圖片轉換成HSV格式,這是一種比較直觀的顏色模型,可以更好的數字化處理顏色。

#轉換格式
img_hsv = cv2.cvtColor(img,cv2.COLOR_RGB2HSV) #把圖片轉換成HSV格式,用於摳圖
show(img_hsv) #顯示圖片

 看下效果:

教你如何用python把玩守望先鋒新英雄

 

雖然不能直視,但做法顯而易見,只要把非藍色的部分提取出來。我們設定一個閾值,在最小閾值以下和最大閾值以上,影像變為0,而在閾值之間的變為255。

#摳圖
lower_blue=np.array([0,0,0]) #獲取最小閾值
upper_blue=np.array([0,255,255]) #獲取最大閾值
mask = cv2.inRange(img_hsv, lower_blue, upper_blue) #建立遮罩
show(mask) #顯示遮罩

 然後,遮罩就這麼給整了出來。

教你如何用python把玩守望先鋒新英雄 

不過,我們發現,人物中間有那麼多小點點,我需要把它們去掉。這裡使用形態學影像處理的基本方法,先腐蝕後膨脹。其原理是在原圖的小區域內取區域性最小值和最大值,背後的邏輯為深度學習中的卷積神經網路。

透過嘗試,我發現還可以使用開運算(先腐蝕後膨脹的整合運算)直接完成這一過程,且效果相對較好。

erode=cv2.erode(mask,None,iterations=3#影像腐蝕
show(erode) #顯示圖片
dilate=cv2.dilate(erode,None,iterations=1#影像膨脹
show(dilate) #顯示圖片

opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8,8))) #開運算
show(opening) #顯示圖片

 大家可以自行比較下腐蝕腐蝕後膨脹開運算的效果:

教你如何用python把玩守望先鋒新英雄

 影像合併 


最後,終於到了影像合併環節。先設定人物在背景圖中的起始位置。再遍歷遮罩中的每個畫素,如果是0(代表黑色),則把人物影像上的顏色賦值到背景影像上。

center = [70,240#設定前景圖開始位置
for i in range(rows):
    for j in range(cols):
        if opening[i,j]==0#代表黑色
            back_img[center[0]+i,center[1]+j] =img[i,j] #賦值顏色
show(back_img) #顯示圖片

 執行完畢,顯示結果:

教你如何用python把玩守望先鋒新英雄

受限於圖片質量和簡化程式碼,略顯粗糙,但大體已經達到功能~

最後,調整圖片格式,並儲存。

back_img = cv2.cvtColor(back_img,cv2.COLOR_RGB2BGR) #影像格式轉換
back_img=cv2.resize(back_img,None,fx=0.8,fy=0.8#影像縮放20%
cv2.imwrite('result.png',back_img) #儲存影像

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31558017/viewspace-2222099/,如需轉載,請註明出處,否則將追究法律責任。

相關文章