第2回「コンピュータビジョン最先端
     ガイド」勉強会
       5.1-5.2章
    presented by takmin
5. グラフカットによる大域最小化
• この章の目的
 – データ項+平滑化項で表される以下のエネル
   ギーを最小切断アルゴリズムを使って,最小化す
   る


E( X )   gv ( X v )      h         uv   (Xu, Xv)
         vV              ( u ,v )E
この章の流れ
• 2値の場合
 – 5.1 2値の大域最小化
 – 5.2 実装例
• 大域最小解を持つための辺の重みの決め方
 – 5.3 劣モジュラ条件
 – 5.4 劣モジュラでないとき:QPBO
• 多値の場合
 – 5.5 多値の大域最小化
 – 5.6 実装例
 – 5.7 一般の凸な平滑化項
5.1 2値の大域最小化
  E( X )   gv ( X v )      h         uv   (Xu, Xv)
           vV              ( u ,v )E



 このエネルギーの大域最小化を行う


問題をグラフで表し,最小切断問題として解く
グラフの構築
       E( X )   gv ( X v )      h         uv   (Xu, Xv)
                vV              ( u ,v )E

頂点を設定: V1  wv | v  V 




wv
グラフの構築
    E( X )   gv ( X v )          h         uv   (Xu, Xv)
             vV                  ( u ,v )E

頂点s,tを追加:   V  V1  s, t
                              t




                          S
グラフの構築
          E( X )   gv ( X v )               h      uv   (Xu, Xv)
                      vV                 ( u ,v )E

辺を追加:  1  ( s, wv ), ( wv , t ) | v  V 
                                      t




                                     S
グラフの構築
        E( X )   gv ( X v )           h       uv   (Xu, Xv)
                    vV              ( u ,v )E

辺を追加:  2  ( wu , wv ) | (u, v)  E
                                 t




      完成!
                                S
グラフの切断
         E( X )   gv ( X v )           h         uv   (Xu, Xv)
                     vV                ( u ,v )E

このグラフの任意の切断(S,T)について:
     0  v  Sのとき
        (w       )
Xv                                t
     1  v  Tのとき
        (w       )



     0           1              0              0              1      1
                wv         wu



                                    S
グラフの切断
              E( X )   gv ( X v )                     h         uv   (Xu, Xv)
                                vV                    ( u ,v )E

   各辺の切断コストを定義:
                           c( wv , t )  g v (0)
                                                   t
c( wu , wv )  huv (0,1)  hvu (1,0)



                             wv            wu


    c( s, wv )  g v (1)
                                                   S
グラフの切断
       E( X )   gv ( X v )      h         uv   (Xu, Xv)
                   vV           ( u ,v )E

切断されたsからtへ向かう辺の切断コストの和とEは等しい
                             t




   0           1         0              0              1      1




                             S
ノイズ除去の例
                                                 
         E ( X )    Yv  X v                    Xu  Xv   (2)
                  vV               ( u ,v )E   2
     エネルギーを計算する

                                                     
     E (X )  (0    0  0  0  0)   0  1  1  0 
                                        2       2      
              
Yv


Xv
ノイズ除去の例
                                                                    
             E ( X )    Yv  X v                                   Xu  Xv         (2)
                           vV                         ( u ,v )E   2
      グラフカットで切断コストを計算する

c( s, wv )   Yv  1
                                           t
c( wv , t )   Yv  0
c( wu , wv )             0                                                λ
                                  λ    0                   0            λ
                   κ             κ             κ                    κ           κ
 Yv
                       κ           κ               κ                    κ           κ

                       λ         0     λ                  λ             0
                                                                                0

                                           S
ノイズ除去の例
                                                         
     E ( X )    Yv  X v                                Xu  Xv         (2)
                vV                         ( u ,v )E   2
     E(X )  0    0  0    0  0    
                                t

                0                                                λ
                       λ    0                   0            λ
        κ             κ             κ                    κ           κ
Yv
            κ           κ               κ                    κ           κ

            λ         0     λ                  λ             0
                                                                     0

                                S
2次元の場合
2次元の場合
3次元の場合
5.2 実装例
• GCライブラリ入手先
 – Vladimir Kolmogorovさんのページ
 – http://www.cs.ucl.ac.uk/staff/V.Kolmogorov/
 – Max Flowライブラリをダウンロード
