void ImageCastToItkAndBack_SamePointer_Success()
  {
    typedef itk::Image<short, 3> ItkImageType;
    ItkImageType::Pointer itkImage = ItkImageType::New();

    std::string m_ImagePath = GetTestDataFilePath("Pic3D.nrrd");
    mitk::Image::Pointer testDataImage = mitk::IOUtil::LoadImage(m_ImagePath);

    // modify ITK image
    itk::Matrix<double, 3, 3> dir = itkImage->GetDirection();
    dir *= 2;
    itkImage->SetDirection(dir);

    CPPUNIT_ASSERT_THROW_MESSAGE("No exception thrown for casting back the same memory",
                                 testDataImage = mitk::GrabItkImageMemory(itkImage, testDataImage),
                                 itk::ExceptionObject);
    CPPUNIT_ASSERT(testDataImage.IsNotNull());
  }
void mitk::RegistrationWrapper::ApplyTransformationToImage(mitk::Image::Pointer img, const mitk::RegistrationWrapper::RidgidTransformType &transformation,double* offset, mitk::Image* resampleReference,  bool binary)
{
  typedef mitk::DiffusionImage<short> DiffusionImageType;

  if (dynamic_cast<DiffusionImageType*> (img.GetPointer()) == NULL)
  {

    ItkImageType::Pointer itkImage = ItkImageType::New();


    MITK_ERROR << "imgCopy  0 " <<  "/" << img->GetReferenceCount();
    MITK_ERROR << "pixel type  " << img->GetPixelType().GetComponentTypeAsString();

    CastToItkImage(img, itkImage);



    typedef itk::Euler3DTransform< double > RigidTransformType;
    RigidTransformType::Pointer rtransform = RigidTransformType::New();
    RigidTransformType::ParametersType parameters(RigidTransformType::ParametersDimension);

    for (int i = 0; i<6;++i)
      parameters[i] = transformation[i];

    rtransform->SetParameters( parameters );

    mitk::Point3D origin = itkImage->GetOrigin();
    origin[0]-=offset[0];
    origin[1]-=offset[1];
    origin[2]-=offset[2];

    mitk::Point3D newOrigin = rtransform->GetInverseTransform()->TransformPoint(origin);

    itk::Matrix<double,3,3> dir = itkImage->GetDirection();
    itk::Matrix<double,3,3> transM  ( vnl_inverse(rtransform->GetMatrix().GetVnlMatrix()));
    itk::Matrix<double,3,3> newDirection = transM * dir;

    itkImage->SetOrigin(newOrigin);
    itkImage->SetDirection(newDirection);

    // Perform Resampling if reference image is provided
    if (resampleReference != NULL)
    {
      typedef itk::ResampleImageFilter<ItkImageType, ItkImageType>  ResampleFilterType;

      ItkImageType::Pointer itkReference = ItkImageType::New();
      CastToItkImage(resampleReference,itkReference);

      typedef itk::WindowedSincInterpolateImageFunction< ItkImageType, 3> WindowedSincInterpolatorType;
      WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New();

      typedef itk::NearestNeighborInterpolateImageFunction< ItkImageType, double > NearestNeighborInterpolatorType;
      NearestNeighborInterpolatorType::Pointer nn_interpolator = NearestNeighborInterpolatorType::New();


      ResampleFilterType::Pointer resampler = ResampleFilterType::New();
      resampler->SetInput(itkImage);
      resampler->SetReferenceImage( itkReference );
      resampler->UseReferenceImageOn();
      if (binary)
        resampler->SetInterpolator(nn_interpolator);
      else
        resampler->SetInterpolator(sinc_interpolator);

      resampler->Update();

      GrabItkImageMemory(resampler->GetOutput(), img);
    }
    else
    {
      // !! CastToItk behaves very differently depending on the original data type
      // if the target type is the same as the original, only a pointer to the data is set
      // and an additional GrabItkImageMemory will cause a segfault when the image is destroyed
      // GrabItkImageMemory - is not necessary in this case since we worked on the original data
      // See Bug 17538.
      if (img->GetPixelType().GetComponentTypeAsString() != "double")
        img = GrabItkImageMemory(itkImage);
    }
  }
  else
  {
    DiffusionImageType::Pointer diffImages = dynamic_cast<DiffusionImageType*>(img.GetPointer());

    typedef itk::Euler3DTransform< double > RigidTransformType;
    RigidTransformType::Pointer rtransform = RigidTransformType::New();
    RigidTransformType::ParametersType parameters(RigidTransformType::ParametersDimension);

    for (int i = 0; i<6;++i)
    {
      parameters[i] = transformation[i];
    }

    rtransform->SetParameters( parameters );

    mitk::Point3D b0origin = diffImages->GetVectorImage()->GetOrigin();
    b0origin[0]-=offset[0];
    b0origin[1]-=offset[1];
    b0origin[2]-=offset[2];

    mitk::Point3D newOrigin = rtransform->GetInverseTransform()->TransformPoint(b0origin);

    itk::Matrix<double,3,3> dir = diffImages->GetVectorImage()->GetDirection();
    itk::Matrix<double,3,3> transM  ( vnl_inverse(rtransform->GetMatrix().GetVnlMatrix()));
    itk::Matrix<double,3,3> newDirection = transM * dir;

    diffImages->GetVectorImage()->SetOrigin(newOrigin);
    diffImages->GetVectorImage()->SetDirection(newDirection);
    diffImages->Modified();

    mitk::DiffusionImageCorrectionFilter<short>::Pointer correctionFilter = mitk::DiffusionImageCorrectionFilter<short>::New();

    // For Diff. Images: Need to rotate the gradients (works in-place)
    correctionFilter->SetImage(diffImages);
    correctionFilter->CorrectDirections(transM.GetVnlMatrix());
    img = diffImages;
  }
}
Example #3
0
/*!
* \brief Command line interface to Fiberfox.
* Simulate a diffusion-weighted image from a tractogram using the specified parameter file.
*/
int main(int argc, char* argv[])
{
  mitkCommandLineParser parser;
  parser.setTitle("Fiberfox");
  parser.setCategory("Diffusion Simulation Tools");
  parser.setContributor("MIC");
  parser.setDescription("Command line interface to Fiberfox." " Simulate a diffusion-weighted image from a tractogram using the specified parameter file.");
  parser.setArgumentPrefix("--", "-");
  parser.addArgument("", "o", mitkCommandLineParser::String, "Output root:", "output folder and file prefix", us::Any(), false, false, false, mitkCommandLineParser::Output);
  parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input tractogram or diffusion-weighted image", us::Any(), false, false, false, mitkCommandLineParser::Input);
  parser.addArgument("parameters", "p", mitkCommandLineParser::String, "Parameter file:", "fiberfox parameter file (.ffp)", us::Any(), false, false, false, mitkCommandLineParser::Input);
  parser.addArgument("template", "t", mitkCommandLineParser::String, "Template image:", "use parameters of the template image", us::Any(), true, false, false, mitkCommandLineParser::Input);
  parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Output additional images:", "output volume fraction images etc.", us::Any());
  parser.addArgument("dont_apply_direction_matrix", "", mitkCommandLineParser::Bool, "Don't apply direction matrix:", "don't rotate gradients by image direction matrix", us::Any());
  parser.addArgument("fix_seed", "", mitkCommandLineParser::Bool, "Use fix random seed:", "always use same sequence of random numbers", us::Any());

  std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
  if (parsedArgs.size()==0)
  {
    return EXIT_FAILURE;
  }
  std::string outName = us::any_cast<std::string>(parsedArgs["o"]);
  std::string paramName = us::any_cast<std::string>(parsedArgs["parameters"]);

  std::string input="";
  if (parsedArgs.count("i"))
    input = us::any_cast<std::string>(parsedArgs["i"]);

  bool fix_seed = false;
  if (parsedArgs.count("fix_seed"))
    fix_seed = us::any_cast<bool>(parsedArgs["fix_seed"]);

  bool verbose = false;
  if (parsedArgs.count("verbose"))
    verbose = us::any_cast<bool>(parsedArgs["verbose"]);

  bool apply_direction_matrix = true;
  if (parsedArgs.count("dont_apply_direction_matrix"))
    apply_direction_matrix = false;

  FiberfoxParameters parameters;
  parameters.LoadParameters(paramName, fix_seed);

  // Test if /path/dir is an existing directory:
  std::string file_extension = "";
  if( itksys::SystemTools::FileIsDirectory( outName ) )
  {
    while( *(--(outName.cend())) == '/')
    {
      outName.pop_back();
    }
    outName = outName + '/';
    parameters.m_Misc.m_OutputPath = outName;
    outName = outName + parameters.m_Misc.m_OutputPrefix; // using default m_OutputPrefix as initialized.
  }
  else
  {
    // outName is NOT an existing directory, so we need to remove all trailing slashes:
    while( *(--(outName.cend())) == '/')
    {
      outName.pop_back();
    }

    // now split up the given outName into directory and (prefix of) filename:
    if( ! itksys::SystemTools::GetFilenamePath( outName ).empty()
        && itksys::SystemTools::FileIsDirectory(itksys::SystemTools::GetFilenamePath( outName ) ) )
    {
      parameters.m_Misc.m_OutputPath = itksys::SystemTools::GetFilenamePath( outName ) + '/';
    }
    else
    {
      parameters.m_Misc.m_OutputPath = itksys::SystemTools::GetCurrentWorkingDirectory() + '/';
    }

    file_extension = itksys::SystemTools::GetFilenameExtension(outName);
    if( ! itksys::SystemTools::GetFilenameWithoutExtension( outName ).empty() )
    {
      parameters.m_Misc.m_OutputPrefix = itksys::SystemTools::GetFilenameWithoutExtension( outName );
    }
    else
    {
      parameters.m_Misc.m_OutputPrefix = "fiberfox";
    }

    outName = parameters.m_Misc.m_OutputPath + parameters.m_Misc.m_OutputPrefix;
  }

  mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images", "Fiberbundles"}, {});
  mitk::BaseData::Pointer inputData = mitk::IOUtil::Load(input, &functor)[0];

  itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New();

  if ( dynamic_cast<mitk::FiberBundle*>(inputData.GetPointer()) )   // simulate dataset from fibers
  {
    tractsToDwiFilter->SetFiberBundle(dynamic_cast<mitk::FiberBundle*>(inputData.GetPointer()));

    if (parsedArgs.count("template"))
    {
      MITK_INFO << "Loading template image";
      typedef itk::VectorImage< short, 3 >    ItkDwiType;
      typedef itk::Image< short, 3 >    ItkImageType;
      mitk::BaseData::Pointer templateData = mitk::IOUtil::Load(us::any_cast<std::string>(parsedArgs["template"]), &functor)[0];
      mitk::Image::Pointer template_image = dynamic_cast<mitk::Image*>(templateData.GetPointer());

      if (mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(template_image))
      {
        ItkDwiType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(template_image);
        parameters.m_SignalGen.m_ImageRegion = itkVectorImagePointer->GetLargestPossibleRegion();
        parameters.m_SignalGen.m_ImageSpacing = itkVectorImagePointer->GetSpacing();
        parameters.m_SignalGen.m_ImageOrigin = itkVectorImagePointer->GetOrigin();
        parameters.m_SignalGen.m_ImageDirection = itkVectorImagePointer->GetDirection();
        parameters.SetBvalue(mitk::DiffusionPropertyHelper::GetReferenceBValue(template_image));
        parameters.SetGradienDirections(mitk::DiffusionPropertyHelper::GetOriginalGradientContainer(template_image));
      }
      else
      {
        ItkImageType::Pointer itkImagePointer = ItkImageType::New();
        mitk::CastToItkImage(template_image, itkImagePointer);
        parameters.m_SignalGen.m_ImageRegion = itkImagePointer->GetLargestPossibleRegion();
        parameters.m_SignalGen.m_ImageSpacing = itkImagePointer->GetSpacing();
        parameters.m_SignalGen.m_ImageOrigin = itkImagePointer->GetOrigin();
        parameters.m_SignalGen.m_ImageDirection = itkImagePointer->GetDirection();
      }
    }
  }
  else if ( dynamic_cast<mitk::Image*>(inputData.GetPointer()) )  // add artifacts to existing image
  {
    typedef itk::VectorImage< short, 3 >    ItkDwiType;
    mitk::Image::Pointer diffImg = dynamic_cast<mitk::Image*>(inputData.GetPointer());
    ItkDwiType::Pointer itkVectorImagePointer = ItkDwiType::New();
    mitk::CastToItkImage(diffImg, itkVectorImagePointer);

    parameters.m_SignalGen.m_SignalScale = 1;
    parameters.m_SignalGen.m_ImageRegion = itkVectorImagePointer->GetLargestPossibleRegion();
    parameters.m_SignalGen.m_ImageSpacing = itkVectorImagePointer->GetSpacing();
    parameters.m_SignalGen.m_ImageOrigin = itkVectorImagePointer->GetOrigin();
    parameters.m_SignalGen.m_ImageDirection = itkVectorImagePointer->GetDirection();
    parameters.SetBvalue(mitk::DiffusionPropertyHelper::GetReferenceBValue(diffImg));
    parameters.SetGradienDirections(mitk::DiffusionPropertyHelper::GetOriginalGradientContainer(diffImg));

    tractsToDwiFilter->SetInputImage(itkVectorImagePointer);
  }

  if (verbose)
  {
    MITK_DEBUG << outName << ".ffp";
    parameters.m_Misc.m_OutputAdditionalImages = true;
    parameters.SaveParameters(outName+".ffp");
  }
  else
    parameters.m_Misc.m_OutputAdditionalImages = false;
  
  if (apply_direction_matrix)
  {
    MITK_INFO << "Applying direction matrix to gradient directions.";
    parameters.ApplyDirectionMatrix();
  }
  tractsToDwiFilter->SetParameters(parameters);
  tractsToDwiFilter->SetUseConstantRandSeed(fix_seed);
  tractsToDwiFilter->Update();

  mitk::Image::Pointer image = mitk::GrabItkImageMemory(tractsToDwiFilter->GetOutput());

  if (parameters.m_SignalGen.GetNumWeightedVolumes()>0)
  {
    if (apply_direction_matrix)
      mitk::DiffusionPropertyHelper::SetGradientContainer(image, parameters.m_SignalGen.GetItkGradientContainer());
    else
      mitk::DiffusionPropertyHelper::SetOriginalGradientContainer(image, parameters.m_SignalGen.GetItkGradientContainer());
    mitk::DiffusionPropertyHelper::SetReferenceBValue(image, parameters.m_SignalGen.GetBvalue());
    mitk::DiffusionPropertyHelper::InitializeImage(image);

    if (file_extension=="")
      mitk::IOUtil::Save(image, "DWI_NIFTI", outName+".nii.gz");
    else if (file_extension==".nii" || file_extension==".nii.gz")
      mitk::IOUtil::Save(image, "DWI_NIFTI", outName+file_extension);
    else
      mitk::IOUtil::Save(image, outName+file_extension);
  }
  else
    mitk::IOUtil::Save(image, outName+".nii.gz");

  if (verbose)
  {
    if (tractsToDwiFilter->GetTickImage().IsNotNull())
    {
      mitk::Image::Pointer mitkImage = mitk::Image::New();
      itk::TractsToDWIImageFilter< short >::Float2DImageType::Pointer itkImage = tractsToDwiFilter->GetTickImage();
      mitkImage = mitk::GrabItkImageMemory( itkImage.GetPointer() );
      mitk::IOUtil::Save(mitkImage, outName+"_Ticks.nii.gz");
    }

    if (tractsToDwiFilter->GetRfImage().IsNotNull())
    {
      mitk::Image::Pointer mitkImage = mitk::Image::New();
      itk::TractsToDWIImageFilter< short >::Float2DImageType::Pointer itkImage = tractsToDwiFilter->GetRfImage();
      mitkImage = mitk::GrabItkImageMemory( itkImage.GetPointer() );
      mitk::IOUtil::Save(mitkImage, outName+"_TimeFromRf.nii.gz");
    }

    std::vector< itk::TractsToDWIImageFilter< short >::ItkDoubleImgType::Pointer > volumeFractions = tractsToDwiFilter->GetVolumeFractions();
    for (unsigned int k=0; k<volumeFractions.size(); k++)
    {
      mitk::Image::Pointer image = mitk::Image::New();
      image->InitializeByItk(volumeFractions.at(k).GetPointer());
      image->SetVolume(volumeFractions.at(k)->GetBufferPointer());
      mitk::IOUtil::Save(image, outName+"_Compartment"+boost::lexical_cast<std::string>(k+1)+".nii.gz");
    }

    if (tractsToDwiFilter->GetPhaseImage().IsNotNull())
    {
      mitk::Image::Pointer image = mitk::Image::New();
      itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer itkPhase = tractsToDwiFilter->GetPhaseImage();
      image = mitk::GrabItkImageMemory( itkPhase.GetPointer() );
      mitk::IOUtil::Save(image, outName+"_Phase.nii.gz");
    }

    if (tractsToDwiFilter->GetKspaceImage().IsNotNull())
    {
      mitk::Image::Pointer image = mitk::Image::New();
      itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer itkImage = tractsToDwiFilter->GetKspaceImage();
      image = mitk::GrabItkImageMemory( itkImage.GetPointer() );
      mitk::IOUtil::Save(image, outName+"_kSpace.nii.gz");
    }

    int c = 1;
    std::vector< itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer > output_real = tractsToDwiFilter->GetOutputImagesReal();
    for (auto real : output_real)
    {
      mitk::Image::Pointer image = mitk::Image::New();
      image->InitializeByItk(real.GetPointer());
      image->SetVolume(real->GetBufferPointer());
      mitk::IOUtil::Save(image, outName+"_Coil-"+boost::lexical_cast<std::string>(c)+"-real.nii.gz");
      ++c;
    }

    c = 1;
    std::vector< itk::TractsToDWIImageFilter< short >::DoubleDwiType::Pointer > output_imag = tractsToDwiFilter->GetOutputImagesImag();
    for (auto imag : output_imag)
    {
      mitk::Image::Pointer image = mitk::Image::New();
      image->InitializeByItk(imag.GetPointer());
      image->SetVolume(imag->GetBufferPointer());
      mitk::IOUtil::Save(image, outName+"_Coil-"+boost::lexical_cast<std::string>(c)+"-imag.nii.gz");
      ++c;
    }
  }

  return EXIT_SUCCESS;
}
void mitk::ConnectomicsNetworkCreator::CalculateCenterOfMass()
{
  const int dimensions = 3;
  typedef itk::Image<int, dimensions > ITKImageType;

  ITKImageType::Pointer itkImage = ITKImageType::New();
  mitk::CastToItkImage( m_Segmentation, itkImage );

  int max = m_Segmentation->GetStatistics()->GetScalarValueMax();
  int min = m_Segmentation->GetStatistics()->GetScalarValueMin();

  int range = max - min +1;

  // each label owns a vector of coordinates
  std::vector< std::vector< std::vector< double> > > coordinatesPerLabelVector;
  coordinatesPerLabelVector.resize( range );

  itk::ImageRegionIteratorWithIndex<ITKImageType> it_itkImage( itkImage, itkImage->GetLargestPossibleRegion() );

  for( it_itkImage.GoToBegin(); !it_itkImage.IsAtEnd(); ++it_itkImage )
  {
    std::vector< double > coordinates;
    coordinates.resize(dimensions);

    itk::Index< dimensions > index = it_itkImage.GetIndex();

    for( int loop(0); loop < dimensions; loop++)
    {
      coordinates.at( loop ) = index.GetElement( loop );
    }

    // add the coordinates to the corresponding label vector
    coordinatesPerLabelVector.at( it_itkImage.Value() - min ).push_back( coordinates );
  }

  for(int currentIndex(0), currentLabel( min ); currentIndex < range; currentIndex++, currentLabel++ )
  {
    std::vector< double > currentCoordinates;
    currentCoordinates.resize(dimensions);

    int numberOfPoints = coordinatesPerLabelVector.at( currentIndex ).size();

    std::vector< double > sumCoords;
    sumCoords.resize( dimensions );

    for( int loop(0); loop < numberOfPoints; loop++ )
    {
      for( int loopDimension( 0 ); loopDimension < dimensions; loopDimension++ )
      {
        sumCoords.at( loopDimension ) += coordinatesPerLabelVector.at( currentIndex ).at( loop ).at( loopDimension );
      }
    }

    for( int loopDimension( 0 ); loopDimension < dimensions; loopDimension++ )
    {
      currentCoordinates.at( loopDimension ) = sumCoords.at( loopDimension ) / numberOfPoints;
    }

    m_LabelsToCoordinatesMap.insert( std::pair< int, std::vector<double> >( currentLabel, currentCoordinates ) );
  }

  //can now use center of mass coordinates
  m_UseCoMCoordinates = true;
}