Example #1
0
    RealImage::Pointer bsplineRegistration(RealImage::Pointer srcImg, RealImage::Pointer dstImg) {

        const unsigned int SpaceDimension = ImageDimension;
        const unsigned int SplineOrder = 3;
        typedef double CoordinateRepType;

        typedef itk::BSplineTransform<CoordinateRepType, SpaceDimension, SplineOrder> TransformType;
        typedef itk::LBFGSOptimizer OptimizerType;
        typedef itk::MeanSquaresImageToImageMetric<ImageType, ImageType> MetricType;
        typedef itk::LinearInterpolateImageFunction<ImageType, double> InterpolatorType;
        typedef itk::ImageRegistrationMethod<ImageType, ImageType> RegistrationType;

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



        // The old registration framework has problems with multi-threading
        // For now, we set the number of threads to 1
//        registration->SetNumberOfThreads(1);
        registration->SetMetric(        metric        );
        registration->SetOptimizer(     optimizer     );
        registration->SetInterpolator(  interpolator  );

        TransformType::Pointer  transform = TransformType::New();
        registration->SetTransform( transform );

        // Setup the registration
        registration->SetFixedImage(  dstImg   );
        registration->SetMovingImage(   srcImg);

        ImageType::RegionType fixedRegion = srcImg->GetBufferedRegion();
        registration->SetFixedImageRegion( fixedRegion );

        //  Here we define the parameters of the BSplineDeformableTransform grid.  We
        //  arbitrarily decide to use a grid with $5 \times 5$ nodes within the image.
        //  The reader should note that the BSpline computation requires a
        //  finite support region ( 1 grid node at the lower borders and 2
        //  grid nodes at upper borders). Therefore in this example, we set
        //  the grid size to be $8 \times 8$ and place the grid origin such that
        //  grid node (1,1) coincides with the first pixel in the fixed image.

        TransformType::PhysicalDimensionsType   fixedPhysicalDimensions;
        TransformType::MeshSizeType             meshSize;
        for (unsigned int i=0; i < ImageDimension; i++) {
            fixedPhysicalDimensions[i] = dstImg->GetSpacing()[i] *
            static_cast<double>(dstImg->GetLargestPossibleRegion().GetSize()[i] - 1 );
            meshSize[i] = dstImg->GetLargestPossibleRegion().GetSize()[i] / 8 - SplineOrder;
        }
//        unsigned int numberOfGridNodesInOneDimension = 15;
//        meshSize.Fill( numberOfGridNodesInOneDimension - SplineOrder );
        transform->SetTransformDomainOrigin( dstImg->GetOrigin() );
        transform->SetTransformDomainPhysicalDimensions( fixedPhysicalDimensions );
        transform->SetTransformDomainMeshSize( meshSize );
        transform->SetTransformDomainDirection( dstImg->GetDirection() );

        typedef TransformType::ParametersType     ParametersType;

        const unsigned int numberOfParameters = transform->GetNumberOfParameters();

        ParametersType parameters( 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;

        //  Next we set the parameters of the LBFGS Optimizer.
        optimizer->SetGradientConvergenceTolerance(0.1);
        optimizer->SetLineSearchAccuracy(0.09);
        optimizer->SetDefaultStepLength(.1);
        optimizer->TraceOn();
        optimizer->SetMaximumNumberOfFunctionEvaluations(1000);

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

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

        OptimizerType::ParametersType finalParameters =
        registration->GetLastTransformParameters();
        
        std::cout << "Last Transform Parameters" << std::endl;
        std::cout << finalParameters << std::endl;
        
        transform->SetParameters( finalParameters );
        
        typedef itk::ResampleImageFilter<ImageType, ImageType>    ResampleFilterType;
        
        ResampleFilterType::Pointer resample = ResampleFilterType::New();
        
        resample->SetTransform( transform );
        resample->SetInput( srcImg );
        
        resample->SetSize(    dstImg->GetLargestPossibleRegion().GetSize() );
        resample->SetOutputOrigin(  dstImg->GetOrigin() );
        resample->SetOutputSpacing( dstImg->GetSpacing() );
        resample->SetOutputDirection( dstImg->GetDirection() );
        resample->SetDefaultPixelValue( 100 );
        resample->Update();
        return resample->GetOutput();
    }
Example #2
0
// perform B-spline registration for 2D image
void runBspline2D(StringVector& args) {
    typedef itk::BSplineTransform<double, 2, 3> TransformType;
    typedef itk::LBFGSOptimizer OptimizerType;
    typedef itk::MeanSquaresImageToImageMetric<RealImage2, RealImage2> MetricType;
    typedef itk:: LinearInterpolateImageFunction<RealImage2, double> InterpolatorType;
    typedef itk::ImageRegistrationMethod<RealImage2, RealImage2> RegistrationType;

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

    // The old registration framework has problems with multi-threading
    // For now, we set the number of threads to 1
    registration->SetNumberOfThreads(1);

    registration->SetMetric(        metric        );
    registration->SetOptimizer(     optimizer     );
    registration->SetInterpolator(  interpolator  );

    TransformType::Pointer  transform = TransformType::New();
    registration->SetTransform( transform );


    ImageIO<RealImage2> io;

    // Create the synthetic images
    RealImage2::Pointer  fixedImage  = io.ReadImage(args[0]);
    RealImage2::Pointer  movingImage  = io.ReadImage(args[1]);

    // Setup the registration
    registration->SetFixedImage(  fixedImage   );
    registration->SetMovingImage(   movingImage);

    RealImage2::RegionType fixedRegion = fixedImage->GetBufferedRegion();
    registration->SetFixedImageRegion( fixedRegion );

    TransformType::PhysicalDimensionsType   fixedPhysicalDimensions;
    TransformType::MeshSizeType             meshSize;
    for( unsigned int i=0; i < 2; i++ )
    {
        fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] *
        static_cast<double>(
                            fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 );
    }
    unsigned int numberOfGridNodesInOneDimension = 18;
    meshSize.Fill( numberOfGridNodesInOneDimension - 3 );
    transform->SetTransformDomainOrigin( fixedImage->GetOrigin() );
    transform->SetTransformDomainPhysicalDimensions( fixedPhysicalDimensions );
    transform->SetTransformDomainMeshSize( meshSize );
    transform->SetTransformDomainDirection( fixedImage->GetDirection() );

    typedef TransformType::ParametersType     ParametersType;

    const unsigned int numberOfParameters =
    transform->GetNumberOfParameters();

    ParametersType parameters( 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;

    //  Next we set the parameters of the LBFGS Optimizer.

    optimizer->SetGradientConvergenceTolerance( 0.005 );
    optimizer->SetLineSearchAccuracy( 0.9 );
    optimizer->SetDefaultStepLength( .1 );
    optimizer->TraceOn();
    optimizer->SetMaximumNumberOfFunctionEvaluations( 1000 );

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

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

    OptimizerType::ParametersType finalParameters =
    registration->GetLastTransformParameters();

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

    transform->SetParameters( finalParameters );

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

    ResampleFilterType::Pointer resample = ResampleFilterType::New();

    resample->SetTransform( transform );
    resample->SetInput( movingImage );

    resample->SetSize(    fixedImage->GetLargestPossibleRegion().GetSize() );
    resample->SetOutputOrigin(  fixedImage->GetOrigin() );
    resample->SetOutputSpacing( fixedImage->GetSpacing() );
    resample->SetOutputDirection( fixedImage->GetDirection() );
    resample->SetDefaultPixelValue( 100 );
    resample->Update();

    io.WriteImage(args[2], resample->GetOutput());
}
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();
}