ライブラリ入手先
Vladimir Kolmogorovさんのページ




        http://www.cs.ucl.ac.uk/staff/V.Kolmogorov/
ソース
void NR2(unsigned char* X, unsigned char* Y, int m, int n)
{
                typedef Graph<int,int,int> GraphType;
                int lambda=100;
                int kappa = 25;
                GraphType* g = new GraphType(n*m, 4*n*m);     // 頂点と辺の概数
                g->add_node(n*m);                    // 画素の数だけ頂点を作る

              int dx[4] = {1,-1,0,1};
              int dy[4] = {0, 1, 1, 1};
              for(int j=0; j<m; j++){
                                  for(int i=0; i<n; i++){
                                                      int g0 = *(Y + n*j + i) * lambda; //g(0)
                                                      int g1 = (1-*(Y + n*j + i)) * lambda; // g(1)
                                                      g->add_tweights(j*n+i,g1,g0);         // (i,j)の頂点はnj+i番目
                                                      for(int d=0; d<4; d++){
                                                                         int x = i + dx[d];
                                                                         int y = j + dy[d];
                                                                         if(0<=x && 0<=y && x<n && y<m){
                                                                                            g->add_edge(j*n+i,y*n+x,kappa,kappa);   // 両方向
                                                                         }
                                                      }
                                  }
              }
              g->maxflow();
              for(int j=0; j<m; j++){
                                  for(int i=0; i<n; i++){
                                                      if(g->what_segment(j*n+i)==GraphType::SOURCE)
                                                                         *(X + n*j + i)=0;
                                                      else
                                                                         *(X + n*j + i)=1;
                                  }
              }
              delete g;
}
手順
1. GraphTypeインスタンス生成
 – GraphType* g = new GraphType(n*m, n*m*4);
                                               頂点の   辺の概数
                                               概数

2. 画素の数だけ頂点を作る
 – g->add_node(n*m);


3. データ項(=C(s, wv),C(wv,t))を設定
 – g->add_tweights(j*n+i, g1, g0)
                      wu   c(s, wv) c(wv, t)
手順
4. 頂点間の辺を作成(双方向)
 – g->add_edge (j*n+i, y*n+x, kappa, kappa);
                   wu    wv    c(wu, wv)   c(wv, wu)


5. 最小切断(最大流)を求める
 – g->maxflow();

6. 各頂点でs,tのどちらが切断されたかを結果
   に格納
 – g->what_segment(j*n+i)
結果
最後に
• 図は,石川先生の講演資料から拝借しました。
 – http://w01.tp1.jp/~a031464501/indexJ.html

