あいどる💖たいむ

あいどるやってます。

deepcolorを動かしてみた

巷で話題のPaintsChainer.その類似手法つかった「deepcolor」を試した.

deepcolorの概要

github.com

PaintsChainerと同じように,ディープラーニングで学習し,線画への着色を自動で行うアプリ.

PaintsChainerの作者さんが,このアプリの手法の論文を紹介されてたので気になってた.

つおい人は年齢に関係なくつおいんだなぁ(ノ゚ρ゚)ノ

学習の概要

英語をあんまり読めないので,ざっくりとまとめ.

着色学習

GANと同様にdiscriminatorとgeneratorを同時に学習させる.
ネットワークはU-NETという構成.ダウンサンプリングの出力結果をアップサンプリングの対応する層の入力としてつかう.(ググって画像見たほうが理解しやすい)

入力は線画(図左)とヒント画像(図中). ラベルは着色画像(図右).
generatorは,入力に対し偽物の着色画像を作る.
discriminatorは,与えられたラベルが本物か偽物かを判断する.
discriminatorに本物の着色画像を与えたときの結果と,generatorが生成した偽物の着色画像を与えたときの結果をもとに,generatorとdiscriminatorが学習していく.
(generatorはより騙せる画像を生成するように,discriminatorはより正確に本物か偽物か見分けるようにってかんじ.)
f:id:shiccocsan:20170708015915p:plain

画像は以下から引用
https://www.pixiv.net/member_illust.php?mode=medium&illust_id=50913967

ヒント画像

訓練データのヒント画像は,着色画像をランダムで数点白抜きし,blur処理を行っている.
このようにヒント画像からの情報を減らすことで,補完して着色してくれるようになるっぽい.すごい!

自動着色

自動着色は,generatorを使って行う. 学習させたgeneratorに線画とヒント画像を与えれば,本物っぽい着色後画像を出力してくれるはず.

実装メモ

main.py

discriminatorとgeneratorの学習を行う.

guess_colors.py

ヒント画像の学習を行う. 自動着色時,ヒントを自分で与えない場合はこれのgeneratorから取得した画像をヒントとして使用する.
今回は動かしてない.

実際に動かしてみる

Python3対応

Python2で作成されているようだが,環境をもってなかったのでPython3用に少し書き換えた .

https://github.com/momocalc/deepcolor/tree/python3-support

学習

クローラを作ってまったり画像を9000枚程度集めたので,それを訓練データとして20epoch学習させた.
処理時間は,GPUがGTX1050-Tiで10時間程度だった.

学習過程

左から,5epoch,10epoch,15epoch,20epoch後のgeneratorの出力 f:id:shiccocsan:20170708014954p:plain

画像は以下から引用

https://www.pixiv.net/member_illust.php?mode=medium&illust_id=62817600

https://www.pixiv.net/member_illust.php?mode=medium&illust_id=50913967

10epoch後は,あまり変化がないようにも見えるが,すこしずつディテールが変化してる感じもする (・_・)

自動着色

学習させたモデルで実際に着色してみる.
server.pyを実行しwebサーバを起動し,デモ画面から自動着色を行う.

左から順に,用意した線画,2値化された線画,ヒントをつけた画像 f:id:shiccocsan:20170708022042p:plain

自動着色結果

f:id:shiccocsan:20170708022221p:plain

神絵師には程遠い_| ̄|○

考察

PaintsChainerさんは訓練に60万もの画像を使ったと書かれてて,訓練画像の少なさに不安があったが以外にうまくいってる気がする.
以下の疑問があるので,もう少し継続して触っていきたい.

  • 線画に2値を使っているが,グレースケールにしたら結果は変わるのか
  • 今回はランダムに画像を集めたが,特定の画風だけを訓練データとした場合,その画風の着色となるのか
  • ぼやけた感じの自動着色臭さ(良くいえば水彩風)を減らすことはできるのか
  • 学習のヒント画像の白抜きを減らしたり,blurを弱めたりしたらどうなるか

おわりに

TensorFlowの実践的なコードを読むことができてよかった.
英語ができないことがめっちゃ足枷になってる.論文読めない (/ω\*)ウゥ…

Chainerのログをプロット

Chainerのjsonログをmatplotlibでグラフに表示する.

gist.github.com

こんなかんじ. f:id:shiccocsan:20170702222747p:plain

OpenCVでモザイク処理

概要

画像全体にモザイク処理をする

環境

実装

import cv2
import numpy as np


def mosaic(img, size=16):
    res = np.empty(img.shape, dtype=np.int16)
    for i in range(0, img.shape[0], size):
        for j in range(0, img.shape[1], size):
            mos_range = img[i:i + size, j:j + size]
            v = mos_range.mean(axis=(0, 1))  # RGB値別の平均を求める
            v = v.astype(np.int16)

            # size * size * 3のリストを作って上書きする
            v_array = [[v] * size] * size
            res[i:i + size, j:j + size] = v_array
    return res


if __name__ == '__main__':
    img = cv2.imread('input.jpg')
    cv2.imwrite('output.jpg', mosaic(img))

sizeで指定したサイズの正方形の範囲別に,RGBそれぞれの平均値を求める.
その範囲を,求めた平均値で埋めている. (画像サイズがsizeで割り切れない場合は,エラーになると思われるので注意)

実行結果

input

f:id:shiccocsan:20170628210026j:plain

output

f:id:shiccocsan:20170628210031j:plain

いらすとやさんの画像をお借りしたが,この画像の需要はどこにあるのか...

考察

ある値でndarrayの指定範囲すべてを更新する方法がわからず,対象範囲と同じ形のリストを作って更新するようにした.
もっと良い方法があるかも...

OpenCVでのリサイズと切り取り

