]> Creatis software - FrontAlgorithms.git/blobdiff - lib/fpa/Common/OriginalRandomWalker.hxx
...
[FrontAlgorithms.git] / lib / fpa / Common / OriginalRandomWalker.hxx
index 9bc08d4c5c461d802deb2de6200f4101d47518e7..2d3dc73a58ea6592175395bf70beebfe678b0d4b 100644 (file)
@@ -5,29 +5,27 @@
 #ifndef __fpa__Common__OriginalRandomWalker__hxx__
 #define __fpa__Common__OriginalRandomWalker__hxx__
 
-#include <cmath>
 #include <itkImageRegionConstIteratorWithIndex.h>
 #include <itkImageRegionIteratorWithIndex.h>
 #include <Eigen/Sparse>
 
 // -------------------------------------------------------------------------
-template< class _TImage, class _TLabels, class _TScalar >
-void fpa::Common::OriginalRandomWalker< _TImage, _TLabels, _TScalar >::
-AddSeed( const TIndex& seed, const TLabel& label )
-{
-  this->m_Seeds.push_back( seed );
-  this->m_Labels.push_back( label );
-  this->Modified( );
-}
+/* TODO
+   template< class _TImage, class _TLabels, class _TScalar >
+   void fpa::Common::OriginalRandomWalker< _TImage, _TLabels, _TScalar >::
+   AddSeed( const TIndex& seed, const TLabel& label )
+   {
+   this->m_Seeds.push_back( seed );
+   this->m_Labels.push_back( label );
+   this->Modified( );
+   }
+*/
 
 // -------------------------------------------------------------------------
 template< class _TImage, class _TLabels, class _TScalar >
 fpa::Common::OriginalRandomWalker< _TImage, _TLabels, _TScalar >::
 OriginalRandomWalker( )
