cmtkSimpleLevelset.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 2010 SRI International
00004 //
00005 //  This file is part of the Computational Morphometry Toolkit.
00006 //
00007 //  http://www.nitrc.org/projects/cmtk/
00008 //
00009 //  The Computational Morphometry Toolkit is free software: you can
00010 //  redistribute it and/or modify it under the terms of the GNU General Public
00011 //  License as published by the Free Software Foundation, either version 3 of
00012 //  the License, or (at your option) any later version.
00013 //
00014 //  The Computational Morphometry Toolkit is distributed in the hope that it
00015 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00016 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 //  GNU General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU General Public License along
00020 //  with the Computational Morphometry Toolkit.  If not, see
00021 //  <http://www.gnu.org/licenses/>.
00022 //
00023 //  $Revision: 2392 $
00024 //
00025 //  $LastChangedDate: 2010-10-05 12:38:47 -0700 (Tue, 05 Oct 2010) $
00026 //
00027 //  $LastChangedBy: torstenrohlfing $
00028 //
00029 */
00030 
00031 #include "cmtkSimpleLevelset.h"
00032 
00033 #include <Base/cmtkMathUtil.h>
00034 #include <Base/cmtkUniformVolume.h>
00035 #include <Base/cmtkUniformVolumePainter.h>
00036 #include <Base/cmtkUniformVolumeFilter.h>
00037 #include <Base/cmtkUnits.h>
00038 
00039 #include <System/cmtkProgress.h>
00040 
00041 #ifdef CMTK_BUILD_DEMO
00042 #  include <IO/cmtkVolumeIO.h>
00043 #endif // #ifdef CMTK_BUILD_DEMO
00044 
00045 void
00046 cmtk::SimpleLevelset
00047 ::InitializeCenteredSphere()
00048 {
00049   this->m_Levelset = this->m_Volume->CloneGrid();
00050   this->m_Levelset->CreateDataArray( TYPE_FLOAT );
00051   this->m_Levelset->GetData()->Fill( -1.0 );
00052   
00053   FixedVector<3,int> center( this->m_Volume->GetDims() );
00054   center /= 2;
00055   
00056   UniformVolumePainter painter( this->m_Levelset );
00057   painter.DrawSphere( center, this->m_ScaleInitialSphere * ((this->m_Levelset->GetDims()[0]+this->m_Levelset->GetDims()[1]+this->m_Levelset->GetDims()[2])/6), 1.0 );
00058 }
00059 
00060 void
00061 cmtk::SimpleLevelset
00062 ::Evolve( const int numberOfIterations, const bool forceIterations, const bool verbose )
00063 {
00064   const size_t numberOfPixels = this->m_Volume->GetNumberOfPixels();
00065   size_t nInsideOld = 0, nInside = 1;
00066 
00067   Progress::Begin( 0, numberOfIterations, 1, "Levelset Evolution" );
00068   for ( int it = 0; (it < numberOfIterations) && ((nInside!=nInsideOld) || forceIterations); ++it )
00069     {
00070     Progress::SetProgress( it );
00071 
00072     nInsideOld = nInside;
00073     nInside = 0;
00074     Types::DataItem insideSum = 0, outsideSum = 0;
00075 
00076     this->m_Levelset->SetData( UniformVolumeFilter( this->m_Levelset ).GetDataGaussFiltered( this->m_FilterSigma ) );
00077 #pragma omp parallel for reduction(+:nInside) reduction(+:insideSum) reduction(+:outsideSum)
00078     for ( size_t n = 0; n < numberOfPixels; ++n )
00079       {
00080       if ( this->m_Levelset->GetDataAt( n ) > 0 )
00081         {
00082         insideSum += this->m_Volume->GetDataAt( n );
00083         ++nInside;
00084         }
00085       else
00086         outsideSum += this->m_Volume->GetDataAt( n );
00087       }
00088 
00089     const size_t nOutside = numberOfPixels - nInside;
00090     const Types::DataItem ratioInOut = 1.0 * nInside / nOutside;
00091     
00092     const Types::DataItem mInside = insideSum / nInside;
00093     const Types::DataItem mOutside = outsideSum / nOutside;
00094 
00095     if ( verbose )
00096       std::cerr << it << " IN: " << nInside << "  " << mInside << "  OUT: " << nOutside << "  " << mOutside << "\r";
00097     
00098 #pragma omp parallel for
00099     for ( size_t n = 0; n < numberOfPixels; ++n )
00100       {
00101       const Types::DataItem data = this->m_Volume->GetDataAt( n );
00102       const Types::DataItem zInside = fabs( mInside - data );
00103       const Types::DataItem zOutside = fabs( mOutside - data );
00104       Types::DataItem newLevel = this->m_Levelset->GetDataAt( n );
00105       if ( zInside>zOutside )
00106         {
00107         newLevel -= this->m_TimeDelta * ratioInOut;
00108         }
00109       else
00110         {
00111         newLevel += this->m_TimeDelta / ratioInOut;
00112         }
00113       this->m_Levelset->SetDataAt( std::min<Types::DataItem>( this->m_LevelsetThreshold, std::max<Types::DataItem>( -this->m_LevelsetThreshold, newLevel ) ), n );
00114       }
00115 
00116 #ifdef CMTK_BUILD_DEMO
00117     UniformVolume::SmartConstPtr slice = this->m_Levelset->ExtractSlice( AXIS_Z, this->m_Levelset->m_Dims[2] / 2 );
00118     
00119     char path[PATH_MAX];
00120     snprintf( path, PATH_MAX, "levelset-%03d.nii", it );
00121     VolumeIO::Write( *slice, path );
00122 #endif
00123     }
00124 
00125   Progress::Done();
00126 }
00127 
00128 cmtk::UniformVolume::SmartPtr&
00129 cmtk::SimpleLevelset
00130 ::GetLevelset( const bool binarize, const float threshold )
00131 {
00132   if ( binarize )
00133     {
00134     this->m_Levelset->GetData()->Binarize( threshold );
00135     this->m_Levelset->SetData( TypedArray::SmartPtr( this->m_Levelset->GetData()->Convert( TYPE_BYTE ) ) );
00136     }
00137 
00138   return this->m_Levelset;
00139 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines