void MutualInformationRegistration::updateRegistration() {
    if(!isReady())
        return;

    convertVolumes();

    //typedef itk::RegularStepGradientDescentOptimizer OptimizerType;
    typedef itk::VersorRigid3DTransformOptimizer OptimizerType;
    typedef OptimizerType::ScalesType       OptimizerScalesType;
    typedef itk::LinearInterpolateImageFunction< InternalImageType, double             > InterpolatorType;
    typedef itk::MattesMutualInformationImageToImageMetric< InternalImageType, InternalImageType >   MetricType;
    typedef itk::MultiResolutionImageRegistrationMethod< InternalImageType, InternalImageType >   RegistrationType;

    typedef itk::MultiResolutionPyramidImageFilter< InternalImageType, InternalImageType >   FixedImagePyramidType;
    typedef itk::MultiResolutionPyramidImageFilter< InternalImageType, InternalImageType >   MovingImagePyramidType;

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

    FixedImagePyramidType::Pointer fixedImagePyramid = FixedImagePyramidType::New();
    MovingImagePyramidType::Pointer movingImagePyramid = MovingImagePyramidType::New();

    registration->SetOptimizer(optimizer);
    registration->SetTransform(transform_);
    registration->SetInterpolator(interpolator);
    registration->SetMetric(metric);
    registration->SetFixedImagePyramid(fixedImagePyramid);
    registration->SetMovingImagePyramid(movingImagePyramid);

    OptimizerScalesType optimizerScales( transform_->GetNumberOfParameters() );

    float rotScale = 1.0 / 1000.0f;
    optimizerScales[0] = 1.0f;
    optimizerScales[1] = 1.0f;
    optimizerScales[2] = 1.0f;
    optimizerScales[3] = rotScale;
    optimizerScales[4] = rotScale;
    optimizerScales[5] = rotScale;
    optimizer->SetScales( optimizerScales );
    optimizer->SetMaximumStepLength(0.2);
    optimizer->SetMinimumStepLength(0.0001);

    InternalImageType::Pointer fixed = voreenToITK<float>(fixedVolumeFloat_);
    InternalImageType::Pointer moving = voreenToITK<float>(movingVolumeFloat_);
    registration->SetFixedImage(fixed);
    registration->SetMovingImage(moving);
    registration->SetFixedImageRegion( fixed->GetBufferedRegion() );

    registration->SetInitialTransformParameters( transform_->GetParameters() );

    metric->SetNumberOfHistogramBins(numHistogramBins_.get());

    size_t numVoxels = hmul(fixedVolumeFloat_->getDimensions());
    metric->SetNumberOfSpatialSamples(numVoxels * numSamples_.get());

    metric->ReinitializeSeed( 76926294 );

    //// Define whether to calculate the metric derivative by explicitly
    //// computing the derivatives of the joint PDF with respect to the Transform
    //// parameters, or doing it by progressively accumulating contributions from
    //// each bin in the joint PDF.
    metric->SetUseExplicitPDFDerivatives(explicitPDF_.get());

    optimizer->SetNumberOfIterations(numIterations_.get());

    optimizer->SetRelaxationFactor(relaxationFactor_.get());

    // Create the Command observer and register it with the optimizer.
    CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New();
    optimizer->AddObserver( itk::IterationEvent(), observer );

    typedef RegistrationInterfaceCommand<RegistrationType> CommandType;
    CommandType::Pointer command = CommandType::New();
    registration->AddObserver( itk::IterationEvent(), command );

    registration->SetNumberOfLevels(numLevels_.get());

    try
    {
        registration->StartRegistration();
        std::cout << "Optimizer stop condition: " << registration->GetOptimizer()->GetStopConditionDescription() << std::endl;
    }
    catch( itk::ExceptionObject & err )
    {
        std::cout << "ExceptionObject caught !" << std::endl;
        std::cout << err << std::endl;
        //return EXIT_FAILURE;
    }

    ParametersType finalParameters = registration->GetLastTransformParameters();
    transform_->SetParameters(finalParameters);

    unsigned int numberOfIterations = optimizer->GetCurrentIteration();

    double bestValue = optimizer->GetValue();

    // Print out results
    std::cout << "Result = " << std::endl;
    std::cout << " Versor " << finalParameters[0] << " " << finalParameters[1] << " " << finalParameters[2] << std::endl;
    std::cout << " Translation " << finalParameters[1] << " " << finalParameters[4] << " " << finalParameters[5] << std::endl;
    std::cout << " Iterations    = " << numberOfIterations << std::endl;
    std::cout << " Metric value  = " << bestValue          << std::endl;

    invalidate(INVALID_RESULT);
}
    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();
}