QuOc

 

Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions

qc::TwoPhaseMSSegmentor< ConfiguratorType > Class Template Reference

Abstract base class for two phase Mumford Shah segmentation. More...

#include <finiteDifferences.h>

Inheritance diagram for qc::TwoPhaseMSSegmentor< ConfiguratorType >:
qc::TVAlgorithmBase< ConfiguratorType > qc::WeightedTwoPhaseMSSegmentor< ConfiguratorType >

List of all members.

Public Types

typedef ConfiguratorType::RealType RealType
typedef ConfiguratorType::ArrayType ArrayType

Public Member Functions

 TwoPhaseMSSegmentor (const typename ConfiguratorType::InitType &Initializer, const RealType Gamma)
virtual ~TwoPhaseMSSegmentor ()
void calcPrimalFromDual (const qc::MultiArray< RealType, ConfiguratorType::Dim > &Dual, ArrayType &Primal, const ArrayType &Indicator1Plus2, const ArrayType &Indicator2) const
void segment (ArrayType &Segmentation, qc::MultiArray< RealType, ConfiguratorType::Dim > *PDual=NULL) const
void setTau (const RealType Tau)
void setIndicatorReference (const int IndicatorNumber, const ArrayType &IndicatorFunction)

Protected Member Functions

virtual void prepareIndicatorFunctionGeneration () const
virtual void generateIndicatorFunction (const int IndicatorNumber, ArrayType &IndicatorFunction) const
virtual void generateEdgeWeight (ArrayType &edgeWeight) const

Protected Attributes

RealType _tau
const ArrayType_pIndicator [2]

Private Member Functions

virtual void doSegment (ArrayType &Segmentation, qc::MultiArray< RealType, ConfiguratorType::Dim > *PDual) const
 Can assume that prepareIndicatorFunctionGeneration ( ) has just been called.

Detailed Description

template<typename ConfiguratorType>
class qc::TwoPhaseMSSegmentor< ConfiguratorType >

Abstract base class for two phase Mumford Shah segmentation.

Minimizes the quadratic Esedoglu like model

\[ \min_{u} \gamma\int_\Omega g|\nabla u|dx + \int_\Omega f_1u^2+f_2(1-u)^2 dx, \]

where $ f_1,f_2 $ are indicator functions for the two different regions to be segmented.

Uses a finite difference scheme closely based on {An Algorithm for Total Variation Minimization and Applications} by Antonin Chambolle:

\[ p^{k+1} = \left(p^k+\tau h^2\nabla\frac{\mathrm{div}p^k-2f_2/\gamma}{2(f_1+f_2)}\right) /\left(1+\frac{\tau h^2}{g}\left|\nabla\frac{\mathrm{div}p^k-2f_2/\gamma}{2(f_1+f_2)}\right|\right) \]

where $ u^k=\frac{2f_2-\gamma\mathrm{div}p^k}{2(f_1+f_2)} $, $ h $ is the grid size, and $ \tau $ can be taken as $ \frac18 $ as shown by Chambolle.

The interface function generateIndicatorFunction, in which $ f_1 $ and $ f_2 $ are defined, needs to be implemented in the derived class. Likewise $ g $ can be defined in the derived class by implementing the interface function generateEdgeWeight.

Author:
Berkels

Definition at line 298 of file finiteDifferences.h.


Member Typedef Documentation

template<typename ConfiguratorType >
typedef ConfiguratorType::ArrayType qc::TwoPhaseMSSegmentor< ConfiguratorType >::ArrayType

Reimplemented in qc::WeightedTwoPhaseMSSegmentor< ConfiguratorType >.

Definition at line 301 of file finiteDifferences.h.

template<typename ConfiguratorType >
typedef ConfiguratorType::RealType qc::TwoPhaseMSSegmentor< ConfiguratorType >::RealType

Constructor & Destructor Documentation

template<typename ConfiguratorType >
qc::TwoPhaseMSSegmentor< ConfiguratorType >::TwoPhaseMSSegmentor ( const typename ConfiguratorType::InitType &  Initializer,
const RealType  Gamma 
) [inline]

Definition at line 317 of file finiteDifferences.h.

References qc::TwoPhaseMSSegmentor< ConfiguratorType >::_pIndicator.

    : TVAlgorithmBase<ConfiguratorType> ( Initializer, Gamma, 1000, 0.01 ),
      _tau ( 0.25 ) {
    _pIndicator[0] = NULL;
    _pIndicator[1] = NULL;
  }

