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();
}
Example #2
0
void SampleGradHistogram(double *pt, double radius, typename TImage::Pointer image, arma::ivec& samples)
{
    typedef TImage ImageType;

    int radius_pix[3]; //radius in voxels, to be calculated


    radius_pix[0] = std::ceil(radius / image->GetSpacing()[0]);
    radius_pix[1] = std::ceil(radius / image->GetSpacing()[1]);
    radius_pix[2] = std::ceil(radius / image->GetSpacing()[2]);
    
#ifdef DEBUG_MESSAGES_HOG
    std::cout << "Requested point: " << pt[0] << ", " << pt[1] << ", " << pt[2] << std::endl;
    std::cout << "Neighborhood size in mm: " << radius << std::endl;
    std::cout << "Neighborhood size in pix: " << radius_pix[0] << ", " << radius_pix[1] << ", " << radius_pix[2] << std::endl;
#endif
    
    if (radius_pix[0] == 0 || radius_pix[1] == 0 || radius_pix[2] == 0) {
        std::cout << "One of the neighborhood dimensions is zero. Please correct the radius. Aborting." << std::endl;
        return;
    }


    //transform the point from physical s1pace
    typename ImageType::PointType point;
    point[0] = pt[0];
    point[1] = pt[1];
    point[2] = pt[2];

    typename ImageType::IndexType pt_pix;
    image->TransformPhysicalPointToIndex(point, pt_pix);


    //define the region around the point of interest
    typename ImageType::IndexType rgn_idx = {
        {pt_pix[0] - radius_pix[0], pt_pix[1] - radius_pix[1], pt_pix[2] - radius_pix[2]}};
    typename ImageType::SizeType rgn_size = {
        {2 * radius_pix[0] + 1, 2 * radius_pix[1] + 1, 2 * radius_pix[2] + 1}};

    //crop the region so that it is inside
    rgn_idx[0] = std::max(rgn_idx[0], image->GetLargestPossibleRegion().GetIndex(0));
    rgn_idx[1] = std::max(rgn_idx[1], image->GetLargestPossibleRegion().GetIndex(1));
    rgn_idx[2] = std::max(rgn_idx[2], image->GetLargestPossibleRegion().GetIndex(2));

    //set it first as a corner for comparison and then undo that operation
    rgn_size[0] = std::min(rgn_size[0]+rgn_idx[0], image->GetLargestPossibleRegion().GetSize(0))-rgn_idx[0];
    rgn_size[1] = std::min(rgn_size[1]+rgn_idx[1], image->GetLargestPossibleRegion().GetSize(1))-rgn_idx[1];
    rgn_size[2] = std::min(rgn_size[2]+rgn_idx[2], image->GetLargestPossibleRegion().GetSize(2))-rgn_idx[2];

    typename ImageType::RegionType window(rgn_idx, rgn_size);

#ifdef DEBUG_MESSAGES_HOG
    std::cout << "Region: " << window << std::endl;
#endif

    samples.set_size(rgn_size[0]*rgn_size[1]*rgn_size[2]);
    samples.zeros();
    
//    itk::ImageRegionConstIterator<typename GradientFilterType::OutputImageType> imageIterator(gradient_filter->GetOutput(), window);
    itk::ImageRegionConstIterator<ImageType> imageIterator(image, window);
    imageIterator.GoToBegin();
    
    int i=0;
    while (!imageIterator.IsAtEnd()) {
        // Get the value of the current pixel
        typename ImageType::PixelType val = imageIterator.Get();
    
        //std::cout << val << std::endl;
            
        samples[i++] = val;
        
        ++imageIterator;
    }

    
       
}
void SampleStatistics(double *pt, double radius, typename TImage::Pointer image, arma::vec& features)
{
    features.set_size(4); //just four features for now
    features.zeros();
    
    
    
    typedef TImage ImageType;

    int radius_pix[3]; //radius in voxels, to be calculated


    radius_pix[0] = std::ceil(radius / image->GetSpacing()[0]);
    radius_pix[1] = std::ceil(radius / image->GetSpacing()[1]);
    radius_pix[2] = std::ceil(radius / image->GetSpacing()[2]);
    
#ifdef DEBUG_MESSAGES_HOG
    std::cout << "Requested point: " << pt[0] << ", " << pt[1] << ", " << pt[2] << std::endl;
    std::cout << "Neighborhood size in mm: " << radius << std::endl;
    std::cout << "Neighborhood size in pix: " << radius_pix[0] << ", " << radius_pix[1] << ", " << radius_pix[2] << std::endl;
#endif
    
    if (radius_pix[0] == 0 || radius_pix[1] == 0 || radius_pix[2] == 0) {
        std::cout << "One of the neighborhood dimensions is zero. Please correct the radius. Aborting." << std::endl;
        return;
    }


    //transform the point from physical s1pace
    typename ImageType::PointType point;
    point[0] = pt[0];
    point[1] = pt[1];
    point[2] = pt[2];

    typename ImageType::IndexType pt_pix;
    image->TransformPhysicalPointToIndex(point, pt_pix);


    //define the region around the point of interest
    typename ImageType::IndexType rgn_idx = {
        {pt_pix[0] - radius_pix[0], pt_pix[1] - radius_pix[1], pt_pix[2] - radius_pix[2]}};
    typename ImageType::SizeType rgn_size = {
        {2 * radius_pix[0] + 1, 2 * radius_pix[1] + 1, 2 * radius_pix[2] + 1}};

    //crop the region so that it is inside
    rgn_idx[0] = std::max(rgn_idx[0], image->GetLargestPossibleRegion().GetIndex(0));
    rgn_idx[1] = std::max(rgn_idx[1], image->GetLargestPossibleRegion().GetIndex(1));
    rgn_idx[2] = std::max(rgn_idx[2], image->GetLargestPossibleRegion().GetIndex(2));

    //set it first as a corner for comparison and then undo that operation
    rgn_size[0] = std::min(rgn_size[0]+rgn_idx[0], image->GetLargestPossibleRegion().GetSize(0))-rgn_idx[0];
    rgn_size[1] = std::min(rgn_size[1]+rgn_idx[1], image->GetLargestPossibleRegion().GetSize(1))-rgn_idx[1];
    rgn_size[2] = std::min(rgn_size[2]+rgn_idx[2], image->GetLargestPossibleRegion().GetSize(2))-rgn_idx[2];

    typename ImageType::RegionType window(rgn_idx, rgn_size);

#ifdef DEBUG_MESSAGES_HOG
    std::cout << "Region: " << window << std::endl;
#endif

    
    itk::ImageRegionConstIterator<ImageType> imageIterator(image, window);
    imageIterator.GoToBegin();

    const int nvoxels = rgn_size[0]*rgn_size[1]*rgn_size[2];
    arma::vec voxels;
    voxels.set_size(nvoxels);
    voxels.zeros();
    
    

    long int i=0;
    while (!imageIterator.IsAtEnd()) {
        // Get the value of the current pixel
        typename ImageType::PixelType val = imageIterator.Get();
    
        //std::cout << val << std::endl;
            

        voxels[i++] = val;
        ++imageIterator;
    }

    //do the statistics

    const double mean = arma::mean(voxels);
    const double std = arma::stddev(voxels);
    
    double E3 = 0; //Accumulate expectation of (X-u)^3
    double E4 = 0; //Accumulate expectation of (X-u)^4
    
    for(int i=0; i<voxels.size(); i++)
    {
        const double diff = voxels[i] - mean;
        const double k = diff*diff*diff/nvoxels;
        E3 += k; //cubed
        E4 += diff*k; //4th power       
    }
       
    features[0] = mean;
    features[1] = std;
    features[2] = E3/(std*std*std); //skewness
    features[3] = E3/(std*std*std*std); //kurtosis
}