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 namespace itk
00028 {
00029
00030
00031
00036 template <class TChainCodePath, class TPathInput>
00037 void MakeChainCodeTracePath( TChainCodePath & chainPath,
00038 const TPathInput & inPath,
00039 bool restrictMovement = false )
00040 {
00041 typedef typename TChainCodePath::OffsetType OffsetType;
00042 typedef typename TChainCodePath::InputType ChainInputType;
00043 typedef typename TChainCodePath::OutputType ChainOutputType;
00044 typedef typename TPathInput::InputType InPathInputType;
00045 typedef typename TPathInput::OutputType InPathOutputType;
00046
00047 OffsetType offset, tempOffset, zeroOffset;
00048 InPathInputType inPathInput;
00049 int dimension = OffsetType::GetOffsetDimension();
00050
00051 zeroOffset.Fill(0);
00052
00053 chainPath.Clear();
00054 inPathInput = inPath.StartOfInput();
00055 chainPath.SetStart( inPath.EvaluateToIndex( inPathInput ) );
00056
00057 for(ChainInputType chainInput=0;;)
00058 {
00059 offset = inPath.IncrementInput(inPathInput);
00060 if( zeroOffset == offset ) { break; }
00061
00062 if( ! restrictMovement )
00063 {
00064 chainPath.InsertStep( chainInput++, offset );
00065 }
00066 else
00067 {
00068 for( int d=0; d<dimension; d++ )
00069 {
00070 tempOffset.Fill(0);
00071 tempOffset[d] = offset[d];
00072 chainPath.InsertStep( chainInput++, tempOffset );
00073 }
00074 }
00075 }
00076 }
00077
00078
00079
00086 template <class TFourierSeriesPath, class TChainCodePath>
00087 void MakeFourierSeriesPathTraceChainCode( TFourierSeriesPath & FSPath,
00088 const TChainCodePath & chainPath,
00089 unsigned int numHarmonics = 8 )
00090 {
00091 typedef typename TFourierSeriesPath::IndexType IndexType;
00092 typedef typename TFourierSeriesPath::OffsetType OffsetType;
00093 typedef typename TFourierSeriesPath::VectorType VectorType;
00095
00096 typedef typename TFourierSeriesPath::InputType FSInputType;
00097 typedef typename TFourierSeriesPath::OutputType FSOutputType;
00098 typedef typename TChainCodePath::InputType ChainInputType;
00099 typedef typename TChainCodePath::OutputType ChainOutputType;
00100
00101 IndexType index;
00102 VectorType indexVector;
00103 VectorType cosCoefficient;
00104 VectorType sinCoefficient;
00105 FSInputType theta;
00106 int dimension = OffsetType::GetOffsetDimension();
00107 unsigned numSteps = chainPath.NumberOfSteps();
00108
00109 const double PI = 4.0 * atan( 1.0 );
00110
00111 FSPath.Clear();
00112
00113
00114 if( numHarmonics <= 1 )
00115 numHarmonics = 2;
00116 else if( numHarmonics*2 > numSteps )
00117 numHarmonics = numSteps / 2;
00118
00119 for( unsigned n=0; n<numHarmonics; n++ )
00120 {
00121 index = chainPath.GetStart();
00122 cosCoefficient.Fill(0.0);
00123 sinCoefficient.Fill(0.0);
00124
00125 for( ChainInputType step=0; step<numSteps; step++ )
00126 {
00127 index += chainPath.Evaluate( step );
00128 theta = 2 * n * PI * ( double(step+1)) / numSteps;
00129
00130
00131 for( int d=0; d<dimension; d++ )
00132 indexVector[d] = index[d];
00133
00134 cosCoefficient += indexVector * (cos(theta)/numSteps);
00135 sinCoefficient += indexVector * (sin(theta)/numSteps);
00136 }
00137
00138 FSPath.AddHarmonic( cosCoefficient, sinCoefficient );
00139 }
00140 }
00141
00142
00143
00144 }
00145
00146 #endif
00147