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