template<class FixedImageType,class MovingImageType,class TransformType> void RegisterPair(const typename FixedImageType::Pointer & fixedImage, const typename MovingImageType::Pointer & movingImage, typename TransformType::Pointer & transform ){


	typedef itk::LogImageAdaptor<FixedImageType,float> LogFixedImageType;

	typedef itk::CenteredTransformInitializer< TransformType,LogFixedImageType,MovingImageType> TransformInitializerType;
	typename TransformInitializerType::Pointer initializer = TransformInitializerType::New();

	typename LogFixedImageType::Pointer logAdaptor=LogFixedImageType::New();
	logAdaptor->SetImage(fixedImage);

	initializer->SetTransform( transform );
	initializer->SetFixedImage( logAdaptor );
	initializer->SetMovingImage( movingImage);

	initializer->MomentsOn();
	initializer->InitializeTransform();

	  // Optimizer Type
	  typedef itk::VersorRigid3DTransformOptimizer OptimizerType;
	 //typedef itk::ConjugateGradientOptimizer OptimizerType;
	  // Metric Type
	  typedef
	  //itk::NormalizedMutualInformationHistogramImageToImageMetric< FixedImageType, MovingImageType >

	  //itk::MutualInformationImageToImageMetric<FixedImageType,MovingImageType >
			  //itk::GradientDifferenceImageToImageMetric<FixedImageType,MovingImageType>
			  itk::NormalizedCorrelationImageToImageMetric< FixedImageType, MovingImageType >
	//		  itk::KullbackLeiblerCompareHistogramImageToImageMetric< FixedImageType, MovingImageType >
			  //itk::MattesMutualInformationImageToImageMetric<FixedImageType,MovingImageType>
			  //itk::MutualInformationHistogramImageToImageMetric<FixedImageType,MovingImageType>
			  //itk::MeanSquaresImageToImageMetric< FixedImageType, MovingImageType >
	  MetricType;


	  // Interpolation technique
	  typedef itk:: LinearInterpolateImageFunction<
	                                    MovingImageType,
	                                    double          >    InterpolatorType;

	  // Registration Method
	  typedef itk::ImageRegistrationMethod<
	                                    FixedImageType,
	                                    MovingImageType >    RegistrationType;


	  typename MetricType::Pointer         metric        = MetricType::New();

	  typename OptimizerType::Pointer      optimizer     = OptimizerType::New();
	  typename InterpolatorType::Pointer   interpolator  = InterpolatorType::New();
	  typename RegistrationType::Pointer   registration  = RegistrationType::New();

  /******************************************************************
   * Set up the optimizer.
   ******************************************************************/
	  typedef typename TransformType::VersorType VersorType;
	  typedef typename VersorType::VectorType VectorType;
	  VersorType rotation;
	  VectorType axis;
	  	axis[0] = 0.0;
	  	axis[1] = 0.0;
	  	axis[2] = 1.0;
	  	const double angle = 0;
	  	rotation.Set( axis, angle );
	  	transform->SetRotation( rotation );

	  	registration->SetInitialTransformParameters( transform->GetParameters() );
	  	// Software Guide : EndCodeSnippet
	  	typedef OptimizerType::ScalesType OptimizerScalesType;
	  	OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() );
	  	const double translationScale = 1.0 / 1000.0;
	  	optimizerScales[0] = 1.0;
	  	optimizerScales[1] = 1.0;
	  	optimizerScales[2] = 1.0;
	  	optimizerScales[3] = translationScale;
	  	optimizerScales[4] = translationScale;
	  	optimizerScales[5] = translationScale;
	  	optimizer->SetScales( optimizerScales );
	  	//optimizer->SetMaximumStepLength( 0.1 );
	  	optimizer->SetMaximumStepLength( 1);
	  	optimizer->SetMinimumStepLength( 0.000000001 );
	  	optimizer->SetNumberOfIterations( 10 );
	  	optimizer->SetMinimize(true);



  /******************************************************************
   * Set up the metric.
   ******************************************************************/
  //metric->SetMovingImageStandardDeviation( 1.0 );
  //metric->SetFixedImageStandardDeviation( 1.0 );

  //metric->SetNumberOfSpatialSamples( 50000000 );
  metric->SetUseAllPixels(true);
  //metric->SetFixedImageRegion( fixedImage->GetBufferedRegion() );

  /******************************************************************
   * Set up the registrator.
   ******************************************************************/

  // connect up the components
  registration->SetMetric( metric );
  registration->SetOptimizer( optimizer );
  registration->SetTransform( transform );
  registration->SetFixedImage( fixedImage );
  registration->SetMovingImage( movingImage );
  registration->SetInterpolator( interpolator );

