記事概要
1. Felzenszwalbらの提案したEfficient Graph-Based Image Segmentation
*1の手法と実装を解説
2. 手法:画像中の各画素を1つのノードとした木から、輝度が類似なノードをまとめていきセグメンテーションを行う
3. 実装:Union-Findを用いることでo(nlogn)となる
Felzenszwalbらの提案したEfficient Graph-Based Image Segmentation を解説してみる。
画像のセグメンテーション*2は1枚の画像を同じような特徴(明るさ、色、テクスチャなど)を持つ複数の領域に分割する処理で、基本的な画像処理技術の1つである。画像合成処理、物体認識、ジェスチャ認識などの前処理として幅広く利用されている。
中でも、2004年にFelzenszwalbらが提案したEfficient Graph-Based Image Segmentationは、現時点で2703回*3も引用されてる重要な論文の1つと言える。プログラムのソースコード(C++)も公開されている。
この辺りはあまり詳しくないものの、最近興味があって勉強していたあるstate-of-the-artな論文がこの論文をベースにしていたことと、これまで何度もこの論文をベースにした手法に出会ったことから、さすがに理解しておこうと思ったのがきっかけとなった。
手法
入力:個のノードと
個のエッジからなるグラフ
出力:のセグメンテーション結果
初期化
1.1 各画素を表すノードと、画像中で隣り合うノード(画素)を結ぶエッジ
から構成される無向グラフ
を構成
1.2 エッジで結ばれるノード(画素)間の輝度差をエッジの重みとして設定
1.3 エッジを重みが昇順になるように並べ
を構成
1.4 各ノードにそれぞれ個別のコンポーネントを割り当てを構成
に対して下記を繰り返す
2.1で結ばれるノード
が
においてそれぞれコンポーネント
に含まれているとする。この時、
かつ
を満たした場合にをマージすることで
が得られ、それ以外の場合は
。
ここで、はエッジ
の重みであり、論文ではエッジ
で結ばれるノード(画素)の輝度値の差となっている。 また、
は、
として定義される。は
(kは定数、|C|はCのノード数)で定義される閾値関数であり、
は最小全域木
の最大重み
である。
最終的に、
が得られる
高速であることと、高い変動性を無視しながら低い変動性を残すことがポイントである。
実装
実装では、素集合としてコンポーネントを捉え、コンポーネントの統合にUnion-Find を用いることで高速な処理を実現している。各コンポーネントを1つの木として表し、ノードが属するコンポーネントの判定(Find)と木の統合(Union)に経路圧縮とランクを用いた高速化を行っている*4。
- ランク:木の高さを持っておき、低い方を高い方に繋げるようにする。
- 経路圧縮:上向きに辿って再帰的に根を調べる際に、調べたら辺を根に直接つなぎ直す。
なお、各コンポーネントに対応する
は個別に保持され、木を統合する際にこの値も更新される。それゆえ最小全域木
がコンポーネント間の比較の度に計算されることはない。
ソースコードが簡潔&完結!(標準ライブラリ以外にライブラリを用いない!)で、利用しやすいというのも引用回数が多いことに影響していると思う。
*1:P. F. Felzenszwalb and D. P. Huttenlocher, “Efficient Graph-Based Image egmentation,”International Journal of Computer Vision, vol. 59, no. 2, 2004.
*2:参考:領域分割 - SICE オンライン・ハンドブック - 計測自動制御学会
*3:2014年10月5日時点