2012年1月31日火曜日

EMアルゴリズムを用いたNon Photorealistic Rendering

ざっくり言うと、画像をガウス分布の重ね合わせで表現しよう!というものです。

Goal-based Caustics
この論文の一部です。

こんな画像を
こんなガウス分布で近似することで
こんな感じになります

画像をいわゆる画素ごとの輝度値ではなく、ガウス分布の重ね合わせで表現します。
イメージとしては、スポットライトをたくさん集めて、画像を作ろうぜ!みたいな。
暗い所はスポットライトの個数を減らして、そのかわり大きな面積に投影してやって、
逆に明るい所はたくさんスポットライトを集めて投影しようっていうアイデア。

どこにどんだけスポットライトを集めて投影するか(ガウス分布をどのように配置するか)
を決定するために、EMアルゴリズムを用いています。

EMアルゴリズム

反復計算によって、クラスタリングを行う手法です。
以下のような混合ガウス分布モデルを考えます。
入力データxと、ガウス分布のパラメータである平均μと共分散行列Σの初期解を与えて、
この入力データに最もよくフィットするガウス分布のパラメータと、各データがどのガウス分布に属しているかのクラスタリングを行います。

EMアルゴリズムの由来は、以下のEステップとMステップの繰り返しを行うことからこののように呼ばれています。

Mステップ:各データがどれくらい各分布に近いかを表す負担率γ(znk)を計算

Eステップ:計算した負担率に基づき,分布のパラメータを決定



このEステップとMステップを繰り返すことで最適化を行います。
停止条件とか収束は、各パラメータの変動を見て、あまり変化がなければ終了ということでいいと思います。
大域的最適の保証はされませんが、各ステップでかならず更新されることは保証されます。


ソースコードはgistにアップロードしました。
https://gist.github.com/1708777

画像の読み込みやデータの入出力以外はシンプルな2次元EMアルゴリズムとして動くと思います。

初期解を与えてやる必要があるんですが、論文ではCCVT(容量保存ボロノイ分割)を用いています。多分K-meansでも動くと思いますが、
下手な初期解を与えると発散します。


この論文のシステム上、画像の画素数よりも少ないけど重ね合わせのできる仕組みを使って画像を表現する必要があるのですが、一般的な用途でも使い道がないわけではありません。
平均と分散がガウス分布のパラメータなので、一つの分布あたり6変数で決めることが出来ます。分布の数にもよりますが、512×512の画像を2048個のガウス分布で近似した場合、画素数は5%まで圧縮できます。

解凍はFFTなどを要しないのですぐにできるのですが、圧縮が1~2分くらいのオーダーでかかってくるので、そこがネックになると思います。

圧縮サンプリング

圧縮サンプリングとは、最近画像処理とか信号処理とかで話題になっている、
劣化画像から劣化する前のきれいな画像を推定する手法です。
となりの研究室のHPにあったので借りてきました

画像とかの劣化過程は以下の数式でモデル化されます。

きれいな画像x, 劣化した画像yに対してどのように劣化したかを表す劣化過程の行列Aを考えます。
Aとyが既知としてxを求めるのが圧縮サンプリング問題です。
数式だけ見ると、逆行列とかをかけてしまえばxを求めれそうな気がするとは思うのですが、画像サイズが100×100とかの場合,xとかyのサイズは10000次元、
Aのサイズは10000×10000とかになってしまって、とてもじゃないけど現実的な時間で解くことが出来ません。

そこで、正則化項を追加したエネルギー最小化問題に変形させます。

このL-1ノルム正則化問題を解いたりするアルゴリズムとか,劣化過程を工夫することで逆演算を高精度化させるとかいろんな研究がされています。

今回は、この圧縮サンプリングのソースをOpenCVで書いてみました。
参考にした論文は
です。

gistにアップロードしています。
https://gist.github.com/1708671

劣化画像から真値画像を推定できるのですが、今回は劣化過程を推測するようにmain関数を書いています。
あしからず。



前処理付き共役勾配法

OpenCVを利用した前処理付き共役勾配法のプログラムです。

共役勾配法とは、

の形で表現される,線形方程式を解く数値計算のアルゴリズムです。
このAのある行列Pを使って

としたほうが高速に解くことが出来たりします。
Pの与え方にはいろいろありますが,P^(-1)AP^(-T)の部分が対角行列に近くなるほど高速になります。

詳しくは、Wikipedia
http://ja.wikipedia.org/wiki/%E5%85%B1%E5%BD%B9%E5%8B%BE%E9%85%8D%E6%B3%95#.E5.89.8D.E5.87.A6.E7.90.86
を見てください。

https://gist.github.com/1708356

gistにソースコードをアップロードしました