OpenCVを使って画像処理の勉強がてらいろいろ遊んでいる今日このごろ。
ふと写真をアニメっぽく出来ないかなと思って試してみました。カメラアプリとかだと漫画調とか絵画調にする機能はあるけど、アニメ調ってのはないなと思って。
さて、Wikipediaによるとアニメ塗りとは、
・輪郭や境界線をはっきり線で書く
・色や影のグラデーションを単純化させ段階的に表現する
だそうです。
こんな感じを目指したいと思います。
引用元:のんのんびより りぴーと
減色する
先ずは色の単純化を試してみました。
RGB画像の色をざっくり減らしてみる
取っ掛かりとして写真をRGB画像(24ビット)として読み込んで、各ピクセルのRGB成分をマスクをかけて減らすとどうなるかやってみました。
R成分 = R成分[元画像] & マスク(0xfe〜0x80);
G成分 = G成分[元画像] & マスク(0xfe〜0x80);
B成分 = B成分[元画像] & マスク(0xfe〜0x80);
結果
0xF0当たりから目に見えて劣化しますね。
単純に色を削っていくだけでは綺麗に減色出来ないことが解りました。
低頻度の色を減色してみる
次に試したのは、「使われる頻度が少ない色を似た他の色に置き換える」という方法です。
手順を簡単に書くと、
1.写真で使われている色ごとに使用回数をカウント
2.使用回数が多い色Xから距離D以内の色YをXに塗り替える
3.色数が目標値より少なくなるまで、距離Dを増やしつつ2を繰り返す
といった感じです。
色同士の距離は、RGB3次元空間のユークリッド距離を使用しています。
結果
元画像はマスク方式(マスク値=0xFE)で予め減色させた画像を使用しています。
64色、32色あたりがベタ塗りっぽいですかね。
影を強調
影部分がはっきりするように強調してみました。
グレースケール画像から影部分を切り出し、減色した画像にオーバラップ(alpha=0.4)させます。
結果
影部分のコントラストが若干強くなりました。
輪郭を付ける
次にCannyエッジ検出を使って輪郭線を追加します。
結果
う〜ん。アニメ風といえば風ですが、まだまだですね。
目を置き換えてみる
よりアニメ絵風にするために思い切って目を置き換えてみます。
OpenCVの物体検知を使って目の位置を検出し、あらかじめ用意した目の画像に置き換えます。
結果
難しいな…。
あとがき
最終的には、動画をアニメ風に変換出来ないかなと思って試してみたけど難しいのんな。
もうちょっといい方法が思いついたらまた試してみるん。