void mitk::SliceBasedInterpolationController::SetWorkingImage(LabelSetImage *newImage)
{
  if (m_WorkingImage != newImage)
  {
    // delete the current working image from the list of interpolators
    InterpolatorMapType::iterator iter = s_InterpolatorForImage.find(m_WorkingImage);
    if (iter != s_InterpolatorForImage.end())
    {
      s_InterpolatorForImage.erase(iter);
    }

    m_WorkingImage = newImage;

    s_InterpolatorForImage.insert(std::make_pair(m_WorkingImage, this));
  }

  this->ResetLabelCount();

  AccessFixedDimensionByItk_1(m_WorkingImage, ScanImageITKProcessing, 3, 0);

  // for all timesteps, scan whole image: TODO: enable this again for 3D+time
  /*
    for (unsigned int timeStep = 0; timeStep < m_WorkingImage->GetTimeSteps(); ++timeStep)
    {
      ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
      timeSelector->SetInput( m_WorkingImage );
      timeSelector->SetTimeNr( timeStep );
      timeSelector->UpdateLargestPossibleRegion();
      Image::Pointer segmentation3D = timeSelector->GetOutput();
      this->SetChangedVolume( segmentation3D.GetPointer(), timeStep );
    }
  */
  //   this->Modified();
}
Beispiel #2
0
void mitk::SegmentationInterpolationController::SetChangedSlice( const Image* sliceDiff, unsigned int sliceDimension, unsigned int sliceIndex, unsigned int timeStep )
{
  if ( !sliceDiff ) return;
  if ( sliceDimension > 2 ) return;
  if ( timeStep >= m_SegmentationCountInSlice.size() ) return;
  if ( sliceIndex >= m_SegmentationCountInSlice[timeStep][sliceDimension].size() ) return;

  unsigned int dim0(0);
  unsigned int dim1(1);

  // determine the other two dimensions
  switch (sliceDimension)
  {
    default:
    case 2:
      dim0 = 0; dim1 = 1; break;
    case 1:
      dim0 = 0; dim1 = 2; break;
    case 0:
      dim0 = 1; dim1 = 2; break;
  }

  //mitkIpPicDescriptor* rawSlice = const_cast<Image*>(sliceDiff)->GetSliceData()->GetPicDescriptor(); // we promise not to change anything!
  unsigned char* rawSlice = (unsigned char*) const_cast<Image*>(sliceDiff)->GetData();
  if (!rawSlice) return;

  AccessFixedDimensionByItk_1( sliceDiff, ScanChangedSlice, 2, SetChangedSliceOptions(sliceDimension, sliceIndex, dim0, dim1, timeStep, rawSlice) );
  
  //PrintStatus();
  
  Modified();
}
Beispiel #3
0
void mitk::SegmentationInterpolationController::SetChangedVolume( const Image* sliceDiff, unsigned int timeStep )
{
  if ( !sliceDiff ) return;
  if ( sliceDiff->GetDimension() != 3 ) return;
  
  AccessFixedDimensionByItk_1( sliceDiff, ScanChangedVolume, 3, timeStep );

  //PrintStatus();
  Modified();
}
void mitk::CorrectorAlgorithm::CalculateDifferenceImage( Image* modifiedImage, Image* originalImage )
{
  /*
   * modifiedImage has ipMITKSegmentationTYPE
   * originalImage may be any type
   *
   * --> we calculate a diff image using ITK, switching for the correct type of originalImage
   */
  m_DifferenceImage = NULL;
  Image::Pointer tmpPtr = originalImage;
  AccessFixedDimensionByItk_1( tmpPtr, ItkCalculateDifferenceImage, 2, modifiedImage );
}
void mitk::SurfaceInterpolationController::SetCurrentInterpolationSession(mitk::Image::Pointer currentSegmentationImage)
{
  if (currentSegmentationImage.GetPointer() == m_SelectedSegmentation)
    return;

  m_ReduceFilter->Reset();
  m_NormalsFilter->Reset();
  m_InterpolateSurfaceFilter->Reset();

  if (currentSegmentationImage.IsNull())
  {
    m_SelectedSegmentation = 0;
    return;
  }
  ContourListMap::iterator it = m_ListOfInterpolationSessions.find(currentSegmentationImage.GetPointer());

  m_SelectedSegmentation = currentSegmentationImage.GetPointer();

  itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New();
  AccessFixedDimensionByItk_1( m_SelectedSegmentation, GetImageBase, 3, itkImage );
  m_InterpolateSurfaceFilter->SetReferenceImage( itkImage.GetPointer() );

  if (it == m_ListOfInterpolationSessions.end())
  {
    ContourPositionPairList newList;
    m_ListOfInterpolationSessions.insert(std::pair<mitk::Image*, ContourPositionPairList>(m_SelectedSegmentation, newList));
    m_InterpolationResult = 0;
    m_CurrentNumberOfReducedContours = 0;

    itk::MemberCommand<SurfaceInterpolationController>::Pointer command = itk::MemberCommand<SurfaceInterpolationController>::New();
    command->SetCallbackFunction(this, &SurfaceInterpolationController::OnSegmentationDeleted);
    m_SegmentationObserverTags.insert( std::pair<mitk::Image*, unsigned long>( m_SelectedSegmentation, m_SelectedSegmentation->AddObserver( itk::DeleteEvent(), command ) ) );

  }
  else
  {
    for (unsigned int i = 0; i < m_ListOfInterpolationSessions[m_SelectedSegmentation].size(); i++)
    {
      m_ReduceFilter->SetInput(i, m_ListOfInterpolationSessions[m_SelectedSegmentation].at(i).contour);
    }

    m_ReduceFilter->Update();

    m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs();

    for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++)
    {
      m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i));
      m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i));
    }
  }
  Modified();
}
mitk::Image::Pointer
mitk::ShapeBasedInterpolationAlgorithm::Interpolate(
                               Image::ConstPointer lowerSlice, unsigned int lowerSliceIndex,
                               Image::ConstPointer upperSlice, unsigned int upperSliceIndex,
                               unsigned int requestedIndex,
                               unsigned int /*sliceDimension*/, // commented variables are not used
                               Image::Pointer resultImage,
                               unsigned int /*timeStep*/,
                               Image::ConstPointer /*referenceImage*/)
{
  mitk::Image::Pointer lowerDistanceImage = mitk::Image::New();
  AccessFixedDimensionByItk_1(lowerSlice, ComputeDistanceMap, 2, lowerDistanceImage);

  mitk::Image::Pointer upperDistanceImage = mitk::Image::New();
  AccessFixedDimensionByItk_1(upperSlice, ComputeDistanceMap, 2, upperDistanceImage);

  // calculate where the current slice is in comparison to the lower and upper neighboring slices
  float ratio = (float)(requestedIndex - lowerSliceIndex) / (float)(upperSliceIndex - lowerSliceIndex);
  AccessFixedDimensionByItk_3(resultImage, InterpolateIntermediateSlice, 2, upperDistanceImage, lowerDistanceImage, ratio);

  return resultImage;
}
void mitk::SurfaceInterpolationController::ReinitializeInterpolation()
{
  // If session has changed reset the pipeline
  m_ReduceFilter->Reset();
  m_NormalsFilter->Reset();
  m_InterpolateSurfaceFilter->Reset();

  itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New();

  if ( m_SelectedSegmentation )
  {
    mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
    timeSelector->SetInput( m_SelectedSegmentation );
    timeSelector->SetTimeNr( m_CurrentTimeStep );
    timeSelector->SetChannelNr( 0 );
    timeSelector->Update();
    mitk::Image::Pointer refSegImage = timeSelector->GetOutput();
    AccessFixedDimensionByItk_1( refSegImage, GetImageBase, 3, itkImage );
    m_InterpolateSurfaceFilter->SetReferenceImage(itkImage.GetPointer());

    unsigned int numTimeSteps = m_SelectedSegmentation->GetTimeSteps();
    unsigned int size = m_ListOfInterpolationSessions[m_SelectedSegmentation].size();
    if ( size != numTimeSteps )
    {
      m_ListOfInterpolationSessions[m_SelectedSegmentation].resize( numTimeSteps );
    }

    if ( m_CurrentTimeStep < numTimeSteps )
    {
      unsigned int numContours = m_ListOfInterpolationSessions[m_SelectedSegmentation][m_CurrentTimeStep].size();
      for ( unsigned int c = 0; c < numContours; ++c )
      {
        m_ReduceFilter->SetInput(c, m_ListOfInterpolationSessions[m_SelectedSegmentation][m_CurrentTimeStep][c].contour);
      }

      m_ReduceFilter->Update();

      m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs();

      for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++)
      {
        m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i));
        m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i));
      }
    }

    Modified();

  }
}
bool mitk::ImageLiveWireContourModelFilter::CreateDynamicCostMap(mitk::ContourModel* path)
{
  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());
  if(!input) return false;

  try
  {
    AccessFixedDimensionByItk_1(input,CreateDynamicCostMapByITK, 2, path);
  }
  catch( itk::ExceptionObject & e )
  {
    MITK_INFO << "Exception caught during dynamic cost map alculation: " << e;
    return false;
  }

  return true;
}
void mitk::SliceBasedInterpolationController::SetChangedSlice(const Image *slice,
                                                              unsigned int sliceDimension,
                                                              unsigned int sliceIndex,
                                                              unsigned int timeStep)
{
  if (!slice)
    return;
  if (slice->GetDimension() != 2)
    return;
  if (sliceDimension > 2)
    return;
  if (m_WorkingImage.IsNull())
    return;

  // check if the number of labels has changed
  int numberOfLabels = m_WorkingImage->GetNumberOfLabels();
  if (m_LabelCountInSlice[0][0][0].size() != numberOfLabels)
    return;

  unsigned int dim0(0);
  unsigned int dim1(1);

  // determine the other two dimensions
  switch (sliceDimension)
  {
    default:
    case 2:
      dim0 = 0;
      dim1 = 1;
      break;
    case 1:
      dim0 = 0;
      dim1 = 2;
      break;
    case 0:
      dim0 = 1;
      dim1 = 2;
      break;
  }

  AccessFixedDimensionByItk_1(
    slice, ScanSliceITKProcessing, 2, SetChangedSliceOptions(sliceDimension, sliceIndex, dim0, dim1, timeStep));

  //  this->Modified();
}
void mitk::AutoCropImageFilter::GenerateData()
{
  mitk::Image::ConstPointer input = this->GetInput();
  mitk::Image::Pointer output = this->GetOutput();

  if(input.IsNull())
    return;

  if(input->GetDimension() <= 2)
  {
    MITK_ERROR << "Only 3D and 4D images supported";
    return;
  }

  if((output->IsInitialized()==false) )
    return;

  if( m_TimeSelector.IsNull() ) m_TimeSelector = mitk::ImageTimeSelector::New();

  m_TimeSelector->SetInput(input);

  mitk::SlicedData::RegionType outputRegion = input->GetRequestedRegion();

  int tstart = outputRegion.GetIndex(3);
  int tmax = tstart + outputRegion.GetSize(3);

  for( int timestep=tstart;timestep<tmax;++timestep )
  {
    m_TimeSelector->SetTimeNr(timestep);
    m_TimeSelector->UpdateLargestPossibleRegion();

    AccessFixedDimensionByItk_1( m_TimeSelector->GetOutput(), ITKCrop3DImage, 3, timestep );
  }

  // this->GetOutput()->Update(); // Not sure if this is necessary...

  m_TimeOfHeaderInitialization.Modified();
}
void mitk::DWIHeadMotionCorrectionFilter<DiffusionPixelType>
  ::GenerateData()
{
  typedef itk::SplitDWImageFilter< DiffusionPixelType, DiffusionPixelType> SplitFilterType;

  DiffusionImageType* input = const_cast<DiffusionImageType*>(this->GetInput(0));

  unsigned int numberOfSteps = input->GetVectorImage()->GetNumberOfComponentsPerPixel () ;
  m_Steps = numberOfSteps;
  //
  //  (1) Extract the b-zero images to a 3d+t image, register them by NCorr metric and
  //     rigid registration : they will then be used are reference image for registering
  //     the gradient images
  //
  typedef itk::B0ImageExtractionToSeparateImageFilter< DiffusionPixelType, DiffusionPixelType> B0ExtractorType;
  typename B0ExtractorType::Pointer b0_extractor = B0ExtractorType::New();
  b0_extractor->SetInput( input->GetVectorImage() );
  b0_extractor->SetDirections( input->GetDirections() );
  b0_extractor->Update();

  mitk::Image::Pointer b0Image = mitk::Image::New();
  b0Image->InitializeByItk( b0_extractor->GetOutput() );
  b0Image->SetImportChannel( b0_extractor->GetOutput()->GetBufferPointer(),
    mitk::Image::CopyMemory );

  // (2.1) Use the extractor to access the extracted b0 volumes
  mitk::ImageTimeSelector::Pointer t_selector =
    mitk::ImageTimeSelector::New();

  t_selector->SetInput( b0Image );
  t_selector->SetTimeNr(0);
  t_selector->Update();

  // first unweighted image as reference space for the registration
  mitk::Image::Pointer b0referenceImage = t_selector->GetOutput();

  mitk::PyramidImageRegistrationMethod::Pointer registrationMethod = mitk::PyramidImageRegistrationMethod::New();
  registrationMethod->SetFixedImage( b0referenceImage );
  registrationMethod->SetTransformToRigid();

  // the unweighted images are of same modality
  registrationMethod->SetCrossModalityOff();

  // use the advanced (windowed sinc) interpolation
  registrationMethod->SetUseAdvancedInterpolation(true);

  // Initialize the temporary output image
  mitk::Image::Pointer registeredB0Image = b0Image->Clone();
  const unsigned int numberOfb0Images = b0Image->GetTimeSteps();

  if( numberOfb0Images > 1)
  {
    mitk::ImageTimeSelector::Pointer t_selector2 =
      mitk::ImageTimeSelector::New();

    t_selector2->SetInput( b0Image );

    for( unsigned int i=1; i<numberOfb0Images; i++)
    {

      m_CurrentStep = i + 1;
      if( m_AbortRegistration == true) {
        m_IsInValidState = false;
        mitkThrow() << "Stopped by user.";
      };

      t_selector2->SetTimeNr(i);
      t_selector2->Update();

      registrationMethod->SetMovingImage( t_selector2->GetOutput() );

      try
      {
        MITK_INFO << " === (" << i <<"/"<< numberOfb0Images-1 << ") :: Starting registration";
        registrationMethod->Update();
      }
      catch( const itk::ExceptionObject& e)
      {
        m_IsInValidState = false;
        mitkThrow() << "Failed to register the b0 images, the PyramidRegistration threw an exception: \n" << e.what();
      }

      // import volume to the inter-results
      mitk::ImageWriteAccessor imac(registrationMethod->GetResampledMovingImage());
      registeredB0Image->SetImportVolume( imac.GetData(),
        i, 0, mitk::Image::ReferenceMemory );

    }

    // use the accumulateImageFilter as provided by the ItkAccumulateFilter method in the header file
    AccessFixedDimensionByItk_1(registeredB0Image, ItkAccumulateFilter, (4), b0referenceImage );

  }


  //
  // (2) Split the diffusion image into a 3d+t regular image, extract only the weighted images
  //
  typename SplitFilterType::Pointer split_filter = SplitFilterType::New();
  split_filter->SetInput (input->GetVectorImage() );
  split_filter->SetExtractAllAboveThreshold(20, input->GetB_ValueMap() );

  try
  {
    split_filter->Update();
  }
  catch( const itk::ExceptionObject &e)
  {
    m_IsInValidState = false;
    mitkThrow() << " Caught exception from SplitImageFilter : " << e.what();
  }

  mitk::Image::Pointer splittedImage = mitk::Image::New();
  splittedImage->InitializeByItk( split_filter->GetOutput() );
  splittedImage->SetImportChannel( split_filter->GetOutput()->GetBufferPointer(),
    mitk::Image::CopyMemory );


  //
  // (3) Use again the time-selector to access the components separately in order
  //     to perform the registration of  Image -> unweighted reference
  //

  mitk::PyramidImageRegistrationMethod::Pointer weightedRegistrationMethod
    = mitk::PyramidImageRegistrationMethod::New();

  weightedRegistrationMethod->SetTransformToAffine();
  weightedRegistrationMethod->SetCrossModalityOn();

  //
  //   - (3.1) Set the reference image
  //      - a single b0 image
  //      - average over the registered b0 images if multiple present
  //
  weightedRegistrationMethod->SetFixedImage( b0referenceImage );
  // use the advanced (windowed sinc) interpolation
  weightedRegistrationMethod->SetUseAdvancedInterpolation(true);

  //
  //   - (3.2) Register all timesteps in the splitted image onto the first reference
  //
  unsigned int maxImageIdx = splittedImage->GetTimeSteps();
  mitk::TimeGeometry* tsg = splittedImage->GetTimeGeometry();
  mitk::ProportionalTimeGeometry* ptg = dynamic_cast<ProportionalTimeGeometry*>(tsg);
  ptg->Expand(maxImageIdx+1);
  ptg->SetTimeStepGeometry( ptg->GetGeometryForTimeStep(0), maxImageIdx );


  mitk::Image::Pointer registeredWeighted = mitk::Image::New();
  registeredWeighted->Initialize( splittedImage->GetPixelType(0), *tsg );

  // insert the first unweighted reference as the first volume
  mitk::ImageWriteAccessor imac(b0referenceImage);
  registeredWeighted->SetImportVolume( imac.GetData(),
    0,0, mitk::Image::CopyMemory );


  // mitk::Image::Pointer registeredWeighted = splittedImage->Clone();
  // this time start at 0, we have only gradient images in the 3d+t file
  // the reference image comes form an other image
  mitk::ImageTimeSelector::Pointer t_selector_w =
    mitk::ImageTimeSelector::New();

  t_selector_w->SetInput( splittedImage );

  // store the rotation parts of the transformations in a vector
  typedef mitk::PyramidImageRegistrationMethod::TransformMatrixType MatrixType;
  std::vector< MatrixType > estimated_transforms;


  for( unsigned int i=0; i<maxImageIdx; i++)
  {
    m_CurrentStep = numberOfb0Images + i + 1;
    if( m_AbortRegistration == true) {
      m_IsInValidState = false;
      mitkThrow() << "Stopped by user.";
    };

    t_selector_w->SetTimeNr(i);
    t_selector_w->Update();

    weightedRegistrationMethod->SetMovingImage( t_selector_w->GetOutput() );

    try
    {
      MITK_INFO << " === (" << i+1 <<"/"<< maxImageIdx << ") :: Starting registration";
      weightedRegistrationMethod->Update();
    }
    catch( const itk::ExceptionObject& e)
    {
      m_IsInValidState = false;
      mitkThrow() << "Failed to register the b0 images, the PyramidRegistration threw an exception: \n" << e.what();
    }

    // allow expansion
    mitk::ImageWriteAccessor imac(weightedRegistrationMethod->GetResampledMovingImage());
    registeredWeighted->SetImportVolume( imac.GetData(),
      i+1, 0, mitk::Image::CopyMemory);

    estimated_transforms.push_back( weightedRegistrationMethod->GetLastRotationMatrix() );
  }


  //
  // (4) Cast the resulting image back to an diffusion weighted image
  //
  typename DiffusionImageType::GradientDirectionContainerType *gradients = input->GetDirections();
  typename DiffusionImageType::GradientDirectionContainerType::Pointer gradients_new =
    DiffusionImageType::GradientDirectionContainerType::New();
  typename DiffusionImageType::GradientDirectionType bzero_vector;
  bzero_vector.fill(0);

  // compose the direction vector
  //  - no direction for the first image
  //  - correct ordering of the directions based on the index list
  gradients_new->push_back( bzero_vector );

  typename SplitFilterType::IndexListType index_list = split_filter->GetIndexList();
  typename SplitFilterType::IndexListType::const_iterator lIter = index_list.begin();

  while( lIter != index_list.end() )
  {
    gradients_new->push_back( gradients->at( *lIter ) );
    ++lIter;
  }

  typename mitk::ImageToDiffusionImageSource< DiffusionPixelType >::Pointer caster =
    mitk::ImageToDiffusionImageSource< DiffusionPixelType >::New();

  caster->SetImage( registeredWeighted );
  caster->SetBValue( input->GetB_Value() );
  caster->SetGradientDirections( gradients_new.GetPointer() );

  try
  {
    caster->Update();
  }
  catch( const itk::ExceptionObject& e)
  {
    m_IsInValidState = false;
    MITK_ERROR << "Casting back to diffusion image failed: ";
    mitkThrow() << "Subprocess failed with exception: " << e.what();
  }

  //
  // (5) Adapt the gradient directions according to the estimated transforms
  //
  typedef mitk::DiffusionImageCorrectionFilter< DiffusionPixelType > CorrectionFilterType;
  typename CorrectionFilterType::Pointer corrector = CorrectionFilterType::New();

  OutputImagePointerType output = caster->GetOutput();
  corrector->SetImage( output );
  corrector->CorrectDirections( estimated_transforms );

  //
  // (6) Pass the corrected image to the filters output port
  //
  m_CurrentStep += 1;
  this->GetOutput()->SetVectorImage(output->GetVectorImage());
  this->GetOutput()->SetB_Value(output->GetB_Value());
  this->GetOutput()->SetDirections(output->GetDirections());
  this->GetOutput()->SetMeasurementFrame(output->GetMeasurementFrame());
  this->GetOutput()->InitializeFromVectorImage();

  this->GetOutput()->Modified();
}
Beispiel #12
0
void mitk::CLUtil::CreateCheckerboardMask(mitk::Image::Pointer image, mitk::Image::Pointer & outimage)
{
  AccessFixedDimensionByItk_1(image, mitk::CLUtil::itkCreateCheckerboardMask,3, outimage);
}
Beispiel #13
0
void mitk::CLUtil::FillHoleGrayscale(mitk::Image::Pointer & image, mitk::Image::Pointer & outimage)
{
  AccessFixedDimensionByItk_1(image, mitk::CLUtil::itkFillHoleGrayscale, 3, outimage);
}
mitk::Image::Pointer mitk::PlanarFigureSegmentationController::GetInterpolationResult()
{
  m_SegmentationAsImage = NULL;

  if ( m_PlanarFigureList.size() == 0 )
  {
    m_SegmentationAsImage = mitk::Image::New();
    m_SegmentationAsImage->Initialize(mitk::MakeScalarPixelType<unsigned char>() , *m_ReferenceImage->GetTimeGeometry());

    return m_SegmentationAsImage;
  }

  itk::ImageBase<3>::Pointer itkImage;
  AccessFixedDimensionByItk_1( m_ReferenceImage.GetPointer(), GetImageBase, 3, itkImage );
  m_DistanceImageCreator->SetReferenceImage( itkImage.GetPointer() );

  m_ReduceFilter->Update();
  m_NormalsFilter->Update();
  m_DistanceImageCreator->Update();

  mitk::Image::Pointer distanceImage = m_DistanceImageCreator->GetOutput();

  // Cleanup the pipeline
  distanceImage->DisconnectPipeline();
  m_DistanceImageCreator = NULL;
  m_NormalsFilter = NULL;
  m_ReduceFilter = NULL;
  itkImage = NULL;

  // If this bool flag is true, the distanceImage will be written to the
  // filesystem as nrrd-image and as surface-representation.
  bool debugOutput(false);
  if ( debugOutput )
  {
    mitk::ImageWriter::Pointer imageWriter = mitk::ImageWriter::New();
    imageWriter->SetInput( distanceImage );
    imageWriter->SetExtension( ".nrrd" );
    imageWriter->SetFileName( "v:/DistanceImage" );
    imageWriter->Update();
  }

  mitk::ImageToSurfaceFilter::Pointer imageToSurfaceFilter = mitk::ImageToSurfaceFilter::New();
  imageToSurfaceFilter->SetInput( distanceImage );
  imageToSurfaceFilter->SetThreshold( 0 );
  imageToSurfaceFilter->Update();

  mitk::Surface::Pointer segmentationAsSurface = imageToSurfaceFilter->GetOutput();

  // Cleanup the pipeline
  segmentationAsSurface->DisconnectPipeline();
  imageToSurfaceFilter = NULL;

  if ( debugOutput )
  {
    mitk::SurfaceVtkWriter<vtkPolyDataWriter>::Pointer surfaceWriter = mitk::SurfaceVtkWriter<vtkPolyDataWriter>::New();
    surfaceWriter->SetInput( segmentationAsSurface );
    surfaceWriter->SetExtension( ".vtk" );
    surfaceWriter->SetFileName( "v:/DistanceImageAsSurface.vtk" );
    surfaceWriter->Update();
  }


  mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New();
  surfaceToImageFilter->SetInput( segmentationAsSurface );
  surfaceToImageFilter->SetImage( m_ReferenceImage );
  surfaceToImageFilter->SetMakeOutputBinary(true);
  surfaceToImageFilter->Update();

  m_SegmentationAsImage = surfaceToImageFilter->GetOutput();

  // Cleanup the pipeline
  m_SegmentationAsImage->DisconnectPipeline();

  return m_SegmentationAsImage;
}
 template <typename ItkOutputImageType> void CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer<ItkOutputImageType>& itkOutputImage)
 {
   AccessFixedDimensionByItk_1(mitkImage, _CastToItkImage2Access, ::itk::GetImageDimension<ItkOutputImageType>::ImageDimension, itkOutputImage);
 }
