圣誕節(jié),教你用Python給微信頭像添加一個圣誕帽!
圣誕節(jié)快到了,每年一到圣誕節(jié)就會有很多人的頭像上多了一頂小紅帽

那么你有想過如何用Python去實現(xiàn)嗎?
如果你嘗試去搜索,會發(fā)現(xiàn)網上教程一大堆,但是由于大多數人都將圣誕帽位置固定了,所以放上自己的圖片后,要不就是圣誕帽偏移了,要不就是帽子比頭還大,代碼也不知道在哪里改,無從下手。
因此,本文將手把手教你如何用Python為你的微信頭像添加一頂圣誕帽,并結合我們之前講過PySimpleGUI,做成一個帶有GUI的小程序,先看效果:
本次主要分為兩個部分講解:
用 opencv對頭像添加圣誕帽結合 PySimpleGUI制作人性化圣誕帽添加軟件

主要涉及的Python模塊有:
PILPySimpleGUIcv2os
在開始之前,你需要使用pip對相關依賴庫進行安裝
pip?install?pillow???#這是對模塊PTL的安裝
pip?install?opencv-python????#這是對cv2的安裝
pip?install?os?
pip?install?PySimpleGui
? 一、利用opencv對頭像處理
本文用到的圣誕帽,是.png格式的,如下
為了識別照片,我們需要安裝一個OpenCV的內置人臉識別插件,安裝步驟:
用瀏覽器打開網址opencv.org---進入Releases---下載對應版本的OpenCV(一定要記住存放這個插件的路徑!!!后面要用到)
和以前一樣,我們先看本節(jié)全部代碼,然后進行講解?
import?cv2
from?PIL?import?Image
personPath?=?'3.jpg'??#頭像
hatPath?=?'sheng.png'??#圣誕帽
personImg?=?cv2.imread(personPath)
face_haar?=?cv2.CascadeClassifier('haarcascade_frontalface_default.xml')#存放的絕對路徑
faces?=?face_haar.detectMultiScale(personImg,?1.1,5)
personImg?=?Image.open(personPath)
personImg?=?personImg.convert('RGBA')
hatImg?=?Image.open(hatPath)
hatImg?=?hatImg.convert('RGBA')
for?face_x,face_y,face_w,face_h?in?faces:
????face_x?-=?face_w-180
????face_y?+=?face_h-250
????face_w?*=?1
????face_h?*=?1
????hatImg?=?hatImg.resize((face_w,?face_h))
????bg?=?(face_x,?face_y?-?face_h?+?100?,?face_x?+?face_w,?face_y?+?100?)
????personImg.paste(hatImg,?bg,?mask?=?hatImg)#將調整好的帽子貼上去
personImg.save('addHat.png')
下面對代碼進行講解。
首先,引入兩個模塊,用cv2.imread(personPath)來讀取相對路徑下的圖片。
“
cv2.imread('圖像路徑','讀取方式'):默認為cv2.imread_color以彩色圖像模式讀取。”
cv2.CascadeClassifier('分類器的路徑'):簡單來說就是做人臉檢測的一個必備方面,專業(yè)名詞叫做級聯(lián)分類器。這個分類器到目前版本容納了Haar特征器和LBP特征分類器兩個分類器。這次我們使用常規(guī)用的Harr特征器
Haar特征分類器就是一個xml文件,是OpenCV官方訓練好的檢測器,它能反應圖像的灰度變化,以像素分模塊求差值的一種特征。下面我們講講它的路徑
在我們準備工作中我們在OpenCV的官網下載了人臉識別的插件。以安裝在D盤為例:Harr特征分類器就在我們的D:\opencv\opencv\sources\data\haarcascades\haarcascade_frontalface_default.xml
注意:在第6行代碼中,我們調用這個特征器的路徑最好使用絕對路徑!上述代碼只是演示
關鍵代碼就是detectMultiScale(image,scaleFactor,minNeighbors):檢驗出圖片中的所有人臉,并以向量類型保存各個人臉的位置和大小,最后用矩形Rect類表示,該函數由分類器((也就是上述的Haar特征分類器))的對象進行調用。
其中參數如下:
“
image是我們要做人臉檢測的圖片。
scaleFactor表示在前后兩次相繼的掃描中,搜索窗口的比例系數。默認為1.1即每次搜索窗口依次擴大10%;”
minNeighbors表示構成檢測目標的相鄰矩形的最小個數(默認為3個)。
而后就是我們常見的用Pillow模塊打開兩張圖片,不過這次的打開方式是以RGBA模式打開,即四通道模式(A指透明度)。
最后一個for循環(huán)就是讀取用cv2解析出來的帽子faces參數,這里有趣的一點是,cv2做人臉識別后,會在兩眼之間畫一條線,并以中間為原點,做x和y軸建立坐標系。最后調節(jié)Pillow解析出來的帽子x和y位置,擺到人頭上方。所有這個方法對正臉敏感,對側臉不太友好。
personImg.save('addHat.png')表示存儲添加圣誕帽后的照片。
? 二、GUI框架整合
現(xiàn)在我們在上一節(jié)的基礎上,將圣誕帽添加與GUI框架進行整合,還是先上代碼之后拆分講解
import?PySimpleGUI?as?sg
import?os.path
sg.change_look_and_feel("BrightColors")
file_list_column?=?[
????[sg.Submit('Go',tooltip='按下面的要素添加圣誕帽',size=(15,?1)),?sg.Cancel(size=(15,?1))],
????[
????????sg.Text("圖片位置"),
????????sg.In(size=(25,?1),?enable_events=True,?key="-FOLDER-"),
????????sg.FolderBrowse('瀏覽'),
????],
????[
????????sg.Text("帽子寬度"),
????????sg.In(size=(25,?1),?enable_events=True,?key="hat-w"),
????],
????[
????????sg.Text("帽子高度"),
????????sg.In(size=(25,?1),?enable_events=True,?key="hat-h"),
????],
????[
????????sg.Text("帽子橫移"),
????????sg.In(size=(25,?1),?enable_events=True,?key="hat-x"),
????],
????[
????????sg.Text("帽子縱移"),
????????sg.In(size=(25,?1),?enable_events=True,?key="hat-y"),
????],
????[
????????sg.Listbox(
????????????values=[],?enable_events=True,?size=(40,?20),?key="-FILE?LIST-"
????????)
????],
]
image_viewer_column?=?[
????[sg.Text("從左邊圖片列表中選擇一張圖片:",size=(60,?1),key?=?"notice")],
????[sg.Text("左邊的四個參數調節(jié)是在上面的參數基礎上進行加減乘除;其中寬度和高度調試單位為個位數(需要大于0且是整數),橫縱移動調試單位可任意調",size=(50,?3),?key="-TOUT-")],
????[sg.Image(key="-IMAGE-")],
]
layout?=?[
????[
????????sg.Column(file_list_column),
????????sg.VSeperator(),
????????sg.Column(image_viewer_column),
????]
]
window?=?sg.Window("圣誕帽添加軟件",?layout)
while?True:
????event,?values?=?window.read()
????if?event?==?"Cancel"?or?event?==?sg.WIN_CLOSED:
????????break
????if?event?==?"-FOLDER-":
????????folder?=?values["-FOLDER-"]
????????try:
????????????file_list?=?os.listdir(folder)
????????except:
????????????file_list?=?[]
????????fnames?=?[
????????????f
????????????for?f?in?file_list
????????????if?os.path.isfile(os.path.join(folder,?f))
????????????and?f.lower().endswith((".jpg",?".png"))
????????]
????????window["-FILE?LIST-"].update(fnames)
????elif?event?==?"-FILE?LIST-":
????????try:
????????????filename?=?os.path.join(
????????????????values["-FOLDER-"],?values["-FILE?LIST-"][0]
????????????)
????????????window["-TOUT-"].update(filename)
????????except:
????????????pass
????elif?event==?"Go"?:
????????personPath?=?filename
??'''
????????圣誕帽添加部分
????????'''
????????window["notice"].update()
????????window["-IMAGE-"].update(filename='addHat.png')
window.close()
代碼解析,這里強烈建議讀者結合GUI進階篇中的圖片查看器講解一起看。當然在做PySimpleGUI之前繼續(xù)嘮叨基本步驟:
“Import ? Create some widgets Create the window Create the event loop
”
由于這個GUI框架是進階篇中的圖片查看器的改進版,對loop事件循環(huán)做了改動和添加一些文本框,并沒有增加新的元素,鍵的使用也是和往常一樣,所以這里就不再介紹元素和鍵了,感興趣的可以回看進階篇(元素介紹部分和鍵部分)。
這里我們layout的擺放思路如下:一個圣誕帽添加鍵、一個退出程序鍵、4個文本框來調節(jié)圖片中的圣誕帽、一個列表箱子裝路徑下的所有圖片、一個圖片顯示框、幾條用于提示用戶的文本框。按照這個思路,我們就有了while循環(huán)上面的代碼編寫。
接著是loop事件循環(huán):這里我們以Go鍵促發(fā)圣誕帽添加,所以我們以這個按鈕為第一個主if元素。
在按鈕Go促發(fā)前我們需要進行兩個判斷:
“一是文本框沒有輸入任何東西、
二是文本框輸入的東西。如果是前者,我們直接調動添加圣誕帽的程序(默認參數)并且在圖片上方顯示4個參數(x,y,w,h),即坐標和帽子大小。
”
如果是后者的話,我們會讓添加圣誕帽程序中的4個參數在原基礎上加減乘除用戶輸入的數字,并在圖片上方顯示最終的4個參數。
最終效果如下
? 三、打包
最后簡單講一下如何將上面的程序打包為exe格式,讓沒有Python環(huán)境的用戶也能使用,首先下載pyinstaller模塊
pip?install?pyinstaller
如果你的上述項目代碼文件命名為:hat.py。那么你要用下面命令在cmd窗口進行打包
pyinstaller?hat.py
打包過程會有點慢。成功后,在py文件所在文件夾找到一個dist的子文件夾。進去之后,找到pachong.exe文件并運行它即可。文件夾里附帶了很多文件,你可以刪除它。
因為打包后的exe較大(200多M),為了方便大家從Python腳本中使用,你必須按照本文開頭提示的安裝對應模塊與下載插件,如果有問題的話,相信下面的tips可以幫到你。
“如果不打包的話,先把圣誕帽的圖片(png格式)和代碼程序放在相同路徑下。
進到軟件后先點擊瀏覽按鈕選擇圖片存儲路徑(注意:路徑內不能出現(xiàn)中文,只能英文+數字,這可能是因為Python中的OpenCV庫的bug)。完畢后就可以看到下方所在文件夾的全部
.jpg和.png文件。點擊一個你想要添加圣誕帽的圖片,在按Go按鈕,在右邊的圖片框中就會刷新已經代碼帽子的頭像!同時,在程序的路徑下也會有這張圖片的.jpg格式文件。圖片框中除了圖片還有4個參數,4個參數的作用就是調節(jié)帽子大小和位置。因為每張圖片不同,所以帽子會出現(xiàn)大小不一、偏移的情況。而后,你就需要在左邊的4個輸入框中輸入參數來調試(4個輸入框是在原參數基礎上進行數乘運算),以達到帽子的最佳效果,如果超出范圍,命令框會提示錯誤。輸入后還是一樣按
”Go鍵,結束按Cancel鍵。
以上就是本文的分享,你可以在本文的基礎上進行修改來實現(xiàn)不同的效果,如果你喜歡的話,請點贊、在看、轉發(fā)支持一下,謝謝!
長按下方進入公眾號回復:圣誕
