00001 #ifndef _PHYS_LEVEL_SET_CXX
00002 #define _PHYS_LEVEL_SET_CXX
00003
00004 #include "Phys_LevelSet.h"
00005
00006 namespace mial
00007 {
00008
00009
00010 #define DEFAULT_PROPAGATION_SCALING 0.5;
00011 #define DEFAULT_CURVATURE_SCALING 1.0;
00012 #define DEFAULT_ADVECTION_SCALING 3.0;
00013 #define DEFAULT_MAX_RMS_ERROR 0.02;
00014 #define DEFAULT_NUM_ITERATIONS 10;
00015
00016
00017 template< class DataType, class InputImageType, int nDims, class MType, class VType >
00018 Phys_LevelSet<DataType, InputImageType, nDims, MType, VType>
00019 ::Phys_LevelSet()
00020 : Physics<DataType, nDims, MType, VType>()
00021 {
00022 inputImg = NULL;
00023 distanceImg = NULL;
00024 edgePotentialImg = NULL;
00025 propagationScaling = DEFAULT_PROPAGATION_SCALING;
00026 curvatureScaling = DEFAULT_CURVATURE_SCALING;
00027 advectionScaling = DEFAULT_ADVECTION_SCALING;
00028 maximumRMSError = DEFAULT_MAX_RMS_ERROR;
00029 numIterations = DEFAULT_NUM_ITERATIONS;
00030 }
00031
00032
00033
00034
00035
00036
00037 template< class DataType, class InputImageType, int nDims, class MType, class VType >
00038 void
00039 Phys_LevelSet<DataType,InputImageType,nDims,MType,VType>
00040 ::initializeDistanceImg()
00041 {
00042 if(inputImg.IsNotNull())
00043 {
00044 std::cout << "Phys_LevelSet: Starting initializeDistanceImg()..." << std::endl;
00047
00048
00049
00050
00052
00053
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 typedef Geom_MeshSpatialObject<DataType, nDims> GeomMeshSpatialObjectType;
00098 typedef typename GeomMeshSpatialObjectType::MeshSpatialObjectType MeshSpatialObjectType;
00099
00100
00101 typename BinaryImageType::SizeType sz = inputImg->GetLargestPossibleRegion().GetSize();
00102 typename BinaryImageType::Pointer binImg = static_cast< GeomMeshSpatialObjectType* > (this->geom.GetPointer())->generateBinaryImageFromTopology( sz);
00103
00104
00105 this->geom->didTopologyChange();
00106 this->geom->didNodesChange();
00107
00108
00109 typedef itk::SignedDanielssonDistanceMapImageFilter<
00110 BinaryImageType,
00111 InternalImageType > DistanceMapFilterType;
00112 typename DistanceMapFilterType::Pointer distanceMapFilter = DistanceMapFilterType::New();
00113
00114 distanceMapFilter->SetInput(binImg );
00115 distanceMapFilter->Update();
00116 distanceImg = distanceMapFilter->GetOutput();
00117
00118
00120
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00133 if(DEBUG)
00134 {
00135 std::cout << "Phys_LevelSet: distance image initialized." << std::endl;
00136 typedef itk::ImageFileWriter< InternalImageType > DistanceWriterType;
00137 typename DistanceWriterType::Pointer distanceImageWriter = DistanceWriterType::New();
00138 std::string distanceImageFileName = "C:\\distanceImage.mhd";
00139 distanceImageWriter->SetFileName( distanceImageFileName.c_str() );
00140 distanceImageWriter->SetInput( distanceImg );
00141 distanceImageWriter->Update();
00142 std::cout << "Phys_LevelSet: distance image written to '"
00143 << distanceImageFileName << "'." << std::endl;
00144
00145 typedef itk::ImageFileWriter< BinaryImageType > BinaryWriterType;
00146 typename BinaryWriterType::Pointer binaryImageWriter = BinaryWriterType::New();
00147 std::string binaryImageFileName = "C:\\binaryImageGeneratedFromMesh.mhd";
00148 binaryImageWriter->SetFileName( binaryImageFileName.c_str() );
00149 binaryImageWriter->SetInput( binImg );
00150 binaryImageWriter->Update();
00151 std::cout << "Phys_LevelSet: generated binary image written to '"
00152 << binaryImageFileName << "'." << std::endl;
00153 }
00154
00155 }
00156 }
00157
00158
00159
00160
00161 template< class DataType, class InputImageType, int nDims, class MType, class VType >
00162 void
00163 Phys_LevelSet<DataType,InputImageType,nDims,MType,VType>
00164 ::initializeEdgePotentialImg()
00165 {
00166 if(inputImg.IsNotNull())
00167 {
00168
00169
00170 typedef itk::GradientMagnitudeRecursiveGaussianImageFilter<
00171 InputImageType,
00172 InternalImageType > GradientFilterType;
00173
00174 typedef itk::SigmoidImageFilter<
00175 InternalImageType,
00176 InternalImageType > SigmoidFilterType;
00177
00178
00179 typename GradientFilterType::Pointer gradientMagnitudeFilter = GradientFilterType::New();
00180 const double sigma = 1.0;
00181 gradientMagnitudeFilter->SetSigma( sigma );
00182
00183
00184 typename SigmoidFilterType::Pointer sigmoidFilter = SigmoidFilterType::New();
00185 sigmoidFilter->SetOutputMinimum( 0.0 );
00186 sigmoidFilter->SetOutputMaximum( 1.0 );
00187 const double alpha = -0.3;
00188 const double beta = 2;
00189 sigmoidFilter->SetAlpha( alpha );
00190 sigmoidFilter->SetBeta( beta );
00191
00192
00193 gradientMagnitudeFilter->SetInput( inputImg );
00194 sigmoidFilter->SetInput( gradientMagnitudeFilter->GetOutput() );
00195
00196
00197 sigmoidFilter->Update();
00198
00199 edgePotentialImg = sigmoidFilter->GetOutput();
00200
00201 }
00202 }
00203
00204
00205
00206 template< class DataType, class InputImageType, int nDims, class MType, class VType >
00207 void
00208 Phys_LevelSet<DataType,InputImageType,nDims,MType,VType>
00209 ::printInternalValues()
00210 {
00211 std::cout << "inputImg initialized: " << inputImg.IsNotNull() << std::endl;
00212 std::cout << "distanceImg initialized: " << distanceImg.IsNotNull() << std::endl;
00213 std::cout << "edgePotentialImg initialized: " << edgePotentialImg.IsNotNull() << std::endl;
00214 std::cout << "propagationScaling: " << propagationScaling << std::endl;
00215 std::cout << "curvatureScaling: " << curvatureScaling << std::endl;
00216 std::cout << "advectionScaling: " << advectionScaling << std::endl;
00217 std::cout << "maximumRMSError: " << maximumRMSError << std::endl;
00218 std::cout << "numIterations: " << numIterations << std::endl;
00219 return;
00220 }
00221
00222
00223 template< class DataType, class InputImageType, int nDims, class MType, class VType >
00224 bool
00225 Phys_LevelSet<DataType,InputImageType,nDims,MType,VType>
00226 ::runDeformation(const std::string defName,typename DeformationType::deformationIn* const arg ,std::stringstream * const stream)
00227 {
00228
00229
00230 if(this->geom->didTopologyChange() || this->geom->didNodesChange())
00231 {
00232
00233 initializeDistanceImg();
00234 }
00235
00236
00237 for(int i=0; i< this->numDeformations; i++)
00238 {
00239 if( defName.compare(this->deformationsList[i]->getName()) == 0 )
00240 {
00241 try
00242 {
00243 typename DeformationType::DefArgSet org;
00244 org.distanceImg = distanceImg;
00245 this->deformationsList[i]->run(arg,&org,stream);
00246 break;
00247 }catch(typename DeformationType::Error * de)
00248 {
00249 std::cerr << "Could not complete deformation" << std::endl;
00250 Error e;
00251 e.msg = "Could not complete deformation";
00252 e.deformationNumber = i;
00253 e.deformationError = de;
00254 throw & e;
00255 }
00256 }
00257 }
00258 return false;
00259 }
00260
00261
00262
00263 template< class DataType, class InputImageType, int nDims, class MType, class VType >
00264 bool
00265 Phys_LevelSet<DataType,InputImageType,nDims,MType,VType>
00266 ::simulate()
00267 {
00268
00269
00270 if( inputImg.IsNull() ) { return -1; }
00271 else
00272 {
00273 if( distanceImg.IsNull() )
00274 {
00275 initializeDistanceImg();
00276
00277 }
00278 if( edgePotentialImg.IsNull() )
00279 {
00280 initializeEdgePotentialImg();
00281 }
00282
00283
00284
00285
00286 typedef itk::GeodesicActiveContourLevelSetImageFilter<
00287 InternalImageType,
00288 InternalImageType,
00289 DataType > GeodesicActiveContourFilterType;
00290
00291 typename GeodesicActiveContourFilterType::Pointer
00292 levelSetFilter = GeodesicActiveContourFilterType::New();
00293
00294
00295 levelSetFilter->SetInput(distanceImg );
00296 levelSetFilter->SetFeatureImage( edgePotentialImg );
00297
00298 levelSetFilter->SetPropagationScaling( propagationScaling );
00299 levelSetFilter->SetCurvatureScaling( curvatureScaling );
00300 levelSetFilter->SetAdvectionScaling( advectionScaling );
00301 levelSetFilter->SetMaximumRMSError( maximumRMSError );
00302 levelSetFilter->SetNumberOfIterations( numIterations );
00303
00304
00305 typedef itk::BinaryThresholdImageFilter<
00306 InternalImageType,
00307 BinaryImageType > ThresholdingFilterType;
00308 typename ThresholdingFilterType::Pointer thresholdFilter = ThresholdingFilterType::New();
00309
00310
00311 thresholdFilter->SetLowerThreshold( -1000.0 );
00312 thresholdFilter->SetUpperThreshold( 0.0 );
00313 thresholdFilter->SetOutsideValue( 0 );
00314 thresholdFilter->SetInsideValue( 255 );
00315
00316
00317 thresholdFilter->SetInput( levelSetFilter->GetOutput() );
00318
00319
00320 thresholdFilter->Update();
00321
00322 outputImg = thresholdFilter->GetOutput();
00323
00324 std::cout << "Phys_LevelSet simulation completed." << std::endl;
00325
00326 distanceImg = levelSetFilter->GetOutput();
00327
00328 std::cout << "Updating geometry" << std::endl;
00329 this->geom->generateTopologyFromBinaryImage(outputImg);
00330
00331 std::cout << "Clock: " << this->time << std::endl;
00332 this->time ++;
00333
00334 return false;
00335 }
00336 }
00337
00338
00339 template< class DataType, class InputImageType, int nDims, class MType, class VType >
00340 void
00341 Phys_LevelSet<DataType,InputImageType,nDims,MType,VType>
00342 ::setExternalForces( void * notUsed)
00343 {
00344
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 }
00357
00358 #endif // _PHYS_LEVEL_SET_CXX included