Graph cut5.1 5.2_takmin

  • 1.
    第2回「コンピュータビジョン最先端 ガイド」勉強会 5.1-5.2章 presented by takmin
  • 2.
    5. グラフカットによる大域最小化 • この章の目的 – データ項+平滑化項で表される以下のエネル ギーを最小切断アルゴリズムを使って,最小化す る E( X )   gv ( X v )  h uv (Xu, Xv) vV ( u ,v )E
  • 3.
    この章の流れ • 2値の場合 –5.1 2値の大域最小化 – 5.2 実装例 • 大域最小解を持つための辺の重みの決め方 – 5.3 劣モジュラ条件 – 5.4 劣モジュラでないとき:QPBO • 多値の場合 – 5.5 多値の大域最小化 – 5.6 実装例 – 5.7 一般の凸な平滑化項
  • 4.
    5.1 2値の大域最小化 E( X )   gv ( X v )  h uv (Xu, Xv) vV ( u ,v )E このエネルギーの大域最小化を行う 問題をグラフで表し,最小切断問題として解く
  • 5.
    グラフの構築 E( X )   gv ( X v )  h uv (Xu, Xv) vV ( u ,v )E 頂点を設定: V1  wv | v  V  wv
  • 6.
    グラフの構築 E( X )   gv ( X v )  h uv (Xu, Xv) vV ( u ,v )E 頂点s,tを追加: V  V1  s, t t S
  • 7.
    グラフの構築 E( X )   gv ( X v )  h uv (Xu, Xv) vV ( u ,v )E 辺を追加:  1  ( s, wv ), ( wv , t ) | v  V  t S
  • 8.
    グラフの構築 E( X )   gv ( X v )  h uv (Xu, Xv) vV ( u ,v )E 辺を追加:  2  ( wu , wv ) | (u, v)  E t 完成! S
  • 9.
    グラフの切断 E( X )   gv ( X v )  h uv (Xu, Xv) vV ( u ,v )E このグラフの任意の切断(S,T)について: 0  v  Sのとき (w ) Xv   t 1  v  Tのとき (w ) 0 1 0 0 1 1 wv wu S
  • 10.
    グラフの切断 E( X )   gv ( X v )  h uv (Xu, Xv) vV ( u ,v )E 各辺の切断コストを定義: c( wv , t )  g v (0) t c( wu , wv )  huv (0,1)  hvu (1,0) wv wu c( s, wv )  g v (1) S
  • 11.
    グラフの切断 E( X )   gv ( X v )  h uv (Xu, Xv) vV ( u ,v )E 切断されたsからtへ向かう辺の切断コストの和とEは等しい t 0 1 0 0 1 1 S
  • 12.
    ノイズ除去の例  E ( X )    Yv  X v   Xu  Xv (2) vV ( u ,v )E 2 エネルギーを計算する    E (X )  (0    0  0  0  0)   0  1  1  0  2 2     Yv Xv
  • 13.
    ノイズ除去の例  E ( X )    Yv  X v   Xu  Xv (2) vV ( u ,v )E 2 グラフカットで切断コストを計算する c( s, wv )   Yv  1 t c( wv , t )   Yv  0 c( wu , wv )   0 λ λ 0 0 λ κ κ κ κ κ Yv κ κ κ κ κ λ 0 λ λ 0 0 S
  • 14.
    ノイズ除去の例  E ( X )    Yv  X v   Xu  Xv (2) vV ( u ,v )E 2 E(X )  0    0  0    0  0     t 0 λ λ 0 0 λ κ κ κ κ κ Yv κ κ κ κ κ λ 0 λ λ 0 0 S
  • 15.
  • 16.
  • 17.
  • 18.
    5.2 実装例 • GCライブラリ入手先 – Vladimir Kolmogorovさんのページ – http://www.cs.ucl.ac.uk/staff/V.Kolmogorov/ – Max Flowライブラリをダウンロード
  • 19.
    ライブラリ入手先 Vladimir Kolmogorovさんのページ http://www.cs.ucl.ac.uk/staff/V.Kolmogorov/
  • 20.
    ソース void NR2(unsigned char*X, unsigned char* Y, int m, int n) { typedef Graph<int,int,int> GraphType; int lambda=100; int kappa = 25; GraphType* g = new GraphType(n*m, 4*n*m); // 頂点と辺の概数 g->add_node(n*m); // 画素の数だけ頂点を作る int dx[4] = {1,-1,0,1}; int dy[4] = {0, 1, 1, 1}; for(int j=0; j<m; j++){ for(int i=0; i<n; i++){ int g0 = *(Y + n*j + i) * lambda; //g(0) int g1 = (1-*(Y + n*j + i)) * lambda; // g(1) g->add_tweights(j*n+i,g1,g0); // (i,j)の頂点はnj+i番目 for(int d=0; d<4; d++){ int x = i + dx[d]; int y = j + dy[d]; if(0<=x && 0<=y && x<n && y<m){ g->add_edge(j*n+i,y*n+x,kappa,kappa); // 両方向 } } } } g->maxflow(); for(int j=0; j<m; j++){ for(int i=0; i<n; i++){ if(g->what_segment(j*n+i)==GraphType::SOURCE) *(X + n*j + i)=0; else *(X + n*j + i)=1; } } delete g; }
  • 21.
    手順 1. GraphTypeインスタンス生成 –GraphType* g = new GraphType(n*m, n*m*4); 頂点の 辺の概数 概数 2. 画素の数だけ頂点を作る – g->add_node(n*m); 3. データ項(=C(s, wv),C(wv,t))を設定 – g->add_tweights(j*n+i, g1, g0) wu c(s, wv) c(wv, t)
  • 22.
    手順 4. 頂点間の辺を作成(双方向) –g->add_edge (j*n+i, y*n+x, kappa, kappa); wu wv c(wu, wv) c(wv, wu) 5. 最小切断(最大流)を求める – g->maxflow(); 6. 各頂点でs,tのどちらが切断されたかを結果 に格納 – g->what_segment(j*n+i)
  • 23.
  • 24.