//  transform->SetIdentity();
//  // set initial parameters to identity
//  typename RegistrationType::ParametersType initialParameters(
//    transform->GetNumberOfParameters() );
//
//  initialParameters.Fill( 0.0 );
//  //initialParameters[3] = 1.0;


	CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();
	optimizer->AddObserver( itk::IterationEvent(), observer );
	try
	{
	registration->Update();
	std::cout << "Optimizer stop condition: "
	<< registration->GetOptimizer()->GetStopConditionDescription()
	<< std::endl;
	}
	catch( itk::ExceptionObject & err )
	{
	std::cerr << "ExceptionObject caught !" << std::endl;
	std::cerr << err << std::endl;
	//return EXIT_FAILURE;
	}
	OptimizerType::ParametersType finalParameters =
	registration->GetLastTransformParameters();
	const double versorX = finalParameters[0];
	const double versorY = finalParameters[1];
	const double versorZ = finalParameters[2];
	const double finalTranslationX = finalParameters[3];
	const double finalTranslationY = finalParameters[4];
	const double finalTranslationZ = finalParameters[5];
	const unsigned int numberOfIterations = optimizer->GetCurrentIteration();
	const double bestValue = optimizer->GetValue();
	// Print out results
	//
	std::cout << std::endl << std::endl;
	std::cout << "Result = " << std::endl;
	std::cout << " versor X = " << versorX << std::endl;
	std::cout << " versor Y = " << versorY << std::endl;
	std::cout << " versor Z = " << versorZ << std::endl;
	std::cout << " Translation X = " << finalTranslationX << std::endl;
	std::cout << " Translation Y = " << finalTranslationY << std::endl;
	std::cout << " Translation Z = " << finalTranslationZ << std::endl;
	std::cout << " Iterations = " << numberOfIterations << std::endl;
	std::cout << " Metric value = " << bestValue << std::endl;



}
Ejemplo n.º 2
0
    void RunRegistration() {
        _transform = TransformType::New();
        OptiReporter::Pointer optiReporter = OptiReporter::New();
        Metric::Pointer metric = Metric::New();
        metric->SetFixedImage(_dst);
        bool useIndexes = false;
        if (useIndexes) {
            _centerOfRotation.SetSize(ImageType::ImageDimension);
            for (int i = 0; i < ImageType::ImageDimension; i++) {
                _centerOfRotation[i] = i;
            }
            itk::ImageRegionConstIteratorWithIndex<LabelType> labelIter(_dstLabel, _dstLabel->GetBufferedRegion());
            int nPixels = 0;
            for (labelIter.GoToBegin(); !labelIter.IsAtEnd(); ++labelIter) {
                LabelType::PixelType label = labelIter.Get();
                if (label > 0) {
                    _labelIndexes.push_back(labelIter.GetIndex());
                    for (int i = 0; i < ImageType::ImageDimension; i++) {
                        _centerOfRotation[i] += labelIter.GetIndex()[i];
                    }
                    nPixels ++;
                }
            }
            for (int i = 0; i < ImageType::ImageDimension; i++) {
                _centerOfRotation[i] /= nPixels;
            }
            metric->SetFixedImageIndexes(_labelIndexes);
            _transform->SetFixedParameters(_centerOfRotation);
        } else {
            metric->SetFixedImageRegion(_dst->GetBufferedRegion());
            metric->SetUseAllPixels(true);
            _centerOfRotation.SetSize(ImageType::ImageDimension);
            for (int i = 0; i < 3; i++) {
                _centerOfRotation[i] = _dstCenter[i];
            }
            _transform->SetFixedParameters(_centerOfRotation);
        }

        cout << "Fixed Parameters: " << _centerOfRotation << endl;

        metric->SetMovingImage(_src);
        metric->SetInterpolator(Interpolator::New());
        metric->SetTransform(_transform);
        metric->Initialize();

        Optimizer::Pointer opti = Optimizer::New();
        opti->SetCostFunction(metric);
        Optimizer::ScalesType scales;
        scales.SetSize(TransformType::ParametersDimension);
        scales.Fill(1);
        if (_method == "affine") {
            cout << "apply affine scaling ..." << endl;
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    if (i == j) {
                        scales[3*i+j] = 160;
                    } else {
                        scales[3*i+j] = 30;
                    }
                }
            }
            scales[9] = scales[10] = scales[11] = 0.1;
        } else if (_method == "scale") {
            scales[0] = scales[1] = scales[2] = 30;
            scales[3] = scales[4] = scales[5] = .5;
            scales[6] = scales[7] = scales[8] = 100;
        } else if (_method == "similar") {
            scales[0] = scales[1] = scales[2] = 10;
            scales[3] = scales[4] = scales[5] = 0.5;
            scales[6] = 100;
        }
        opti->SetScales(scales);

        const int maxIters = 100;
