cmtkImageOperationMedialSkeleton.cxx

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 2009-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: 2398 $
00024 //
00025 //  $LastChangedDate: 2010-10-05 14:54:37 -0700 (Tue, 05 Oct 2010) $
00026 //
00027 //  $LastChangedBy: torstenrohlfing $
00028 //
00029 */
00030 
00031 #include "cmtkImageOperationMedialSkeleton.h"
00032 
00033 #include <Base/cmtkEigenSystemSymmetricMatrix3x3.h>
00034 
00035 cmtk::UniformVolume::SmartPtr  
00036 cmtk::ImageOperationMedialSkeleton
00037 ::Apply( cmtk::UniformVolume::SmartPtr& volume )
00038 {
00039   UniformVolume::SmartPtr iMap = DistanceMapType( *volume, DistanceMapType::INSIDE ).Get();  
00040 
00041   UniformVolume::SmartPtr skeleton( iMap->CloneGrid() );
00042   skeleton->CreateDataArray( TYPE_COORDINATE );
00043   skeleton->GetData()->ClearArray();
00044 
00045   const int* dims = iMap->GetDims().begin();
00046 #pragma omp parallel for
00047   for ( int k = 2; k < dims[2]-2; ++k )
00048     {
00049     for ( int j = 2; j < dims[1]-2; ++j )
00050       {
00051       for ( int i = 2; i < dims[0]-2; ++i )
00052         {
00053 // Ridgeness operator implemented following http://en.wikipedia.org/wiki/Ridge_detection#Definition_of_ridges_and_valleys_in_N_dimensions
00054         
00055         Matrix3x3<Types::DataItem> hessian;
00056         iMap->GetHessianAt( hessian, i, j, k );
00057         
00058         EigenSystemSymmetricMatrix3x3<Types::DataItem> eigenSystem( hessian, false /*sortAbsolute*/ );
00059         
00060         Types::DataItem result = iMap->GetDataAt( i, j, k );
00061         if ( eigenSystem.GetNthEigenvalue( 2-this->m_Dimensionality ) < 0 )
00062           {
00063           const UniformVolume::CoordinateVectorType gradient = iMap->GetGradientAt( i, j, k );
00064 
00065           for ( int n = 0; n < 3-this->m_Dimensionality; ++n )
00066             {
00067             const UniformVolume::CoordinateVectorType ev = eigenSystem.GetNthEigenvector( n );
00068 
00069             if ( fabs( ev * gradient ) > 1e-2 )
00070               result = 0;
00071             }
00072           }
00073         else
00074           {
00075           result = 0;
00076           }
00077         skeleton->SetDataAt( result, i, j, k );
00078         }
00079       }
00080     }
00081   
00082   return skeleton;
00083 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines