使用這個(gè)工具,你也可以成為一名優(yōu)秀“畫家”

圖像風(fēng)格遷移已經(jīng)屬于比較成熟的領(lǐng)域了,現(xiàn)在連實(shí)時(shí)的風(fēng)格遷移都不成問題。之前一直想出一篇這樣的文章,但無奈于大部分開源項(xiàng)目配置起來非常麻煩,比如 luanfujun/deep-photo-styletransfer 項(xiàng)目,需要安裝 CUDA、pytorch、cudnn等等,配置能花一天的時(shí)間。
不過最近我發(fā)現(xiàn)一個(gè)非常好的開源應(yīng)用項(xiàng)目,那就是基于OpenCV的DNN圖像風(fēng)格遷移。你只需要安裝OpenCV就可以使用。
它也有局限性,我們只能用別人訓(xùn)練好的模型進(jìn)行風(fēng)格遷移,如果我們要自定義風(fēng)格,那就必須配置cudn等工具,使用 deep-photo-styletransfer 等項(xiàng)目的方法進(jìn)行訓(xùn)練。
不過作為初學(xué)者,我們只需要體驗(yàn)一下這樣的風(fēng)格遷移算法即可。感興趣的同學(xué)可以再自己深入研究。今天的教程我們拿 fast-neural-style 訓(xùn)練好的模型對下面的圖片做一次風(fēng)格遷移。

1.準(zhǔn)備
開始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上,如果沒有,可以訪問這篇文章:超詳細(xì)Python安裝指南?進(jìn)行安裝。
(可選1)?如果你用Python的目的是數(shù)據(jù)分析,可以直接安裝Anaconda:Python數(shù)據(jù)分析與挖掘好幫手—Anaconda,它內(nèi)置了Python和pip.
(可選2)?此外,推薦大家用VSCode編輯器,它有許多的優(yōu)點(diǎn):Python 編程的最好搭檔—VSCode 詳細(xì)指南。
請選擇以下任一種方式輸入命令安裝依賴:
1. Windows 環(huán)境 打開 Cmd (開始-運(yùn)行-CMD)。
2. MacOS 環(huán)境 打開 Terminal (command+空格輸入Terminal)。
3. 如果你用的是 VSCode編輯器 或 Pycharm,可以直接使用界面下方的Terminal.
pip install?python-opencv2.選擇模型
fast-neural-style放出的模型風(fēng)格一共有9種,我們將一一嘗試,其中部分風(fēng)格如下比如:


mosaic

starry_night

udnie
模型文件可以掃描下方二維碼關(guān)注?Python實(shí)用寶典,回復(fù)?風(fēng)格遷移?下載,里面有全部9個(gè)模型風(fēng)格的資源和源代碼。
3.克隆OpenCV源碼
我們直接克隆OpenCV開源項(xiàng)目中關(guān)于DNN圖像遷移的例子,地址是:
https://github.com/opencv/opencv/blob/3.4.0/samples/dnn/fast_neural_style.py
代碼:
import?cv2 as?cv
import?numpy as?np
import?argparse
parser = argparse.ArgumentParser(
????????description='This script is used to run style transfer models from '
????????????????????'https://github.com/jcjohnson/fast-neural-style using OpenCV')
parser.add_argument('--input', help='Path to image or video. Skip to capture frames from camera')
parser.add_argument('--model', help='Path to .t7 model')
parser.add_argument('--width', default=-1, type=int, help='Resize input to specific width.')
parser.add_argument('--height', default=-1, type=int, help='Resize input to specific height.')
parser.add_argument('--median_filter', default=0, type=int, help='Kernel size of postprocessing blurring.')
args = parser.parse_args()
net = cv.dnn.readNetFromTorch(args.model)
if?args.input:
????cap = cv.VideoCapture(args.input)
else:
????cap = cv.VideoCapture(0)
cv.namedWindow('Styled image', cv.WINDOW_NORMAL)
while?cv.waitKey(1) < 0:
????hasFrame, frame = cap.read()
????if?not?hasFrame:
????????cv.waitKey()
????????break
????inWidth = args.width if?args.width != -1?else?frame.shape[1]
????inHeight = args.height if?args.height != -1?else?frame.shape[0]
????inp = cv.dnn.blobFromImage(frame, 1.0, (inWidth, inHeight),
??????????????????????????????(103.939, 116.779, 123.68), swapRB=False, crop=False)
????net.setInput(inp)
????out = net.forward()
????out = out.reshape(3, out.shape[2], out.shape[3])
????out[0] += 103.939
????out[1] += 116.779
????out[2] += 123.68
????out /= 255
????out = out.transpose(1, 2, 0)
????t, _ = net.getPerfProfile()
????freq = cv.getTickFrequency() / 1000
????print?t / freq, 'ms'
????if?args.median_filter:
????????out = cv.medianBlur(out, args.median_filter)
????cv.imshow('Styled image', out)注意,源代碼是基于Python2的,所以第46行少了括號,如果你是Python3請注意補(bǔ)上括號。
這份代碼可以直接使用, parser 里定義了5個(gè)參數(shù),--input輸入要遷移的圖像寬度和高度, median_filter 是中值濾波器,基本思想是用像素點(diǎn)鄰域灰度值的中值來代替該像素點(diǎn)的灰度值,因此理論上數(shù)值越大,圖像越平滑,輸出的結(jié)果細(xì)節(jié)越好(不確定)。
親自試了一下median_filter對圖像的影響,發(fā)現(xiàn)改變微乎其微,因此直接為默認(rèn)值即可。
4.開始遷移
將第二步的代碼保存到一個(gè)文件中,命名為1.py,在CMD/Terminal中帶參數(shù)運(yùn)行腳本,其中input是源圖像路徑,model是遷移的風(fēng)格模型文件,如運(yùn)行:
python 1.py --input 1.jpg --model udnie.t7效果:

全部9種風(fēng)格的遷移效果:


如果你喜歡今天的Python 教程,請持續(xù)關(guān)注Python實(shí)用寶典,如果對你有幫助,麻煩在下面點(diǎn)一個(gè)贊/在看
,有任何問題都可以在下方留言,我們會耐心解答的!
源代碼和模型文件可以關(guān)注我們下方公眾號?Python實(shí)用寶典,回復(fù)?風(fēng)格遷移?下載,里面有全部9個(gè)模型風(fēng)格的資源和源代碼。
點(diǎn)擊下方閱讀原文可以獲取所有代碼和原圖哦!
Python實(shí)用寶典?(pythondict.com)
不只是一個(gè)寶典
歡迎關(guān)注公眾號:Python實(shí)用寶典