void mitk::SurfaceStampImageFilter::SurfaceStamp(int time)
{
  mitk::Image::Pointer inputImage = this->GetInput();

  const mitk::TimeGeometry *surfaceTimeGeometry = GetInput()->GetTimeGeometry();
  const mitk::TimeGeometry *imageTimeGeometry = inputImage->GetTimeGeometry();

  // Convert time step from image time-frame to surface time-frame
  mitk::TimePointType matchingTimePoint = imageTimeGeometry->TimeStepToTimePoint(time);
  mitk::TimeStepType surfaceTimeStep = surfaceTimeGeometry->TimePointToTimeStep(matchingTimePoint);

  vtkPolyData *polydata = m_Surface->GetVtkPolyData(surfaceTimeStep);
  if (!polydata)
    mitkThrow() << "Polydata is null.";

  vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  transformFilter->SetInputData(polydata);
  //  transformFilter->ReleaseDataFlagOn();

  vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
  BaseGeometry::Pointer geometry = surfaceTimeGeometry->GetGeometryForTimeStep(surfaceTimeStep);

  transform->PostMultiply();
  transform->Concatenate(geometry->GetVtkTransform()->GetMatrix());
  // take image geometry into account. vtk-Image information will be changed to unit spacing and zero origin below.
  BaseGeometry::Pointer imageGeometry = imageTimeGeometry->GetGeometryForTimeStep(time);

  transform->Concatenate(imageGeometry->GetVtkTransform()->GetLinearInverse());
  transformFilter->SetTransform(transform);
  transformFilter->Update();

  polydata = transformFilter->GetOutput();

  if (!polydata || !polydata->GetNumberOfPoints())
    mitkThrow() << "Polydata retrieved from transformation is null or has no points.";

  MeshType::Pointer mesh = MeshType::New();
  mesh->SetCellsAllocationMethod(MeshType::CellsAllocatedDynamicallyCellByCell);
  unsigned int numberOfPoints = polydata->GetNumberOfPoints();
  mesh->GetPoints()->Reserve(numberOfPoints);

  vtkPoints *points = polydata->GetPoints();

  MeshType::PointType point;
  for (unsigned int i = 0; i < numberOfPoints; i++)
  {
    double *aux = points->GetPoint(i);
    point[0] = aux[0];
    point[1] = aux[1];
    point[2] = aux[2];
    mesh->SetPoint(i, point);
  }

  // Load the polygons into the itk::Mesh
  typedef MeshType::CellAutoPointer CellAutoPointerType;
  typedef MeshType::CellType CellType;
  typedef itk::TriangleCell<CellType> TriangleCellType;
  typedef MeshType::PointIdentifier PointIdentifierType;
  typedef MeshType::CellIdentifier CellIdentifierType;

  // Read the number of polygons
  CellIdentifierType numberOfPolygons = 0;
  numberOfPolygons = polydata->GetNumberOfPolys();

  PointIdentifierType numberOfCellPoints = 3;
  CellIdentifierType i = 0;

  for (i = 0; i < numberOfPolygons; i++)
  {
    vtkIdList *cellIds;
    vtkCell *vcell = polydata->GetCell(i);
    cellIds = vcell->GetPointIds();

    CellAutoPointerType cell;
    auto *triangleCell = new TriangleCellType;
    PointIdentifierType k;
    for (k = 0; k < numberOfCellPoints; k++)
    {
      triangleCell->SetPointId(k, cellIds->GetId(k));
    }

    cell.TakeOwnership(triangleCell);
    mesh->SetCell(i, cell);
  }

  if (!mesh->GetNumberOfPoints())
    mitkThrow() << "Generated itk mesh is empty.";

  if (m_MakeOutputBinary)
  {
    this->SurfaceStampBinaryOutputProcessing(mesh);
  }
  else
  {
    AccessFixedDimensionByItk_1(inputImage, SurfaceStampProcessing, 3, mesh);
  }
}