예제 #1
0
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;
  }
}
int mitkPyramidImageRegistrationMethodTest( int argc, char* argv[] )
{
  if( argc < 4 )
  {
    MITK_ERROR << "Not enough input \n Usage: <TEST_NAME> fixed moving type [output_image [output_transform]]"
               << "\n \t fixed : the path to the fixed image \n"
               << " \t moving : path to the image to be registered"
               << " \t type : Affine or Rigid defining the type of the transformation"
               << " \t output_image : output file optional, (full) path, and optionally output_transform : also (full)path to file";
    return EXIT_FAILURE;
  }

  MITK_TEST_BEGIN("PyramidImageRegistrationMethodTest");

  mitk::Image::Pointer fixedImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load( argv[1] )[0].GetPointer());
  mitk::Image::Pointer movingImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::Load( argv[2] )[0].GetPointer());

  std::string type_flag( argv[3] );

  mitk::PyramidImageRegistrationMethod::Pointer registrationMethod = mitk::PyramidImageRegistrationMethod::New();
  registrationMethod->SetFixedImage( fixedImage );
  registrationMethod->SetMovingImage( movingImage );

  if( type_flag == "Rigid" )
  {
    registrationMethod->SetTransformToRigid();
  }
  else if( type_flag == "Affine" )
  {
    registrationMethod->SetTransformToAffine();
  }
  else
  {
    MITK_WARN << " No type specified, using 'Affine' .";
  }

  registrationMethod->Update();

  bool imageOutput = false;
  bool transformOutput = false;

  std::string image_out_filename, transform_out_filename;

  std::string first_output( argv[4] );
  // check for txt, otherwise suppose it is an image
  if( first_output.find(".txt") != std::string::npos )
  {
    transformOutput = true;
    transform_out_filename = first_output;
  }
  else
  {
    imageOutput = true;
    image_out_filename = first_output;
  }

  if( argc > 4 )
  {
    std::string second_output( argv[5] );
    if( second_output.find(".txt") != std::string::npos )
    {
      transformOutput = true;
      transform_out_filename = second_output;
    }
  }

  MITK_INFO << " Selected output: " << transform_out_filename  << " " << image_out_filename;

  try{

    unsigned int paramCount = registrationMethod->GetNumberOfParameters();
    double* params = new double[ paramCount ];
    registrationMethod->GetParameters( &params[0] );

    std::cout << "Parameters: ";
    for( unsigned int i=0; i< paramCount; i++)
    {
      std::cout << params[ i ] << " ";
    }
    std::cout << std::endl;

    if( imageOutput )
    {
      mitk::IOUtil::Save( registrationMethod->GetResampledMovingImage(), image_out_filename.c_str() );
    }


    if( transformOutput )
    {

      itk::TransformFileWriter::Pointer writer = itk::TransformFileWriter::New();

      // Get transform parameter for resampling / saving
      // Affine
      if( paramCount == 12 )
      {
        typedef itk::AffineTransform< double > TransformType;
        TransformType::Pointer transform = TransformType::New();

        TransformType::ParametersType affine_params( paramCount );
        registrationMethod->GetParameters( &affine_params[0] );

        transform->SetParameters( affine_params );
        writer->SetInput( transform );
      }
      // Rigid
      else
      {
        typedef itk::Euler3DTransform< double > RigidTransformType;
        RigidTransformType::Pointer rtransform = RigidTransformType::New();

        RigidTransformType::ParametersType rigid_params( paramCount );
        registrationMethod->GetParameters( &rigid_params[0] );

        rtransform->SetParameters( rigid_params );
        writer->SetInput( rtransform );
      }

      writer->SetFileName( transform_out_filename );
      writer->Update();
    }

  }
  catch( const std::exception &e)
  {
    MITK_ERROR << "Caught exception: " << e.what();
  }


  MITK_TEST_END();
}