template<typename ConfiguratorType >
virtual qc::TwoPhaseMSSegmentor< ConfiguratorType >::~TwoPhaseMSSegmentor (  )  [inline, virtual]

Definition at line 325 of file finiteDifferences.h.

{}


Member Function Documentation

template<typename ConfiguratorType >
void qc::TwoPhaseMSSegmentor< ConfiguratorType >::calcPrimalFromDual ( const qc::MultiArray< RealType, ConfiguratorType::Dim > &  Dual,
ArrayType Primal,
const ArrayType Indicator1Plus2,
const ArrayType Indicator2 
) const [inline]

Definition at line 327 of file finiteDifferences.h.

References qc::TVAlgorithmBase< ConfiguratorType >::_gamma, and qc::TVAlgorithmBase< ConfiguratorType >::_grid.

Referenced by qc::TwoPhaseMSSegmentor< ConfiguratorType >::doSegment().

                                                                {
    qc::calculateBackwardFDDivergence<RealType, ConfiguratorType::Dim> ( Dual, Primal );
    Primal *= -0.5 * this->_gamma / this->_grid.H();
    Primal += Indicator2;
    Primal /= Indicator1Plus2;
  }

template<typename ConfiguratorType >
virtual void qc::TwoPhaseMSSegmentor< ConfiguratorType >::doSegment ( ArrayType Segmentation,
qc::MultiArray< RealType, ConfiguratorType::Dim > *  PDual 
) const [inline, private, virtual]

Can assume that prepareIndicatorFunctionGeneration ( ) has just been called.

Definition at line 344 of file finiteDifferences.h.

References qc::TVAlgorithmBase< ConfiguratorType >::_gamma, qc::TVAlgorithmBase< ConfiguratorType >::_grid, qc::TVAlgorithmBase< ConfiguratorType >::_maxIterations, qc::TVAlgorithmBase< ConfiguratorType >::_pStepSaver, qc::TVAlgorithmBase< ConfiguratorType >::_stopEpsilon, qc::TwoPhaseMSSegmentor< ConfiguratorType >::_tau, qc::TwoPhaseMSSegmentor< ConfiguratorType >::calcPrimalFromDual(), aol::ProgressBar< _showPercentage, _showBar, TYPE, _screenWidth, _leftBrace, _rightBrace, _empty, _full >::display(), aol::ProgressBar< _showPercentage, _showBar, TYPE, _screenWidth, _leftBrace, _rightBrace, _empty, _full >::finish(), qc::TwoPhaseMSSegmentor< ConfiguratorType >::generateEdgeWeight(), qc::TwoPhaseMSSegmentor< ConfiguratorType >::generateIndicatorFunction(), aol::MultiVector< DataType >::norm(), aol::StepSaverBase< RealType, SaveInputType >::saveStep(), and aol::ProgressBar< _showPercentage, _showBar, TYPE, _screenWidth, _leftBrace, _rightBrace, _empty, _full >::start().

Referenced by qc::TwoPhaseMSSegmentor< ConfiguratorType >::segment().

                                                                                                               {
    ArrayType indicator2 ( this->_grid );
    ArrayType indicator1Plus2 ( this->_grid );
    ArrayType edgeWeight ( this->_grid );

    generateIndicatorFunction ( 1, indicator2 );
    generateIndicatorFunction ( 0, indicator1Plus2 );
    ArrayType indicator2OverGamma ( indicator2 );
    generateEdgeWeight ( edgeWeight );
    indicator1Plus2 += indicator2;
    indicator2OverGamma *= static_cast<RealType> ( this->_grid.H() ) / this->_gamma;

    qc::MultiArray<RealType, ConfiguratorType::Dim> pOld ( this->_grid );
    if ( PDual != NULL )
      pOld = *PDual;
    qc::MultiArray<RealType, ConfiguratorType::Dim> pNew ( this->_grid );
    ArrayType temp ( this->_grid );
    const int numPrimalDofs = temp.size();
    qc::MultiArray<RealType, ConfiguratorType::Dim> gradient ( this->_grid );

    aol::ProgressBar<> progressBar ( "Segmenting" );
    progressBar.start ( this->_maxIterations );
    progressBar.display ( cerr );

    for ( int fixpointIterations = 0; fixpointIterations < this->_maxIterations; fixpointIterations++ ) {
      qc::calculateBackwardFDDivergence<RealType, ConfiguratorType::Dim> ( pOld, temp );
#ifdef _OPENMP
#pragma omp parallel for
#endif
      for ( int j = 0; j < numPrimalDofs; ++j ) {
        temp[j] = ( temp[j] * 0.5 - indicator2OverGamma[j] ) / indicator1Plus2[j];
      }
      qc::calculateForwardFDGradient<RealType, ConfiguratorType::Dim> ( temp, gradient );

      typename ConfiguratorType::VecType gradientVec;
#ifdef _OPENMP
#pragma omp parallel for firstprivate ( gradientVec )
#endif
      for ( int j = 0; j < numPrimalDofs; ++j ) {
        for ( int i = 0; i < ConfiguratorType::Dim; ++i )
          gradientVec[i] = gradient[i][j];
        const RealType gradientVecNorm = gradientVec.norm();
        for ( int i = 0; i < ConfiguratorType::Dim; ++i ) {
          pNew[i][j] = ( pOld[i][j] + _tau * gradientVec[i] ) / ( 1 + _tau * gradientVecNorm / edgeWeight[j] );
        }
      }
      pOld -= pNew;
      const RealType change = pOld.norm();
      pOld = pNew;

      if ( this->_pStepSaver ) {
        calcPrimalFromDual ( pNew, temp, indicator1Plus2, indicator2 );
        this->_pStepSaver->saveStep ( temp, fixpointIterations );
      }

      // If the change is small enough, we consider the gradient descent to have converged.
      if ( change < this->_stopEpsilon )
        break;

      progressBar++;
    }
    progressBar.finish();
    calcPrimalFromDual ( pOld,  Segmentation, indicator1Plus2, indicator2 );
    if ( PDual != NULL )
      *PDual = pOld;
  }

