00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _itkPathFunctions_h
00019 #define _itkPathFunctions_h
00020
00021
00022 #include "itkPath.h"
00023 #include "itkChainCodePath.h"
00024 #include "itkFourierSeriesPath.h"
00025 #include "itkOffset.h"
00026 #include <math.h>
00027
00028
00029 #ifndef M_PI
00030 #define M_PI 3.14159265358979323846
00031 #endif
00032
00033 namespace itk
00034 {
00035
00036
00037
00042 template <class TChainCodePath, class TPathInput>
00043 void MakeChainCodeTracePath( TChainCodePath & chainPath,
00044 const TPathInput & inPath,
00045 bool restrictMovement = false )
00046 {
00047 typedef typename TChainCodePath::OffsetType OffsetType;
00048 typedef typename TChainCodePath::InputType ChainInputType;
00049 typedef typename TChainCodePath::OutputType ChainOutputType;
00050 typedef typename TPathInput::InputType InPathInputType;
00051 typedef typename TPathInput::OutputType InPathOutputType;
00052
00053 OffsetType offset, tempOffset, zeroOffset;
00054 InPathInputType inPathInput;
00055 int dimension = OffsetType::GetOffsetDimension();
00056
00057 zeroOffset.Fill(0);
00058
00059 chainPath.Clear();
00060 inPathInput = inPath.StartOfInput();
00061 chainPath.SetStart( inPath.EvaluateToIndex( inPathInput ) );
00062
00063 for(ChainInputType chainInput=0;;)
00064 {
00065 offset = inPath.IncrementInput(inPathInput);
00066 if( zeroOffset == offset ) { break; }
00067
00068 if( ! restrictMovement )
00069 {
00070 chainPath.InsertStep( chainInput++, offset );
00071 }
00072 else
00073 {
00074 for( int d=0; d<dimension; d++ )
00075 {
00076 tempOffset.Fill(0);
00077 tempOffset[d] = offset[d];
00078 chainPath.InsertStep( chainInput++, tempOffset );
00079 }
00080 }
00081 }
00082 }
00083
00084
00085
00092 template <class TFourierSeriesPath, class TChainCodePath>
00093 void MakeFourierSeriesPathTraceChainCode( TFourierSeriesPath & FSPath,
00094 const TChainCodePath & chainPath,
00095 unsigned int numHarmonics = 8 )
00096 {
00097 typedef typename TFourierSeriesPath::IndexType IndexType;
00098 typedef typename TFourierSeriesPath::OffsetType OffsetType;
00099 typedef typename TFourierSeriesPath::VectorType VectorType;
00100
00101 typedef typename TFourierSeriesPath::InputType FSInputType;
00102 typedef typename TFourierSeriesPath::OutputType FSOutputType;
00103 typedef typename TChainCodePath::InputType ChainInputType;
00104 typedef typename TChainCodePath::OutputType ChainOutputType;
00105
00106 IndexType index;
00107 VectorType indexVector;
00108 VectorType cosCoefficient;
00109 VectorType sinCoefficient;
00110 FSInputType theta;
00111 int dimension = OffsetType::GetOffsetDimension();
00112 unsigned numSteps = chainPath.NumberOfSteps();
00113
00114 FSPath.Clear();
00115
00116
00117 if( numHarmonics <= 1 )
00118 numHarmonics = 2;
00119 else if( numHarmonics*2 > numSteps )
00120 numHarmonics = numSteps / 2;
00121
00122 for( unsigned n=0; n<numHarmonics; n++ )
00123 {
00124 index = chainPath.GetStart();
00125 cosCoefficient.Fill(0.0);
00126 sinCoefficient.Fill(0.0);
00127
00128 for( ChainInputType step=0; step<numSteps; step++ )
00129 {
00130 index += chainPath.Evaluate( step );
00131 theta = 2*n*M_PI*(double(step+1))/numSteps;
00132
00133
00134 for( int d=0; d<dimension; d++ )
00135 indexVector[d] = index[d];
00136
00137 cosCoefficient += indexVector * (cos(theta)/numSteps);
00138 sinCoefficient += indexVector * (sin(theta)/numSteps);
00139 }
00140
00141 FSPath.AddHarmonic( cosCoefficient, sinCoefficient );
00142 }
00143 }
00144
00145
00146
00147 }
00148
00149 #endif