学習済み画風変換モデルを使って画像を好みの画風に変換する

機械学習

はじめに

Fast Style Transferを用いて画像を好みの画風に変換できるようになりました。
ただ、画風を学習させる環境によっては、学習に半日以上要します。

もう少し簡単に画風を変換をできないか。

Webで調べたところ、学習済み機械学習モデルのリポジトリであるtensorflow_hubに画風変換モデルがありましたので、試してみました。

<参考にさせてもらったサイト>

実行環境

パッケージのバージョン

Python 3.6.2
tensorflow 2.2.0
tensorflow-hub 0.12.0

実行端末のスペック

OS Windows 10 pro
CPU Intel Corei7-8750H 2.20GHz
GPU NVIDIA GeForce GTX 1050 Ti
メモリ 16GB

準備

プログラムを実行するために必要なライブラリをインストールしておきます。

pip install tensorflow
pip install tensorflow_hub
pip install scikit-image

C:\tmpを作成し、その配下にimageフォルダ、styleフォルダ、resultフォルダを作成します

C:\tmp\imageに画風を変更したい画像を保存しておきます。
C:\tmp\styleに好みの画風を保存しておきます。
C:\tmp\resultには、画風を変換した後の画像が保存されます。

画風変換プログラム

下記のコードを任意の「ファイル名.py」で保存して実行します。

<プログラムの概要>

  • 2~6行目:ライブラリを読み込む
  • 9行目:画風を変換したい画像を指定する
  • 12行目:好みの画風を指定する
  • 15~26行目:画像を読み込む関数
  • 30~52行目:読み込んだ画像を画風変換モデルで読み込めるように画像変換する関数
  • 56~57行目:変換元の画像と反映させたい画風の画像を画像変換する
  • 61行目:任意の画風に変換するためのモジュールを読み込む
  • 64行目:画像の画風を変換する
  • 67~76行目:画風を変換した画像を描画する
  • 79行目:画風を変換した画像を保存する
# ライブラリを読み込む
import tensorflow as tf
import tensorflow_hub as hub

import matplotlib.pyplot as plt
from skimage import io

# 画風を変換する画像を指定する
content_path = r'C:\tmp\image\sample.png'

# 画風を指定する
style_path = r'C:\tmp\style\wave.jpg'

# 画像の縮尺をmax_dimで調整する
def img_scaler(image, max_dim=512):
    # 読み込んだ画像の テンソルをfloat32でセットする
    original_shape = tf.cast(tf.shape(image)[:-1], tf.float32)

    # 画像の縮尺を設定する
    scale_ratio = max_dim / max(original_shape)

    # 設定した縮尺とint32で、new_shapeにテンソルをセットする
    new_shape = tf.cast(original_shape * scale_ratio, tf.int32)

    # 画像の縮尺を変換する
    return tf.image.resize(image, new_shape)


# モデルが画像を読み込めるように変換する
def load_img(path_to_img):
    # 画像をデータとして読み込む
    img = tf.io.read_file(path_to_img)

    # 画像データをRGBのテンソルに変換する
    img = tf.image.decode_image(img, channels=3)

    # 変換した配列のshapeを確認する
    # [縦 横 チャンネル]の配列になる
    print('変換する画像', path_to_img)
    print('変換前のshape', img.get_shape()[:])

    # RGBのテンソルのデータ型をfloat32に変換する
    img = tf.image.convert_image_dtype(img, tf.float32)

    # 画像の縮尺を変換する
    img = img_scaler(img)

    # 変換した配列のshapeを確認する
    # [縦 横 チャンネル]の配列になる
    print('返還後のshape', img.get_shape()[:])

    return img[tf.newaxis, :]


# 画像を画風変換モデルで扱えるようにテンソルへ変換する
content_image = load_img(content_path)
style_image = load_img(style_path)


# tensorflow_hubからmagentaの任意の画風に変換するためのモジュールを読み込む
hub_module = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2')

# 画像の画風を変換する
stylized_image = hub_module(tf.constant(content_image), tf.constant(style_image))[0]

# 画像を描画するための準備
fig = plt.figure()
plt.imshow(stylized_image[0])

# 軸と目盛を表示しない設定
plt.axis('off')
# 画像を保存するときに余白を無くすための設定
plt.subplots_adjust(left=0, right=1, bottom=0, top=1)

# 画風を変換した画像を表示する
plt.show()

# 画風を変換した画像を保存する
io.imsave(r'C:\tmp\result\sample_wave.png', stylized_image[0])

実行結果

<変換前の画像>

<画風変換の結果>

学習済みの画風変換モデルと、自前の画風変換モデルを比較するために、前回作成した自前の画風変換モデルも掲載しています。

画風 学習済みの画風変換モデルで
画像を変換(今回の結果)
自前の画風変換モデルで
画像を変換(前回の結果)

北斎 神奈川沖浪裏 (富嶽三十六景)

Lassen swim in the moon

出典:ウィットビー

tensorflow_hubで公開されている学習済み画風変換モデルを使用することで、簡単に画風を変換することができました。ただ、画風変換は少し荒いように感じます。

学習済み画風変換モデルと自前の画風変換モデルのどちらが好みか、と問われると自前の画風変換モデルのほうが好みです。

アンパンマン風の画風変換は、、、自前の画風変換と同じで気持ち悪い感じになってしまいました。

 

 

 

 

 

 

 

 

 

 

 

 

コメント

タイトルとURLをコピーしました