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