template<typename ConfiguratorType >
virtual void qc::TwoPhaseMSSegmentor< ConfiguratorType >::generateEdgeWeight ( ArrayType edgeWeight  )  const [inline, protected, virtual]

Definition at line 312 of file finiteDifferences.h.

Referenced by qc::TwoPhaseMSSegmentor< ConfiguratorType >::doSegment().

                                                                   {
    edgeWeight.setAll ( aol::ZOTrait<RealType>::one );
  }

template<typename ConfiguratorType >
virtual void qc::TwoPhaseMSSegmentor< ConfiguratorType >::generateIndicatorFunction ( const int  IndicatorNumber,
ArrayType IndicatorFunction 
) const [inline, protected, virtual]

Definition at line 306 of file finiteDifferences.h.

References qc::TwoPhaseMSSegmentor< ConfiguratorType >::_pIndicator, and aol::strprintf().

Referenced by qc::TwoPhaseMSSegmentor< ConfiguratorType >::doSegment().

                                                                                                           {
    if ( _pIndicator[IndicatorNumber] == NULL )
      throw ( aol::Exception ( aol::strprintf ( "Indicator %d not set and generateIndicatorFunction() not overloaded.", IndicatorNumber ), __FILE__, __LINE__ ) );

    IndicatorFunction = *( _pIndicator[IndicatorNumber] );
  }

template<typename ConfiguratorType >
virtual void qc::TwoPhaseMSSegmentor< ConfiguratorType >::prepareIndicatorFunctionGeneration (  )  const [inline, protected, virtual]
template<typename ConfiguratorType >
void qc::TwoPhaseMSSegmentor< ConfiguratorType >::segment ( ArrayType Segmentation,
qc::MultiArray< RealType, ConfiguratorType::Dim > *  PDual = NULL 
) const [inline]
template<typename ConfiguratorType >
void qc::TwoPhaseMSSegmentor< ConfiguratorType >::setIndicatorReference ( const int  IndicatorNumber,
const ArrayType IndicatorFunction 
) [inline]

Definition at line 416 of file finiteDifferences.h.

References qc::TwoPhaseMSSegmentor< ConfiguratorType >::_pIndicator.

                                                                                               {
    _pIndicator[IndicatorNumber] = &IndicatorFunction;
  }

template<typename ConfiguratorType >
void qc::TwoPhaseMSSegmentor< ConfiguratorType >::setTau ( const RealType  Tau  )  [inline]

Definition at line 412 of file finiteDifferences.h.

References qc::TwoPhaseMSSegmentor< ConfiguratorType >::_tau.

                                    {
    _tau = Tau;
  }


Member Data Documentation

template<typename ConfiguratorType >
RealType qc::TwoPhaseMSSegmentor< ConfiguratorType >::_tau [protected]

The documentation for this class was generated from the following file:

Generated on Fri Sep 9 2011 21:09:45 for QuocMesh by doxygen 1.7.1