Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00054
00055 Matrix3x3<Types::DataItem> hessian;
00056 iMap->GetHessianAt( hessian, i, j, k );
00057
00058 EigenSystemSymmetricMatrix3x3<Types::DataItem> eigenSystem( hessian, false );
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 }