画像を正方形にリサイズする。
画像の短辺を正方形の辺の長さ®ã«åˆã‚ã›ã¦ä¸­å¤®ã«é…ç½®ã—、長辺のはみでた部分は切り捨てる。

コード

import cv2

def resize_and_crop_square(img, r):
    """
    画像を正方形に切り取る
    短辺をrに合わせるようリサイズし、長辺のはみ出す部分は切り捨てる
    :param img:
    :param r: 正方形の辺の長さ
    :return: resized image
    """
    org_h, org_w = img.shape[:2]

    if org_h > org_w:
        h = int(org_h * r / org_w)
        w = r
    else:
        h = r
        w = int(org_w * r / org_h)

    # resize
    w = max(w, r)
    h = max(h, r)
    img2 = cv2.resize(img, (w, h))

    # crop
    top = (h - r) // 2
    left = (w - r) // 2
    return img2[top:top + r, left:left + r]

_img = cv2.imread('images/pexels-photo-297743.jpeg', cv2.IMREAD_COLOR)
_img2 = resize_and_crop_square(_img, 256)
cv2.imshow('res', _img2)
cv2.waitKey(0)

実行結果

左が元画像、右が編集後の画像

f:id:shiccocsan:20170622193937j:plain

OpenCVを使って彩度を変更する

OpenCVを使って彩度の変更をしてみる。

環境 

>>> import cv2
>>> cv2.__version__
'3.2.0'

実装

大まかな流れ

  1. cv2.imreadで画像読み込み
  2. 彩度をあつかうので、RGBからHSVへ変換(OpenCVで読み込んだ配列はBGRの並び)
  3. 各ピクセルの彩度(index:1)を変更する。ここでは0.3倍
  4. HSVからRGBに戻し、保存と表示

ちなみに、HSVの値の範囲は、

For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255].

とのこと。

OpenCV: Changing Colorspaces

コード

import cv2
import numpy as np

img = cv2.imread('images/pexels-photo-297743.jpeg', cv2.IMREAD_COLOR)
dst = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)  # BGRからHSVへ変換

print(dst.shape)

for i in range(dst.shape[0]):
    for j in range(dst.shape[1]):
        # Vの値を上書きする
        dst[i, j, 1] = int(dst[i, j, 1] * 0.3)

img = cv2.cvtColor(dst, cv2.COLOR_HSV2BGR)  # HSVからBGRに戻す
cv2.imshow('res', img)
cv2.imwrite('images/result.jpg', img)
cv2.waitKey(0)

実行結果

左が元画像、右が変換後の画像。 彩度が下がっていることは明らか。

f:id:shiccocsan:20170622161554j:plain

おわりに

彩度の変更は、numpy配列の演算で1ピクセルごとでなく一括で変更できるのではないかと思う。

参考

HSV色空間 - Wikipedia

OpenCV: OpenCV modules

jlisting.styの導入

LaTeXにソースコードを埋め込むにはlisting.styを使うが,ソースコードに日本語を含む場合はjlisting.styが必要とのこと.なので導入.

環境

macに以下の本のDVDでLaTeXをインストールした状態.

[改訂第7版]LaTeX2ε美文書作成入門

[改訂第7版]LaTeX2ε美文書作成入門

jlisting.styを導入

jlisting.styをダウンロードする
http://prdownloads.sourceforge.jp/mytexpert/26068/jlisting.sty.bz2

つぎのように,解凍したjlisting.styをlistingsのディレクトリにコピー

sudo cp jlisting.sty /Applications/TeXLive/Library/texlive/2016/texmf-dist/tex/latex/listings

ls-Rの更新

ls-Rを更新する必要があるようなので,mktexlsrを実行

sudo mktexlsr

LaTeXサンプル

実際に,使用してみる.

コード

Â¥documentclass[papersize]{jsarticle}

%listingsの設定
Â¥usepackage{listings,jlisting }
Â¥usepackage{color}

% ソースコードのスタイル設定
Â¥lstset{% 
language={python}, 
basicstyle={Â¥small},% 
identifierstyle={Â¥small},% 
commentstyle={¥small¥ttfamily ¥color[rgb]{0,0,0}},% 
keywordstyle={¥small¥bfseries ¥color[rgb]{0,0,1}},% 
ndkeywordstyle={Â¥small},% 
stringstyle={¥small¥ttfamily}, 
frame={tb}, 
breaklines=true, 
columns=[l]{fullflexible},% 
numbers=left,% 
xrightmargin=0zw,% 
xleftmargin=3zw,% 
numberstyle={Â¥scriptsize},% 
stepnumber=1, 
numbersep=1zw,% 
morecomment=[l]{//}% 
} 

Â¥begin{document}
Â¥begin{lstlisting}[caption=spam,label=ham] 
   # 入力
   hoge = input()
   # 出力
   print(hoge)
Â¥end{lstlisting}

Â¥end{document}

スタイルはlstsetに記述するらしい.
サンプルのものは,以下サイトからお借りした.
http://www.biwako.shiga-u.ac.jp/sensei/kumazawa/tex/listings.html

出力

f:id:shiccocsan:20170607141037p:plain

参考

chainercvを動かしてみた

写真の被写体の個数に応じて処理をしたいなと思ったので,chainercvを使って物体検出してみた. github.com

環境

インストールはInstallationのとおり

実装

gist.github.com

モデルはSSD512というのを使用.
ほとんどexampleどおりだけど,モデルを作成したらpickleで保存するようにしてみた.

実行結果

f:id:shiccocsan:20170531131318p:plain

こんなかんじで検出箇所を囲ってくれる(≧∇≦)b

テスト用画像は以下のものをお借りした
https://www.pexels.com/photo/building-buildings-busy-car-297743/