-  : Superclass( ),
-    m_Beta( TScalar( 90 ) ),
-    m_Epsilon( TScalar( 1e-5 ) ),
-    m_NormalizeWeights( true )
+  : Superclass( )
 {
   fpaFilterInputConfigureMacro( InputLabels, TLabels );
   fpaFilterOutputConfigureMacro( OutputProbabilities, TScalarImage );
@@ -51,82 +49,92 @@ GenerateData( )
   typedef Eigen::SparseMatrix< TScalar >    _TMatrix;
   typedef Eigen::SimplicialLDLT< _TMatrix > _TSolver;
 
+  // Configure edge function
+  if( this->m_EdgeFunction.IsNull( ) )
+    itkExceptionMacro( << "Undefined edge function." );
+  const TImage* input = this->GetInput( );
+  this->m_EdgeFunction->SetDataObject( input );
+
   // Allocate outputs
   this->AllocateOutputs( );
 
-  // Build boundary triplets and count labels
-  _TTriplets St, Bt;
-  std::map< TLabel, unsigned long > labels;
-  this->_Boundary( St, labels );
-  struct _TTripletsOrd
-  {
-    bool operator()( const _TTriplet& a, const _TTriplet& b )
-      {
-        return( a.row( ) < b.row( ) );
-      }
-  };
-  std::sort( St.begin( ), St.end( ), _TTripletsOrd( ) );
-  for( unsigned long i = 0; i < St.size( ); ++i )
-    Bt.push_back( _TTriplet( i, labels[ St[ i ].col( ) ], St[ i ].value( ) ) );
-
-  // Laplacian triplets
-  _TTriplets At, Rt;
-  this->_Laplacian( At, Rt, St );
-
-  // Matrices
-  TRegion region = this->GetInput( )->GetRequestedRegion( );
-  unsigned long nSeeds = St.size( );
-  unsigned long nLabels = labels.size( );
-  unsigned long N = region.GetNumberOfPixels( );
-
-  std::vector< TLabel > invLabels( nLabels );
-  for( typename std::map< TLabel, unsigned long >::value_type s: labels )
-    invLabels[ s.second ] = s.first;
-
-  _TMatrix B( nSeeds, nLabels );
-  B.setFromTriplets( Bt.begin( ), Bt.end( ) );
-  B.makeCompressed( );
-
-  _TMatrix R( N - nSeeds, nSeeds );
-  R.setFromTriplets( Rt.begin( ), Rt.end( ) );
-  R.makeCompressed( );
-
-  _TMatrix A( N - nSeeds, N - nSeeds );
-  A.setFromTriplets( At.begin( ), At.end( ) );
-  A.makeCompressed( );
+  // Persisting objects
+  _TMatrix A( 1, 1 ), C( 1, 1 );
+  _TTriplets St;
+  std::vector< TLabel > invLabels;
+
+  { // begin
+    // Build boundary triplets and count labels
+    _TTriplets Bt;
+    std::map< TLabel, unsigned long > labels;
+    itkDebugMacro( << "Building boundary matrix..." );
+    this->_Boundary( St, labels );
+    struct _TTripletsOrd
+    {
+      bool operator()( const _TTriplet& a, const _TTriplet& b )
+        {
+          return( a.row( ) < b.row( ) );
+        }
+    };
+    itkDebugMacro( << "Sorting boundary pixels..." );
+    std::sort( St.begin( ), St.end( ), _TTripletsOrd( ) );
+    itkDebugMacro( << "Assigning boundary pixels..." );
+    for( unsigned long i = 0; i < St.size( ); ++i )
+      Bt.push_back(
+        _TTriplet( i, labels[ St[ i ].col( ) ], St[ i ].value( ) )
+        );
+
+    // Laplacian triplets
+    itkDebugMacro( << "Building laplacian matrix..." );
+    _TTriplets At, Rt;
+    this->_Laplacian( At, Rt, St );
+
+    // Matrices
+    TRegion region = input->GetRequestedRegion( );
+    unsigned long nSeeds = St.size( );
+    unsigned long nLabels = labels.size( );
+    unsigned long N = region.GetNumberOfPixels( );
+
+    itkDebugMacro( << "Creating inverse labels..." );
+    invLabels.resize( nLabels );
+    for( typename std::map< TLabel, unsigned long >::value_type s: labels )
+      invLabels[ s.second ] = s.first;
+
+    itkDebugMacro( << "Creating B matrix..." );
+    _TMatrix B( nSeeds, nLabels );
+    B.setFromTriplets( Bt.begin( ), Bt.end( ) );
+    B.makeCompressed( );
+
+    itkDebugMacro( << "Creating R matrix..." );
+    _TMatrix R( N - nSeeds, nSeeds );
+    R.setFromTriplets( Rt.begin( ), Rt.end( ) );
+    R.makeCompressed( );
+
+    itkDebugMacro( << "Creating C matrix..." );
+    C = R * B;
+
+    itkDebugMacro( << "Creating A matrix..." );
+    A.resize( N - nSeeds, N - nSeeds );
+    A.setFromTriplets( At.begin( ), At.end( ) );
+    A.makeCompressed( );
+  } // end
 
   // Solve dirichlet problem
   _TSolver solver;
+  itkDebugMacro( << "Factorizing problem..." );
   solver.compute( A );
   if( solver.info( ) != Eigen::Success )
-  {
-    std::cerr << "Error computing." << std::endl;
-  } // fi
-  _TMatrix x = solver.solve( R * B );
+    itkExceptionMacro( << "Error decomposing matrix." );
+  itkDebugMacro( << "Solving problem..." );
+  _TMatrix x = solver.solve( C );
   if( solver.info( ) != Eigen::Success )
-  {
-    std::cerr << "Error solving." << std::endl;
-  } // fi
+    itkExceptionMacro( << "Error solving system." );
 
   // Fill outputs
+  itkDebugMacro( << "Filling output..." );
   this->_Output( x, St, invLabels );
 }
 
