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