Python 超簡單實現 9 種影像風格遷移

pythondict發表於2020-05-16

Python 影像風格遷移已經屬於比較成熟的領域了,現在連實時的風格遷移都不成問題。之前一直想出一篇這樣的文章,但無奈於大部分開源專案配置起來非常麻煩,比如 luanfujun/deep-photo-styletransfer 專案,需要安裝 CUDA、pytorch、cudnn等等,配置完一天都過去了。

不過現在我們有了非常好的開源應用專案,那就是OpenCV的DNN影像風格遷移。你只需要安裝OpenCV就可以使用了,在cmd/terminal中輸入(如果你還沒有安裝Python,請看這篇文章:Python安裝):

pip install python-opencv

不過它也是有侷限性的,我們只能用別人訓練好的模型進行風格遷移,如果我們要自定義風格,那就必須配置cudn等工具,使用 deep-photo-styletransfer 等專案的方法進行訓練,今天的教程我們拿fast-neural-style訓練好的模型對下面的圖片做一次風格遷移。

喵喵喵

1.選擇模型

fast-neural-style放出的模型風格一共有9種,我們將一一嘗試,其中部分風格如下比如:

candy.jpg

mosaic.jpg

starry_night.jpg

udnie.jpg

模型檔案可以關注我們下方公眾號 Python實用寶典,回覆 風格遷移 下載,裡面有全部10個模型風格的資源。

2.克隆OpenCV原始碼

我們直接克隆OpenCV開源專案中關於Python DNN影像遷移的例子,地址是:

github.com/opencv/opencv/blob/3.4....

程式碼如下:

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請注意補上括號。這份程式碼可以直接使用, parser 裡定義了5個引數,–input輸入要遷移的影像位置,–model指要使用的模型,–width/–height指的是遷移後的影像寬度和高度, median_filter 是中值濾波器, 基本思想是用畫素點鄰域灰度值的中值來代替該畫素點的灰度值,因此理論上數值越大,影像越平滑,輸出的結果細節越好(不確定)。 median_filter 親自試了一下,對結果的影響不大。

3.開始遷移

將上述程式碼儲存到一個檔案中,命名為1.py,在CMD/Terminal中帶引數執行指令碼即可遷移。如:

$ python 1.py --input 1.jpg --model udnie.t7

效果如下:

全部9種風格的遷移效果:

文章到此就結束啦,如果你喜歡今天的Python 教程,請持續關注Python實用寶典,如果對你有幫助,麻煩在下面點一個贊/在看哦有任何問題都可以在下方留言區留言,我們會耐心解答的!


​Python實用寶典 (pythondict.com)
不只是一個寶典
歡迎關注公眾號:Python實用寶典

原文來自Python實用寶典:Python 遷移9種影像風格
Python實用寶典

本作品採用《CC 協議》,轉載必須註明作者和本文連結

Python實用寶典, pythondict.com

相關文章