-// -------------------------------------------------------------------------
-template< class _TImage, class _TLabels, class _TScalar >
-_TScalar fpa::Common::OriginalRandomWalker< _TImage, _TLabels, _TScalar >::
-_W( const TIndex& i, const TIndex& j )
-{
-  const TImage* in = this->GetInput( );
-  TScalar a = TScalar( in->GetPixel( i ) );
-  TScalar b = TScalar( in->GetPixel( j ) );
-  TScalar v = std::exp( -this->m_Beta * std::fabs( a - b ) );
-  if( v < this->m_Epsilon )
-    return( this->m_Epsilon );
-  else
-    return( v );
-}
-
 // -------------------------------------------------------------------------
 template< class _TImage, class _TLabels, class _TScalar >
 _TScalar fpa::Common::OriginalRandomWalker< _TImage, _TLabels, _TScalar >::
@@ -143,7 +151,7 @@ _L( const TIndex& i, const TIndex& j )
         TIndex k = i;
         k[ d ] += n;
         if( r.IsInside( k ) )
-          s += this->_W( i, k );
+          s += this->m_EdgeFunction->Evaluate( i, k );
 
       } // rof
 
@@ -151,7 +159,7 @@ _L( const TIndex& i, const TIndex& j )
     return( s );
   }
   else
-    return( this->_W( i, j ) * TScalar( -1 ) );
+    return( -( this->m_EdgeFunction->Evaluate( i, j ) ) );
 }
 
 // -------------------------------------------------------------------------
@@ -261,7 +269,7 @@ _Laplacian( _TTriplets& A, _TTriplets& R, const _TTriplets& B )
   thrStr.B = reinterpret_cast< const void* >( &B );
 
   // Configure threader
-  const TImage* in = this->GetInputLabels( );
+  const TImage* in = this->GetInput( );
   const itk::ImageRegionSplitterBase* split = this->GetImageRegionSplitter( );
   const unsigned int nThreads =
     split->GetNumberOfSplits(
@@ -317,13 +325,13 @@ _ThreadedLaplacian(
 
   const TImage* in = this->GetInput( );
   const TLabels* in_labels = this->GetInputLabels( );
-  TRegion rqRegion = in->GetRequestedRegion( );
+  TRegion reqRegion = in->GetRequestedRegion( );
   _TIt it( in, region );
   for( it.GoToBegin( ); !it.IsAtEnd( ); ++it )
   {
     TIndex idx = it.GetIndex( );
     bool iSeed = ( in_labels->GetPixel( idx ) != 0 );
-    unsigned long i = Self::_1D( idx, rqRegion );
+    unsigned long i = Self::_1D( idx, reqRegion );
     unsigned long si;
 
     // A's diagonal values
@@ -344,10 +352,10 @@ _ThreadedLaplacian(
       {
         TIndex jdx = idx;
         jdx[ d ] += s;
-        if( rqRegion.IsInside( jdx ) )
+        if( reqRegion.IsInside( jdx ) )
         {
           TScalar L = this->_L( idx, jdx );
-          unsigned long j = Self::_1D( jdx, rqRegion );
+          unsigned long j = Self::_1D( jdx, reqRegion );
           bool jSeed = ( in_labels->GetPixel( jdx ) != 0 );
           if( !jSeed )
           {
@@ -365,7 +373,7 @@ _ThreadedLaplacian(
               this->m_Mutex.Unlock( );
 
             } // fi
-            
+
           } // fi
 
         } // fi
@@ -451,6 +459,7 @@ _ThreadedOutput(
   const TLabels* in_labels = this->GetInputLabels( );
   TLabels* out_labels = this->GetOutput( );
   TScalarImage* out_probs = this->GetOutputProbabilities( );
+  TRegion reqRegion = out_labels->GetRequestedRegion( );
   itk::ImageRegionConstIteratorWithIndex< TLabels > iIt( in_labels, region );
   itk::ImageRegionIteratorWithIndex< TLabels > oIt( out_labels, region );
   itk::ImageRegionIteratorWithIndex< TScalarImage > pIt( out_probs, region );
@@ -461,7 +470,7 @@ _ThreadedOutput(
   {
     if( iIt.Get( ) == 0 )
     {
-      unsigned long i = Self::_1D( iIt.GetIndex( ), region );
+      unsigned long i = Self::_1D( iIt.GetIndex( ), reqRegion );
       unsigned long j = Self::_NearSeedIndex( i, *S );
       TScalar maxP = X->coeff( j, 0 );
       unsigned long maxL = 0;