SMILX  1.01
milxRegistration.cxx
1 /*=========================================================================
2 Program: MILX MixView
3 Module: milxRegistration.cxx
4 Author: Jurgen Fripp
5 Modified by:
6 Language: C++
7 Created: Tue 24 Mar 2009 16:25:48 EST
8 
9 Copyright: (c) 2009 CSIRO, Australia.
10 
11 This software is protected by international copyright laws.
12 Any unauthorised copying, distribution or reverse engineering is prohibited.
13 
14 Licence:
15 All rights in this Software are reserved to CSIRO. You are only permitted
16 to have this Software in your possession and to make use of it if you have
17 agreed to a Software License with CSIRO.
18 
19 BioMedIA Lab: http://www.ict.csiro.au/BioMedIA/
20 =========================================================================*/
21 
22 // #define USE_BOOST
23 //TODO ND: this should really be set by cmake
24 
25 //TODO Set Affine transform to initialise NR registration (method missing in ITK 4.0.0)
26 
27 #include "milxRegistration.h"
28 
29 #include <itkTransformFileReader.h>
30 #include <itkTransformFileWriter.h>
31 #include <itkImageFileReader.h>
32 #include <itkImageFileWriter.h>
33 #include <itkExtractImageFilter.h>
34 #include <itkMinimumMaximumImageFilter.h>
35 #include <itkFlipImageFilter.h>
36 #include <itkPermuteAxesImageFilter.h>
37 #include <itkDiffeomorphicDemonsRegistrationFilter.h>
38 #include "itkHistogramMatchingImageFilter.h"
39 #include "itkMultiResolutionPDEDeformableRegistration.h"
40 
41 #include <itkImageRegionIteratorWithIndex.h>
42 
43 #include <itkResampleImageFilter.h>
44 #include <itkIdentityTransform.h>
45 
46 #include <itkIdentityTransform.h>
47 #include <itkImageFileReader.h>
48 #include <itkImageFileWriter.h>
49 #include <itkCenteredTransformInitializer.h>
50 #include <itkVersorRigid3DTransform.h>
51 #include <itkVersorRigid3DTransformOptimizer.h>
52 #include <itkAffineTransform.h>
53 #include <itkEuler3DTransform.h>
54 #include <itkResampleImageFilter.h>
55 #include <itkBSplineResampleImageFunction.h>
56 #include <itkBSplineDecompositionImageFilter.h>
57 #include <itkRecursiveMultiResolutionPyramidImageFilter.h>
58 #include <itkNormalizeImageFilter.h>
59 #include "itkImageMaskSpatialObject.h"
60 #include <itkThresholdImageFilter.h>
61 #include <itkLabelStatisticsImageFilter.h>
62 #include <itkBinaryThresholdImageFilter.h>
63 
64 #include <itkTimeProbesCollectorBase.h>
65 #include <itkTransformFileWriter.h>
66 #if ITK_VERSION_MAJOR < 4
67 #include <itkOrientedImage.h>
68 #include <itkBSplineDeformableTransform.h>
69 #include <itkCompose3DVectorImageFilter.h>
70 #else
71 #include <itkImage.h>
72 #include <itkBSplineTransform.h>
73 #include <itkComposeImageFilter.h>
74 #endif
75 
76 #include <cmath>
77 
78 #include <itkLinearInterpolateImageFunction.h>
79 #include <itkImageRegistrationMethod.h>
80 #include <itkMultiResolutionImageRegistrationMethod.h>
81 #include "itkMattesMutualInformationImageToImageMetric.h"
82 #include "itkMeanSquaresHistogramImageToImageMetric.h"
83 #include <itkRegularStepGradientDescentOptimizer.h>
84 #include <itkCenteredVersorTransformInitializer.h>
85 #include <itkSpatialObjectToImageFilter.h>
86 
87 #include <fstream>
88 #include <iostream>
89 
91 //#define USE_BOOST
92 #ifdef USE_BOOST
93 #include "itkAliBabaPyramidWrapper.h"
94 #endif
95 
96 namespace milx {
97 
98 
99 /* STAPLE Filter files */
100 #define USE_EXTERNAL_CALL2VOTE 1
101 #define STAPLE_EXEC "itkMultiLabelSTAPLEImageFilter"
102 #define STAPLE_TYPE "VOTE"
103 #define STAPLE_TYPE2 "MULTISTAPLE"
104 
105 #define MILXBSPLINE "nrr"
106 
107 /********************** DEFAULT PARAMETERS ************************/
108 
109 const unsigned int RIGID_ITERATIONS = 1200;
110 const float RIGID_MAX_STEP = 2;
111 const float RIGID_MIN_STEP = 0.01;
112 
113 const unsigned int RIGID_AFFINE_ITERATIONS = 1200;
114 const float RIGID_AFFINE_MAX_STEP = 2;
115 const float RIGID_AFFINE_MIN_STEP = 0.2;
116 
117 const unsigned int AFFINE_ITERATIONS = 800;
118 const float AFFINE_MAX_STEP = 2;
119 const float AFFINE_MIN_STEP = 0.01;
120 
121 const unsigned int NRR_ITERATIONS_ONE = 800;
122 const unsigned int NRR_ITERATIONS_TWO = 400;
123 const unsigned int NRR_ITERATIONS_THREE = 200;
124 const float NRR_MAX_STEP_ONE = 10;
125 const float NRR_MAX_STEP_TWO = 8.6;
126 const float NRR_MAX_STEP_THREE = 7;
127 const float NRR_MIN_STEP = 0.00001;
128 const float NRR_RELAXATION_FACTOR = 0.7;
129 const float NRR_GRADIENT_MAGNITUDE_TOLERANCE = 0.0000001;
130 const unsigned int PYRAMID_RESOLUTION_ONE = 2;
131 const unsigned int PYRAMID_RESOLUTION_TWO = 2;
132 const unsigned int PYRAMID_RESOLUTION_THREE = 2;
133 const unsigned int GRID_POINT_SPACING_ONE = 20;
134 const unsigned int GRID_POINT_SPACING_TWO = 10;
135 const unsigned int GRID_POINT_SPACING_THREE = 5;
136 
137 const unsigned int SplineOrder = 3;
138 #define ImageDimension 3
139 #define SpaceDimension 3
140 /*******************************************************************/
141 
142 #include "itkCommand.h"
143 class CommandIterationUpdate : public itk::Command
144 {
145 public:
147  typedef itk::Command Superclass;
148  typedef itk::SmartPointer<Self> Pointer;
149  itkNewMacro( Self );
150 protected:
152 public:
153  typedef itk::RegularStepGradientDescentOptimizer OptimizerType;
154 
155  typedef const OptimizerType * OptimizerPointer;
156 
157  void Execute(itk::Object *caller, const itk::EventObject & event)
158  {
159  Execute( (const itk::Object *)caller, event);
160  }
161 
162  void Execute(const itk::Object * object, const itk::EventObject & event)
163  {
164  OptimizerPointer optimizer = dynamic_cast< OptimizerPointer >( object );
165  if( !(itk::IterationEvent().CheckEvent( &event )) )
166  {
167  return;
168  }
169  if(optimizer->GetCurrentIteration()%50 == 0)
170  {
171  std::cout << optimizer->GetCurrentIteration() << " ";
172  std::cout << optimizer->GetValue() << " ";
173  std::cout << std::endl;
174  }
175  }
176 };
177 
178 class RegistrationIterationUpdate : public itk::Command
179 {
180 public:
182  typedef itk::Command Superclass;
183  typedef itk::SmartPointer<Self> Pointer;
184  itkNewMacro( Self );
185 
186  typedef float InputPixelType;
187 #if ITK_VERSION_MAJOR < 4
188  typedef itk::OrientedImage< InputPixelType, 3> FixedImageType;
189  typedef itk::OrientedImage< InputPixelType, 3 > MovingImageType;
190 #else
191  typedef itk::Image< InputPixelType, 3> FixedImageType;
192  typedef itk::Image< InputPixelType, 3 > MovingImageType;
193 #endif
194  typedef itk::MultiResolutionImageRegistrationMethod< FixedImageType, MovingImageType > RegistrationType;
195 
196  typedef const RegistrationType * RegistrationPointer;
197  typedef RegistrationType * Registration2Pointer;
198 
199  typedef itk::RegularStepGradientDescentOptimizer OptimizerType;
200  typedef OptimizerType * Optimizer2Pointer;
201 
202  typedef itk::MattesMutualInformationImageToImageMetric< FixedImageType, MovingImageType > MetricType;
203  typedef MetricType * Metric2Pointer;
204 
205  void Execute(itk::Object *caller, const itk::EventObject & event)
206  {
207  //Execute( (const itk::Object *)caller, event);
208 
209  Registration2Pointer registration = dynamic_cast< Registration2Pointer >( caller );
210  if( !(itk::IterationEvent().CheckEvent( &event )) )
211  {
212  return;
213  }
214 
215  Optimizer2Pointer optimizer = dynamic_cast< Optimizer2Pointer >(registration->GetOptimizer());
216  int iterations = optimizer->GetNumberOfIterations();
217  int current = optimizer->GetCurrentIteration();
218  if(current > 0)
219  {
220  std::cout << "Iteration event for registration entered: Prev Iterations: " << current << " of " << iterations << std::endl;
221  //if(iterations == current)
222  optimizer->SetNumberOfIterations( (iterations+1)/2 );
223  std::cout << " Next level use " << optimizer->GetNumberOfIterations() << " iterations" << std::endl;
224 
225  // Update Max-Min Step lengths
226  //std::cout << " Next level use " << optimizer->GetCurrentStepLength() << " Max Step Length" << std::endl;
227  optimizer->SetMaximumStepLength( optimizer->GetMaximumStepLength()/2.0 );
228  optimizer->SetMinimumStepLength( optimizer->GetMinimumStepLength()/2.0 );
229  std::cout << " Next level use " << optimizer->GetMinimumStepLength() << " Min Step Length" << std::endl;
230 
231  Metric2Pointer metric = dynamic_cast< Metric2Pointer >(registration->GetMetric());
232  int samples = metric->GetNumberOfSpatialSamples();
233  //std::cout << " Metric samples previously used " << samples << std::endl;
234  if(metric->GetUseAllPixels() == false)
235  {
236  metric->SetNumberOfSpatialSamples( static_cast<int>(4*samples) );
237  //metric->SetFixedImageSamplesIntensityThreshold(-0.6);
238  //metric->Initialize();
239  std::cout << " Will now use metric sampling: " << metric->GetNumberOfSpatialSamples() << std::endl;
240  }
241  }
242  }
243 
244  void Execute(const itk::Object * object, const itk::EventObject & event)
245  {
246  RegistrationPointer( dynamic_cast< RegistrationPointer >( object ) ); //ND
247  if( !(itk::IterationEvent().CheckEvent( &event )) )
248  {
249  return;
250  }
251  }
252 
253 protected:
255 
256 };
257 
258 Registration
259 ::Registration()
260 {
261  m_NearestNeighborInterpolator = NearestNeighborInterpolatorType::New();
262  m_LinearInterpolator = LinearInterpolatorType::New();
263  m_BsplineInterpolator = BsplineInterpolatorType::New();
264  m_BsplineInterpolator->SetSplineOrder(3);
265 
266  m_NearestNeighborOrientatedInterpolator = NearestNeighborOrientatedInterpolatorType::New();
267  m_LinearOrientatedInterpolator = LinearOrientatedInterpolatorType::New();
268  m_BsplineOrientatedInterpolator = BsplineOrientatedInterpolatorType::New();
269  m_BsplineOrientatedInterpolator->SetSplineOrder(3);
270 
271  m_ConsensusMode = VOTING;
272  m_RegistrationMode = ALADIN_DIFFDEMONS;
273  m_RegistrationInterpolation = INTERP_LINEAR;
274  m_AtlasInterpolation = INTERP_BSPLINE;
275  m_LabelledImageInterpolation = INTERP_NEAREST;
276 
277  m_UseConsensus = false;
278 
279  m_SaveFiles = 5;
280 }
281 
282 Registration
283 ::~Registration()
284 {
285 
286 }
287 
288 bool
289 Registration
290 ::PropagateAffine(std::string dataFile,
291  std::string outFile,
292  std::string targetFile,
293  double * array, InterpolateMode mode,
294  itk::SpatialOrientation::ValidCoordinateOrientationFlags &/*flag*/,
295  itk::SpatialOrientationAdapter::DirectionType &dir)
296 {
297  typedef itk::AffineTransform< double, 3 > AffineTransformType;
298  AffineTransformType::Pointer affineTransform = AffineTransformType::New();
299 
300  typedef AffineTransformType::ParametersType ParametersType;
301  ParametersType params( 12 );
302 
303  for(int i = 0; i < 12; i++)
304  {
305  params[i] = array[i];
306  }
307  affineTransform->SetParameters(params);
308 
309  itk::ImageFileReader<InputImageType>::Pointer reader;
310  reader = itk::ImageFileReader<InputImageType>::New();
311  reader->SetFileName(dataFile);
312  reader->Update();
313 
314  //InputImageType::SpacingType inputSpacing = reader->GetOutput()->GetSpacing();
315  //InputImageType::SizeType inputSize = reader->GetOutput()->GetLargestPossibleRegion().GetSize();
316 
317  itk::ImageFileReader<OutputImageType>::Pointer reader2;
318  reader2 = itk::ImageFileReader<OutputImageType>::New();
319  reader2->SetFileName(targetFile);
320  reader2->Update();
321 
322  OutputImageType::SpacingType outputSpacing = reader2->GetOutput()->GetSpacing();
323  OutputImageType::SizeType outputSize = reader2->GetOutput()->GetLargestPossibleRegion().GetSize();
324  OutputImageType::PointType outputOrigin = reader2->GetOutput()->GetOrigin();
325 
326  // We want to resample based on affine transform and given spacing!
327  typedef itk::ResampleImageFilter< InputImageType, OutputImageType > ResampleFilterType;
328  ResampleFilterType::Pointer resampleImageFilter = ResampleFilterType::New();
329  if( mode == INTERP_NEAREST)
330  resampleImageFilter->SetInterpolator( m_NearestNeighborInterpolator );
331  else if(mode == INTERP_LINEAR)
332  resampleImageFilter->SetInterpolator( m_LinearInterpolator );
333  else if(mode == INTERP_BSPLINE)
334  {
335  m_BsplineInterpolator->SetSplineOrder(3);
336  resampleImageFilter->SetInterpolator( m_BsplineInterpolator);
337  }
338  else
339  {
340  m_BsplineInterpolator->SetSplineOrder(5);
341  resampleImageFilter->SetInterpolator( m_BsplineInterpolator);
342  }
343  resampleImageFilter->SetTransform( affineTransform );
344  resampleImageFilter->SetDefaultPixelValue( 0 );
345 
346  // As Aladin transforms are in voxel space
347  OutputImageType::SpacingType dummySpacing;
348  dummySpacing[0] = dummySpacing[1] = dummySpacing[2] = 1.0;
349  reader->GetOutput()->SetSpacing(dummySpacing);
350  resampleImageFilter->SetOutputSpacing( dummySpacing );
351  resampleImageFilter->SetSize( outputSize );
352  OutputImageType::PointType dummyOrigin;
353  dummyOrigin[0] = dummyOrigin[1] = dummyOrigin[2] = 0.0;
354  resampleImageFilter->SetOutputOrigin( dummyOrigin );
355  resampleImageFilter->SetInput(reader->GetOutput());
356  resampleImageFilter->Update();
357 
358  OutputImageType::Pointer image = OutputImageType::New();
359  OutputImageType::IndexType imageStart;
360  imageStart[0] = 0;
361  imageStart[1] = 0;
362  imageStart[2] = 0;
363  OutputImageType::RegionType imageRegion;
364  imageRegion.SetSize(outputSize);
365  imageRegion.SetIndex(imageStart);
366  image->SetRegions(imageRegion);
367  image->Allocate();
368  //outputSpacing[0] = outputSpacing[0];
369  //outputSpacing[1] = outputSpacing[1];
370  //outputSpacing[2] = outputSpacing[2];
371  image->SetSpacing(outputSpacing);
372  image->SetOrigin(outputOrigin);
373 
374  typedef itk::ImageRegionIteratorWithIndex<OutputImageType> ImageRegionIteratorWithIndexType;
375  ImageRegionIteratorWithIndexType it( resampleImageFilter->GetOutput(), resampleImageFilter->GetOutput()->GetRequestedRegion() );
376  it.GoToBegin();
377 
378  OutputImageType::IndexType index;
379  while ( ! it.IsAtEnd() )
380  {
381  index = it.GetIndex();
382  image->SetPixel(index, it.Value());
383  ++it;
384  }
385  image->SetDirection(dir);
386 
387  // Save resampled image
388  itk::ImageFileWriter<OutputImageType>::Pointer writer;
389  writer = itk::ImageFileWriter<OutputImageType>::New();
390  writer->SetInput(image);
391  writer->SetFileName(outFile);
392  writer->Write();
393 
394  return true;
395 }
396 
397 // Simple function to convert a string into an array of char
398 // which can be passed as an input for the nifty-reg executables
399 // which have been converted in libraries but still take (int argc, char *argv[]) as input
400 unsigned int
401 Registration
402 ::StringToCharArray(std::string & cmdline, char ** argument )
403 {
404  unsigned int count=0;
405 
406  std::string word;
407 
408  // transform the string into a stream
409  std::stringstream stream(cmdline);
410 
411  // split the string
412  while( getline(stream, word, ' ') )
413  {
414  char *tmp_word;
415  // allocate a new char array
416  tmp_word = new char[word.length() + 1];
417  // copy the substring into the char array
418  std::strcpy(tmp_word,word.c_str());
419  // assign the pointer of the char array to the argument array
420  argument[count++] = tmp_word;
421  }
422  // return argument count
423  return count;
424 }
425 
426 bool
427 Registration
428 ::RegisterMilxNonRigid(std::string dataFile, std::string atlasFile,
429  std::string outputName, bool /*Invert*/)
430 {
431 
432  if (dataFile.length() == 0 || atlasFile.length() == 0) {
433  return false;
434  }
435 
436  /*
437  milx::Orientation::ValidCoordinateOrientationFlagsType inputFlag;
438  milx::Orientation::DirectionType inputDirection;
439  milx::Orientation::ValidCoordinateOrientationFlagsType atlasFlag;
440  milx::Orientation::DirectionType atlasDirection;
441  milx::Orientation *imageOrientation = new milx::Orientation();
442  bool result = imageOrientation->GetSpatialOrientation(dataFile.c_str(), inputFlag, inputDirection);
443  if (result == false) {
444  delete imageOrientation;
445  return false;
446  }
447  result = imageOrientation->GetSpatialOrientation(atlasFile.c_str(), atlasFlag, atlasDirection);
448  if (result == false) {
449  delete imageOrientation;
450  return false;
451  }
452  // Need to apply orientation to each output file.
453  delete imageOrientation;
454  */
455 
456  itk::ImageFileReader<InputImageType>::Pointer reader = itk::ImageFileReader<InputImageType>::New();
457  reader->SetFileName(dataFile);
458  try
459  {
460  reader->Update();
461  }
462  catch (itk::ExceptionObject & ex)
463  {
464  std::cerr << "Failed reading data file" << std::endl;
465  std::cerr << ex.GetDescription() << std::endl;
466  return false;
467  }
468 
469  itk::ImageFileReader<InputImageType>::Pointer atlasReader = itk::ImageFileReader<InputImageType>::New();
470  atlasReader->SetFileName(atlasFile);
471  try
472  {
473  atlasReader->Update();
474  }
475  catch (itk::ExceptionObject & ex)
476  {
477  std::cerr << "Failed reading atlas file" << std::endl;
478  std::cerr << ex.GetDescription() << std::endl;
479  return false;
480  }
481 
482  InputImageType::Pointer atlas = atlasReader->GetOutput();
483  InputImageType::Pointer mriData = reader->GetOutput();
484 
485  typedef itk::HistogramMatchingImageFilter <InputImageType, InputImageType> MatchingFilterType;
486  MatchingFilterType::Pointer matcher = MatchingFilterType::New();
487  matcher->SetInput(atlas);
488  matcher->SetReferenceImage(mriData);
489  matcher->SetNumberOfHistogramLevels(1024);
490  matcher->SetNumberOfMatchPoints(7);
491  matcher->ThresholdAtMeanIntensityOn();
492 
493  typedef itk::PDEDeformableRegistrationFilter < InputImageType, InputImageType, DemonsDeformationFieldType> BaseRegistrationFilterType;
494  BaseRegistrationFilterType::Pointer filter;
495 
496  // s <- s o exp(u) (Diffeomorphic demons)
497  typedef itk::DiffeomorphicDemonsRegistrationFilter < InputImageType, InputImageType, DemonsDeformationFieldType> ActualRegistrationFilterType;
498  typedef ActualRegistrationFilterType::GradientType GradientType;
499 
500  ActualRegistrationFilterType::Pointer actualfilter = ActualRegistrationFilterType::New();
501 
502  actualfilter->SetMaximumUpdateStepLength(2.0);
503  actualfilter->SetUseGradientType(static_cast<GradientType>(0));
504  filter = actualfilter;
505 #if ITK_VERSION_MAJOR < 4
506  filter->SmoothDeformationFieldOn();
507 #else
508  filter->SetSmoothDisplacementField(true);
509 #endif
510  filter->SetStandardDeviations(3.0);
511 
512 
513  typedef itk::MultiResolutionPDEDeformableRegistration< InputImageType, InputImageType, DemonsDeformationFieldType, float > MultiResRegistrationFilterType;
514  MultiResRegistrationFilterType::Pointer multires = MultiResRegistrationFilterType::New();
515 
516  int numLevels = 3;
517  std::vector<unsigned int> numIterations;
518  numIterations = std::vector<unsigned int>(numLevels, 10u);
519 
520  multires->SetRegistrationFilter(filter);
521  multires->SetNumberOfLevels(numLevels);
522  multires->SetNumberOfIterations(&numIterations[0]);
523 
524  multires->SetFixedImage(mriData);
525  multires->SetMovingImage(matcher->GetOutput());
526 
527  // Compute the deformation field
528  try
529  {
530  multires->UpdateLargestPossibleRegion();
531  }
532  catch (itk::ExceptionObject& err)
533  {
534  std::cout << "Unexpected error." << std::endl;
535  std::cout << err << std::endl;
536  return false;
537  }
538 
539  // The outputs
540  DemonsDeformationFieldType::Pointer defField = multires->GetOutput();
541 
542  // We want to save deformation field
543  // and propogated aal
544 
545  itk::ImageFileWriter<DemonsDeformationFieldType>::Pointer defWriter = itk::ImageFileWriter<DemonsDeformationFieldType>::New();
546  defWriter->SetInput(defField);
547  std::string filename1 = outputName;
548  defWriter->SetFileName(filename1);
549  try
550  {
551  defWriter->Write();
552  }
553  catch (itk::ExceptionObject & ex)
554  {
555  std::cerr << "Failed writing file" << std::endl;
556  std::cerr << ex.GetDescription() << std::endl;
557  return false;
558  }
559 
560  return true;
561 }
562 
563 void
564 Registration
565 ::LoadTRSF(std::string filename1, std::string filename2, double * array, bool invert)
566 {
567  std::cout << "Loading file with name " << filename1 << std::endl;
568  std::cout << "Loading file with name " << filename2 << std::endl;
569  char * buffer1 = new char[512];
570  char * buffer2 = new char[512];
571  gzFile fin1 = ::gzopen( filename1.c_str(), "rb" );
572  gzFile fin2 = ::gzopen( filename2.c_str(), "rb" );
573  if((fin1 == NULL) || (fin2 == NULL))
574  {
575  std::cerr << "Cannot read " << filename1 << std::endl;
576  delete [] buffer1;
577  delete [] buffer2;
578  }
579  buffer1 = ::gzgets (fin1, buffer1, 512);
580  buffer2 = ::gzgets (fin2, buffer2, 512);
581  if((buffer1[0] != '(') || (buffer2[0] != '('))
582  {
583  std::cerr << "File is not a transform file " << buffer1[0] << std::endl;
584  }
585  buffer1 = ::gzgets (fin1, buffer1, 512);
586  buffer2 = ::gzgets (fin2, buffer2, 512);
587  if(((buffer1[0] != 0) && (buffer1[1] != '8')) || (((buffer2[0] != 0) && (buffer2[1] != '8'))))
588  {
589  // Failed Magic number test ;)
590  std::cerr << buffer1 << std::endl;
591  std::cerr << "File is not a transform file" << buffer1[1] << std::endl;
592  }
593  char * str1 = new char [128];
594  char * str2 = new char [128];
595  char * str3 = new char [128];
596  char * str4 = new char [128];
597 
598  vnl_matrix<double> matrix1(4,4);
599  vnl_matrix<double> matrix2(4,4);
600  for (unsigned long i = 0; i < 4; i++)
601  {
602  buffer1 = ::gzgets (fin1, buffer1, 512);
603  sscanf(buffer1,"%s %s %s %s", str1, str2, str3, str4);
604  matrix1(i, 0) = atof(str1);
605  matrix1(i, 1) = atof(str2);
606  matrix1(i, 2) = atof(str3);
607  matrix1(i, 3) = atof(str4);
608 
609  buffer2 = ::gzgets (fin2, buffer2, 512);
610  sscanf(buffer2,"%s %s %s %s", str1, str2, str3, str4);
611  matrix2(i, 0) = atof(str1);
612  matrix2(i, 1) = atof(str2);
613  matrix2(i, 2) = atof(str3);
614  matrix2(i, 3) = atof(str4);
615  //std::cout << "(" << str1 << "," << str2 << "," << str3 << "," << str4 << ")" << std::endl;
616  }
617 
618  vnl_matrix<double> matrixComposite = matrix2*matrix1;
619  //std::cout << "Transform Matrix 1 is " << std::endl;
620  //std::cout << matrixComposite << std::endl;
621 
622  if(invert == true)
623  {
624  matrixComposite = vnl_matrix_inverse<double>(matrixComposite);
625  //std::cout << "Inverse Matrix is " << std::endl;
626  //std::cout << matrixComposite << std::endl;
627  }
628 
629  //matrix.set_identity();
630  for(int i = 0; i < 3; i++)
631  {
632  for(int j = 0; j < 3; j++)
633  array[3*i+j] = matrixComposite(i,j);
634  array[9+i] = matrixComposite(i, 3);
635  }
636 
637  // Get last line
638  buffer1 = ::gzgets (fin1, buffer1, 512);
639  if(buffer1[0] != ')')
640  {
641  std::cerr << buffer1 << std::endl;
642  std::cerr << "File is not a valid trsf transform file ?" << std::endl;
643  }
644  delete [] buffer1;
645  delete [] buffer2;
646  delete [] str1;
647  delete [] str2;
648  delete [] str3;
649  delete [] str4;
650  gzclose(fin1);
651  gzclose(fin2);
652 }
653 
654 void
655 Registration
656 ::LoadTRSF(std::string filename, double * array, bool invert)
657 {
658  std::cout << "Loading file with name " << filename << std::endl;
659  char * buffer = new char[512];
660  gzFile fin = ::gzopen( filename.c_str(), "rb" );
661  if(fin == NULL)
662  {
663  std::cerr << "Cannot read " << filename << std::endl;
664  delete [] buffer;
665  }
666  buffer = ::gzgets (fin, buffer, 512);
667  if(buffer[0] != '(')
668  {
669  std::cerr << "File is not a transform file " << buffer[0] << std::endl;
670  }
671  buffer = ::gzgets (fin, buffer, 512);
672  if((buffer[0] != 0) && (buffer[1] != '8'))
673  {
674  // Failed Magic number test ;)
675  std::cerr << buffer << std::endl;
676  std::cerr << "File is not a transform file" << buffer[1] << std::endl;
677  }
678  char * str1 = new char [128];
679  char * str2 = new char [128];
680  char * str3 = new char [128];
681  char * str4 = new char [128];
682 
683  vnl_matrix<double> matrix(4,4);
684  for (unsigned long i = 0; i < 4; i++)
685  {
686  buffer = ::gzgets (fin, buffer, 512);
687  sscanf(buffer,"%s %s %s %s", str1, str2, str3, str4);
688  matrix(i, 0) = atof(str1);
689  matrix(i, 1) = atof(str2);
690  matrix(i, 2) = atof(str3);
691  matrix(i, 3) = atof(str4);
692  //std::cout << "(" << str1 << "," << str2 << "," << str3 << "," << str4 << ")" << std::endl;
693  }
694  //std::cout << "Transform Matrix is " << std::endl;
695  //std::cout << matrix << std::endl;
696 
697  if(invert == true)
698  {
699  matrix = vnl_matrix_inverse<double>(matrix);
700  //std::cout << "Inverse Matrix is " << std::endl;
701  //std::cout << matrix << std::endl;
702  }
703 
704  //matrix.set_identity();
705  for(int i = 0; i < 3; i++)
706  {
707  for(int j = 0; j < 3; j++)
708  array[3*i+j] = matrix(i,j);
709  array[9+i] = matrix(i, 3);
710  }
711 
712  // Get last line
713  buffer = ::gzgets (fin, buffer, 512);
714  if(buffer[0] != ')')
715  {
716  std::cerr << buffer << std::endl;
717  std::cerr << "File is not a valid trsf transform file ?" << std::endl;
718  }
719  delete [] buffer;
720  delete [] str1;
721  delete [] str2;
722  delete [] str3;
723  delete [] str4;
724  gzclose(fin);
725 }
726 
727 bool
729 ::RegisterRigidITK(std::string dataFile, std::string atlasFile,
730  std::string outputName, bool /*Invert*/,
731  std::string dataMaskFile, std::string atlasMaskFile)
732 {
733  bool writeFiles = false;
734  char outputFileName[512];
735  typedef double CoordinateRepType;
736 
737  typedef itk::VersorRigid3DTransform< CoordinateRepType > RigidTransformType;
738  typedef itk::CenteredTransformInitializer< RigidTransformType, FixedImageType, MovingImageType > TransformInitializerType;
739  typedef itk::LinearInterpolateImageFunction< MovingImageType, double> InterpolatorType;
740  typedef itk::MultiResolutionImageRegistrationMethod< FixedImageType, MovingImageType > RegistrationType;
741  typedef itk::RegularStepGradientDescentOptimizer OptimizerType;
742  typedef itk::MattesMutualInformationImageToImageMetric< FixedImageType, MovingImageType > MetricType;
743  typedef itk::ResampleImageFilter< MovingImageType, FixedImageType > ResampleFilterType;
744  typedef itk::RecursiveMultiResolutionPyramidImageFilter< FixedImageType, FixedImageType > PyramidType;
745 
746  OptimizerType::Pointer optimizer = OptimizerType::New();
747  InterpolatorType::Pointer interpolator = InterpolatorType::New();
748  RegistrationType::Pointer registration = RegistrationType::New();
749  MetricType::Pointer metric = MetricType::New();
750  TransformInitializerType::Pointer initializer = TransformInitializerType::New();
751 
752  // Enable the use of Cubic spline interpolation in registration scheme
753 
754  registration->SetMetric( metric );
755  registration->SetOptimizer( optimizer );
756  registration->SetInterpolator( interpolator );
757 
758  RegistrationIterationUpdate::Pointer observer1 = RegistrationIterationUpdate::New();
759  registration->AddObserver( itk::IterationEvent(), observer1 );
760 
761  // Auxiliary identity transform.
762  typedef itk::IdentityTransform<double,SpaceDimension> IdentityTransformType;
763  IdentityTransformType::Pointer identityTransform = IdentityTransformType::New();
764 
765  // Read in the files and set them to the registration object
766  MovingImageType::Pointer movingImage = this->readFile3D( atlasFile );
767  FixedImageType::Pointer fixedImage = this->readFile3D( dataFile );
768 
769  // This is another copy of the moving image to be used for transforming (re-orientating) during optimisation
770  registration->SetFixedImage( fixedImage );
771  registration->SetMovingImage( movingImage );
772 
773  // Add a time and memory probes collector for profiling the computation time of every stage.
774  //itkProbesCreate();
775 
776  /*********************************************************************************
777  * *
778  * Perform Rigid Registration *
779  * *
780  *********************************************************************************/
781 
782  RigidTransformType::Pointer rigidTransform = RigidTransformType::New();
783  initializer->SetTransform( rigidTransform );
784  initializer->SetFixedImage( fixedImage );
785  initializer->SetMovingImage( movingImage );
786  //initializer->MomentsOn();
787  initializer->GeometryOn();
788  initializer->InitializeTransform();
789  // Display initial transform
790  std::cout << "Initial Rigid Parameters " << rigidTransform->GetParameters() << std::endl;
791 
792 
793  FixedImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion();
794  registration->SetFixedImageRegion( fixedRegion );
795  registration->SetInitialTransformParameters( rigidTransform->GetParameters() );
796  registration->SetTransform( rigidTransform );
797 
798  //itk::Array2D<unsigned int> schedule;
799  RegistrationType::ScheduleType fixedSchedule(3,3);
800  fixedSchedule[0][0] = 8;
801  fixedSchedule[0][1] = 8;
802  fixedSchedule[0][2] = 8;
803  fixedSchedule[1][0] = 4;
804  fixedSchedule[1][1] = 4;
805  fixedSchedule[1][2] = 4;
806  fixedSchedule[2][0] = 2;
807  fixedSchedule[2][1] = 2;
808  fixedSchedule[2][2] = 2;
809 
810  RegistrationType::ScheduleType movingSchedule(3,3);
811  movingSchedule[0][0] = 8;
812  movingSchedule[0][1] = 8;
813  movingSchedule[0][2] = 8;
814  movingSchedule[1][0] = 4;
815  movingSchedule[1][1] = 4;
816  movingSchedule[1][2] = 4;
817  movingSchedule[2][0] = 2;
818  movingSchedule[2][1] = 2;
819  movingSchedule[2][2] = 2;
820  registration->SetSchedules(fixedSchedule, movingSchedule);
821  //registration->SetNumberOfLevels(3);
822 
823  // Add mask
824  typedef itk::ImageMaskSpatialObject< SpaceDimension > MaskType;
825  typedef itk::Image< unsigned char, SpaceDimension > ImageMaskType;
826  typedef itk::ImageFileReader< ImageMaskType > MaskReaderType;
827 
828  typedef itk::LabelStatisticsImageFilter<FixedImageType, ImageMaskType> LabelStatisticsImageFilterType;
829  LabelStatisticsImageFilterType::Pointer labelStatisticsImageFilter = LabelStatisticsImageFilterType::New();
830 
831  int numberOfVoxelsInMask = 0;
832  bool useFixedMask = false;
833 
834  if ( dataMaskFile.length() != 0) {
835  useFixedMask = true;
836  }
837 
838 
839  MaskReaderType::Pointer fixedImageMaskReader = MaskReaderType::New();
840  MaskType::Pointer spatialObjectMask = MaskType::New();
841  if(useFixedMask)
842  {
843  std::cout << "RegisterRigidITK: Using Fixed mask " << dataMaskFile << std::endl;
844  fixedImageMaskReader->SetFileName( dataMaskFile );
845  try {
846  fixedImageMaskReader->Update();
847  } catch (itk::ExceptionObject & excp) {
848  std::cerr << excp << std::endl;
849  return EXIT_FAILURE;
850  }
851  typedef itk::BinaryThresholdImageFilter<ImageMaskType,ImageMaskType> BinaryThresholdImageFilterType;
852  BinaryThresholdImageFilterType::Pointer threshold = BinaryThresholdImageFilterType::New();
853  threshold->SetInput(fixedImageMaskReader->GetOutput());
854  threshold->SetLowerThreshold(1);
855  threshold->SetUpperThreshold(255);
856  threshold->SetOutsideValue(0);
857  threshold->SetInsideValue(255);
858  threshold->Update();
859 
860  spatialObjectMask->SetImage( threshold->GetOutput() );
861  useFixedMask = true;
862 
863  labelStatisticsImageFilter->SetInput(fixedImage);
864  labelStatisticsImageFilter->SetLabelInput(threshold->GetOutput());
865  labelStatisticsImageFilter->Update();
866  //for(int i = 50; i < 300; i++)
867  numberOfVoxelsInMask = labelStatisticsImageFilter->GetCount(255);
868  std::cout << "We have " << numberOfVoxelsInMask << " in fixed mask region" << std::endl;
869 
870  }
871  bool useMovingMask = false;
872  if ( atlasMaskFile.length() != 0)
873  useMovingMask = true;
874 
875  MaskReaderType::Pointer movingImageMaskReader = MaskReaderType::New();
876  MaskType::Pointer movingSpatialObjectMask = MaskType::New();
877  if(useMovingMask)
878  {
879  std::cout << "RegisterRigidITK: Using Moving mask: " << atlasMaskFile << std::endl;
880  movingImageMaskReader->SetFileName( atlasMaskFile );
881  try {
882  movingImageMaskReader->Update();
883  } catch (itk::ExceptionObject & excp) {
884  std::cerr << excp << std::endl;
885  return EXIT_FAILURE;
886  }
887  typedef itk::BinaryThresholdImageFilter<ImageMaskType,ImageMaskType> BinaryThresholdImageFilterType;
888  BinaryThresholdImageFilterType::Pointer threshold = BinaryThresholdImageFilterType::New();
889  threshold->SetInput(movingImageMaskReader->GetOutput());
890  threshold->SetLowerThreshold(1);
891  threshold->SetUpperThreshold(255);
892  threshold->SetOutsideValue(0);
893  threshold->SetInsideValue(255);
894  threshold->Update();
895 
896  movingSpatialObjectMask->SetImage( threshold->GetOutput() );
897  useMovingMask = true;
898 
899  labelStatisticsImageFilter->SetInput(movingImage);
900  labelStatisticsImageFilter->SetLabelInput(threshold->GetOutput());
901  labelStatisticsImageFilter->Update();
902  //for(int i = 50; i < 300; i++)
903  numberOfVoxelsInMask = labelStatisticsImageFilter->GetCount(255);
904  std::cout << "We have " << numberOfVoxelsInMask << " in moving mask region" << std::endl;
905  }
906 
907  const unsigned int numberOfPixels = fixedRegion.GetNumberOfPixels();
908  metric->SetNumberOfHistogramBins( 128 );
909  metric->SetUseExplicitPDFDerivatives( true );
910  metric->SetUseCachingOfBSplineWeights(false);
911  metric->ReinitializeSeed( 76926294 );
912 
913  // Define optimizer normalization to compensate for different dynamic range of rotations and translations
914  typedef OptimizerType::ScalesType OptimizerScalesType;
915  OptimizerScalesType optimizerScales( rigidTransform->GetNumberOfParameters() );
916  const double translationScale = 1.0 / 4000.0;
917  optimizerScales[0] = 1.0;
918  optimizerScales[1] = 1.0;
919  optimizerScales[2] = 1.0;
920  optimizerScales[3] = translationScale;
921  optimizerScales[4] = translationScale;
922  optimizerScales[5] = translationScale;
923  optimizer->SetScales( optimizerScales );
924 
925  optimizer->SetMaximumStepLength( RIGID_MAX_STEP );
926  optimizer->SetMinimumStepLength( RIGID_MIN_STEP );
927  optimizer->SetNumberOfIterations( RIGID_ITERATIONS );
928 
929  // Create the Command observer and register it with the optimizer.
930  CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();
931  optimizer->AddObserver( itk::IterationEvent(), observer );
932 
933  std::cout << "Number of Pixels " << numberOfPixels << std::endl;
934 
935  if(useFixedMask)
936  {
937  metric->SetFixedImageMask( spatialObjectMask );
938  if(numberOfVoxelsInMask > numberOfPixels/4.0)
939  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4*16)) );
940  else
941  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4)) );
942  }
943  else
944  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfPixels / (256)) );
945 
946  std::cout << "Initialize metric with " << metric->GetNumberOfSpatialSamples() << " samples " << std::endl;
947 
948  std::cout << "Starting Rigid Registration " << std::endl;
949 
950  try {
951  //itkProbesStart( "Rigid Registration" );
952 #if ITK_VERSION_MAJOR < 4
953  registration->StartRegistration();
954 #else
955  registration->Update();
956 #endif //itkProbesStop( "Rigid Registration" );
957  }
958  catch( itk::ExceptionObject & err ) {
959  std::cerr << "ExceptionObject caught !" << std::endl;
960  std::cerr << err << std::endl;
961  return EXIT_FAILURE;
962  }
963 
964  std::cout << "Rigid Registration completed" << std::endl;
965  std::cout << std::endl;
966 
967  rigidTransform->SetParameters( registration->GetLastTransformParameters() );
968 
969  /*********************************************************************************
970  * *
971  * Output the Rigid Parameters *
972  * *
973  *********************************************************************************/
974 
975  //sprintf(outputFileName,"%s%s", outputPrefix.c_str(),"rigid.txt");
976  sprintf(outputFileName, "%s%s", outputName.c_str(), "_rigidtransform.txt");
977 
978  itk::TransformFileWriter::Pointer transformWriter = itk::TransformFileWriter::New();
979  transformWriter->AddTransform(rigidTransform);
980  transformWriter->SetFileName(outputFileName);
981  try {
982  transformWriter->Update();
983  } catch (itk::ExceptionObject & excp) {
984  std::cerr << excp << std::endl;
985  return false;
986  }
987 
988  /*********************************************************************************
989  * *
990  * Output the Rigid Transformed Image *
991  * *
992  *********************************************************************************/
993 
994  if (writeFiles == true) {
995  //sprintf(outputFileName,"%s%s", outputPrefix.c_str(),"rigid_orig.nii.gz");
996  sprintf(outputFileName, "%s", outputName.c_str());
997  ResampleFilterType::Pointer resampleAffine = ResampleFilterType::New();
998  resampleAffine->SetTransform( rigidTransform );
999  resampleAffine->SetInput( movingImage );
1000  resampleAffine->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
1001  resampleAffine->SetOutputOrigin( fixedImage->GetOrigin() );
1002  resampleAffine->SetOutputSpacing( fixedImage->GetSpacing() );
1003  resampleAffine->SetOutputDirection( fixedImage->GetDirection() );
1004  resampleAffine->SetDefaultPixelValue(0.0);
1005  resampleAffine->Update();
1006 
1007  std::cout << std::endl << "Writing Rigid resampled moving image..." << std::flush;
1008  writeFile3D( resampleAffine->GetOutput() , outputFileName );
1009  std::cout << " Done!" << std::endl << std::endl;
1010  }
1011 
1012  return true;
1013 }
1014 
1015 
1016 bool
1017 Registration
1018 ::RegisterAffineITK(std::string dataFile, std::string atlasFile,
1019  std::string outputName, bool /*Invert*/, std::string dataMaskFile,
1020  std::string atlasMaskFile)
1021 {
1022  bool writeFiles = true;
1023  char outputFileName[512];
1024  typedef double CoordinateRepType;
1025 
1026  typedef itk::VersorRigid3DTransform< CoordinateRepType > RigidTransformType;
1027  typedef itk::AffineTransform< CoordinateRepType, SpaceDimension > AffineTransformType;
1028  //typedef itk::BSplineDeformableTransform< CoordinateRepType, SpaceDimension, SplineOrder > DeformableTransformType;
1029  typedef itk::CenteredTransformInitializer< RigidTransformType, FixedImageType, MovingImageType > TransformInitializerType;
1030  //typedef itk::CenteredVersorTransformInitializer< MovingImageType, MovingImageType > TransformInitializerType;
1031  typedef itk::LinearInterpolateImageFunction< MovingImageType, double> InterpolatorType;
1032  //typedef itk::ImageRegistrationMethod< FixedImageType, MovingImageType > ImageRegistrationType;
1033  typedef itk::MultiResolutionImageRegistrationMethod< FixedImageType, MovingImageType > RegistrationType;
1034  typedef itk::RegularStepGradientDescentOptimizer OptimizerType;
1035  //typedef itk::VersorRigid3DTransformOptimizer VersorOptimizerType;
1036  typedef itk::MattesMutualInformationImageToImageMetric< FixedImageType, MovingImageType > MetricType;
1037  typedef itk::ResampleImageFilter< MovingImageType, FixedImageType > ResampleFilterType;
1038  typedef itk::RecursiveMultiResolutionPyramidImageFilter< FixedImageType, FixedImageType > PyramidType;
1039 
1040  OptimizerType::Pointer optimizer = OptimizerType::New();
1041  //VersorOptimizerType::Pointer VersorOptimizer = VersorOptimizerType::New();
1042  InterpolatorType::Pointer interpolator = InterpolatorType::New();
1043  RegistrationType::Pointer registration = RegistrationType::New();
1044  MetricType::Pointer metric = MetricType::New();
1045  TransformInitializerType::Pointer initializer = TransformInitializerType::New();
1046 
1047  registration->SetMetric( metric );
1048  //registration->SetOptimizer( VersorOptimizer );
1049  registration->SetOptimizer( optimizer );
1050  registration->SetInterpolator( interpolator );
1051 
1052  RegistrationIterationUpdate::Pointer observer1 = RegistrationIterationUpdate::New();
1053  registration->AddObserver( itk::IterationEvent(), observer1 );
1054 
1055  // Auxiliary identity transform.
1056  //typedef itk::IdentityTransform<double,SpaceDimension> IdentityTransformType;
1057  //IdentityTransformType::Pointer identityTransform = IdentityTransformType::New();
1058 
1059  // Read in the files and set them to the registration object
1060  MovingImageType::Pointer movingImage = this->readFile3D( atlasFile );
1061  FixedImageType::Pointer fixedImage = this->readFile3D( dataFile );
1062 
1063  // This is another copy of the moving image to be used for transforming (re-orientating) during optimisation
1064  registration->SetFixedImage( fixedImage );
1065  registration->SetMovingImage( movingImage );
1066 
1067  FixedImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion();
1068  FixedImageType::SizeType fixedImageSize = fixedRegion.GetSize();
1069  FixedImageType::SpacingType fixedImageSpacing = fixedImage->GetSpacing();
1070  std::cout << "ImageSize: " << fixedImageSize[0] << ", " << fixedImageSize[1] << ", " << fixedImageSize[2] << std::endl;
1071  std::cout << "ImageSpacing: " << fixedImageSpacing[0] << ", " << fixedImageSpacing[1] << ", " << fixedImageSpacing[2] << std::endl;
1072  std::cout << "ImageOrigin: " << fixedImage->GetOrigin() << std::endl;
1073 
1074  // Add a time and memory probes collector for profiling the computation time of every stage.
1075  //itkProbesCreate();
1076 
1077  /*********************************************************************************
1078  * *
1079  * Perform Rigid Registration *
1080  * *
1081  *********************************************************************************/
1082 
1083  RigidTransformType::Pointer rigidTransform = RigidTransformType::New();
1084  initializer->SetTransform( rigidTransform );
1085  initializer->SetFixedImage( fixedImage );
1086  initializer->SetMovingImage( movingImage );
1087  //initializer->MomentsOn();
1088  initializer->GeometryOn();
1089  initializer->InitializeTransform();
1090 
1091  registration->SetFixedImageRegion( fixedRegion );
1092  registration->SetInitialTransformParameters( rigidTransform->GetParameters() );
1093  registration->SetTransform( rigidTransform );
1094 
1095  RegistrationType::ScheduleType fixedSchedule(3,3);
1096  fixedSchedule[0][0] = 8;
1097  fixedSchedule[0][1] = 8;
1098  fixedSchedule[0][2] = 8;
1099  fixedSchedule[1][0] = 4;
1100  fixedSchedule[1][1] = 4;
1101  fixedSchedule[1][2] = 4;
1102  fixedSchedule[2][0] = 2;
1103  fixedSchedule[2][1] = 2;
1104  fixedSchedule[2][2] = 2;
1105 
1106  RegistrationType::ScheduleType movingSchedule(3,3);
1107  movingSchedule[0][0] = 8;
1108  movingSchedule[0][1] = 8;
1109  movingSchedule[0][2] = 8;
1110  movingSchedule[1][0] = 4;
1111  movingSchedule[1][1] = 4;
1112  movingSchedule[1][2] = 4;
1113  movingSchedule[2][0] = 2;
1114  movingSchedule[2][1] = 2;
1115  movingSchedule[2][2] = 2;
1116  registration->SetSchedules(fixedSchedule, movingSchedule);
1117  //registration->SetNumberOfLevels(3);
1118 
1119  // Add mask
1120  typedef itk::ImageMaskSpatialObject< SpaceDimension > MaskType;
1121 #if ITK_VERSION_MAJOR < 4
1122  typedef itk::OrientedImage< unsigned char, SpaceDimension > ImageMaskType;
1123 #else
1124  typedef itk::Image< unsigned char, SpaceDimension > ImageMaskType;
1125 #endif
1126  typedef itk::ImageFileReader< FixedImageType > MaskReaderType;
1127 
1128  int numberOfVoxelsInMask = 0;
1129  bool useFixedMask = false;
1130 
1131  if ( dataMaskFile.length() != 0) {
1132  useFixedMask = true;
1133  }
1134 
1135  MaskReaderType::Pointer fixedImageMaskReader = MaskReaderType::New();
1136  MaskType::Pointer spatialObjectMask = MaskType::New();
1137 
1138  typedef itk::LabelStatisticsImageFilter<FixedImageType, ImageMaskType> LabelStatisticsImageFilterType;
1139  LabelStatisticsImageFilterType::Pointer labelStatisticsImageFilter = LabelStatisticsImageFilterType::New();
1140 
1141  if(useFixedMask)
1142  {
1143  std::cout << "RegisterAffineITK: Using Fixed mask " << dataMaskFile << std::endl;
1144  fixedImageMaskReader->SetFileName( dataMaskFile );
1145  try {
1146  fixedImageMaskReader->Update();
1147  } catch (itk::ExceptionObject & excp) {
1148  std::cerr << excp << std::endl;
1149  return false;
1150  }
1151  typedef itk::BinaryThresholdImageFilter<FixedImageType,ImageMaskType> BinaryThresholdImageFilterType;
1152  BinaryThresholdImageFilterType::Pointer threshold = BinaryThresholdImageFilterType::New();
1153  threshold->SetInput(fixedImageMaskReader->GetOutput());
1154  threshold->SetLowerThreshold(0.1);
1155  threshold->SetUpperThreshold(255);
1156  threshold->SetOutsideValue(0);
1157  threshold->SetInsideValue(255);
1158  threshold->Update();
1159 
1160  std::cout << "Direction " << threshold->GetOutput()->GetDirection() << std::endl;
1161  std::cout << "Origin " << threshold->GetOutput()->GetOrigin() << std::endl;
1162 
1163  spatialObjectMask->SetImage( threshold->GetOutput() );
1164  useFixedMask = true;
1165 
1166 
1167  labelStatisticsImageFilter->SetInput(fixedImage);
1168  labelStatisticsImageFilter->SetLabelInput(threshold->GetOutput());
1169  labelStatisticsImageFilter->Update();
1170  //for(int i = 50; i < 300; i++)
1171  numberOfVoxelsInMask = labelStatisticsImageFilter->GetCount(255);
1172  std::cout << "We have " << numberOfVoxelsInMask << " in fixed mask region" << std::endl;
1173  }
1174 
1175  bool useMovingMask = false;
1176  if ( atlasMaskFile.length() != 0) {
1177  useMovingMask = true;
1178  }
1179 
1180  MaskReaderType::Pointer movingImageMaskReader = MaskReaderType::New();
1181  MaskType::Pointer movingSpatialObjectMask = MaskType::New();
1182  if(useMovingMask)
1183  {
1184  std::cout << "RegisterAffineITK: Using Moving mask: " << atlasMaskFile << std::endl;
1185  movingImageMaskReader->SetFileName( atlasMaskFile );
1186  try {
1187  movingImageMaskReader->Update();
1188  } catch (itk::ExceptionObject & excp) {
1189  std::cerr << excp << std::endl;
1190  return EXIT_FAILURE;
1191  }
1192 
1193  FixedImageType::Pointer image = FixedImageType::New();
1194  FixedImageType::IndexType imageStart;
1195  imageStart[0] = 0;
1196  imageStart[1] = 0;
1197  imageStart[2] = 0;
1198  FixedImageType::RegionType imageRegion;
1199  imageRegion.SetSize(movingImageMaskReader->GetOutput()->GetLargestPossibleRegion().GetSize());
1200  imageRegion.SetIndex(imageStart);
1201  image->SetRegions(imageRegion);
1202  image->Allocate();
1203 
1204  image->SetSpacing(movingImageMaskReader->GetOutput()->GetSpacing());
1205  image->SetOrigin(movingImageMaskReader->GetOutput()->GetOrigin());
1206  //image->SetDirection(reader->GetOutput()->GetDirection());
1207 
1208  // Apply Direction Cosine to mask as ITK doesn't support this properly.
1209  // Need to apply Direction and resample
1210  //typedef itk::IdentityTransform< InputPixelType, 3 > IdentityTransformType;
1211  //IdentityTransformType::Pointer identityInterpolator = IdentityTransformType::New();
1212  typedef itk::ResampleImageFilter< FixedImageType, FixedImageType > ResampleFilterType2;
1213  ResampleFilterType2::Pointer resampleAffine = ResampleFilterType2::New();
1214  //resampleAffine->SetInterpolator( identityInterpolator );
1215  //resampleAffine->SetTransform( affineTransform );
1216  resampleAffine->SetInput( movingImageMaskReader->GetOutput() );
1217  resampleAffine->SetReferenceImage(image);
1218  resampleAffine->SetUseReferenceImage(true);
1219  // By default 1,1,1 ?
1220  //resampleAffine->SetOutputDirection( fixedImage->GetDirection() );
1221  resampleAffine->SetDefaultPixelValue(0.0);
1222  try {
1223  resampleAffine->Update();
1224  } catch (itk::ExceptionObject & err) {
1225  std::cerr << "ExceptionObject caught:" << std::endl;
1226  std::cerr << err << std::endl;
1227  exit(1);
1228  }
1229 
1230  typedef itk::BinaryThresholdImageFilter<FixedImageType,ImageMaskType> BinaryThresholdImageFilterType;
1231  BinaryThresholdImageFilterType::Pointer threshold = BinaryThresholdImageFilterType::New();
1232  threshold->SetInput(resampleAffine->GetOutput());
1233  threshold->SetLowerThreshold(0.1);
1234  threshold->SetUpperThreshold(255);
1235  threshold->SetOutsideValue(0);
1236  threshold->SetInsideValue(255);
1237  threshold->Update();
1238 
1239  std::cout << "Direction " << threshold->GetOutput()->GetDirection() << std::endl;
1240  std::cout << "Origin " << threshold->GetOutput()->GetOrigin() << std::endl;
1241 
1242  //movingSpatialObjectMask->DebugOn();
1243  movingSpatialObjectMask->SetImage( threshold->GetOutput() );
1244  std::cout << movingSpatialObjectMask->GetIndexToWorldTransform()->GetMatrix() << std::endl;
1245  std::cout << movingSpatialObjectMask->GetIndexToObjectTransform()->GetMatrix() << std::endl;
1246  useMovingMask = true;
1247 
1248  // Save Spatial Object
1249  typedef itk::SpatialObjectToImageFilter< MaskType, ImageMaskType > SpatialObjectToImageFilterType;
1250  SpatialObjectToImageFilterType::Pointer spat = SpatialObjectToImageFilterType::New();
1251  spat->SetInput(movingSpatialObjectMask);
1252  //spat->SetDirection(threshold->GetOutput()->GetDirection());
1253  spat->SetOrigin(threshold->GetOutput()->GetOrigin());
1254  spat->SetSpacing(threshold->GetOutput()->GetSpacing());
1255  spat->SetSize(threshold->GetOutput()->GetLargestPossibleRegion().GetSize());
1256 
1257  spat->Update();
1258 
1259  typedef itk::ImageFileWriter< ImageMaskType > WriterType;
1260  WriterType::Pointer writer = WriterType::New();
1261  writer->SetInput(spat->GetOutput());
1262  writer->SetFileName("testMask.nii.gz");
1263  try {
1264  writer->Update();
1265  } catch (itk::ExceptionObject & err) {
1266  std::cerr << "ExceptionObject caught:" << std::endl;
1267  std::cerr << err << std::endl;
1268  exit(1);
1269  }
1270 
1271  }
1272 
1273  const unsigned int numberOfPixels = fixedRegion.GetNumberOfPixels();
1274  metric->SetNumberOfHistogramBins( 128 );
1275  metric->SetUseExplicitPDFDerivatives( true );
1276  metric->SetUseCachingOfBSplineWeights(false);
1277  metric->ReinitializeSeed( 76926294 );
1278 
1279  // Define optimizer normalization to compensate for different dynamic range of rotations and translations
1280  typedef OptimizerType::ScalesType OptimizerScalesType;
1281  OptimizerScalesType optimizerScales( rigidTransform->GetNumberOfParameters() );
1282  const double translationScale = 1.0 / 4000.0;
1283  optimizerScales[0] = 1.0;
1284  optimizerScales[1] = 1.0;
1285  optimizerScales[2] = 1.0;
1286  optimizerScales[3] = translationScale;
1287  optimizerScales[4] = translationScale;
1288  optimizerScales[5] = translationScale;
1289  optimizer->SetScales( optimizerScales );
1290 
1291  optimizer->SetMaximumStepLength( RIGID_AFFINE_MAX_STEP );
1292  optimizer->SetMinimumStepLength( RIGID_AFFINE_MIN_STEP );
1293  optimizer->SetNumberOfIterations( RIGID_AFFINE_ITERATIONS );
1294 
1295  // Create the Command observer and register it with the optimizer.
1296  CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();
1297  optimizer->AddObserver( itk::IterationEvent(), observer );
1298 
1299  //CommandIterationUpdate::Pointer VersorObserver = CommandIterationUpdate::New();
1300  //VersorOptimizer->AddObserver( itk::IterationEvent(), VersorObserver );
1301 
1302  if(useFixedMask)
1303  {
1304  metric->SetFixedImageMask( spatialObjectMask );
1305  if(numberOfVoxelsInMask > numberOfPixels/4.0)
1306  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4*16)) );
1307  else
1308  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4)) );
1309  }
1310  else if(useMovingMask)
1311  {
1312  metric->DebugOn();
1313  metric->SetMovingImageMask( movingSpatialObjectMask );
1314  if(numberOfVoxelsInMask > numberOfPixels/4.0)
1315  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4*16)) );
1316  else
1317  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4)) );
1318  }
1319  else
1320  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfPixels / (256)) );
1321 
1322  std::cout << "Initialize metric with " << metric->GetNumberOfSpatialSamples() << std::endl;
1323 
1324  std::cout << "Starting Rigid Registration " << std::endl;
1325 
1326  try {
1327  //itkProbesStart( "Rigid Registration" );
1328 #if ITK_VERSION_MAJOR < 4
1329  registration->StartRegistration();
1330 #else
1331  registration->Update();
1332 #endif
1333  //itkProbesStop( "Rigid Registration" );
1334  }
1335  catch( itk::ExceptionObject & err ) {
1336  std::cerr << "ExceptionObject caught !" << std::endl;
1337  std::cerr << err << std::endl;
1338  return false;
1339  }
1340 
1341  std::cout << "Rigid Registration completed" << std::endl;
1342  std::cout << std::endl;
1343 
1344  rigidTransform->SetParameters( registration->GetLastTransformParameters() );
1345 
1346  /*********************************************************************************
1347  * *
1348  * Output the Rigid Parameters *
1349  * *
1350  *********************************************************************************/
1351 
1352  /*
1353  if (writeFiles == true) {
1354  //sprintf(outputFileName,"%s%s", outputPrefix.c_str(),"_rigid.txt");
1355  sprintf(outputFileName, "%s%s", outputName.c_str(), "_rigidtransform.txt");
1356 
1357  itk::TransformFileWriter::Pointer transformWriter = itk::TransformFileWriter::New();
1358  transformWriter->AddTransform(rigidTransform);
1359  transformWriter->SetFileName(outputFileName);
1360  try {
1361  transformWriter->Update();
1362  } catch (itk::ExceptionObject & excp) {
1363  std::cerr << excp << std::endl;
1364  return false;
1365  }
1366  }
1367  */
1368  /*********************************************************************************
1369  * *
1370  * Output the Rigid Transformed Image *
1371  * *
1372  *********************************************************************************/
1373 
1374  writeFiles = false;
1375  if (writeFiles == true) {
1376  //sprintf(outputFileName,"%s%s", outputPrefix.c_str(),"rigid.nii.gz");
1377  sprintf(outputFileName, "%s", outputName.c_str());
1378  ResampleFilterType::Pointer resampleAffine = ResampleFilterType::New();
1379  resampleAffine->SetTransform( rigidTransform );
1380  resampleAffine->SetInput( movingImage );
1381  resampleAffine->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
1382  resampleAffine->SetOutputOrigin( fixedImage->GetOrigin() );
1383  resampleAffine->SetOutputSpacing( fixedImage->GetSpacing() );
1384  resampleAffine->SetOutputDirection( fixedImage->GetDirection() );
1385  resampleAffine->SetDefaultPixelValue(0.0);
1386  resampleAffine->Update();
1387 
1388  std::cout << std::endl << "Writing Rigid resampled moving image..." << std::flush;
1389  writeFile3D( resampleAffine->GetOutput() , outputFileName );
1390  std::cout << " Done!" << std::endl << std::endl;
1391  }
1392  writeFiles = true;
1393 
1394 
1395  /*********************************************************************************
1396  * *
1397  * Perform Affine Registration *
1398  * *
1399  *********************************************************************************/
1400 
1401  registration->SetOptimizer( optimizer );
1402 
1403  // Setup the affine transform based on the result of the rigid
1404  AffineTransformType::Pointer affineTransform = AffineTransformType::New();
1405  affineTransform->SetCenter( rigidTransform->GetCenter() );
1406  affineTransform->SetTranslation( rigidTransform->GetTranslation() );
1407  affineTransform->SetMatrix( rigidTransform->GetMatrix() );
1408  registration->SetTransform( affineTransform );
1409  registration->SetInitialTransformParameters( affineTransform->GetParameters() );
1410 
1411  RegistrationType::ScheduleType fixedScheduleAffine(2,3);
1412  fixedScheduleAffine[0][0] = 4;
1413  fixedScheduleAffine[0][1] = 4;
1414  fixedScheduleAffine[0][2] = 4;
1415  fixedScheduleAffine[1][0] = 2;
1416  fixedScheduleAffine[1][1] = 2;
1417  fixedScheduleAffine[1][2] = 2;
1418  RegistrationType::ScheduleType movingScheduleAffine(2,3);
1419  movingScheduleAffine[0][0] = 4;
1420  movingScheduleAffine[0][1] = 4;
1421  movingScheduleAffine[0][2] = 4;
1422  movingScheduleAffine[1][0] = 2;
1423  movingScheduleAffine[1][1] = 2;
1424  movingScheduleAffine[1][2] = 2;
1425 
1426  registration->SetSchedules(fixedScheduleAffine, movingScheduleAffine);
1427  //registration->SetNumberOfLevels(2);
1428 
1429  // Define optimizer normaliztion to compensate for different dynamic range of rotations and translations.
1430  optimizerScales = OptimizerScalesType( affineTransform->GetNumberOfParameters() );
1431  optimizerScales[0] = 1.0;
1432  optimizerScales[1] = 1.0;
1433  optimizerScales[2] = 1.0;
1434  optimizerScales[3] = 1.0;
1435  optimizerScales[4] = 1.0;
1436  optimizerScales[5] = 1.0;
1437  optimizerScales[6] = 1.0;
1438  optimizerScales[7] = 1.0;
1439  optimizerScales[8] = 1.0;
1440  optimizerScales[9] = translationScale;
1441  optimizerScales[10] = translationScale;
1442  optimizerScales[11] = translationScale;
1443  optimizer->SetScales( optimizerScales );
1444 
1445  optimizer->SetMaximumStepLength( AFFINE_MAX_STEP );
1446  optimizer->SetMinimumStepLength( AFFINE_MIN_STEP );
1447  //optimizer->SetMaximumStepLength( optimizer->GetCurrentStepLength() );
1448  //optimizer->SetMinimumStepLength( 10*optimizer->GetMinimumStepLength() );
1449  optimizer->SetNumberOfIterations( 2*AFFINE_ITERATIONS );
1450 
1451  //#ifdef MATTES
1452  // Start with N/(2*64) then inc by 8 (3 level pyramid
1453  //metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfPixels / 16) );
1454  // Hack as bug makes it run obs 1st it
1455 
1456  // Use mask region on Fixed Image
1457  if(useFixedMask)
1458  {
1459  metric->SetFixedImageMask( spatialObjectMask );
1460  if(numberOfVoxelsInMask > numberOfPixels/4.0)
1461  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4*16)) );
1462  else
1463  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4)) );
1464  }
1465  else if(useMovingMask)
1466  {
1467  metric->SetMovingImageMask( spatialObjectMask );
1468  if(numberOfVoxelsInMask > numberOfPixels/4.0)
1469  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4*16)) );
1470  else
1471  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4)) );
1472  }
1473  else
1474  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfPixels / (256)) );
1475 
1476  //#endif
1477  // metric->UseAllPixelsOn();
1478  // metric->SetUseAllPixels(true);
1479 
1480  std::cout << "Starting Affine Registration " << std::endl;
1481 
1482  try {
1483  //itkProbesStart( "Affine Registration" );
1484 #if ITK_VERSION_MAJOR < 4
1485  registration->StartRegistration();
1486 #else
1487  registration->Update();
1488 #endif
1489  //itkProbesStop( "Affine Registration" );
1490  }
1491  catch( itk::ExceptionObject & err ) {
1492  std::cerr << "ExceptionObject caught !" << std::endl;
1493  std::cerr << err << std::endl;
1494  return false;
1495  }
1496 
1497  std::cout << "Affine Registration completed" << std::endl;
1498  std::cout << std::endl;
1499 
1500  affineTransform->SetParameters( registration->GetLastTransformParameters() );
1501 
1502  /*********************************************************************************
1503  * *
1504  * Output the Affine Parameters *
1505  * *
1506  *********************************************************************************/
1507 
1508  /*
1509  if (writeFiles == true) {
1510  //sprintf(outputFileName,"%s%s", outputPrefix.c_str(),"_affine.txt");
1511  sprintf(outputFileName, "%s%s", outputName.c_str(), "_affinetransform.txt");
1512 
1513  itk::TransformFileWriter::Pointer transformWriter = itk::TransformFileWriter::New();
1514  transformWriter->AddTransform(affineTransform);
1515  transformWriter->SetFileName(outputFileName);
1516  try {
1517  transformWriter->Update();
1518  } catch (itk::ExceptionObject & excp) {
1519  std::cerr << excp << std::endl;
1520  return false;
1521  }
1522  }*/
1523 
1524  /*********************************************************************************
1525  * *
1526  * Output the Affine Transformed Image *
1527  * *
1528  *********************************************************************************/
1529 
1530  if (writeFiles == true) {
1531  sprintf(outputFileName,"%s", outputName.c_str());
1532  ResampleFilterType::Pointer resampleAffine = ResampleFilterType::New();
1533  resampleAffine->SetTransform( affineTransform );
1534  resampleAffine->SetInput( movingImage );
1535  resampleAffine->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
1536  resampleAffine->SetOutputOrigin( fixedImage->GetOrigin() );
1537  resampleAffine->SetOutputSpacing( fixedImage->GetSpacing() );
1538  resampleAffine->SetOutputDirection( fixedImage->GetDirection() );
1539  resampleAffine->SetDefaultPixelValue(0.0);
1540  resampleAffine->Update();
1541 
1542  std::cout << std::endl << "Writing Affine resampled moving image..." << std::flush;
1543  writeFile3D( resampleAffine->GetOutput() , outputFileName );
1544  std::cout << " Done!" << std::endl << std::endl;
1545  }
1546  return true;
1547 }
1548 
1549 bool
1550 Registration
1551 ::RegisterNonRigidBsplineITK(std::string dataFile, std::string atlasFile,
1552  std::string outputName, bool /*Invert*/, std::string dataMaskFile,
1553  std::string atlasMaskFile)
1554 {
1555  bool writeFiles = false;
1556  char outputFileName[512];
1557  typedef double CoordinateRepType;
1558 
1559  typedef itk::AffineTransform< CoordinateRepType, SpaceDimension > AffineTransformType;
1560 #if ITK_VERSION_MAJOR < 4
1561  typedef itk::BSplineDeformableTransform< CoordinateRepType, SpaceDimension, SplineOrder > DeformableTransformType;
1562 #else
1563  typedef itk::BSplineTransform< CoordinateRepType, SpaceDimension, SplineOrder > DeformableTransformType;
1564 #endif
1565 
1566  typedef itk::LinearInterpolateImageFunction< MovingImageType, double> InterpolatorType;
1567  typedef itk::ImageRegistrationMethod< FixedImageType, MovingImageType > RegistrationType;
1568  typedef itk::RegularStepGradientDescentOptimizer OptimizerType;
1569  typedef itk::MattesMutualInformationImageToImageMetric< FixedImageType, MovingImageType > MetricType;
1570  typedef itk::ResampleImageFilter< MovingImageType, FixedImageType > ResampleFilterType;
1571  typedef itk::RecursiveMultiResolutionPyramidImageFilter< FixedImageType, FixedImageType > PyramidType;
1572 
1573  OptimizerType::Pointer optimizer = OptimizerType::New();
1574  InterpolatorType::Pointer interpolator = InterpolatorType::New();
1575  RegistrationType::Pointer image_registration = RegistrationType::New();
1576  MetricType::Pointer metric = MetricType::New();
1577 
1578  image_registration->SetMetric( metric );
1579  image_registration->SetOptimizer( optimizer );
1580  image_registration->SetInterpolator( interpolator );
1581 
1582  CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();
1583  optimizer->AddObserver( itk::IterationEvent(), observer );
1584 
1585  RegistrationIterationUpdate::Pointer observer1 = RegistrationIterationUpdate::New();
1586  image_registration->AddObserver( itk::IterationEvent(), observer1 );
1587 
1588  // Auxiliary identity transform.
1589  typedef itk::IdentityTransform<double,SpaceDimension> IdentityTransformType;
1590  IdentityTransformType::Pointer identityTransform = IdentityTransformType::New();
1591 
1592  // Read in the files and set them to the registration object
1593  std::cout << "Moving image " << atlasFile << std::endl;
1594  MovingImageType::Pointer movingImage = this->readFile3D( atlasFile );
1595  FixedImageType::Pointer fixedImage = this->readFile3D( dataFile );
1596 
1597  // Read in ITK transform
1598  //sprintf(outputFileName,"%s%s", outputPrefix.c_str(),"affine.txt");
1599  sprintf(outputFileName, "%s%s", outputName.c_str(), "_affinetransform.txt");
1600 
1601  itk::TransformFileReader::Pointer affineReader = itk::TransformFileReader::New();
1602  affineReader->SetFileName(outputFileName);
1603  try {
1604  affineReader->Update();
1605  } catch(itk::ExceptionObject &ex)
1606  {
1607  std::cerr << "Failed reading Transform" << std::endl;
1608  // Output the error to the terminal
1609  std::cout << "Failed reading Transform... " << ex.GetDescription() << std::endl;
1610  return false;
1611  }
1612 
1613  typedef itk::AffineTransform< double, ImageDimension > AffineTransformType;
1614  AffineTransformType::Pointer affineTransform;
1615 
1616  /* copy the transform into a new AffineTransform object */
1617  if(!strcmp(affineReader->GetTransformList()->front()->GetNameOfClass(), "AffineTransform"))
1618  {
1619  affineTransform = static_cast<AffineTransformType*>(affineReader->GetTransformList()->front().GetPointer());
1620  }
1621  else
1622  {
1623  std::cerr << "Affine Transform Input is not of AffineTransformType" << std::endl;
1624  return false;
1625  }
1626 
1627  // Add mask
1628  typedef itk::ImageMaskSpatialObject< SpaceDimension > MaskType;
1629  typedef itk::Image< unsigned char, SpaceDimension > ImageMaskType;
1630  typedef itk::ImageFileReader< ImageMaskType > MaskReaderType;
1631 
1632  int numberOfVoxelsInMask = 0;
1633  bool useFixedMask = false;
1634  if ( dataMaskFile.length() != 0)
1635  useFixedMask = true;
1636 
1637 
1638  MaskReaderType::Pointer fixedImageMaskReader = MaskReaderType::New();
1639  MaskType::Pointer spatialObjectMask = MaskType::New();
1640  if(useFixedMask)
1641  {
1642  std::cout << "Using Fixed mask " << dataMaskFile << std::endl;
1643  fixedImageMaskReader->SetFileName( dataMaskFile );
1644 
1645  try {
1646  fixedImageMaskReader->Update();
1647  } catch (itk::ExceptionObject & excp) {
1648  std::cerr << excp << std::endl;
1649  return EXIT_FAILURE;
1650  }
1651  typedef itk::BinaryThresholdImageFilter<ImageMaskType,ImageMaskType> BinaryThresholdImageFilterType;
1652  BinaryThresholdImageFilterType::Pointer threshold = BinaryThresholdImageFilterType::New();
1653  threshold->SetInput(fixedImageMaskReader->GetOutput());
1654  threshold->SetLowerThreshold(1);
1655  threshold->SetUpperThreshold(255);
1656  threshold->SetOutsideValue(0);
1657  threshold->SetInsideValue(255);
1658  threshold->Update();
1659 
1660  spatialObjectMask->SetImage( threshold->GetOutput() );
1661  useFixedMask = true;
1662 
1663  typedef itk::LabelStatisticsImageFilter<FixedImageType, ImageMaskType> LabelStatisticsImageFilterType;
1664  LabelStatisticsImageFilterType::Pointer labelStatisticsImageFilter = LabelStatisticsImageFilterType::New();
1665  labelStatisticsImageFilter->SetInput(fixedImage);
1666  labelStatisticsImageFilter->SetLabelInput(threshold->GetOutput());
1667  labelStatisticsImageFilter->Update();
1668  //for(int i = 50; i < 300; i++)
1669  numberOfVoxelsInMask = labelStatisticsImageFilter->GetCount(255);
1670  std::cout << "We have " << numberOfVoxelsInMask << " in fixed mask region" << std::endl;
1671 
1672  }
1673  bool useMovingMask = false;
1674  if ( atlasMaskFile.length() != 0)
1675  useMovingMask = true;
1676  MaskReaderType::Pointer movingImageMaskReader = MaskReaderType::New();
1677  MaskType::Pointer movingSpatialObjectMask = MaskType::New();
1678  if(useMovingMask)
1679  {
1680  std::cout << "Using Moving mask: " << atlasMaskFile << std::endl;
1681  movingImageMaskReader->SetFileName( atlasMaskFile );
1682  try {
1683  movingImageMaskReader->Update();
1684  } catch (itk::ExceptionObject & excp) {
1685  std::cerr << excp << std::endl;
1686  return EXIT_FAILURE;
1687  }
1688  typedef itk::BinaryThresholdImageFilter<ImageMaskType,ImageMaskType> BinaryThresholdImageFilterType;
1689  BinaryThresholdImageFilterType::Pointer threshold = BinaryThresholdImageFilterType::New();
1690  threshold->SetInput(movingImageMaskReader->GetOutput());
1691  threshold->SetLowerThreshold(1);
1692  threshold->SetUpperThreshold(255);
1693  threshold->SetOutsideValue(0);
1694  threshold->SetInsideValue(255);
1695  threshold->Update();
1696 
1697  movingSpatialObjectMask->SetImage( threshold->GetOutput() );
1698  useMovingMask = true;
1699  }
1700 
1701  /*********************************************************************************
1702  * *
1703  * Perform Coarse Deformable Registration *
1704  * *
1705  *********************************************************************************/
1706 
1707  DeformableTransformType::Pointer bsplineTransformCoarse = DeformableTransformType::New();
1708 
1709  // Setup the resample pyramid schedule
1710  PyramidType::Pointer movingPyramid = PyramidType::New();
1711  PyramidType::Pointer fixedPyramid = PyramidType::New();
1712  int levels = 3;
1713  fixedPyramid->SetNumberOfLevels( levels );
1714  movingPyramid->SetNumberOfLevels( levels );
1715  fixedPyramid->SetInput( readFile3D( dataFile ) );
1716  movingPyramid->SetInput( readFile3D( atlasFile ) );
1717  itk::Array2D<unsigned int> schedule = fixedPyramid->GetSchedule();
1718  //for (int levelCounter = 0; levelCounter < levels; levelCounter++) schedule[levelCounter][3] = 0; // ensure that the 4th dimension is not rescaled
1719  //fixedPyramid->SetSchedule( schedule );
1720  //movingPyramid->SetSchedule( schedule );
1721  fixedPyramid->Update();
1722  movingPyramid->Update();
1723 
1724  fixedImage = fixedPyramid->GetOutput( PYRAMID_RESOLUTION_ONE );
1725  movingImage = movingPyramid->GetOutput( PYRAMID_RESOLUTION_ONE );
1726  FixedImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion();
1727  image_registration->SetFixedImage( fixedImage );
1728  image_registration->SetMovingImage( movingImage );
1729  //image_registration->SetNumberOfLevels(1);
1730 
1731  std::cout << "------ Multi level resolution one ------" << std::endl;
1732  FixedImageType::SizeType fixedImageSize = fixedRegion.GetSize();
1733  FixedImageType::SpacingType fixedImageSpacing = fixedImage->GetSpacing();
1734  std::cout << "ImageSize: " << fixedImageSize[0] << ", " << fixedImageSize[1] << ", " << fixedImageSize[2] << std::endl;
1735  std::cout << "ImageSpacing: " << fixedImageSpacing[0] << ", " << fixedImageSpacing[1] << ", " << fixedImageSpacing[2] << std::endl;
1736  std::cout << "ImageOrigin: " << fixedImage->GetOrigin() << std::endl;
1737 
1738  unsigned int coarseSpacing = GRID_POINT_SPACING_ONE; // Set the initial gridpoint spacing to 10mm
1739  std::cout << "Coarse Grid Point Spacing (mm): " << coarseSpacing << std::endl;
1740 
1741 #if ITK_VERSION_MAJOR < 4
1742  typedef DeformableTransformType::RegionType RegionType;
1743  RegionType bsplineRegion;
1744  RegionType::SizeType gridSizeOnImage;
1745  RegionType::SizeType gridBorderSize;
1746  RegionType::SizeType totalGridSize;
1747 
1748  gridSizeOnImage[0] = (int)floor( fixedImageSize[0] * fixedImageSpacing[0] / coarseSpacing );
1749  gridSizeOnImage[1] = (int)floor( fixedImageSize[1] * fixedImageSpacing[1] / coarseSpacing );
1750  gridSizeOnImage[2] = (int)floor( fixedImageSize[2] * fixedImageSpacing[2] / coarseSpacing );
1751  std::cout << "Number of grid points: " << gridSizeOnImage[0] << ", " << gridSizeOnImage[1] << ", " << gridSizeOnImage[2] << ", " << std::endl;
1752  gridBorderSize.Fill( SplineOrder ); // Border for spline order = 3 ( 1 lower, 2 upper )
1753  totalGridSize = gridSizeOnImage + gridBorderSize;
1754 
1755  bsplineRegion.SetSize( totalGridSize );
1756 
1757  typedef DeformableTransformType::SpacingType SpacingType;
1758  SpacingType spacing = fixedImage->GetSpacing();
1759 
1760  typedef DeformableTransformType::OriginType OriginType;
1761  OriginType origin = fixedImage->GetOrigin();
1762 
1763  for(unsigned int r=0; r<ImageDimension; r++) {
1764  spacing[r] *= static_cast<double>( fixedImageSize[r] - 1) / static_cast<double>(gridSizeOnImage[r] - 1 );
1765  }
1766 
1767  FixedImageType::DirectionType gridDirection = fixedImage->GetDirection();
1768  SpacingType gridOriginOffset = gridDirection * spacing;
1769  OriginType gridOrigin = origin - gridOriginOffset;
1770 
1771  std::cout << "Direction " << gridDirection << std::endl;
1772  std::cout << "Spacing " << spacing << std::endl;
1773  std::cout << "GridOrigin " << gridOrigin << std::endl;
1774 
1775  bsplineTransformCoarse->SetGridSpacing( spacing );
1776  bsplineTransformCoarse->SetGridOrigin( gridOrigin );
1777  bsplineTransformCoarse->SetGridRegion( bsplineRegion );
1778  bsplineTransformCoarse->SetGridDirection( gridDirection );
1779 
1780  bsplineTransformCoarse->SetBulkTransform( affineTransform );
1781 
1782 #else
1783 
1784  DeformableTransformType::PhysicalDimensionsType fixedPhysicalDimensions;
1785  DeformableTransformType::MeshSizeType meshSize;
1786  for( unsigned int i=0; i < ImageDimension; i++ )
1787  {
1788  fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] *
1789  static_cast<double>(
1790  fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 );
1791  }
1792 // unsigned int numberOfGridNodesInOneDimension = (int)floor( fixedImageSize[0] * fixedImageSpacing[0] / coarseSpacing );
1793 
1794  for( unsigned int i=0; i < ImageDimension; i++ )
1795  {
1796  meshSize[i] = (int)floor( fixedImageSize[i] * fixedImageSpacing[i] / coarseSpacing ) - SplineOrder;
1797  }
1798 // meshSize.Fill( numberOfGridNodesInOneDimension - SplineOrder );
1799  bsplineTransformCoarse->SetTransformDomainOrigin( fixedImage->GetOrigin() );
1800  bsplineTransformCoarse->SetTransformDomainPhysicalDimensions( fixedPhysicalDimensions );
1801  bsplineTransformCoarse->SetTransformDomainMeshSize( meshSize );
1802  bsplineTransformCoarse->SetTransformDomainDirection( fixedImage->GetDirection() );
1803  //TODO Set Affine transform to initialise NR registration
1804 
1805 #endif
1806 
1807 
1808  typedef DeformableTransformType::ParametersType ParametersType;
1809 
1810  unsigned int numberOfBSplineParameters = bsplineTransformCoarse->GetNumberOfParameters();
1811 
1812  typedef OptimizerType::ScalesType OptimizerScalesType;
1813  OptimizerScalesType optimizerScales = OptimizerScalesType( numberOfBSplineParameters );
1814  optimizerScales.Fill( 1.0 );
1815  optimizer->SetScales( optimizerScales );
1816 
1817  ParametersType initialDeformableTransformParameters( numberOfBSplineParameters );
1818  initialDeformableTransformParameters.Fill( 0.0 );
1819  bsplineTransformCoarse->SetParameters( initialDeformableTransformParameters );
1820 
1821  image_registration->SetInitialTransformParameters( bsplineTransformCoarse->GetParameters() );
1822  image_registration->SetTransform( bsplineTransformCoarse );
1823 
1824  // Next we set the parameters of the RegularStepGradientDescentOptimizer object.
1825  optimizer->SetMaximumStepLength( NRR_MAX_STEP_ONE );
1826  optimizer->SetMinimumStepLength( NRR_MIN_STEP );
1827  optimizer->SetRelaxationFactor( NRR_RELAXATION_FACTOR);
1828  optimizer->SetNumberOfIterations( NRR_ITERATIONS_ONE );
1829  optimizer->SetGradientMagnitudeTolerance( NRR_GRADIENT_MAGNITUDE_TOLERANCE);
1830 
1831  //#ifdef MATTES
1832  const unsigned int numberOfPixels = fixedRegion.GetNumberOfPixels();
1833  if(useFixedMask)
1834  {
1835  metric->SetFixedImageMask( spatialObjectMask );
1836  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (2*16)) );
1837  }
1838  else
1839  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfPixels / (2*32)) );
1840 
1841  //#endif
1842  //metric->UseAllPixelsOn();
1843  std::cout << std::endl << "Starting Deformable Registration Coarse Grid" << std::endl;
1844  try {
1845  //itkProbesStart( "Deformable Registration Coarse" );
1846 #if ITK_VERSION_MAJOR < 4
1847  image_registration->StartRegistration();
1848 #else
1849  image_registration->Update();
1850 #endif
1851  //itkProbesStop( "Deformable Registration Coarse" );
1852  }
1853  catch( itk::ExceptionObject & err ) {
1854  std::cerr << "ExceptionObject caught !" << std::endl;
1855  std::cerr << err << std::endl;
1856  return false;
1857  }
1858  std::cout << "Deformable Registration Coarse Grid completed" << std::endl << std::endl;
1859 
1860  OptimizerType::ParametersType finalParameters = image_registration->GetLastTransformParameters();
1861  bsplineTransformCoarse->SetParameters( finalParameters );
1862 
1863  if (writeFiles == true) {
1864  //sprintf(outputFileName,"%s%s", outputPrefix.c_str(),"coarse_nrr.nii.gz");
1865  sprintf(outputFileName, "%s", outputName.c_str());
1866 
1867  ResampleFilterType::Pointer resampleNRR = ResampleFilterType::New();
1868  resampleNRR->SetTransform(bsplineTransformCoarse );
1869  resampleNRR->SetInput( movingImage );
1870  resampleNRR->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
1871  resampleNRR->SetOutputOrigin( fixedImage->GetOrigin() );
1872  resampleNRR->SetOutputSpacing( fixedImage->GetSpacing() );
1873  resampleNRR->SetOutputDirection( fixedImage->GetDirection() );
1874  resampleNRR->SetDefaultPixelValue(0.0);
1875  std::cout << "Computing NRR output" << std::endl;
1876  resampleNRR->Update();
1877 
1878  std::cout << "Writing coarse NRR resampled moving image..." << std::flush;
1879  writeFile3D( resampleNRR->GetOutput() , outputFileName );
1880  std::cout << " Done!" << std::endl;
1881 
1882  //sprintf(outputFileName,"%s%s", outputPrefix.c_str(),"coarse_Bsplines.txt");
1883  sprintf(outputFileName, "%s%s", outputName.c_str(), "_coarse_Bsplines_transform.txt");
1884  itk::TransformFileWriter::Pointer transformWriter = itk::TransformFileWriter::New();
1885  transformWriter->AddTransform(bsplineTransformCoarse);
1886  transformWriter->SetFileName(outputFileName);
1887  try {
1888  transformWriter->Update();
1889  } catch (itk::ExceptionObject & excp) {
1890  std::cerr << excp << std::endl;
1891  return false;
1892  }
1893 
1894  //sprintf(outputFileName,"%s%s", outputPrefix.c_str(),"coarse_Bsplines.nii.gz");
1895  sprintf(outputFileName,"%s", outputName.c_str());
1896 #if ITK_VERSION_MAJOR < 4
1897  typedef itk::Compose3DVectorImageFilter<DeformableTransformType::ImageType, FieldType> VectorComposerType;
1898  VectorComposerType::Pointer composer = VectorComposerType::New();
1899  composer->SetInput1(bsplineTransformCoarse->GetCoefficientImage()[0]);
1900  composer->SetInput2(bsplineTransformCoarse->GetCoefficientImage()[1]);
1901  composer->SetInput3(bsplineTransformCoarse->GetCoefficientImage()[2]);
1902  composer->Update();
1903  typedef itk::ImageFileWriter<VectorComposerType::OutputImageType> CoeffWriterType;
1904  CoeffWriterType::Pointer coeffWriter = CoeffWriterType::New();
1905  coeffWriter->SetInput(composer->GetOutput());
1906  coeffWriter->SetFileName( outputFileName );
1907  coeffWriter->Update();
1908 #else
1909  typedef itk::TransformFileWriter TransformWriterType;
1910  TransformWriterType::Pointer coeffWriter = TransformWriterType::New();
1911  coeffWriter->SetInput(bsplineTransformCoarse);
1912  coeffWriter->SetFileName( outputFileName );
1913  coeffWriter->Update();
1914 #endif
1915 
1916  sprintf(outputFileName,"%s%s", outputName.c_str(),"_coarse_DefField.nii.gz");
1917 
1918  FieldType::Pointer field = FieldType::New();
1919  field->SetRegions( fixedRegion );
1920  field->SetOrigin( fixedImage->GetOrigin() );
1921  field->SetSpacing( fixedImage->GetSpacing() );
1922  field->SetDirection( fixedImage->GetDirection() );
1923  field->Allocate();
1924 
1925  typedef itk::ImageRegionIterator< FieldType > FieldIterator;
1926  FieldIterator fi( field, fixedRegion );
1927  fi.GoToBegin();
1928 
1929  DeformableTransformType::InputPointType fixedPoint;
1930  DeformableTransformType::OutputPointType movingPoint;
1931  FieldType::IndexType index;
1932  VectorType displacement;
1933 
1934  while( ! fi.IsAtEnd() ) {
1935  index = fi.GetIndex();
1936  field->TransformIndexToPhysicalPoint( index, fixedPoint );
1937  movingPoint = bsplineTransformCoarse->TransformPoint( fixedPoint );
1938  displacement = movingPoint - fixedPoint;
1939  fi.Set( displacement );
1940  ++fi;
1941  }
1942 
1943  std::cout << "Writing deformation field ..." << std::flush;
1944  //writeFile4D( convertFromVectorDFImage( field ), argv[6] );
1945  typedef itk::ImageFileWriter<FieldType> DFWriterType;
1946  DFWriterType::Pointer DFWriter = DFWriterType::New();
1947  DFWriter->SetInput(field);
1948  DFWriter->SetFileName( outputFileName );
1949  DFWriter->Update();
1950  std::cout << " Done!" << std::endl << std::endl;
1951  }
1952 
1953  /*********************************************************************************
1954  * *
1955  * Perform Medium Deformable Registration *
1956  * *
1957  *********************************************************************************/
1958  metric->SetUseExplicitPDFDerivatives( false );
1959 
1960  DeformableTransformType::Pointer bsplineTransformMedium = DeformableTransformType::New();
1961 
1962  fixedImage = fixedPyramid->GetOutput( PYRAMID_RESOLUTION_TWO );
1963  movingImage = movingPyramid->GetOutput( PYRAMID_RESOLUTION_TWO );
1964  fixedRegion = fixedImage->GetBufferedRegion();
1965  image_registration->SetFixedImage( fixedImage );
1966  image_registration->SetMovingImage( movingImage );
1967  //image_registration->SetNumberOfLevels(1);
1968 
1969  std::cout << "------ Multi level resolution two ------" << std::endl;
1970  fixedImageSize = fixedRegion.GetSize();
1971  fixedImageSpacing = fixedImage->GetSpacing();
1972  std::cout << "ImageSize: " << fixedImageSize[0] << ", " << fixedImageSize[1] << ", " << fixedImageSize[2] << std::endl;
1973  std::cout << "ImageSpacing: " << fixedImageSpacing[0] << ", " << fixedImageSpacing[1] << ", " << fixedImageSpacing[2] << std::endl;
1974 
1975  unsigned int mediumSpacing = GRID_POINT_SPACING_TWO;
1976  std::cout << "Medium Grid Point Spacing (mm): " << mediumSpacing << std::endl;
1977 
1978 #if ITK_VERSION_MAJOR < 4
1979 
1980  RegionType::SizeType gridMediumSizeOnImage;
1981  gridMediumSizeOnImage[0] = (int)floor(fixedImageSize[0] * fixedImageSpacing[0] / mediumSpacing);
1982  gridMediumSizeOnImage[1] = (int)floor(fixedImageSize[1] * fixedImageSpacing[1] / mediumSpacing);
1983  gridMediumSizeOnImage[2] = (int)floor(fixedImageSize[2] * fixedImageSpacing[2] / mediumSpacing);
1984  std::cout << "Number of grid points: " << gridMediumSizeOnImage[0] << ", " << gridMediumSizeOnImage[1] << ", " << gridMediumSizeOnImage[2] << ", " << std::endl;
1985 
1986  totalGridSize = gridMediumSizeOnImage + gridBorderSize;
1987  bsplineRegion.SetSize( totalGridSize );
1988 
1989  SpacingType spacingMedium = fixedImage->GetSpacing();
1990  OriginType originMedium = fixedImage->GetOrigin();
1991 
1992  for(unsigned int rh=0; rh<ImageDimension; rh++)
1993  {
1994  spacingMedium[rh] *= static_cast<double>(fixedImageSize[rh] - 1) / static_cast<double>(gridMediumSizeOnImage[rh] - 1);
1995  originMedium[rh] -= spacingMedium[rh];
1996  }
1997 
1998  gridDirection = fixedImage->GetDirection();
1999  SpacingType gridOriginOffsetMedium = gridDirection * spacingMedium;
2000  OriginType gridOriginMedium = origin - gridOriginOffsetMedium;
2001 
2002  bsplineTransformMedium->SetGridSpacing( spacingMedium );
2003  bsplineTransformMedium->SetGridOrigin( gridOriginMedium );
2004  bsplineTransformMedium->SetGridRegion( bsplineRegion );
2005  bsplineTransformMedium->SetGridDirection( gridDirection );
2006 
2007  bsplineTransformMedium->SetBulkTransform( affineTransform );
2008 
2009 #else
2010 
2011  for( unsigned int i=0; i < ImageDimension; i++ )
2012  {
2013  fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] *
2014  static_cast<double>(
2015  fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 );
2016  meshSize[i] = fixedImage->GetSpacing()[i] * static_cast<double>(fixedImageSize[i] - 1) / static_cast<double>((int)floor(fixedImageSize[i] * fixedImageSpacing[i] / mediumSpacing) - 1) - SplineOrder;
2017  }
2018  /* meshSize.Fill( numberOfGridNodesInOneDimension - SplineOrder );*/
2019  bsplineTransformMedium->SetTransformDomainOrigin( fixedImage->GetOrigin() );
2020  bsplineTransformMedium->SetTransformDomainPhysicalDimensions( fixedPhysicalDimensions );
2021  bsplineTransformMedium->SetTransformDomainMeshSize( meshSize );
2022  bsplineTransformMedium->SetTransformDomainDirection( fixedImage->GetDirection() );
2023  //TODO Set Affine transform to initialise NR registration
2024 
2025 #endif
2026 
2027 
2028  numberOfBSplineParameters = bsplineTransformMedium->GetNumberOfParameters();
2029  ParametersType parametersMedium( numberOfBSplineParameters );
2030  parametersMedium.Fill( 0.0 );
2031 
2032  // Now we need to initialize the BSpline coefficients of the higher resolution
2033  // transform. This is done by first computing the actual deformation field
2034  // at the higher resolution from the lower resolution BSpline coefficients.
2035  // Then a BSpline decomposition is done to obtain the BSpline coefficient of
2036  // the higher resolution transform.
2037 
2038 #if ITK_VERSION_MAJOR < 4
2039  unsigned int counter = 0;
2040 
2041  for ( unsigned int k = 0; k < SpaceDimension; k++ ) {
2042  typedef DeformableTransformType::ImageType ParametersImageType;
2043  typedef itk::ResampleImageFilter<ParametersImageType,ParametersImageType> ResamplerType;
2044  ResamplerType::Pointer upsampler = ResamplerType::New();
2045 
2046  typedef itk::BSplineResampleImageFunction<ParametersImageType,double> FunctionType;
2047  FunctionType::Pointer function = FunctionType::New();
2048 
2049  upsampler->SetInput( bsplineTransformCoarse->GetCoefficientImage()[k] );
2050  upsampler->SetInterpolator( function );
2051  upsampler->SetTransform( identityTransform );
2052  upsampler->SetSize( bsplineTransformMedium->GetGridRegion().GetSize() );
2053  upsampler->SetOutputSpacing( bsplineTransformMedium->GetGridSpacing() );
2054  upsampler->SetOutputOrigin( bsplineTransformMedium->GetGridOrigin() );
2055 
2056  typedef itk::BSplineDecompositionImageFilter<ParametersImageType,ParametersImageType> DecompositionType;
2057  DecompositionType::Pointer decomposition = DecompositionType::New();
2058  decomposition->SetSplineOrder( SplineOrder );
2059  decomposition->SetInput( upsampler->GetOutput() );
2060  decomposition->Update();
2061 
2062  ParametersImageType::Pointer newCoefficients = decomposition->GetOutput();
2063 
2064  // copy the coefficients into the parameter array
2065  typedef itk::ImageRegionIterator<ParametersImageType> Iterator;
2066  Iterator it( newCoefficients, bsplineTransformMedium->GetGridRegion() );
2067  while ( !it.IsAtEnd() )
2068  {
2069  parametersMedium[ counter++ ] = it.Get();
2070  ++it;
2071  }
2072  }
2073  bsplineTransformMedium->SetParameters( parametersMedium );
2074 #else
2075 
2076 
2077 #endif
2078 
2079  optimizerScales = OptimizerScalesType( numberOfBSplineParameters );
2080  optimizerScales.Fill( 1.0 );
2081  optimizer->SetScales( optimizerScales );
2082 
2083 
2084  if (false) {
2085  sprintf(outputFileName,"%s%s", outputName.c_str(),"mediumMR_initial.nii.gz");
2086 
2087  ResampleFilterType::Pointer resampleNRR = ResampleFilterType::New();
2088  resampleNRR->SetTransform(bsplineTransformMedium);
2089  resampleNRR->SetInput( movingImage );
2090  resampleNRR->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
2091  resampleNRR->SetOutputOrigin( fixedImage->GetOrigin() );
2092  resampleNRR->SetOutputSpacing( fixedImage->GetSpacing() );
2093  resampleNRR->SetOutputDirection( fixedImage->GetDirection() );
2094  resampleNRR->SetDefaultPixelValue(0.0);
2095  std::cout << "Computing NRR output" << std::endl;
2096  resampleNRR->Update();
2097 
2098  std::cout << "Writing medium NRR resampled moving image..." << std::flush;
2099  writeFile3D( resampleNRR->GetOutput() , outputFileName );
2100  std::cout << " Done!" << std::endl;
2101 
2102  sprintf(outputFileName, "%s%s", outputName.c_str(), "mediumBspline_initial.txt");
2103 
2104  itk::TransformFileWriter::Pointer transformWriter = itk::TransformFileWriter::New();
2105  transformWriter->AddTransform(bsplineTransformMedium);
2106  transformWriter->SetFileName(outputFileName);
2107  try {
2108  transformWriter->Update();
2109  } catch (itk::ExceptionObject & excp) {
2110  std::cerr << excp << std::endl;
2111  return EXIT_FAILURE;
2112  }
2113 
2114  sprintf(outputFileName,"%s%s", outputName.c_str(),"mediumBspline_initial.nii.gz");
2115 
2116 #if ITK_VERSION_MAJOR < 4
2117  typedef itk::Compose3DVectorImageFilter<DeformableTransformType::ImageType, FieldType> VectorComposerType;
2118  VectorComposerType::Pointer composer = VectorComposerType::New();
2119  composer->SetInput1(bsplineTransformMedium->GetCoefficientImage()[0]);
2120  composer->SetInput2(bsplineTransformMedium->GetCoefficientImage()[1]);
2121  composer->SetInput3(bsplineTransformMedium->GetCoefficientImage()[2]);
2122  composer->Update();
2123  typedef itk::ImageFileWriter<VectorComposerType::OutputImageType> CoeffWriterType;
2124  CoeffWriterType::Pointer coeffWriter = CoeffWriterType::New();
2125  coeffWriter->SetInput(composer->GetOutput());
2126  coeffWriter->SetFileName( outputFileName );
2127  coeffWriter->Update();
2128 #else
2129  typedef itk::TransformFileWriter TransformWriterType;
2130  TransformWriterType::Pointer coeffWriter = TransformWriterType::New();
2131  coeffWriter->SetInput(bsplineTransformMedium);
2132  coeffWriter->SetFileName( outputFileName );
2133  coeffWriter->Update();
2134 #endif
2135 
2136 
2137 
2138  sprintf(outputFileName, "%s%s", outputName.c_str(), "mediumDefField_initial.nii.gz");
2139 
2140  FieldType::Pointer field = FieldType::New();
2141  field->SetRegions( fixedRegion );
2142  field->SetOrigin( fixedImage->GetOrigin() );
2143  field->SetSpacing( fixedImage->GetSpacing() );
2144  field->SetDirection( fixedImage->GetDirection() );
2145  field->Allocate();
2146 
2147  typedef itk::ImageRegionIterator< FieldType > FieldIterator;
2148  FieldIterator fi( field, fixedRegion );
2149  fi.GoToBegin();
2150 
2151  DeformableTransformType::InputPointType fixedPoint;
2152  DeformableTransformType::OutputPointType movingPoint;
2153  FieldType::IndexType index;
2154  VectorType displacement;
2155 
2156  while( ! fi.IsAtEnd() ) {
2157  index = fi.GetIndex();
2158  field->TransformIndexToPhysicalPoint( index, fixedPoint );
2159  movingPoint = bsplineTransformMedium->TransformPoint( fixedPoint );
2160  displacement = movingPoint - fixedPoint;
2161  fi.Set( displacement );
2162  ++fi;
2163  }
2164 
2165  std::cout << "Writing deformation field ..." << std::flush;
2166  //writeFile4D( convertFromVectorDFImage( field ), argv[6] );
2167  typedef itk::ImageFileWriter<FieldType> DFWriterType;
2168  DFWriterType::Pointer DFWriter = DFWriterType::New();
2169  DFWriter->SetInput(field);
2170  DFWriter->SetFileName( outputFileName );
2171  DFWriter->Update();
2172  std::cout << " Done!" << std::endl << std::endl;
2173 
2174  //ResampleFilterType::Pointer resampleNRR = ResampleFilterType::New();
2175  sprintf(outputFileName,"%s%s", outputName.c_str(),"mediumNRR_initial.nii.gz");
2176 
2177  resampleNRR->SetTransform( bsplineTransformMedium );
2178  resampleNRR->SetInput( movingImage );
2179  resampleNRR->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
2180  resampleNRR->SetOutputOrigin( fixedImage->GetOrigin() );
2181  resampleNRR->SetOutputSpacing( fixedImage->GetSpacing() );
2182  resampleNRR->SetOutputDirection( fixedImage->GetDirection() );
2183  resampleNRR->SetDefaultPixelValue(0.0);
2184  std::cout << "Computing NRR output" << std::endl;
2185  resampleNRR->Update();
2186 
2187  std::cout << "Writing NRR resampled moving image..." << std::flush;
2188  writeFile3D( resampleNRR->GetOutput() , outputFileName );
2189  std::cout << " Done!" << std::endl;
2190 
2191  }
2192 
2193 
2194  // We now pass the parameters of the medium resolution transform as the initial
2195  // parameters to be used in a second stage of the registration process.
2196 
2197  std::cout << "Starting Registration with medium resolution transform" << std::endl;
2198 
2199  image_registration->SetInitialTransformParameters( bsplineTransformMedium->GetParameters() );
2200  image_registration->SetTransform( bsplineTransformMedium );
2201 
2202  optimizer->SetMaximumStepLength( NRR_MAX_STEP_TWO );
2203  optimizer->SetNumberOfIterations( NRR_ITERATIONS_TWO );
2204 
2205  if(useFixedMask)
2206  {
2207  metric->SetFixedImageMask( spatialObjectMask );
2208  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (16)) );
2209  }
2210  else
2211  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfPixels / (32)) );
2212  //#ifdef MATTES
2213  // metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfPixels / 3) );
2214  //#endif
2215 
2216  try {
2217  //itkProbesStart( "Deformable Registration Medium" );
2218 #if ITK_VERSION_MAJOR < 4
2219  image_registration->StartRegistration();
2220 #else
2221  image_registration->Update();
2222 #endif
2223 
2224  // itkProbesStop( "Deformable Registration Medium" );
2225  }
2226  catch( itk::ExceptionObject & err ) {
2227  std::cerr << "ExceptionObject caught !" << std::endl;
2228  std::cerr << err << std::endl;
2229  return EXIT_FAILURE;
2230  }
2231 
2232  std::cout << "Deformable Registration Medium Grid completed" << std::endl << std::endl;
2233 
2234  finalParameters = image_registration->GetLastTransformParameters();
2235  bsplineTransformMedium->SetParameters( finalParameters );
2236 
2237  if (writeFiles == true) {
2238  sprintf(outputFileName, "%s%s", outputName.c_str(), "medium_nrr.nii.gz");
2239 
2240  ResampleFilterType::Pointer resampleNRR = ResampleFilterType::New();
2241  resampleNRR->SetTransform(bsplineTransformMedium);
2242  resampleNRR->SetInput( movingImage );
2243  resampleNRR->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
2244  resampleNRR->SetOutputOrigin( fixedImage->GetOrigin() );
2245  resampleNRR->SetOutputSpacing( fixedImage->GetSpacing() );
2246  resampleNRR->SetOutputDirection( fixedImage->GetDirection() );
2247  resampleNRR->SetDefaultPixelValue(0.0);
2248  std::cout << "Computing NRR output" << std::endl;
2249  resampleNRR->Update();
2250 
2251  std::cout << "Writing medium NRR resampled moving image..." << std::flush;
2252  writeFile3D( resampleNRR->GetOutput() , outputFileName );
2253  std::cout << " Done!" << std::endl;
2254 
2255  sprintf(outputFileName, "%s%s", outputName.c_str(), "medium_Bspline.txt");
2256 
2257  itk::TransformFileWriter::Pointer transformWriter = itk::TransformFileWriter::New();
2258  transformWriter->AddTransform(bsplineTransformMedium);
2259  transformWriter->SetFileName(outputFileName);
2260  try {
2261  transformWriter->Update();
2262  } catch (itk::ExceptionObject & excp) {
2263  std::cerr << excp << std::endl;
2264  return EXIT_FAILURE;
2265  }
2266 
2267  sprintf(outputFileName,"%s%s", outputName.c_str(),"medium_Bspline.nii.gz");
2268 
2269 #if ITK_VERSION_MAJOR < 4
2270  typedef itk::Compose3DVectorImageFilter<DeformableTransformType::ImageType, FieldType> VectorComposerType;
2271  VectorComposerType::Pointer composer = VectorComposerType::New();
2272  composer->SetInput1(bsplineTransformMedium->GetCoefficientImage()[0]);
2273  composer->SetInput2(bsplineTransformMedium->GetCoefficientImage()[1]);
2274  composer->SetInput3(bsplineTransformMedium->GetCoefficientImage()[2]);
2275  composer->Update();
2276  typedef itk::ImageFileWriter<VectorComposerType::OutputImageType> CoeffWriterType;
2277  CoeffWriterType::Pointer coeffWriter = CoeffWriterType::New();
2278  coeffWriter->SetInput(composer->GetOutput());
2279  coeffWriter->SetFileName( outputFileName );
2280  coeffWriter->Update();
2281 #else
2282  typedef itk::TransformFileWriter TransformWriterType;
2283  TransformWriterType::Pointer coeffWriter = TransformWriterType::New();
2284  coeffWriter->SetInput(bsplineTransformMedium);
2285  coeffWriter->SetFileName( outputFileName );
2286  coeffWriter->Update();
2287 #endif
2288 
2289  sprintf(outputFileName, "%s%s", outputName.c_str(), "medium_DefField.nii.gz");
2290 
2291  FieldType::Pointer field = FieldType::New();
2292  field->SetRegions( fixedRegion );
2293  field->SetOrigin( fixedImage->GetOrigin() );
2294  field->SetSpacing( fixedImage->GetSpacing() );
2295  field->SetDirection( fixedImage->GetDirection() );
2296  field->Allocate();
2297 
2298  typedef itk::ImageRegionIterator< FieldType > FieldIterator;
2299  FieldIterator fi( field, fixedRegion );
2300  fi.GoToBegin();
2301 
2302  DeformableTransformType::InputPointType fixedPoint;
2303  DeformableTransformType::OutputPointType movingPoint;
2304  FieldType::IndexType index;
2305  VectorType displacement;
2306 
2307  while( ! fi.IsAtEnd() ) {
2308  index = fi.GetIndex();
2309  field->TransformIndexToPhysicalPoint( index, fixedPoint );
2310  movingPoint = bsplineTransformMedium->TransformPoint( fixedPoint );
2311  displacement = movingPoint - fixedPoint;
2312  fi.Set( displacement );
2313  ++fi;
2314  }
2315 
2316  std::cout << "Writing deformation field ..." << std::flush;
2317  //writeFile4D( convertFromVectorDFImage( field ), argv[6] );
2318  typedef itk::ImageFileWriter<FieldType> DFWriterType;
2319  DFWriterType::Pointer DFWriter = DFWriterType::New();
2320  DFWriter->SetInput(field);
2321  DFWriter->SetFileName( outputFileName );
2322  DFWriter->Update();
2323  std::cout << " Done!" << std::endl << std::endl;
2324 
2325  }
2326 
2327 
2328  /*********************************************************************************
2329  * *
2330  * Perform Fine Deformable Registration *
2331  * *
2332  *********************************************************************************/
2333 
2334  DeformableTransformType::Pointer bsplineTransformFine = DeformableTransformType::New();
2335 
2336  //fixedImage = fixedPyramid->GetOutput(PYRAMID_RESOLUTION_THREE) ;
2337  //movingImage = movingPyramid->GetOutput(PYRAMID_RESOLUTION_THREE) ;
2338 
2339  movingImage = readFile3D( atlasFile );
2340  fixedImage = readFile3D( dataFile );
2341 
2342  fixedRegion = fixedImage->GetBufferedRegion();
2343  image_registration->SetFixedImage( fixedImage );
2344  image_registration->SetMovingImage( movingImage );
2345  //registration->SetNumberOfLevels(1);
2346 
2347  std::cout << "------ Multi level resolution three ------" << std::endl;
2348  fixedImageSize = fixedRegion.GetSize();
2349  fixedImageSpacing = fixedImage->GetSpacing();
2350  std::cout << "ImageSize: " << fixedImageSize[0] << ", " << fixedImageSize[1] << ", " << fixedImageSize[2] << std::endl;
2351  std::cout << "ImageSpacing: " << fixedImageSpacing[0] << ", " << fixedImageSpacing[1] << ", " << fixedImageSpacing[2] << std::endl;
2352 
2353  unsigned int fineSpacing = GRID_POINT_SPACING_THREE; // Set the initial gridpoint spacing to 10mm
2354  std::cout << "Fine Grid Point Spacing (mm): " << fineSpacing << std::endl;
2355 
2356 #if ITK_VERSION_MAJOR < 4
2357 
2358  RegionType::SizeType gridHighSizeOnImage;
2359  gridHighSizeOnImage[0] = (int)floor( fixedImageSize[0] * fixedImageSpacing[0] / fineSpacing );
2360  gridHighSizeOnImage[1] = (int)floor( fixedImageSize[1] * fixedImageSpacing[1] / fineSpacing );
2361  gridHighSizeOnImage[2] = (int)floor( fixedImageSize[2] * fixedImageSpacing[2] / fineSpacing );
2362  std::cout << "Number of grid points: " << gridHighSizeOnImage[0] << ", " << gridHighSizeOnImage[1] << ", " << gridHighSizeOnImage[2] << ", " << std::endl;
2363  totalGridSize = gridSizeOnImage + gridBorderSize;
2364  totalGridSize = gridHighSizeOnImage + gridBorderSize;
2365  bsplineRegion.SetSize( totalGridSize );
2366 
2367  SpacingType spacingHigh = fixedImage->GetSpacing();
2368  OriginType originHigh = fixedImage->GetOrigin();
2369 
2370  for(unsigned int rh=0; rh<ImageDimension; rh++)
2371  {
2372  spacingHigh[rh] *= static_cast<double>(fixedImageSize[rh] - 1) / static_cast<double>(gridHighSizeOnImage[rh] - 1);
2373  originHigh[rh] -= spacingHigh[rh];
2374  }
2375 
2376  gridDirection = fixedImage->GetDirection();
2377  SpacingType gridOriginOffsetHigh = gridDirection * spacingHigh;
2378  OriginType gridOriginHigh = origin - gridOriginOffsetHigh;
2379 
2380  bsplineTransformFine->SetGridSpacing( spacingHigh );
2381  bsplineTransformFine->SetGridOrigin( gridOriginHigh );
2382  bsplineTransformFine->SetGridRegion( bsplineRegion );
2383  bsplineTransformFine->SetGridDirection( gridDirection );
2384  bsplineTransformFine->SetBulkTransform( affineTransform );
2385 
2386 #else
2387 
2388  for( unsigned int i=0; i < ImageDimension; i++ )
2389  {
2390  fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] *
2391  static_cast<double>(
2392  fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 );
2393  meshSize[i] = (int)floor( fixedImageSize[0] * fixedImageSpacing[0] / fineSpacing ) - SplineOrder;
2394  }
2395  /* meshSize.Fill( numberOfGridNodesInOneDimension - SplineOrder );*/
2396  bsplineTransformFine->SetTransformDomainOrigin( fixedImage->GetOrigin() );
2397  bsplineTransformFine->SetTransformDomainPhysicalDimensions( fixedPhysicalDimensions );
2398  bsplineTransformFine->SetTransformDomainMeshSize( meshSize );
2399  bsplineTransformFine->SetTransformDomainDirection( fixedImage->GetDirection() );
2400  //TODO Set Affine transform to initialise NR registration
2401 
2402 #endif
2403 
2404  numberOfBSplineParameters = bsplineTransformFine->GetNumberOfParameters();
2405  ParametersType parametersHigh( numberOfBSplineParameters );
2406  parametersHigh.Fill( 0.0 );
2407 
2408 #if ITK_VERSION_MAJOR < 4
2409  // Now we need to initialize the BSpline coefficients of the higher resolution transform.
2410  counter = 0;
2411 
2412  for ( unsigned int k = 0; k < SpaceDimension; k++ )
2413  {
2414 
2415  typedef DeformableTransformType::ImageType ParametersImageType;
2416  typedef itk::ResampleImageFilter<ParametersImageType,ParametersImageType> ResamplerType;
2417  ResamplerType::Pointer upsampler = ResamplerType::New();
2418 
2419  typedef itk::BSplineResampleImageFunction<ParametersImageType,double> FunctionType;
2420  FunctionType::Pointer function = FunctionType::New();
2421 
2422  upsampler->SetInput( bsplineTransformMedium->GetCoefficientImage()[k] );
2423  upsampler->SetInterpolator( function );
2424  upsampler->SetTransform( identityTransform );
2425  upsampler->SetSize( bsplineTransformFine->GetGridRegion().GetSize() );
2426  upsampler->SetOutputSpacing( bsplineTransformFine->GetGridSpacing() );
2427  upsampler->SetOutputOrigin( bsplineTransformFine->GetGridOrigin() );
2428 
2429  typedef itk::BSplineDecompositionImageFilter<ParametersImageType,ParametersImageType> DecompositionType;
2430  DecompositionType::Pointer decomposition = DecompositionType::New();
2431 
2432  decomposition->SetSplineOrder( SplineOrder );
2433  decomposition->SetInput( upsampler->GetOutput() );
2434  decomposition->Update();
2435 
2436  ParametersImageType::Pointer newCoefficients = decomposition->GetOutput();
2437 
2438  // copy the coefficients into the parameter array
2439  typedef itk::ImageRegionIterator<ParametersImageType> Iterator;
2440  Iterator it( newCoefficients, bsplineTransformFine->GetGridRegion() );
2441  while ( !it.IsAtEnd() ) {
2442  parametersHigh[ counter++ ] = it.Get();
2443  ++it;
2444  }
2445 
2446  }
2447  bsplineTransformFine->SetParameters( parametersHigh );
2448 #else
2449 
2450 #endif
2451 
2452  optimizerScales = OptimizerScalesType( numberOfBSplineParameters );
2453  optimizerScales.Fill( 1.0 );
2454  optimizer->SetScales( optimizerScales );
2455 
2456 
2457  // We now pass the parameters of the high resolution transform as the initial
2458  // parameters to be used in a second stage of the registration process.
2459 
2460  std::cout << "Starting Registration with high resolution transform" << std::endl;
2461 
2462  image_registration->SetInitialTransformParameters( bsplineTransformFine->GetParameters() );
2463  image_registration->SetTransform( bsplineTransformFine );
2464 
2465  optimizer->SetMaximumStepLength( NRR_MAX_STEP_THREE );
2466  optimizer->SetNumberOfIterations( NRR_ITERATIONS_THREE );
2467 
2468  if(useFixedMask)
2469  {
2470  metric->SetFixedImageMask( spatialObjectMask );
2471  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfVoxelsInMask / (4)) );
2472  }
2473  else
2474  metric->SetNumberOfSpatialSamples( static_cast<int>(numberOfPixels / (4)) );
2475 
2476  try
2477  {
2478  //itkProbesStart( "Deformable Registration Fine" );
2479 #if ITK_VERSION_MAJOR < 4
2480  image_registration->StartRegistration();
2481 #else
2482  image_registration->Update();
2483 #endif
2484  //itkProbesStop( "Deformable Registration Fine" );
2485  }
2486  catch( itk::ExceptionObject & err )
2487  {
2488  std::cerr << "ExceptionObject caught !" << std::endl;
2489  std::cerr << err << std::endl;
2490  return EXIT_FAILURE;
2491  }
2492 
2493  std::cout << "Deformable Registration Fine Grid completed" << std::endl;
2494  std::cout << std::endl << std::endl;
2495 
2496  finalParameters = image_registration->GetLastTransformParameters();
2497  bsplineTransformFine->SetParameters( finalParameters );
2498 
2499  //itkProbesReport( std::cout );
2500  /*********************************************************************************
2501  * *
2502  * Output the B-spline transform parameters & Coeff Image *
2503  * *
2504  *********************************************************************************/
2505  std::cout << "Write transform" << std::endl;
2506  std::cout << std::endl << std::endl;
2507 
2508  sprintf(outputFileName, "%s%s", outputName.c_str(), "fine_Bsplines.txt");
2509 
2510  itk::TransformFileWriter::Pointer transformWriter = itk::TransformFileWriter::New();
2511  transformWriter->AddTransform(bsplineTransformFine);
2512  transformWriter->SetFileName(outputFileName);
2513  try {
2514  transformWriter->Update();
2515  } catch (itk::ExceptionObject & excp) {
2516  std::cerr << excp << std::endl;
2517  return EXIT_FAILURE;
2518  }
2519 
2520  if (writeFiles == true) {
2521  sprintf(outputFileName,"%s%s", outputName.c_str(),"fine_Bsplines.nii.gz");
2522 
2523 #if ITK_VERSION_MAJOR < 4
2524  typedef itk::Compose3DVectorImageFilter<DeformableTransformType::ImageType, FieldType> VectorComposerType;
2525  VectorComposerType::Pointer composer = VectorComposerType::New();
2526  composer->SetInput1(bsplineTransformFine->GetCoefficientImage()[0]);
2527  composer->SetInput2(bsplineTransformFine->GetCoefficientImage()[1]);
2528  composer->SetInput3(bsplineTransformFine->GetCoefficientImage()[2]);
2529  composer->Update();
2530  typedef itk::ImageFileWriter<VectorComposerType::OutputImageType> CoeffWriterType;
2531  CoeffWriterType::Pointer coeffWriter = CoeffWriterType::New();
2532  coeffWriter->SetInput(composer->GetOutput());
2533  coeffWriter->SetFileName( outputFileName );
2534  coeffWriter->Update();
2535 #else
2536  typedef itk::TransformFileWriter TransformWriterType;
2537  TransformWriterType::Pointer coeffWriter = TransformWriterType::New();
2538  coeffWriter->SetInput(bsplineTransformFine);
2539  coeffWriter->SetFileName( outputFileName );
2540  coeffWriter->Update();
2541 #endif
2542 
2543  }
2544 
2545 
2546  /*********************************************************************************
2547  * *
2548  * Output the Deformation Field *
2549  * *
2550  *********************************************************************************/
2551 
2552  if (writeFiles == true) {
2553  sprintf(outputFileName, "%s%s", outputName.c_str(), "fine_DefField.nii.gz");
2554 
2555  FieldType::Pointer field = FieldType::New();
2556  field->SetRegions( fixedRegion );
2557  field->SetOrigin( fixedImage->GetOrigin() );
2558  field->SetSpacing( fixedImage->GetSpacing() );
2559  field->SetDirection( fixedImage->GetDirection() );
2560  field->Allocate();
2561 
2562  typedef itk::ImageRegionIterator< FieldType > FieldIterator;
2563  FieldIterator fi( field, fixedRegion );
2564  fi.GoToBegin();
2565 
2566  DeformableTransformType::InputPointType fixedPoint;
2567  DeformableTransformType::OutputPointType movingPoint;
2568  FieldType::IndexType index;
2569  VectorType displacement;
2570 
2571  while( ! fi.IsAtEnd() ) {
2572  index = fi.GetIndex();
2573  field->TransformIndexToPhysicalPoint( index, fixedPoint );
2574  movingPoint = bsplineTransformFine->TransformPoint( fixedPoint );
2575  displacement = movingPoint - fixedPoint;
2576  fi.Set( displacement );
2577  ++fi;
2578  }
2579 
2580  std::cout << "Writing deformation field ..." << std::flush;
2581  //writeFile4D( convertFromVectorDFImage( field ), argv[6] );
2582  typedef itk::ImageFileWriter<FieldType> DFWriterType;
2583  DFWriterType::Pointer DFWriter = DFWriterType::New();
2584  DFWriter->SetInput(field);
2585  DFWriter->SetFileName( outputFileName );
2586  DFWriter->Update();
2587  std::cout << " Done!" << std::endl << std::endl;
2588  }
2589 
2590  /*********************************************************************************
2591  * *
2592  * Output the Non-rigid Transformed Image *
2593  * *
2594  *********************************************************************************/
2595 
2596  if (writeFiles == true) {
2597  sprintf(outputFileName, "%s%s", outputName.c_str(), "fine_nrr.nii.gz");
2598 
2599  ResampleFilterType::Pointer resampleNRR = ResampleFilterType::New();
2600  resampleNRR->SetTransform( bsplineTransformFine );
2601  resampleNRR->SetInput( movingImage );
2602  resampleNRR->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
2603  resampleNRR->SetOutputOrigin( fixedImage->GetOrigin() );
2604  resampleNRR->SetOutputSpacing( fixedImage->GetSpacing() );
2605  resampleNRR->SetOutputDirection( fixedImage->GetDirection() );
2606  resampleNRR->SetDefaultPixelValue(0.0);
2607  std::cout << "Computing NRR output" << std::endl;
2608  resampleNRR->Update();
2609 
2610  std::cout << "Writing NRR resampled moving image..." << std::flush;
2611  this->writeFile3D( resampleNRR->GetOutput() , outputFileName );
2612  std::cout << " Done!" << std::endl;
2613 
2614  }
2615  std::cout << "Finished ITK NRR" << std::endl;
2616  return true;
2617 }
2618 
2624 void
2626 ::writeFile3D(FixedImageType::Pointer image, std::string outputFileName) {
2627  typedef itk::ImageFileWriter< FixedImageType > WriterType;
2628  WriterType::Pointer writer = WriterType::New();
2629  writer->SetInput(image);
2630  writer->SetFileName(outputFileName);
2631  try {
2632  writer->Update();
2633  } catch (itk::ExceptionObject & err) {
2634  std::cerr << "ExceptionObject caught:" << std::endl;
2635  std::cerr << err << std::endl;
2636  exit(1);
2637  }
2638  std::cout << "File written: " << outputFileName << std::endl;
2639 }
2640 
2646 Registration::FixedImageType::Pointer
2648 ::readFile3D(std::string fileName) {
2649  typedef itk::ImageFileReader< FixedImageType > ReaderType;
2650  ReaderType::Pointer reader = ReaderType::New();
2651  reader->SetFileName(fileName);
2652  try {
2653  reader->Update();
2654  } catch (itk::ExceptionObject & err) {
2655  std::cerr << "ExceptionObject caught:" << std::endl;
2656  std::cerr << err << std::endl;
2657  exit(1);
2658  }
2659  return reader->GetOutput();
2660 }
2661 
2662 
2663 void
2664 Registration
2665 ::Voting(std::vector<std::string> inputFilenames, std::string outputFilename, int modulo, int N, ConsensusMode consensusMode)
2666 {
2667  std::string cmd_staple(STAPLE_EXEC);
2668 
2669  cmd_staple.append(" -m ");
2670 
2671  if(consensusMode == VOTING)
2672  cmd_staple.append(STAPLE_TYPE);
2673  else
2674  cmd_staple.append(STAPLE_TYPE2);
2675 
2676  cmd_staple.append(" -in ");
2677 
2678  /*1 create the source_files*/
2679  for (unsigned int i = 0; i < inputFilenames.size(); i++)
2680  {
2681  if((i+1)%N == static_cast<unsigned int>(modulo) )
2682  {
2683  cmd_staple.append(inputFilenames[i]);
2684  cmd_staple.append(" ");
2685  }
2686  }
2687 
2688  cmd_staple.append("-n 117 -outh ");
2689  //cmd_gm.append(" -iv 0 254 -ov 0 1 -outh ");
2690 
2691  cmd_staple.append(outputFilename);
2692 
2693  if (system(cmd_staple.c_str()) != 0 ) {
2694  std::cerr << "Error: External call to STAPLE was unsuccesful." << std::endl;
2695  }
2696 
2697 }
2698 
2699 bool
2700 Registration
2701 ::PropagateITKRigid(std::string inputImage, std::string outputImageFileName, std::string targetFile, std::string inputTransform, InterpolateMode mode)
2702 {
2703 
2704  std::cout << "Read rigid transform " << inputTransform << std::endl;
2705  // Read in ITK transform
2706  typedef itk::VersorRigid3DTransform< double >VersorRigid3DTransformType;
2707  VersorRigid3DTransformType::Pointer rigidVersorTransform;
2708 
2709  typedef itk::Euler3DTransform< double >Euler3DTransformType;
2710  Euler3DTransformType::Pointer rigidEulerTransform;
2711 
2712  typedef itk::ResampleImageFilter< MovingImageType, FixedImageType > ResampleFilterType;
2713  ResampleFilterType::Pointer resampleAffine = ResampleFilterType::New();
2714 
2715 
2716  itk::TransformFileReader::Pointer rigidReader = itk::TransformFileReader::New();
2717  std::string ra = inputTransform;
2718  rigidReader->SetFileName(ra);
2719  try {
2720  rigidReader->Update();
2721  }
2722  catch(itk::ExceptionObject &ex) {
2723  std::cout << "Failed reading rigid " << std::endl;
2724  throw ex;
2725  return false;
2726  }
2727  if(!strcmp(rigidReader->GetTransformList()->front()->GetNameOfClass(), "VersorRigid3DTransform"))
2728  {
2729  rigidVersorTransform = static_cast<VersorRigid3DTransformType*>(rigidReader->GetTransformList()->front().GetPointer());
2730  resampleAffine->SetTransform( rigidVersorTransform );
2731  }
2732  else if(!strcmp(rigidReader->GetTransformList()->front()->GetNameOfClass(), "Euler3DTransform"))
2733  {
2734  rigidEulerTransform = static_cast<Euler3DTransformType*>(rigidReader->GetTransformList()->front().GetPointer());
2735  resampleAffine->SetTransform( rigidEulerTransform );
2736  }
2737  else
2738  {
2739  std::cerr << "Transform Input is not of VersorRigid3DTransform" << std::endl;
2740  return false;
2741  }
2742 
2743  FixedImageType::Pointer movingImage = this->readFile3D( targetFile );
2744  MovingImageType::Pointer fixedImage = readFile3D( inputImage );
2745 
2746  std::cout << fixedImage->GetLargestPossibleRegion().GetSize() << std::endl;
2747  std::cout <<fixedImage->GetSpacing()<< std::endl;
2748 
2749 
2750  if( mode == INTERP_NEAREST)
2751  resampleAffine->SetInterpolator( m_NearestNeighborOrientatedInterpolator );
2752  else if(mode == INTERP_LINEAR)
2753  resampleAffine->SetInterpolator( m_LinearOrientatedInterpolator );
2754  else if(mode == INTERP_BSPLINE)
2755  {
2756  m_BsplineOrientatedInterpolator->SetSplineOrder(3);
2757  resampleAffine->SetInterpolator( m_BsplineOrientatedInterpolator);
2758  }
2759  else
2760  {
2761  m_BsplineOrientatedInterpolator->SetSplineOrder(5);
2762  resampleAffine->SetInterpolator( m_BsplineOrientatedInterpolator);
2763  }
2764 
2765 
2766  resampleAffine->SetInput( movingImage );
2767  resampleAffine->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
2768  resampleAffine->SetOutputOrigin( fixedImage->GetOrigin() );
2769  resampleAffine->SetOutputSpacing( fixedImage->GetSpacing() );
2770  resampleAffine->SetOutputDirection( fixedImage->GetDirection() );
2771  resampleAffine->SetDefaultPixelValue(0.0);
2772  try {
2773  resampleAffine->Update();
2774  } catch (itk::ExceptionObject & err) {
2775  std::cerr << "ExceptionObject caught:" << std::endl;
2776  std::cerr << err << std::endl;
2777  return false;
2778  }
2779 
2780  writeFile3D( resampleAffine->GetOutput() , outputImageFileName );
2781  return true;
2782 }
2783 
2784 bool
2785 Registration
2786 ::PropagateITKAffine(std::string inputImage,
2787  std::string outputImageFileName,
2788  std::string targetFile,
2789  std::string inputTransform,
2790  InterpolateMode mode)
2791 {
2792 
2793  std::cout << "Read transform " << inputTransform << std::endl;
2794  // Read in ITK transform
2795  typedef itk::AffineTransform< double, ImageDimension > AffineTransformType;
2796  AffineTransformType::Pointer affineTransform;
2797 
2798  itk::TransformFileReader::Pointer affineReader = itk::TransformFileReader::New();
2799  try {
2800  affineReader->SetFileName(inputTransform);
2801  affineReader->Update();
2802  } catch(itk::ExceptionObject &ex) {
2803  throw ex;
2804  return 0;
2805  }
2806 
2807  if(!strcmp(affineReader->GetTransformList()->front()->GetNameOfClass(), "AffineTransform")) {
2808  affineTransform = static_cast<AffineTransformType*>(affineReader->GetTransformList()->front().GetPointer());
2809  } else {
2810  std::cerr << "Affine Transform Input is not of AffineTransformType" << std::endl;
2811  return EXIT_FAILURE;
2812  }
2813 
2814  FixedImageType::Pointer fixedImage = this->readFile3D( inputImage );
2815  MovingImageType::Pointer movingImage = readFile3D( targetFile );
2816 
2817  typedef itk::ResampleImageFilter< MovingImageType, FixedImageType > ResampleFilterType;
2818  ResampleFilterType::Pointer resampleAffine = ResampleFilterType::New();
2819 
2820  if( mode == INTERP_NEAREST)
2821  resampleAffine->SetInterpolator( m_NearestNeighborOrientatedInterpolator );
2822  else if(mode == INTERP_LINEAR)
2823  resampleAffine->SetInterpolator( m_LinearOrientatedInterpolator );
2824  else if(mode == INTERP_BSPLINE)
2825  {
2826  m_BsplineOrientatedInterpolator->SetSplineOrder(3);
2827  resampleAffine->SetInterpolator( m_BsplineOrientatedInterpolator);
2828  }
2829  else
2830  {
2831  m_BsplineOrientatedInterpolator->SetSplineOrder(5);
2832  resampleAffine->SetInterpolator( m_BsplineOrientatedInterpolator);
2833  }
2834 
2835 
2836  resampleAffine->SetTransform( affineTransform );
2837  resampleAffine->SetInput( movingImage );
2838  resampleAffine->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
2839  resampleAffine->SetOutputOrigin( fixedImage->GetOrigin() );
2840  resampleAffine->SetOutputSpacing( fixedImage->GetSpacing() );
2841  resampleAffine->SetOutputDirection( fixedImage->GetDirection() );
2842  resampleAffine->SetDefaultPixelValue(0.0);
2843  try {
2844  resampleAffine->Update();
2845  } catch (itk::ExceptionObject & err) {
2846  std::cerr << "ExceptionObject caught:" << std::endl;
2847  std::cerr << err << std::endl;
2848  exit(1);
2849  }
2850 
2851  writeFile3D( resampleAffine->GetOutput() , outputImageFileName );
2852  return true;
2853 }
2854 
2855 bool
2856 Registration
2857 ::PropagateITKAffineBspline(std::string inputImage, std::string targetFile, std::string outputFilename, std::string inputTransform, std::string inputBsplineTransform, InterpolateMode mode)
2858 {
2859 
2860  std::cout << "About to propogate ITK NRR" << std::endl;
2861  // Read in ITK transform
2862  typedef itk::AffineTransform< double, ImageDimension > AffineTransformType;
2863  AffineTransformType::Pointer affineTransform;
2864 
2865  itk::TransformFileReader::Pointer affineReader = itk::TransformFileReader::New();
2866  try {
2867  affineReader->SetFileName(inputTransform);
2868  affineReader->Update();
2869  } catch(itk::ExceptionObject &ex) {
2870  throw ex;
2871  return 0;
2872  }
2873 
2874  if(!strcmp(affineReader->GetTransformList()->front()->GetNameOfClass(), "AffineTransform")) {
2875  affineTransform = static_cast<AffineTransformType*>(affineReader->GetTransformList()->front().GetPointer());
2876  } else {
2877  std::cerr << "Affine Transform Input is not of AffineTransformType" << std::endl;
2878  return EXIT_FAILURE;
2879  }
2880 
2881  std::cout << "About to read NRR transform" << std::endl;
2882  /* read the bspline transform from a file */
2883  itk::TransformFileReader::Pointer nrrReader = itk::TransformFileReader::New();
2884  try {
2885  nrrReader->SetFileName(inputBsplineTransform);
2886  nrrReader->Update();
2887  } catch(itk::ExceptionObject &ex) {
2888  throw ex;
2889  return 0;
2890  }
2891  std::cout << "Check" << std::endl;
2892  /* copy the transform into a new B-Spline Transform object and set the Affine bulk transform */
2893 #if ITK_VERSION_MAJOR < 4
2894  typedef itk::BSplineDeformableTransform< double, ImageDimension, SplineOrder > DeformableTransformType;
2895 #else
2896  typedef itk::BSplineTransform< double, ImageDimension, SplineOrder > DeformableTransformType;
2897 #endif
2898 
2899  DeformableTransformType::Pointer bSplineTransform;
2900 
2901  if (!strcmp(nrrReader->GetTransformList()->front()->GetNameOfClass(), "BSplineDeformableTransform")) {
2902  bSplineTransform = static_cast<DeformableTransformType*>(nrrReader->GetTransformList()->front().GetPointer());
2903  } else {
2904  std::cerr << "NRR BSpline Transform Input is not of BSplineDeformableTransformType" << std::endl;
2905  return EXIT_FAILURE;
2906  }
2907  std::cout << "Read transforms" << std::endl;
2908 
2909 #if ITK_VERSION_MAJOR < 4
2910  bSplineTransform->SetBulkTransform( affineTransform );
2911 #else
2912 //TODO Set Affine transform to initialise NR registration
2913 #endif
2914 
2915  std::cout << "Read Fixed " <<inputImage << std::endl;
2916  FixedImageType::Pointer fixedImage = this->readFile3D( inputImage );
2917  std::cout << "Read Moving " <<targetFile<< std::endl;
2918  MovingImageType::Pointer movingImage = readFile3D( targetFile );
2919 
2920  std::cout << "Resample " << std::endl;
2921  typedef itk::ResampleImageFilter< MovingImageType, FixedImageType > ResampleFilterType;
2922  ResampleFilterType::Pointer resampleNRR = ResampleFilterType::New();
2923 
2924  if( mode == INTERP_NEAREST)
2925  resampleNRR->SetInterpolator( m_NearestNeighborOrientatedInterpolator );
2926  else if(mode == INTERP_LINEAR)
2927  resampleNRR->SetInterpolator( m_LinearOrientatedInterpolator );
2928  else if(mode == INTERP_BSPLINE)
2929  {
2930  m_BsplineOrientatedInterpolator->SetSplineOrder(3);
2931  resampleNRR->SetInterpolator( m_BsplineOrientatedInterpolator);
2932  }
2933  else
2934  {
2935  m_BsplineOrientatedInterpolator->SetSplineOrder(5);
2936  resampleNRR->SetInterpolator( m_BsplineOrientatedInterpolator);
2937  }
2938 
2939 
2940  resampleNRR->SetTransform( bSplineTransform );
2941  resampleNRR->SetInput( movingImage );
2942  resampleNRR->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() );
2943  resampleNRR->SetOutputOrigin( fixedImage->GetOrigin() );
2944  resampleNRR->SetOutputSpacing( fixedImage->GetSpacing() );
2945  resampleNRR->SetOutputDirection( fixedImage->GetDirection() );
2946  resampleNRR->SetDefaultPixelValue(0.0);
2947  resampleNRR->Update();
2948  std::cout << "Done " << std::endl;
2949  this->writeFile3D( resampleNRR->GetOutput() , outputFilename );
2950 
2951  return true;
2952 }
2953 
2954 }
void writeFile3D(FixedImageType::Pointer image, std::string outputFileName)
FixedImageType::Pointer readFile3D(std::string fileName)
bool RegisterRigidITK(std::string dataFile, std::string atlasFile, std::string outputPrefix, bool Invert, std::string dataMaskFile, std::string atlasMaskFile)