00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkPathFunctions_h
00018 #define __itkPathFunctions_h
00019
00020
00021 #include "itkPath.h"
00022 #include "itkChainCodePath.h"
00023 #include "itkFourierSeriesPath.h"
00024 #include "itkOffset.h"
00025 #include <math.h>
00026
00027
00028 #ifndef M_PI
00029 #define M_PI 3.14159265358979323846
00030 #endif
00031
00032 namespace itk
00033 {
00034
00035
00036
00041 template <class TChainCodePath, class TPathInput>
00042 void MakeChainCodeTracePath( TChainCodePath & chainPath,
00043 const TPathInput & inPath,
00044 bool restrictMovement = false )
00045 {
00046 typedef typename TChainCodePath::OffsetType OffsetType;
00047 typedef typename TChainCodePath::InputType ChainInputType;
00048 typedef typename TChainCodePath::OutputType ChainOutputType;
00049 typedef typename TPathInput::InputType InPathInputType;
00050 typedef typename TPathInput::OutputType InPathOutputType;
00051
00052 OffsetType offset, tempOffset, zeroOffset;
00053 InPathInputType inPathInput;
00054 int dimension = OffsetType::GetOffsetDimension();
00055
00056 zeroOffset.Fill(0);
00057
00058 chainPath.Clear();
00059 inPathInput = inPath.StartOfInput();
00060 chainPath.SetStart( inPath.EvaluateToIndex( inPathInput ) );
00061
00062 for(ChainInputType chainInput=0;;)
00063 {
00064 offset = inPath.IncrementInput(inPathInput);
00065 if( zeroOffset == offset ) { break; }
00066
00067 if( ! restrictMovement )
00068 {
00069 chainPath.InsertStep( chainInput++, offset );
00070 }
00071 else
00072 {
00073 for( int d=0; d<dimension; d++ )
00074 {
00075 tempOffset.Fill(0);
00076 tempOffset[d] = offset[d];
00077 chainPath.InsertStep( chainInput++, tempOffset );
00078 }
00079 }
00080 }
00081 }
00082
00083
00084
00091 template <class TFourierSeriesPath, class TChainCodePath>
00092 void MakeFourierSeriesPathTraceChainCode( TFourierSeriesPath & FSPath,
00093 const TChainCodePath & chainPath,
00094 unsigned int numHarmonics = 8 )
00095 {
00096 typedef typename TFourierSeriesPath::IndexType IndexType;
00097 typedef typename TFourierSeriesPath::OffsetType OffsetType;
00098 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
00150