#ifdef USE_CG_OPTIMIZER
        opti->SetMaximumIteration(maxIters);
        opti->SetMaximumLineIteration(10);
        opti->SetUseUnitLengthGradient(true);
        opti->SetStepLength(1);
        opti->SetToFletchReeves();
#endif

#ifdef USE_GD_OPTIMIZER
        opti->SetNumberOfIterations(maxIters);
        opti->SetMinimumStepLength(1e-4);
        opti->SetMaximumStepLength(3);
        opti->SetRelaxationFactor(.5);
        opti->SetGradientMagnitudeTolerance(1e-4);
#endif

        opti->SetInitialPosition(_transform->GetParameters());
        opti->AddObserver(itk::StartEvent(), optiReporter);
        opti->AddObserver(itk::IterationEvent(), optiReporter);
        opti->StartOptimization();
        cout << "Current Cost: " << opti->GetValue() << endl;
        _transformResult = opti->GetCurrentPosition();
        _transform->SetParameters(opti->GetCurrentPosition());
    }
    void BSplineRegistration::GenerateData2( itk::Image<TPixel, VImageDimension>* itkImage1)
  {
    std::cout << "start bspline registration" << std::endl;
    
    // Typedefs
    typedef typename itk::Image< TPixel, VImageDimension >  InternalImageType;
       
    typedef typename itk::Vector< float, VImageDimension >    VectorPixelType;
    typedef typename itk::Image<  VectorPixelType, VImageDimension > DeformationFieldType;

    typedef itk::BSplineDeformableTransform<
                                double,
                                VImageDimension,
                                3 >                         TransformType;

    typedef typename TransformType::ParametersType          ParametersType;



    
    //typedef itk::LBFGSOptimizer                             OptimizerType;
    typedef itk::SingleValuedNonLinearOptimizer             OptimizerType;
    //typedef itk::SingleValuedCostFunction                   MetricType;

    typedef itk::MattesMutualInformationImageToImageMetric<
                                InternalImageType,
                                InternalImageType >           MetricType;

    typedef itk::MeanSquaresImageToImageMetric<
                                InternalImageType,
                                InternalImageType >           MetricTypeMS;

    typedef itk::LinearInterpolateImageFunction<
                                InternalImageType,
                                double >                    InterpolatorType;

    typedef itk::ImageRegistrationMethod<
                                InternalImageType,
                                InternalImageType >           RegistrationType;

    typedef typename itk::WarpImageFilter<
                            InternalImageType, 
                            InternalImageType,
                            DeformationFieldType  >         WarperType;

    typedef typename TransformType::SpacingType                      SpacingType;

    typedef typename TransformType::OriginType                       OriginType;

    typedef itk::ResampleImageFilter< 
                                InternalImageType, 
                                InternalImageType >            ResampleFilterType;

    typedef itk::Image< TPixel, VImageDimension >           OutputImageType;
  

    // Sample new image with the same image type as the fixed image
    typedef itk::CastImageFilter< 
                                InternalImageType,
                                InternalImageType >            CastFilterType;
                    
    
    typedef itk::Vector< float, VImageDimension >           VectorType;
    typedef itk::Image< VectorType, VImageDimension >       DeformationFieldType;


    typedef itk::BSplineDeformableTransformInitializer <
                                TransformType,
                                InternalImageType >            InitializerType;
    

    typename InterpolatorType::Pointer   interpolator  = InterpolatorType::New();
    typename RegistrationType::Pointer   registration  = RegistrationType::New();   
    typename InitializerType::Pointer    initializer   = InitializerType::New();
    typename TransformType::Pointer      transform     = TransformType::New();
    
    
    if(m_Metric==0 || m_Metric==1)
    {
      typename MetricType::Pointer metric = MetricType::New();
      metric->SetNumberOfHistogramBins( 32);
      metric->SetNumberOfSpatialSamples(90000);
      registration->SetMetric(          metric       );
    }
    else{
      typename MetricTypeMS::Pointer metric = MetricTypeMS::New();  
      registration->SetMetric(          metric       );
    }
     
    typename OptimizerFactory::Pointer optFac = OptimizerFactory::New();
    optFac->SetOptimizerParameters(m_OptimizerParameters);
    optFac->SetNumberOfTransformParameters(transform->GetNumberOfParameters());
    OptimizerType::Pointer optimizer = optFac->GetOptimizer();    

    optimizer->AddObserver(itk::AnyEvent(), m_Observer);
    
    //typedef mitk::MetricFactory <TPixel, VImageDimension> MetricFactoryType;
    //typename MetricFactoryType::Pointer metricFac = MetricFactoryType::New();
    //metricFac->SetMetricParameters(m_MetricParameters);
    ////MetricType::Pointer metric = metricFac->GetMetric();


    typename InternalImageType::Pointer fixedImage = InternalImageType::New();
    mitk::CastToItkImage(m_ReferenceImage, fixedImage);    
    typename InternalImageType::Pointer movingImage = itkImage1;
    typename InternalImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion();
    typename InternalImageType::RegionType movingRegion = movingImage->GetBufferedRegion();

    
    if(m_MatchHistograms)
    {
      typedef itk::RescaleIntensityImageFilter<InternalImageType,InternalImageType> FilterType;   
      typedef itk::HistogramMatchingImageFilter<InternalImageType,InternalImageType> HEFilterType;

      typename FilterType::Pointer inputRescaleFilter = FilterType::New();  
      typename FilterType::Pointer referenceRescaleFilter = FilterType::New();  

      referenceRescaleFilter->SetInput(fixedImage);
      inputRescaleFilter->SetInput(movingImage);

      TPixel desiredMinimum =  0;
      TPixel desiredMaximum =  255;
      
      referenceRescaleFilter->SetOutputMinimum( desiredMinimum );
      referenceRescaleFilter->SetOutputMaximum( desiredMaximum );
      referenceRescaleFilter->UpdateLargestPossibleRegion();  
      inputRescaleFilter->SetOutputMinimum( desiredMinimum );
      inputRescaleFilter->SetOutputMaximum( desiredMaximum );
      inputRescaleFilter->UpdateLargestPossibleRegion();

      // Histogram match the images
      typename HEFilterType::Pointer intensityEqualizeFilter = HEFilterType::New();

      intensityEqualizeFilter->SetReferenceImage( inputRescaleFilter->GetOutput() );
      intensityEqualizeFilter->SetInput( referenceRescaleFilter->GetOutput() );
      intensityEqualizeFilter->SetNumberOfHistogramLevels( 64 );
      intensityEqualizeFilter->SetNumberOfMatchPoints( 12 );
      intensityEqualizeFilter->ThresholdAtMeanIntensityOn();
      intensityEqualizeFilter->Update();

      //fixedImage = referenceRescaleFilter->GetOutput();
      //movingImage = IntensityEqualizeFilter->GetOutput();

      fixedImage = intensityEqualizeFilter->GetOutput();
      movingImage = inputRescaleFilter->GetOutput();
    }


    //
    registration->SetOptimizer(       optimizer     );
    registration->SetInterpolator(    interpolator  );  
    registration->SetFixedImage(      fixedImage    );
    registration->SetMovingImage(     movingImage   );    
    registration->SetFixedImageRegion(fixedRegion   );

    initializer->SetTransform(transform);
    initializer->SetImage(fixedImage);
    initializer->SetNumberOfGridNodesInsideTheImage( m_NumberOfGridPoints );
    initializer->InitializeTransform();

    registration->SetTransform( transform );    

    const unsigned int numberOfParameters = transform->GetNumberOfParameters();
    
    typename itk::BSplineDeformableTransform<
                                double,
                                VImageDimension,
                                3 >::ParametersType  parameters;

    parameters.set_size(numberOfParameters);
    parameters.Fill( 0.0 );
    transform->SetParameters( parameters );

    // We now pass the parameters of the current transform as the initial
    // parameters to be used when the registration process starts.
    registration->SetInitialTransformParameters( transform->GetParameters() );
    
    std::cout << "Intial Parameters = " << std::endl;
    std::cout << transform->GetParameters() << std::endl;
 

    std::cout << std::endl << "Starting Registration" << std::endl;

    try 
    { 
      double tstart(clock());     
      registration->StartRegistration();    
      double time = clock() - tstart;
      time = time / CLOCKS_PER_SEC;
      MITK_INFO << "Registration time: " << time;
    } 
    catch( itk::ExceptionObject & err ) 
    { 
      std::cerr << "ExceptionObject caught !" << std::endl; 
      std::cerr << err << std::endl;       
    } 
    
    typename OptimizerType::ParametersType finalParameters = 
                      registration->GetLastTransformParameters();

    std::cout << "Last Transform Parameters" << std::endl;
    std::cout << finalParameters << std::endl;

    transform->SetParameters( finalParameters );

/*
    ResampleFilterType::Pointer       resampler = ResampleFilterType::New();
    resampler->SetTransform(          transform );
    resampler->SetInput(              movingImage );
    resampler->SetSize(               fixedImage->GetLargestPossibleRegion().GetSize() );
    resampler->SetOutputOrigin(       fixedImage->GetOrigin() );
    resampler->SetOutputSpacing(      fixedImage->GetSpacing() );
    resampler->SetOutputDirection(    fixedImage->GetDirection() );
    resampler->SetDefaultPixelValue(  100 );
    resampler->SetInterpolator(       interpolator);
    resampler->Update();*/



    // Generate deformation field
    typename DeformationFieldType::Pointer field = DeformationFieldType::New();    
    field->SetRegions( movingRegion );
    field->SetOrigin( movingImage->GetOrigin() );
    field->SetSpacing( movingImage->GetSpacing() );
    field->SetDirection( movingImage->GetDirection() );   
    field->Allocate();


    typedef itk::ImageRegionIterator< DeformationFieldType > FieldIterator;
    FieldIterator fi( field, movingRegion );
    fi.GoToBegin();

    typename TransformType::InputPointType  fixedPoint;
    typename TransformType::OutputPointType movingPoint;
    typename DeformationFieldType::IndexType index;

    VectorType displacement;

    while( ! fi.IsAtEnd() )
    {
      index = fi.GetIndex();
      field->TransformIndexToPhysicalPoint( index, fixedPoint );
      movingPoint = transform->TransformPoint( fixedPoint );
      displacement = movingPoint - fixedPoint;
      fi.Set( displacement );
      ++fi;
    }


    // Use the deformation field to warp the moving image
    typename WarperType::Pointer warper = WarperType::New();    
    warper->SetInput( movingImage );
    warper->SetInterpolator( interpolator );
    warper->SetOutputSpacing( movingImage->GetSpacing() );
    warper->SetOutputOrigin( movingImage->GetOrigin() );
    warper->SetOutputDirection( movingImage->GetDirection() );
    warper->SetDeformationField( field );
    warper->Update();

    typename InternalImageType::Pointer result = warper->GetOutput();    

    if(m_UpdateInputImage)
    {   
      Image::Pointer outputImage = this->GetOutput();
      mitk::CastToMitkImage( result, outputImage );
    }


    // Save the deformationfield resulting from the registration    
    if(m_SaveDeformationField)
    {      
      typedef itk::ImageFileWriter< DeformationFieldType >  FieldWriterType;
      typename FieldWriterType::Pointer fieldWriter = FieldWriterType::New();

      fieldWriter->SetInput( field );
      
      fieldWriter->SetFileName( m_DeformationFileName );
      try
      {
        fieldWriter->Update();
      }
      catch( itk::ExceptionObject & excp )
      {
        std::cerr << "Exception thrown " << std::endl;
        std::cerr << excp << std::endl;
        //return EXIT_FAILURE;
      }
    }



  }
