機略戦記

Maneuver warfare

論文ザクッと読み: KNN Matting

そんなに新しい論文でも無いけど、このKNN Mattingという論文が面白かった。

http://cqf.io/papers/KNN_Matting_CVPR2012.pdf

KNN Mattingとは、Image Mattingと呼ばれる画像処理タスクを行う手法の1つである。

そもそもImage mattingとは

全然しらなかったんだけど画像処理のタスクとしてImage Mattingと呼ばれるタスクがあるらしい。

Image Mattingとはどんなタスクなのか?

まず、概要としてはImage Matting画像を背景と前景に分離するタスクだ。 そのために、2つの入力画像を必要とし、処理の結果として1つの画像を返す。

  • 入力
    • その1: Input ... 背景と前景を分離したい画像(下図: 右から2番目)
    • その2: Trimap ... 後で説明する(下図: 一番右)
  • 出力
    • Output ... 前景と背景を分離するalpha image. (下図: 一番左)

f:id:Shinya_131:20171015122803p:plain

InputとOutputはそのまんまだから特に説明は無い。 面白いのはTrimapと呼ばれる入力画像だ。これは通常は人が描いてやらねばいけないもので、3つの色で構成される。

  1. 真っ白な部分 ... 確実に前景であると指定した領域。
  2. 真っ黒な部分 ... 確実に背景であると指定した領域。
  3. 上記以外の灰色な部分 ... 背景であるか前景であるかTrimap作成時には明示しなかった領域。

このTrimapでどこが前景でどこが背景なのか一部分を人が指定してやる事で、残る灰色の部分にある前景と背景の境界を、アルゴリズムが判定してくれるというわけだ。

KNN Matting

さて、前述したようにImage MattingではTrimapの灰色な領域をアルゴリズムが前景と背景に判定してくれる。

判定方法には様々な手法があり、今回読んだ論文ではk近傍法(KNN)を利用しているようだ。残念ながら僕の数学力と英語力ではこれ以上の説明できるほど詳しくは理解できなかった。

KNN Mattingを動かしてみる

さて、素晴らしい事にGithubにKNN Mattingの実装があったので動かしてみた。

  • 1つは、KNN Mattingのauthorの1人であるDingzeyu LiがコミットしているMatlabのコードだ。

github.com

  • もう1つは、どなたなのかは分からないがPythonで実装してくれたコードだ。

github.com

Python版のコードには、オリジナルのMatlab版コードとやや異なる実装になっている部分があるらしい。

Python版コードのリポジトリにあったISSUEよると、

The original code uses an approximate nearest neighbour with two levels of spatial coherence.

だが、Python版ではそうなっていないらしい。

参照: https://github.com/MarcoForte/knn-matting/issues/1

Matlab版の冒頭に、こんな部分があるので、おそらくこの辺りが再現されていないと言うことなんだろう。

% [10;2] means 10 neighbors with default(level) spatial coherence and 
% 2 neighbors with weak spatial coherence.
nn = [10; 2];

https://github.com/dingzeyuli/knn-matting/blob/master/src/knn_matting.m#L3

精度や動作速度にどんな影響があるのかは良くわからなかった。

とにかくPython版を動かしてみる。

f:id:Shinya_131:20171015134644p:plain

動かしてみた。

Core i5を積んだMacBook Proで約1分ほどかかる。 scipy.sparse.linalg.spsolve()してる辺りが重いようである。

他の画像でもやってみよう。 似たような色合いの背景と前景がどこまで上手く分離出来るのかやってみたい。

これは今私が居る部屋においてある机とリモコンである。

f:id:Shinya_131:20171015155920p:plain:w300

こいつ用にTrimapを描いてみる。 かなりざっくり目に。

f:id:Shinya_131:20171015160013p:plain:w300

KNN-Matting...あ、ダメっぽい。

f:id:Shinya_131:20171015160037p:plain:w300

元の画像にAlphaChannelとして統合してみよう。 分かりやすいように背景は青くした。

f:id:Shinya_131:20171015160125p:plain:w300

Trimapをもうちょっと丁寧に書いてもう一度…

f:id:Shinya_131:20171015161513p:plain:w300

f:id:Shinya_131:20171015161604p:plain:w300

んんんー、ちょっと改善したけどダメですね。

他の画像で試してみる。

f:id:Shinya_131:20171015164633p:plain:w300

f:id:Shinya_131:20171015164656p:plain:w300

f:id:Shinya_131:20171015164802p:plain:w300

おお! これはかなり良い。 本の下側の部分が上手く切り取れてないですが、そこ以外は大体キレイですね。

リモコンは背景との色が近すぎるのかな。

よく読んでないけど、元論文によると色空間をRGBじゃなくてHSVにしたら上手く行ったケースが紹介されているようですね。

色空間によっては上手く行ったりするんだろうか。

そういえば、ハイパーパラメーターも全くいじってないですね。 あ、そもそもGithubにISSUとして上げられていたweak spatial coherenceが設定出来ないという問題もありましたね。 この辺りも改善の余地がある可能性が。

補足と感想

今回は、2012年に発表されたKNN mattingを動かしてみたが、その後もこのImage Mattingのジャンルでは色々な手法が検討されているようだ。例えば、DeepLarningでImage Mattingを行う"Deep Matting"とか。

KNN以外の主要や、手法間の比較については、このサイトが参考になる。

Alpha Matting Evaluation Website

この技術については、使い道が色々ありそうであり、気が向いたらまたいじってみようと思う。