typename TImage::Pointer modelBasedImageToImageRegistration(std::string referenceFilename,
																					std::string targetFilename, 
																					typename TStatisticalModelType::Pointer model,
																					std::string outputDfFilename,
																					unsigned numberOfIterations){

	typedef itk::ImageFileReader<TImage> ImageReaderType;
	typedef itk::InterpolatingStatisticalDeformationModelTransform<TRepresenter, double, VImageDimension> TransformType;
	typedef itk::LBFGSOptimizer OptimizerType;
	typedef itk::ImageRegistrationMethod<TImage, TImage> RegistrationFilterType;
	typedef itk::WarpImageFilter< TImage, TImage, TVectorImage > WarperType;
	typedef itk::LinearInterpolateImageFunction< TImage, double > InterpolatorType;
	
	typename ImageReaderType::Pointer referenceReader = ImageReaderType::New();
	referenceReader->SetFileName(referenceFilename.c_str());
	referenceReader->Update();
	typename TImage::Pointer referenceImage = referenceReader->GetOutput();
	referenceImage->Update();

	typename ImageReaderType::Pointer targetReader = ImageReaderType::New();
	targetReader->SetFileName(targetFilename.c_str());
	targetReader->Update();
	typename TImage::Pointer targetImage = targetReader->GetOutput();
	targetImage->Update();

	// do the fitting
	typename TransformType::Pointer transform = TransformType::New();
	transform->SetStatisticalModel(model);
	transform->SetIdentity();

	// Setting up the fitting
	OptimizerType::Pointer optimizer = OptimizerType::New();
	optimizer->MinimizeOn();
	optimizer->SetMaximumNumberOfFunctionEvaluations(numberOfIterations);

	typedef  IterationStatusObserver ObserverType;
	ObserverType::Pointer observer = ObserverType::New();
	optimizer->AddObserver( itk::IterationEvent(), observer );

	typename TMetricType::Pointer metric = TMetricType::New();
	typename InterpolatorType::Pointer interpolator = InterpolatorType::New();

	typename RegistrationFilterType::Pointer registration = RegistrationFilterType::New();
	registration->SetInitialTransformParameters(transform->GetParameters());
	registration->SetMetric(metric);
	registration->SetOptimizer(   optimizer   );
	registration->SetTransform(   transform );
	registration->SetInterpolator( interpolator );
	registration->SetFixedImage( targetImage );
	registration->SetFixedImageRegion(targetImage->GetBufferedRegion() );
	registration->SetMovingImage( referenceImage );

	try {
		std::cout << "Performing registration... " << std::flush;
		registration->Update();
		std::cout << "[done]" << std::endl;

	} catch ( itk::ExceptionObject& o ) {
		std::cout << "caught exception " << o << std::endl;
	}

	typename TVectorImage::Pointer df = model->DrawSample(transform->GetCoefficients());

	// write deformation field
	if(outputDfFilename.size()>0){
		typename itk::ImageFileWriter<TVectorImage>::Pointer df_writer = itk::ImageFileWriter<TVectorImage>::New();
		df_writer->SetFileName(outputDfFilename);
		df_writer->SetInput(df);
		df_writer->Update();
	}

	
	// warp reference
	std::cout << "Warping reference... " << std::flush;
	typename WarperType::Pointer warper = WarperType::New();
	warper->SetInput(referenceImage  );
	warper->SetInterpolator( interpolator );
	warper->SetOutputSpacing( targetImage->GetSpacing() );
	warper->SetOutputOrigin( targetImage->GetOrigin() );
	warper->SetOutputDirection( targetImage->GetDirection() );
	warper->SetDisplacementField( df );
	warper->Update();
	std::cout << "[done]" << std::endl;

	return warper->GetOutput();
}