Ejemplo n.º 1
0
void mitk::FastMarchingTool3D::Update()
{
  if (m_NeedUpdate)
  {
    m_ProgressCommand->AddStepsToDo(200);
    CurrentlyBusy.Send(true);
    try
    {
      m_ThresholdFilter->Update();
    }
    catch( itk::ExceptionObject & excep )
    {
     MITK_ERROR << "Exception caught: " << excep.GetDescription();

     m_ProgressCommand->SetRemainingProgress(100);
     CurrentlyBusy.Send(false);

     std::string msg = excep.GetDescription();
     ErrorMessage.Send(msg);

     return;
    }
    m_ProgressCommand->SetRemainingProgress(100);
    CurrentlyBusy.Send(false);

    //make output visible
    mitk::Image::Pointer result = mitk::Image::New();
    CastToMitkImage( m_ThresholdFilter->GetOutput(), result);
    result->GetGeometry()->SetOrigin(m_ReferenceImage->GetGeometry()->GetOrigin() );
    result->GetGeometry()->SetIndexToWorldTransform(m_ReferenceImage->GetGeometry()->GetIndexToWorldTransform() );
    m_ResultImageNode->SetData(result);
    m_ResultImageNode->SetVisibility(true);
    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  }
}
Ejemplo n.º 2
0
  /*
   * Generate a sphere with a radius of TestvolumeSize / 4.0
   */
  static void ItkVolumeGeneration ()
  {
    typedef itk::Image<unsigned char, 3> TestVolumeType;

    typedef itk::ImageRegionConstIterator< TestVolumeType > ImageIterator;

    TestVolumeType::Pointer sphereImage = TestVolumeType::New();

    TestVolumeType::IndexType start;
    start[0] = start[1] = start[2] = 0;

    TestVolumeType::SizeType size;
    size[0] = size[1] = size[2] = TestvolumeSize;

    TestVolumeType::RegionType imgRegion;
    imgRegion.SetSize(size);
    imgRegion.SetIndex(start);

    sphereImage->SetRegions(imgRegion);
    sphereImage->SetSpacing(1.0);
    sphereImage->Allocate();

    sphereImage->FillBuffer(0);


    mitk::Vector3D center;
    center[0] = center[1] = center[2] = TestvolumeSize / 2.0;


    double radius = TestvolumeSize / 4.0;

    double pixelValue = pixelValueSet;


    ImageIterator imageIterator( sphereImage, sphereImage->GetLargestPossibleRegion() );
    imageIterator.GoToBegin();


    mitk::Vector3D currentVoxelInIndex;

    while ( !imageIterator.IsAtEnd() )
    {
      currentVoxelInIndex[0] = imageIterator.GetIndex()[0];
      currentVoxelInIndex[1] = imageIterator.GetIndex()[1];
      currentVoxelInIndex[2] = imageIterator.GetIndex()[2];

      double distanceToCenter = (center + ( currentVoxelInIndex * -1.0 )).GetNorm();

      //if distance to center is smaller then the radius of the sphere
      if( distanceToCenter < radius)
      {
        sphereImage->SetPixel(imageIterator.GetIndex(), pixelValue);
      }

      ++imageIterator;
    }

    CastToMitkImage(sphereImage, TestVolume);
  }
Ejemplo n.º 3
0
  /*
   * random a voxel. define plane through this voxel. reslice at the plane. compare the pixel vaues of the voxel
   * in the volume with the pixel value in the resliced image.
   * there are some indice shifting problems which causes the test to fail for oblique planes. seems like the chosen
   * worldcoordinate is not corrresponding to the index in the 2D image. and so the pixel values are not the same as
   * expected.
   */
  static void PixelvalueBasedTest()
  {
    /* setup itk image */
    typedef itk::Image<unsigned short, 3> ImageType;

    typedef itk::ImageRegionConstIterator< ImageType > ImageIterator;

    ImageType::Pointer image = ImageType::New();

    ImageType::IndexType start;
    start[0] = start[1] = start[2] = 0;

    ImageType::SizeType size;
    size[0] = size[1] = size[2] = 32;

    ImageType::RegionType imgRegion;
    imgRegion.SetSize(size);
    imgRegion.SetIndex(start);

    image->SetRegions(imgRegion);
    image->SetSpacing(1.0);
    image->Allocate();


    ImageIterator imageIterator( image, image->GetLargestPossibleRegion() );
    imageIterator.GoToBegin();


    unsigned short pixelValue = 0;

    //fill the image with distinct values
    while ( !imageIterator.IsAtEnd() )
    {
      image->SetPixel(imageIterator.GetIndex(), pixelValue);
      ++imageIterator;
      ++pixelValue;
    }
    /* end setup itk image */



    mitk::Image::Pointer imageInMitk;
    CastToMitkImage(image, imageInMitk);



    /*mitk::ImageWriter::Pointer writer = mitk::ImageWriter::New();
    writer->SetInput(imageInMitk);
    std::string file = "C:\\Users\\schroedt\\Desktop\\cube.nrrd";
    writer->SetFileName(file);
    writer->Update();*/

                PixelvalueBasedTestByPlane(imageInMitk, mitk::PlaneGeometry::Frontal);
                PixelvalueBasedTestByPlane(imageInMitk, mitk::PlaneGeometry::Sagittal);
                PixelvalueBasedTestByPlane(imageInMitk, mitk::PlaneGeometry::Axial);

  }
void mitk::CorrectorAlgorithm::GenerateData()
{
  Image::Pointer inputImage = const_cast<Image*>(ImageToImageFilter::GetInput(0));

  if (inputImage.IsNull() || inputImage->GetDimension() != 2)
  {
    itkExceptionMacro("CorrectorAlgorithm needs a 2D image as input.");
  }

  if (m_Contour.IsNull())
  {
    itkExceptionMacro("CorrectorAlgorithm needs a Contour object as input.");
  }

  // copy the input (since m_WorkingImage will be changed later)
  m_WorkingImage = inputImage;

  TimeGeometry::Pointer originalGeometry = NULL;

  if (inputImage->GetTimeGeometry() )
  {
    originalGeometry = inputImage->GetTimeGeometry()->Clone();
    m_WorkingImage->SetTimeGeometry( originalGeometry );
  }
  else
  {
    itkExceptionMacro("Original image does not have a 'Time sliced geometry'! Cannot copy.");
  }

  Image::Pointer temporarySlice;
  // Convert to ipMITKSegmentationTYPE (because TobiasHeimannCorrectionAlgorithm relys on that data type)
  {
    itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
    CastToItkImage( m_WorkingImage, correctPixelTypeImage );
    assert (correctPixelTypeImage.IsNotNull() );

    // possible bug in CastToItkImage ?
    // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in
    // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479:
    // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed
    // solution here: we overwrite it with an unity matrix
    itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
    imageDirection.SetIdentity();
    //correctPixelTypeImage->SetDirection(imageDirection);

    temporarySlice = this->GetOutput();
    //  temporarySlice = ImportItkImage( correctPixelTypeImage );
    m_FillColor = 1;
    m_EraseColor = 0;
    ImprovedHeimannCorrectionAlgorithm(correctPixelTypeImage);
    CastToMitkImage( correctPixelTypeImage, temporarySlice );
  }
  temporarySlice->SetTimeGeometry(originalGeometry);
}
Ejemplo n.º 5
0
static void ExecuteOneImageFilterWithFunctorNonParameter(ImageType* imageA, double , bool returnDoubleImage, bool , bool , mitk::Image::Pointer & outputImage)
{
  typedef itk::UnaryFunctorImageFilter< ImageType, ImageType, DefaultFunctorType > DefaultFilterType;
  typedef itk::UnaryFunctorImageFilter< ImageType, DoubleImageType, DoubleFunctorType > DoubleFilterType;

  if (returnDoubleImage)
  {
    typename DoubleFilterType::Pointer filter = DoubleFilterType::New();
    filter->SetInput(imageA);
    filter->Update();
    CastToMitkImage(filter->GetOutput(), outputImage);
  }
  else
  {
    typename DefaultFilterType::Pointer filter = DefaultFilterType::New();
    filter->SetInput(imageA);
    filter->Update();
    CastToMitkImage(filter->GetOutput(), outputImage);
  }
}
Ejemplo n.º 6
0
void mitk::NonStaticArithmeticOperation::ExecuteTwoImageFilterWithFunctor(Image1Type* imageA, Image2Type* imageB)
{
  typedef itk::BinaryFunctorImageFilter< Image1Type, Image2Type, Image1Type,DefaultFunctorType > DefaultFilterType;
  typedef itk::BinaryFunctorImageFilter< Image1Type, Image2Type, DoubleImageType, DoubleFunctorType > DoubleFilterType;

  if (m_GenerateDoubleOutput)
  {
    typename DoubleFilterType::Pointer filter = DoubleFilterType::New();
    filter->SetInput1(imageA);
    filter->SetInput2(imageB);
    filter->Update();
    CastToMitkImage(filter->GetOutput(), m_ResultImage);
  }
  else
  {
    typename DefaultFilterType::Pointer filter = DefaultFilterType::New();
    filter->SetInput1(imageA);
    filter->SetInput2(imageB);
    filter->Update();
    CastToMitkImage(filter->GetOutput(), m_ResultImage);
  }
}
Ejemplo n.º 7
0
void mitk::FastMarchingTool::Update()
{
  const unsigned int progress_steps = 20;

  // update FastMarching pipeline and show result
  if (m_NeedUpdate)
  {
    m_ProgressCommand->AddStepsToDo(progress_steps);
    CurrentlyBusy.Send(true);
    try
    {
      m_ThresholdFilter->Update();
    }
    catch( itk::ExceptionObject & excep )
    {
     MITK_ERROR << "Exception caught: " << excep.GetDescription();

     // progress by max step count, will force
     m_ProgressCommand->SetProgress(progress_steps);
     CurrentlyBusy.Send(false);

     std::string msg = excep.GetDescription();
     ErrorMessage.Send(msg);

     return;
    }
    m_ProgressCommand->SetProgress(progress_steps);
    CurrentlyBusy.Send(false);

    //make output visible
    mitk::Image::Pointer result = mitk::Image::New();
    CastToMitkImage( m_ThresholdFilter->GetOutput(), result);
    result->GetGeometry()->SetOrigin(m_ReferenceImageSlice->GetGeometry()->GetOrigin() );
    result->GetGeometry()->SetIndexToWorldTransform(m_ReferenceImageSlice->GetGeometry()->GetIndexToWorldTransform() );
    m_ResultImageNode->SetData(result);
    m_ResultImageNode->SetVisibility(true);
    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  }
}
Ejemplo n.º 8
0
void mitk::BinaryThresholdULTool::UpdatePreview()
{
  typedef itk::Image<int, 3> ImageType;
  typedef itk::Image<unsigned char, 3> SegmentationType;
  typedef itk::BinaryThresholdImageFilter<ImageType, SegmentationType> ThresholdFilterType;
  mitk::Image::Pointer thresholdimage = dynamic_cast<mitk::Image*> (m_NodeForThresholding->GetData());
  if(thresholdimage)
  {
    ImageType::Pointer itkImage = ImageType::New();
    CastToItkImage(thresholdimage, itkImage);
    ThresholdFilterType::Pointer filter = ThresholdFilterType::New();
    filter->SetInput(itkImage);
    filter->SetLowerThreshold(m_CurrentLowerThresholdValue);
    filter->SetUpperThreshold(m_CurrentUpperThresholdValue);
    filter->SetInsideValue(1);
    filter->SetOutsideValue(0);
    filter->Update();

    mitk::Image::Pointer new_image = mitk::Image::New();
    CastToMitkImage(filter->GetOutput(), new_image);
    m_ThresholdFeedbackNode->SetData(new_image);
  }
  RenderingManager::GetInstance()->RequestUpdateAll();
}
Ejemplo n.º 9
0
void mitk::CreateDistanceImageFromSurfaceFilter::CreateDistanceImage()
{
  typedef itk::Image<double, 3> DistanceImageType;
  typedef itk::ImageRegionIteratorWithIndex<DistanceImageType> ImageIterator;
  typedef itk::NeighborhoodIterator<DistanceImageType> NeighborhoodImageIterator;

  DistanceImageType::Pointer distanceImg = DistanceImageType::New();

  //Determin the bounding box of the delineated contours
  double xmin = m_Centers.at(0)[0];
  double ymin = m_Centers.at(0)[1];
  double zmin = m_Centers.at(0)[2];
  double xmax = m_Centers.at(0)[0];
  double ymax = m_Centers.at(0)[1];
  double zmax = m_Centers.at(0)[2];

  for (unsigned int i = 1; i < m_Centers.size(); i++)
  {
    if (xmin > m_Centers.at(i)[0])
    {
      xmin = m_Centers.at(i)[0];
    }
    if (ymin > m_Centers.at(i)[1])
    {
      ymin = m_Centers.at(i)[1];
    }
    if (zmin > m_Centers.at(i)[2])
    {
      zmin = m_Centers.at(i)[2];
    }
    if (xmax < m_Centers.at(i)[0])
    {
      xmax = m_Centers.at(i)[0];
    }
    if (ymax < m_Centers.at(i)[1])
    {
      ymax = m_Centers.at(i)[1];
    }
    if (zmax < m_Centers.at(i)[2])
    {
      zmax = m_Centers.at(i)[2];
    }
  }

  Vector3D extentMM;
  extentMM[0] = xmax - xmin + 2;
  extentMM[1] = ymax - ymin + 2;
  extentMM[2] = zmax - zmin + 2;

  //Shifting the distance image's offest to achieve an exact distance calculation
  xmin = xmin - 2;
  ymin = ymin - 2;
  zmin = zmin - 2;

  /*
    Now create an empty distance image. The create image will always have the same size, independent from
    the original image (e.g. always consists of 500000 pixels) and will have an isotropic spacing.
    The spacing is calculated like the following:
    The image's volume = 500000 Pixels = extentX*spacing*extentY*spacing*extentZ*spacing
    So the spacing is: spacing = ( 500000 / extentX*extentY*extentZ )^(1/3)
  */

  double basis = (extentMM[0]*extentMM[1]*extentMM[2]) / m_DistanceImageVolume;
  double exponent = 1.0/3.0;
  double distImgSpacing = pow(basis, exponent);
  int tempSpacing = (distImgSpacing+0.05)*10;
  m_DistanceImageSpacing = (double)tempSpacing/10.0;

  unsigned int numberOfXPixel = extentMM[0] / m_DistanceImageSpacing;
  unsigned int numberOfYPixel = extentMM[1] / m_DistanceImageSpacing;
  unsigned int numberOfZPixel = extentMM[2] / m_DistanceImageSpacing;

  DistanceImageType::SizeType size;

  //Increase the distance image's size a little bit to achieve an exact distance calculation
  size[0] = numberOfXPixel + 5;
  size[1] = numberOfYPixel + 5;
  size[2] = numberOfZPixel + 5;

  DistanceImageType::IndexType start;
  start[0] = 0;
  start[1] = 0;
  start[2] = 0;

  DistanceImageType::RegionType lpRegion;

  lpRegion.SetSize(size);
  lpRegion.SetIndex(start);

  distanceImg->SetRegions( lpRegion );
  distanceImg->SetSpacing( m_DistanceImageSpacing );
  distanceImg->Allocate();

  //First of all the image is initialized with the value 10 for each pixel
  distanceImg->FillBuffer(10);

  /*
    Now we must caculate the distance for each pixel. But instead of calculating the distance value
    for all of the image's pixels we proceed similar to the region growing algorithm:

    1. Take the first pixel from the narrowband_point_list and calculate the distance for each neighbor (6er)
    2. If the current index's distance value is below a certain threshold push it into the list
    3. Next iteration take the next index from the list and start with 1. again

    This is done until the narrowband_point_list is empty.
  */
  std::queue<DistanceImageType::IndexType> narrowbandPoints;
  PointType currentPoint = m_Centers.at(0);
  double distance = this->CalculateDistanceValue(currentPoint);

  DistanceImageType::IndexType currentIndex;
  currentIndex[0] = ( currentPoint[0]-xmin ) / m_DistanceImageSpacing;
  currentIndex[1] = ( currentPoint[1]-ymin ) / m_DistanceImageSpacing;
  currentIndex[2] = ( currentPoint[2]-zmin ) / m_DistanceImageSpacing;

  narrowbandPoints.push(currentIndex);
  distanceImg->SetPixel(currentIndex, distance);

  NeighborhoodImageIterator::RadiusType radius;
  radius.Fill(1);
  NeighborhoodImageIterator nIt(radius, distanceImg, distanceImg->GetLargestPossibleRegion());
  unsigned int relativeNbIdx[] = {4, 10, 12, 14, 16, 22};

  bool isInBounds = false;

  while ( !narrowbandPoints.empty() )
  {

    nIt.SetLocation(narrowbandPoints.front());
    narrowbandPoints.pop();

    for (int i = 0; i < 6; i++)
    {
      nIt.GetPixel(relativeNbIdx[i], isInBounds);
      if( isInBounds && nIt.GetPixel(relativeNbIdx[i]) == 10)
      {
        currentIndex = nIt.GetIndex(relativeNbIdx[i]);

        currentPoint[0] = currentIndex[0]*m_DistanceImageSpacing + xmin;
        currentPoint[1] = currentIndex[1]*m_DistanceImageSpacing + ymin;
        currentPoint[2] = currentIndex[2]*m_DistanceImageSpacing + zmin;

        distance = this->CalculateDistanceValue(currentPoint);
        if ( abs(distance) <= m_DistanceImageSpacing*2 )
        {
          nIt.SetPixel(relativeNbIdx[i], distance);
          narrowbandPoints.push(currentIndex);
        }
      }
    }
  }

  ImageIterator imgRegionIterator (distanceImg, distanceImg->GetLargestPossibleRegion());
  imgRegionIterator.GoToBegin();

  double prevPixelVal = 1;

  unsigned int _size[3] = { (unsigned int)(size[0] - 1), (unsigned int)(size[1] - 1), (unsigned int)(size[2] - 1) };

  //Set every pixel inside the surface to -10 except the edge point (so that the received surface is closed)
  while (!imgRegionIterator.IsAtEnd()) {

    if ( imgRegionIterator.Get() == 10 && prevPixelVal < 0 )
    {

      while (imgRegionIterator.Get() == 10)
      {
        if (imgRegionIterator.GetIndex()[0] == _size[0] || imgRegionIterator.GetIndex()[1] == _size[1] || imgRegionIterator.GetIndex()[2] == _size[2] 
            || imgRegionIterator.GetIndex()[0] == 0U || imgRegionIterator.GetIndex()[1] == 0U || imgRegionIterator.GetIndex()[2] == 0U )
        {
          imgRegionIterator.Set(10);
          prevPixelVal = 10;
          ++imgRegionIterator;
          break;
        }
        else
        {
          imgRegionIterator.Set(-10);
          ++imgRegionIterator;
          prevPixelVal = -10;
        }

      }

    }
    else if (imgRegionIterator.GetIndex()[0] == _size[0] || imgRegionIterator.GetIndex()[1] == _size[1] || imgRegionIterator.GetIndex()[2] == _size[2] 
            || imgRegionIterator.GetIndex()[0] == 0U || imgRegionIterator.GetIndex()[1] == 0U || imgRegionIterator.GetIndex()[2] == 0U)
    {
      imgRegionIterator.Set(10);
      prevPixelVal = 10;
      ++imgRegionIterator;
    }
    else {
        prevPixelVal = imgRegionIterator.Get();
        ++imgRegionIterator;
    }

  }

  Image::Pointer resultImage = this->GetOutput();

  Point3D origin;
  origin[0] = xmin;
  origin[1] = ymin;
  origin[2] = zmin;

  CastToMitkImage(distanceImg, resultImage);
  resultImage->GetGeometry()->SetOrigin(origin);
  resultImage->SetOrigin(origin);
}
void mitk::CreateDistanceImageFromSurfaceFilter::FillDistanceImage()
{
  /*
  * Now we must calculate the distance for each pixel. But instead of calculating the distance value
  * for all of the image's pixels we proceed similar to the region growing algorithm:
  *
  * 1. Take the first pixel from the narrowband_point_list and calculate the distance for each neighbor (6er)
  * 2. If the current index's distance value is below a certain threshold push it into the list
  * 3. Next iteration take the next index from the list and originAsIndex with 1. again
  *
  * This is done until the narrowband_point_list is empty.
  */

  typedef itk::ImageRegionIteratorWithIndex<DistanceImageType> ImageIterator;
  typedef itk::NeighborhoodIterator<DistanceImageType> NeighborhoodImageIterator;

  std::queue<DistanceImageType::IndexType> narrowbandPoints;
  PointType currentPoint = m_Centers.at(0);
  double distance = this->CalculateDistanceValue(currentPoint);

  // create itk::Point from vnl_vector
  DistanceImageType::PointType currentPointAsPoint;
  currentPointAsPoint[0] = currentPoint[0];
  currentPointAsPoint[1] = currentPoint[1];
  currentPointAsPoint[2] = currentPoint[2];

  // Transform the input point in world-coordinates to index-coordinates
  DistanceImageType::IndexType currentIndex;
  m_DistanceImageITK->TransformPhysicalPointToIndex( currentPointAsPoint, currentIndex );

  assert( m_DistanceImageITK->GetLargestPossibleRegion().IsInside(currentIndex) ); // we are quite certain this should hold

  narrowbandPoints.push(currentIndex);
  m_DistanceImageITK->SetPixel(currentIndex, distance);

  NeighborhoodImageIterator::RadiusType radius;
  radius.Fill(1);
  NeighborhoodImageIterator nIt(radius, m_DistanceImageITK, m_DistanceImageITK->GetLargestPossibleRegion());
  unsigned int relativeNbIdx[] = {4, 10, 12, 14, 16, 22};

  bool isInBounds = false;
  while ( !narrowbandPoints.empty() )
  {

    nIt.SetLocation(narrowbandPoints.front());
    narrowbandPoints.pop();

    unsigned int* relativeNb = &relativeNbIdx[0];
    for (int i = 0; i < 6; i++)
    {
      nIt.GetPixel(*relativeNb, isInBounds);
      if( isInBounds && nIt.GetPixel(*relativeNb) == m_DistanceImageDefaultBufferValue)
      {
        currentIndex = nIt.GetIndex(*relativeNb);

        // Transform the currently checked point from index-coordinates to
        // world-coordinates
        m_DistanceImageITK->TransformIndexToPhysicalPoint( currentIndex, currentPointAsPoint );

        // create a vnl_vector
        currentPoint[0] = currentPointAsPoint[0];
        currentPoint[1] = currentPointAsPoint[1];
        currentPoint[2] = currentPointAsPoint[2];

        // and check the distance
        distance = this->CalculateDistanceValue(currentPoint);
        if ( std::fabs(distance) <= m_DistanceImageSpacing*2 )
        {
          nIt.SetPixel(*relativeNb, distance);
          narrowbandPoints.push(currentIndex);
        }
      }
      relativeNb++;
    }
  }


  ImageIterator imgRegionIterator (m_DistanceImageITK, m_DistanceImageITK->GetLargestPossibleRegion());
  imgRegionIterator.GoToBegin();

  double prevPixelVal = 1;

  DistanceImageType::IndexType _size;
  _size.Fill(-1);
  _size += m_DistanceImageITK->GetLargestPossibleRegion().GetSize();

  //Set every pixel inside the surface to -m_DistanceImageDefaultBufferValue except the edge point (so that the received surface is closed)
  while (!imgRegionIterator.IsAtEnd()) {

    if ( imgRegionIterator.Get() == m_DistanceImageDefaultBufferValue && prevPixelVal < 0 )
    {

      while (imgRegionIterator.Get() == m_DistanceImageDefaultBufferValue)
      {
        if (imgRegionIterator.GetIndex()[0] == _size[0] || imgRegionIterator.GetIndex()[1] == _size[1] || imgRegionIterator.GetIndex()[2] == _size[2]
            || imgRegionIterator.GetIndex()[0] == 0U || imgRegionIterator.GetIndex()[1] == 0U || imgRegionIterator.GetIndex()[2] == 0U )
        {
          imgRegionIterator.Set(m_DistanceImageDefaultBufferValue);
          prevPixelVal = m_DistanceImageDefaultBufferValue;
          ++imgRegionIterator;
          break;
        }
        else
        {
          imgRegionIterator.Set((-1)*m_DistanceImageDefaultBufferValue);
          ++imgRegionIterator;
          prevPixelVal = (-1)*m_DistanceImageDefaultBufferValue;
        }

      }

    }
    else if (imgRegionIterator.GetIndex()[0] == _size[0] || imgRegionIterator.GetIndex()[1] == _size[1] || imgRegionIterator.GetIndex()[2] == _size[2]
             || imgRegionIterator.GetIndex()[0] == 0U || imgRegionIterator.GetIndex()[1] == 0U || imgRegionIterator.GetIndex()[2] == 0U)

    {
      imgRegionIterator.Set(m_DistanceImageDefaultBufferValue);
      prevPixelVal = m_DistanceImageDefaultBufferValue;
      ++imgRegionIterator;
    }
    else
    {
      prevPixelVal = imgRegionIterator.Get();
      ++imgRegionIterator;
    }
  }

  Image::Pointer resultImage = this->GetOutput();

  // Cast the created distance-Image from itk::Image to the mitk::Image
  // that is our output.
  CastToMitkImage(m_DistanceImageITK, resultImage);
}
Ejemplo n.º 11
0
/**
 1 Determine which slice is clicked into
 2 Determine if the user clicked inside or outside of the segmentation
 3 Depending on the pixel value under the mouse click position, two different things happen: (separated out into OnMousePressedInside and OnMousePressedOutside)
   3.1 Create a skeletonization of the segmentation and try to find a nice cut
     3.1.1 Call a ipSegmentation algorithm to create a nice cut
     3.1.2 Set the result of this algorithm as the feedback contour
   3.2 Initialize region growing
     3.2.1 Determine memory offset inside the original image
     3.2.2 Determine initial region growing parameters from the level window settings of the image
     3.2.3 Perform a region growing (which generates a new feedback contour)
 */
bool mitk::RegionGrowingTool::OnMousePressed ( StateMachineAction*, InteractionEvent* interactionEvent )
{
  mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
  //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
  if (!positionEvent) return false;

  m_LastEventSender = positionEvent->GetSender();
  m_LastEventSlice = m_LastEventSender->GetSlice();

  //ToolLogger::SetVerboseness(3);

  MITK_DEBUG << "OnMousePressed" << std::endl;
  if ( FeedbackContourTool::CanHandleEvent(interactionEvent) > 0.0 )
  {
    MITK_DEBUG << "OnMousePressed: FeedbackContourTool says ok" << std::endl;

    // 1. Find out which slice the user clicked, find out which slice of the toolmanager's reference and working image corresponds to that
    if (positionEvent)
    {
      MITK_DEBUG << "OnMousePressed: got positionEvent" << std::endl;

      m_ReferenceSlice = FeedbackContourTool::GetAffectedReferenceSlice( positionEvent );
      m_WorkingSlice   = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent );

      if ( m_WorkingSlice.IsNotNull() ) // can't do anything without the segmentation
      {
        MITK_DEBUG << "OnMousePressed: got working slice" << std::endl;

        // 2. Determine if the user clicked inside or outside of the segmentation
          const Geometry3D* workingSliceGeometry = m_WorkingSlice->GetGeometry();
          Point3D mprojectedPointIn2D;
          workingSliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), mprojectedPointIn2D);
          itk::Index<2> projectedPointInWorkingSlice2D;
          projectedPointInWorkingSlice2D[0] = static_cast<int>( mprojectedPointIn2D[0] - 0.5 );
          projectedPointInWorkingSlice2D[1] = static_cast<int>( mprojectedPointIn2D[1] - 0.5 );

          if ( workingSliceGeometry->IsIndexInside( projectedPointInWorkingSlice2D ) )
          {
            MITK_DEBUG << "OnMousePressed: point " << positionEvent->GetPositionInWorld() << " (index coordinates " << projectedPointInWorkingSlice2D << ") IS in working slice" << std::endl;

            // Convert to ipMITKSegmentationTYPE (because getting pixels relys on that data type)
            itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
            CastToItkImage( m_WorkingSlice, correctPixelTypeImage );
            assert (correctPixelTypeImage.IsNotNull() );

          // possible bug in CastToItkImage ?
          // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in
          // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479:
          // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed
          // solution here: we overwrite it with an unity matrix
          itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
          imageDirection.SetIdentity();
          correctPixelTypeImage->SetDirection(imageDirection);

          Image::Pointer temporarySlice = Image::New();
        //  temporarySlice = ImportItkImage( correctPixelTypeImage );
          CastToMitkImage( correctPixelTypeImage, temporarySlice );

          mitkIpPicDescriptor* workingPicSlice = mitkIpPicNew();
          CastToIpPicDescriptor(temporarySlice, workingPicSlice);

          int initialWorkingOffset = projectedPointInWorkingSlice2D[1] * workingPicSlice->n[0] + projectedPointInWorkingSlice2D[0];

          if ( initialWorkingOffset < static_cast<int>( workingPicSlice->n[0] * workingPicSlice->n[1] ) &&
               initialWorkingOffset >= 0 )
          {
            // 3. determine the pixel value under the last click
            bool inside = static_cast<ipMITKSegmentationTYPE*>(workingPicSlice->data)[initialWorkingOffset] != 0;
            m_PaintingPixelValue = inside ? 0 : 1; // if inside, we want to remove a part, otherwise we want to add something

            if ( m_LastWorkingSeed >= static_cast<int>( workingPicSlice->n[0] * workingPicSlice->n[1] ) ||
                 m_LastWorkingSeed < 0 )
            {
              inside = false;
            }

            if ( m_ReferenceSlice.IsNotNull() )
            {
              MITK_DEBUG << "OnMousePressed: got reference slice" << std::endl;

              m_OriginalPicSlice = mitkIpPicNew();
              CastToIpPicDescriptor(m_ReferenceSlice, m_OriginalPicSlice);

              // 3.1. Switch depending on the pixel value
              if (inside)
              {
                OnMousePressedInside( NULL, interactionEvent, workingPicSlice, initialWorkingOffset);
              }
              else
              {
                OnMousePressedOutside( NULL, interactionEvent);
              }
            }
          }
        }
      }
    }
  }

  MITK_DEBUG << "end OnMousePressed" << std::endl;
  return true;
}
Ejemplo n.º 12
0
void mitk::CorrectorAlgorithm::GenerateData()
{
  Image::Pointer inputImage = const_cast<Image*>(ImageToImageFilter::GetInput(0));

  if (inputImage.IsNull() || inputImage->GetDimension() != 2)
  {
    itkExceptionMacro("CorrectorAlgorithm needs a 2D image as input.");
  }

  if (m_Contour.IsNull())
  {
    itkExceptionMacro("CorrectorAlgorithm needs a Contour object as input.");
  }

   // copy the input (since m_WorkingImage will be changed later)
  m_WorkingImage = Image::New();
  m_WorkingImage->Initialize( inputImage );
  m_WorkingImage->SetVolume( inputImage.GetPointer()->GetData() );

  if (inputImage->GetTimeSlicedGeometry() )
  {
    AffineGeometryFrame3D::Pointer originalGeometryAGF = inputImage->GetTimeSlicedGeometry()->Clone();
    TimeSlicedGeometry::Pointer originalGeometry = dynamic_cast<TimeSlicedGeometry*>( originalGeometryAGF.GetPointer() );
    m_WorkingImage->SetGeometry( originalGeometry );
  }
  else
  {
    itkExceptionMacro("Original image does not have a 'Time sliced geometry'! Cannot copy.");
  }

 
  // Convert to ipMITKSegmentationTYPE (because TobiasHeimannCorrectionAlgorithm relys on that data type)
  itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
  CastToItkImage( m_WorkingImage, correctPixelTypeImage );
  assert (correctPixelTypeImage.IsNotNull() );

  // possible bug in CastToItkImage ?
  // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in
  // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479:
  // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed
  // solution here: we overwrite it with an unity matrix
  itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
  imageDirection.SetIdentity();
  correctPixelTypeImage->SetDirection(imageDirection);

  Image::Pointer temporarySlice = this->GetOutput();
  //  temporarySlice = ImportItkImage( correctPixelTypeImage );
  CastToMitkImage( correctPixelTypeImage, temporarySlice );

  TobiasHeimannCorrectionAlgorithm( temporarySlice->GetSliceData()->GetPicDescriptor() );

  // temporarySlice is our return value (user  can get it by calling GetOutput() )

  CalculateDifferenceImage( temporarySlice, inputImage );
  if ( m_DifferenceImage.IsNotNull() && inputImage->GetTimeSlicedGeometry() )
  {
    AffineGeometryFrame3D::Pointer originalGeometryAGF = inputImage->GetTimeSlicedGeometry()->Clone();
    TimeSlicedGeometry::Pointer originalGeometry = dynamic_cast<TimeSlicedGeometry*>( originalGeometryAGF.GetPointer() );
    m_DifferenceImage->SetGeometry( originalGeometry );
  }
  else
  {
    itkExceptionMacro("Original image does not have a 'Time sliced geometry'! Cannot copy.");
  }
}
  std::vector<BaseData::Pointer> DICOMSegmentationIO::Read()
  {
    mitk::LocaleSwitch localeSwitch("C");

    LabelSetImage::Pointer labelSetImage;
    std::vector<BaseData::Pointer> result;

    const std::string path = this->GetLocalFileName();

    MITK_INFO << "loading " << path << std::endl;

    if (path.empty())
      mitkThrow() << "Empty filename in mitk::ItkImageIO ";

    try
    {
      // Get the dcm data set from file path
      DcmFileFormat dcmFileFormat;
      OFCondition status = dcmFileFormat.loadFile(path.c_str());
      if (status.bad())
        mitkThrow() << "Can't read the input file!";

      DcmDataset *dataSet = dcmFileFormat.getDataset();
      if (dataSet == nullptr)
        mitkThrow() << "Can't read data from input file!";

      // Read the DICOM SEG images (segItkImages) and DICOM tags (metaInfo)
      dcmqi::ImageSEGConverter *converter = new dcmqi::ImageSEGConverter();
      pair<map<unsigned, ImageType::Pointer>, string> dcmqiOutput = converter->dcmSegmentation2itkimage(dataSet);

      map<unsigned, ImageType::Pointer> segItkImages = dcmqiOutput.first;

      // For each itk image add a layer to the LabelSetImage output
      for (auto &element : segItkImages)
      {
        // Get the labeled image and cast it to mitkImage
        typedef itk::CastImageFilter<itkInternalImageType, itkInputImageType> castItkImageFilterType;
        castItkImageFilterType::Pointer castFilter = castItkImageFilterType::New();
        castFilter->SetInput(element.second);
        castFilter->Update();

        Image::Pointer layerImage;
        CastToMitkImage(castFilter->GetOutput(), layerImage);

        // Get pixel value of the label
        itkInternalImageType::ValueType segValue = 1;
        typedef itk::ImageRegionIterator<const itkInternalImageType> IteratorType;
        // Iterate over the image to find the pixel value of the label
        IteratorType iter(element.second, element.second->GetLargestPossibleRegion());
        iter.GoToBegin();
        while (!iter.IsAtEnd())
        {
          itkInputImageType::PixelType value = iter.Get();
          if (value != 0)
          {
            segValue = value;
            break;
          }
          ++iter;
        }

        dcmqi::JSONSegmentationMetaInformationHandler metaInfo(dcmqiOutput.second.c_str());
        metaInfo.read();
        MITK_INFO << "Input " << metaInfo.getJSONOutputAsString();
        // TODO: Read all DICOM Tags

        // Get the label information from segment attributes
        vector<map<unsigned, dcmqi::SegmentAttributes *>>::const_iterator segmentIter =
          metaInfo.segmentsAttributesMappingList.begin();
        map<unsigned, dcmqi::SegmentAttributes *> segmentMap = (*segmentIter);
        map<unsigned, dcmqi::SegmentAttributes *>::const_iterator segmentMapIter = (*segmentIter).begin();
        dcmqi::SegmentAttributes *segmentAttr = (*segmentMapIter).second;

        OFString labelName;

        if (segmentAttr->getSegmentedPropertyTypeCodeSequence() != nullptr)
          segmentAttr->getSegmentedPropertyTypeCodeSequence()->getCodeMeaning(labelName);
        else
        {
          labelName = std::to_string(segmentAttr->getLabelID()).c_str();
          if (labelName.empty())
            labelName = "Unnamed";
        }

        float tmp[3] = {0.0, 0.0, 0.0};
        if (segmentAttr->getRecommendedDisplayRGBValue() != nullptr)
        {
          tmp[0] = segmentAttr->getRecommendedDisplayRGBValue()[0] / 255.0;
          tmp[1] = segmentAttr->getRecommendedDisplayRGBValue()[1] / 255.0;
          tmp[2] = segmentAttr->getRecommendedDisplayRGBValue()[2] / 255.0;
        }

        // If labelSetImage do not exists (first image)
        if (labelSetImage.IsNull())
        {
          // Initialize the labelSetImage with the read image
          labelSetImage = LabelSetImage::New();
          labelSetImage->InitializeByLabeledImage(layerImage);
          // Already a label was generated, so set the information to this
          Label *activeLabel = labelSetImage->GetActiveLabel(labelSetImage->GetActiveLayer());
          activeLabel->SetName(labelName.c_str());
          activeLabel->SetColor(Color(tmp));
          activeLabel->SetValue(segValue);
        }
        else
        {
          // Add a new layer to the labelSetImage. Background label is set automatically
          labelSetImage->AddLayer(layerImage);

          // Add new label
          Label *newLabel = new Label;
          newLabel->SetName(labelName.c_str());
          newLabel->SetColor(Color(tmp));
          newLabel->SetValue(segValue);

          labelSetImage->GetLabelSet(labelSetImage->GetActiveLayer())->AddLabel(newLabel);
        }

        ++segmentIter;
      }
      // Clean up
      if (converter != nullptr)
        delete converter;
    }
    catch (const std::exception &e)
    {
      MITK_ERROR << "An error occurred while reading the DICOM Seg file: " << e.what();
      return result;
    }

    // Set active layer to th first layer of the labelset image
    if (labelSetImage->GetNumberOfLayers() > 1 && labelSetImage->GetActiveLayer() != 0)
      labelSetImage->SetActiveLayer(0);

    result.push_back(labelSetImage.GetPointer());

    return result;
  }
bool mitk::SetRegionTool::OnMousePressed ( StateMachineAction*, InteractionEvent* interactionEvent )
{
  mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
  //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
  if (!positionEvent) return false;

  m_LastEventSender = positionEvent->GetSender();
  m_LastEventSlice = m_LastEventSender->GetSlice();
  int timeStep = positionEvent->GetSender()->GetTimeStep();

  // 1. Get the working image
  Image::Pointer workingSlice   = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent );
  if ( workingSlice.IsNull() ) return false; // can't do anything without the segmentation

  // if click was outside the image, don't continue
  const BaseGeometry* sliceGeometry = workingSlice->GetGeometry();
  itk::Index<2> projectedPointIn2D;
  sliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), projectedPointIn2D );
  if ( !sliceGeometry->IsIndexInside( projectedPointIn2D ) )
  {
    MITK_ERROR << "point apparently not inside segmentation slice" << std::endl;
    return false; // can't use that as a seed point
  }

    // Convert to ipMITKSegmentationTYPE (because ipMITKSegmentationGetContour8N relys on that data type)
    itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
    CastToItkImage( workingSlice, correctPixelTypeImage );
    assert (correctPixelTypeImage.IsNotNull() );

  // possible bug in CastToItkImage ?
  // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in
  // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479:
  // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed
  // solution here: we overwrite it with an unity matrix
  itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
  imageDirection.SetIdentity();
  correctPixelTypeImage->SetDirection(imageDirection);

    Image::Pointer temporarySlice = Image::New();
  //  temporarySlice = ImportItkImage( correctPixelTypeImage );
    CastToMitkImage( correctPixelTypeImage, temporarySlice );


  // check index positions
  mitkIpPicDescriptor* originalPicSlice = mitkIpPicNew();
  CastToIpPicDescriptor( temporarySlice, originalPicSlice );

  int m_SeedPointMemoryOffset = projectedPointIn2D[1] * originalPicSlice->n[0] + projectedPointIn2D[0];

  if ( m_SeedPointMemoryOffset >= static_cast<int>( originalPicSlice->n[0] * originalPicSlice->n[1] ) ||
       m_SeedPointMemoryOffset < 0 )
  {
    MITK_ERROR << "Memory offset calculation if mitk::SetRegionTool has some serious flaw! Aborting.." << std::endl;
    return false;
  }

  // 2. Determine the contour that surronds the selected "piece of the image"

  // find a contour seed point
  unsigned int oneContourOffset = static_cast<unsigned int>( m_SeedPointMemoryOffset ); // safe because of earlier check if m_SeedPointMemoryOffset < 0

  /**
    * The logic of finding a starting point for the contour is the following:
    *
    *  - If the initial seed point is 0, we are either inside a hole or outside of every segmentation.
    *    We move to the right until we hit a 1, which must be part of a contour.
    *
    *  - If the initial seed point is 1, then ...
    *    we now do the same (running to the right) until we hit a 1
    *
    *  In both cases the found contour point is used to extract a contour and
    *  then a test is applied to find out if the initial seed point is contained
    *  in the contour. If this is the case, filling should be applied, otherwise
    *  nothing is done.
    */
  unsigned int size = originalPicSlice->n[0] * originalPicSlice->n[1];
/*
  unsigned int rowSize = originalPicSlice->n[0];
*/
  ipMITKSegmentationTYPE* data = static_cast<ipMITKSegmentationTYPE*>(originalPicSlice->data);

  if ( data[oneContourOffset] == 0 ) // initial seed 0
  {
    for ( ; oneContourOffset < size; ++oneContourOffset )
    {
      if ( data[oneContourOffset] > 0 ) break;
    }
  }
  else if ( data[oneContourOffset] == 1 ) // initial seed 1
  {
    unsigned int lastValidPixel = size-1; // initialization, will be changed lateron
    bool inSeg = true;    // inside segmentation?
    for ( ; oneContourOffset < size; ++oneContourOffset )
    {
      if ( ( data[oneContourOffset] == 0 ) && inSeg ) // pixel 0 and inside-flag set: this happens at the first pixel outside a filled region
      {
        inSeg = false;
        lastValidPixel = oneContourOffset - 1; // store the last pixel position inside a filled region
        break;
      }
      else // pixel 1, inside-flag doesn't matter: this happens while we are inside a filled region
      {
        inSeg = true; // first iteration lands here
      }

    }
    oneContourOffset = lastValidPixel;
  }
  else
  {
    MITK_ERROR << "Fill/Erase was never intended to work with other than binary images." << std::endl;
    m_FillContour = false;
    return false;
  }

  if (oneContourOffset == size) // nothing found until end of slice
  {
    m_FillContour = false;
    return false;
  }

  int numberOfContourPoints( 0 );
  int newBufferSize( 0 );
  //MITK_INFO << "getting contour from offset " << oneContourOffset << " ("<<oneContourOffset%originalPicSlice->n[0]<<","<<oneContourOffset/originalPicSlice->n[0]<<")"<<std::endl;
  float* contourPoints = ipMITKSegmentationGetContour8N( originalPicSlice, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc

  //MITK_INFO << "contourPoints " << contourPoints << " (N="<<numberOfContourPoints<<")"<<std::endl;
  assert(contourPoints == NULL || numberOfContourPoints > 0);

  bool cursorInsideContour = ipMITKSegmentationIsInsideContour( contourPoints, numberOfContourPoints, projectedPointIn2D[0], projectedPointIn2D[1]);

  // decide if contour should be filled or not
  m_FillContour = cursorInsideContour;

  if (m_FillContour)
  {
    // copy point from float* to mitk::Contour
    ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
    contourInImageIndexCoordinates->Expand(timeStep + 1);
    contourInImageIndexCoordinates->SetClosed(true, timeStep);
    Point3D newPoint;
    for (int index = 0; index < numberOfContourPoints; ++index)
    {
      newPoint[0] = contourPoints[ 2 * index + 0 ] - 0.5;
      newPoint[1] = contourPoints[ 2 * index + 1] - 0.5;
      newPoint[2] = 0;

      contourInImageIndexCoordinates->AddVertex(newPoint, timeStep);
    }

    m_SegmentationContourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true, correct the result from ipMITKSegmentationGetContour8N

    // 3. Show the contour
    FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );

    FeedbackContourTool::SetFeedbackContourVisible(true);
    mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
  }

  // always generate a second contour, containing the whole image (used when CTRL is pressed)
  {
    // copy point from float* to mitk::Contour
    ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
    contourInImageIndexCoordinates->Expand(timeStep + 1);
    contourInImageIndexCoordinates->SetClosed(true, timeStep);
    Point3D newPoint;
    newPoint[0] = 0; newPoint[1] = 0; newPoint[2] = 0.0;
    contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );
    newPoint[0] = originalPicSlice->n[0]; newPoint[1] = 0; newPoint[2] = 0.0;
    contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );
    newPoint[0] = originalPicSlice->n[0]; newPoint[1] = originalPicSlice->n[1]; newPoint[2] = 0.0;
    contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );
    newPoint[0] = 0; newPoint[1] = originalPicSlice->n[1]; newPoint[2] = 0.0;
    contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );

    m_WholeImageContourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true, correct the result from ipMITKSegmentationGetContour8N

    // 3. Show the contour
    FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );

    FeedbackContourTool::SetFeedbackContourVisible(true);
    mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
  }


  free(contourPoints);

  return true;
}
void mitk::CreateDistanceImageFromSurfaceFilter::CreateDistanceImage()
{
  DistanceImageType::Pointer distanceImg = DistanceImageType::New();

  // Determine the bounds of the input points in index- and world-coordinates
  DistanceImageType::PointType minPointInWorldCoordinates, maxPointInWorldCoordinates;
  DistanceImageType::IndexType minPointInIndexCoordinates, maxPointInIndexCoordinates;

  DetermineBounds( minPointInWorldCoordinates, maxPointInWorldCoordinates,
                   minPointInIndexCoordinates, maxPointInIndexCoordinates );


  // Calculate the extent of the region that contains all given points in MM.
  // To do this, we take the difference between the maximal and minimal
  // index-coordinates (must not be less than 1) and multiply it with the
  // spacing of the reference-image.
  Vector3D extentMM;
  for (unsigned int dim = 0; dim < 3; ++dim)
  {
    extentMM[dim] = (int)
      (
                    (std::max( std::abs(maxPointInIndexCoordinates[dim] - minPointInIndexCoordinates[dim]),
                              (DistanceImageType::IndexType::IndexValueType) 1
                            ) + 1.0) // (max-index - min-index)+1 because the pixels between index 3 and 5 cover 2+1=3 pixels (pixel 3,4, and 5)
                    * m_ReferenceImage->GetSpacing()[dim]
      ) + 1; // (int) ((...) + 1) -> we round up to the next BIGGER int value
  }

  /*
  * Now create an empty distance image. The create image will always have the same sizeOfRegion, independent from
  * the original image (e.g. always consists of 500000 pixels) and will have an isotropic spacing.
  * The spacing is calculated like the following:
  * The image's volume = 500000 Pixels = extentX*spacing*extentY*spacing*extentZ*spacing
  * So the spacing is: spacing = ( 500000 / extentX*extentY*extentZ )^(1/3)
  */
  double basis = (extentMM[0]*extentMM[1]*extentMM[2]) / m_DistanceImageVolume;
  double exponent = 1.0/3.0;
  double distImgSpacing = pow(basis, exponent);
  int tempSpacing = (distImgSpacing+0.05)*10;
  m_DistanceImageSpacing = (double)tempSpacing/10.0;

  // calculate the number of pixels of the distance image for each direction
  unsigned int numberOfXPixel = extentMM[0] / m_DistanceImageSpacing;
  unsigned int numberOfYPixel = extentMM[1] / m_DistanceImageSpacing;
  unsigned int numberOfZPixel = extentMM[2] / m_DistanceImageSpacing;

  // We increase the sizeOfRegion by 4 as we decrease the origin by 2 later.
  // This expansion of the region is necessary to achieve a complete
  // interpolation.
  DistanceImageType::SizeType sizeOfRegion;
  sizeOfRegion[0] = numberOfXPixel + 4;
  sizeOfRegion[1] = numberOfYPixel + 4;
  sizeOfRegion[2] = numberOfZPixel + 4;

  // The region starts at index 0,0,0
  DistanceImageType::IndexType initialOriginAsIndex;
  initialOriginAsIndex.Fill(0);

  DistanceImageType::PointType originAsWorld = minPointInWorldCoordinates;

  DistanceImageType::RegionType lpRegion;
  lpRegion.SetSize(sizeOfRegion);
  lpRegion.SetIndex(initialOriginAsIndex);

  // We initialize the itk::Image with
  //  * origin and direction to have it correctly placed and rotated in the world
  //  * the largest possible region to set the extent to be calculated
  //  * the isotropic spacing that we have calculated above
  distanceImg->SetOrigin( originAsWorld );
  distanceImg->SetDirection( m_ReferenceImage->GetDirection() );
  distanceImg->SetRegions( lpRegion );
  distanceImg->SetSpacing( m_DistanceImageSpacing );
  distanceImg->Allocate();

  //First of all the image is initialized with the value 10 for each pixel
  distanceImg->FillBuffer(10);

  // Now we move the origin of the distanceImage 2 index-Coordinates
  // in all directions
  DistanceImageType::IndexType originAsIndex;
  distanceImg->TransformPhysicalPointToIndex( originAsWorld, originAsIndex );
  originAsIndex[0] -= 2;
  originAsIndex[1] -= 2;
  originAsIndex[2] -= 2;
  distanceImg->TransformIndexToPhysicalPoint( originAsIndex, originAsWorld );
  distanceImg->SetOrigin( originAsWorld );

  /*
  * Now we must calculate the distance for each pixel. But instead of calculating the distance value
  * for all of the image's pixels we proceed similar to the region growing algorithm:
  *
  * 1. Take the first pixel from the narrowband_point_list and calculate the distance for each neighbor (6er)
  * 2. If the current index's distance value is below a certain threshold push it into the list
  * 3. Next iteration take the next index from the list and originAsIndex with 1. again
  *
  * This is done until the narrowband_point_list is empty.
  */
  std::queue<DistanceImageType::IndexType> narrowbandPoints;
  PointType currentPoint = m_Centers.at(0);
  double distance = this->CalculateDistanceValue(currentPoint);

  // create itk::Point from vnl_vector
  DistanceImageType::PointType currentPointAsPoint;
  currentPointAsPoint[0] = currentPoint[0];
  currentPointAsPoint[1] = currentPoint[1];
  currentPointAsPoint[2] = currentPoint[2];

  // Transform the input point in world-coordinates to index-coordinates
  DistanceImageType::IndexType currentIndex;
  distanceImg->TransformPhysicalPointToIndex( currentPointAsPoint, currentIndex );

  assert( lpRegion.IsInside(currentIndex) ); // we are quite certain this should hold

  narrowbandPoints.push(currentIndex);
  distanceImg->SetPixel(currentIndex, distance);

  NeighborhoodImageIterator::RadiusType radius;
  radius.Fill(1);
  NeighborhoodImageIterator nIt(radius, distanceImg, distanceImg->GetLargestPossibleRegion());
  unsigned int relativeNbIdx[] = {4, 10, 12, 14, 16, 22};

  bool isInBounds = false;
  while ( !narrowbandPoints.empty() )
  {

    nIt.SetLocation(narrowbandPoints.front());
    narrowbandPoints.pop();

    unsigned int* relativeNb = &relativeNbIdx[0];
    for (int i = 0; i < 6; i++)
    {
      nIt.GetPixel(*relativeNb, isInBounds);
      if( isInBounds && nIt.GetPixel(*relativeNb) == 10)
      {
        currentIndex = nIt.GetIndex(*relativeNb);

        // Transform the currently checked point from index-coordinates to
        // world-coordinates
        distanceImg->TransformIndexToPhysicalPoint( currentIndex, currentPointAsPoint );

        // create a vnl_vector
        currentPoint[0] = currentPointAsPoint[0];
        currentPoint[1] = currentPointAsPoint[1];
        currentPoint[2] = currentPointAsPoint[2];

        // and check the distance
        distance = this->CalculateDistanceValue(currentPoint);
        if ( abs(distance) <= m_DistanceImageSpacing )
        {
          nIt.SetPixel(*relativeNb, distance);
          narrowbandPoints.push(currentIndex);
        }
      }
      relativeNb++;
    }
  }

  // Fist we set the border slices of the image to value 1000 so that we can perform a
  // region growing afterwards starting from the middle of the image

  DistanceImageType::SizeType reqSize;

  reqSize[0] = distanceImg->GetLargestPossibleRegion().GetSize()[0];
  reqSize[1] = distanceImg->GetLargestPossibleRegion().GetSize()[1];
  reqSize[2] = 1;

  DistanceImageType::IndexType reqStart;
  reqStart[0] = 0;
  reqStart[1] = 0;
  reqStart[2] = 0;

  DistanceImageType::RegionType reqRegion;

  reqRegion.SetSize(reqSize);
  reqRegion.SetIndex(reqStart);

  this->FillImageRegion(reqRegion, 1000, distanceImg);

  reqStart[0] = 0;
  reqStart[1] = 0;
  reqStart[2] = distanceImg->GetLargestPossibleRegion().GetSize()[2]-1;

  reqRegion.SetIndex(reqStart);

  this->FillImageRegion(reqRegion, 1000, distanceImg);

  reqSize[0] = 1;
  reqSize[1] = distanceImg->GetLargestPossibleRegion().GetSize()[1];
  reqSize[2] = distanceImg->GetLargestPossibleRegion().GetSize()[2];;

  reqStart[0] = 0;
  reqStart[1] = 0;
  reqStart[2] = 0;

  reqRegion.SetSize(reqSize);
  reqRegion.SetIndex(reqStart);

  this->FillImageRegion(reqRegion, 1000, distanceImg);

  reqStart[0] = distanceImg->GetLargestPossibleRegion().GetSize()[0]-1;
  reqStart[1] = 0;
  reqStart[2] = 0;

  reqRegion.SetIndex(reqStart);

  this->FillImageRegion(reqRegion, 1000, distanceImg);

  reqSize[0] = distanceImg->GetLargestPossibleRegion().GetSize()[0];
  reqSize[1] = 1;
  reqSize[2] = distanceImg->GetLargestPossibleRegion().GetSize()[2];;

  reqStart[0] = 0;
  reqStart[1] = 0;
  reqStart[2] = 0;

  reqRegion.SetSize(reqSize);
  reqRegion.SetIndex(reqStart);

  this->FillImageRegion(reqRegion, 1000, distanceImg);

  reqStart[0] = 0;
  reqStart[1] = distanceImg->GetLargestPossibleRegion().GetSize()[1]-1;
  reqStart[2] = 0;

  reqRegion.SetIndex(reqStart);

  this->FillImageRegion(reqRegion, 1000, distanceImg);

  // Now we make some kind of region growing from the middle of the image to set all
  // inner pixels to -10. In this way we assure to extract a valid surface
  NeighborhoodImageIterator nIt2(radius, distanceImg, distanceImg->GetLargestPossibleRegion());

  currentIndex[0] = distanceImg->GetLargestPossibleRegion().GetSize()[0]*0.5;
  currentIndex[1] = distanceImg->GetLargestPossibleRegion().GetSize()[1]*0.5;
  currentIndex[2] = distanceImg->GetLargestPossibleRegion().GetSize()[2]*0.5;

  narrowbandPoints.push(currentIndex);
  distanceImg->SetPixel(currentIndex, -10);

  while ( !narrowbandPoints.empty() )
  {

    nIt2.SetLocation(narrowbandPoints.front());
    narrowbandPoints.pop();

    for (int i = 0; i < 6; i++)
    {
      if( nIt2.GetPixel(relativeNbIdx[i]) == 10)
      {
          currentIndex = nIt2.GetIndex(relativeNbIdx[i]);
          nIt2.SetPixel(relativeNbIdx[i], -10);
          narrowbandPoints.push(currentIndex);
      }
    }
  }

  Image::Pointer resultImage = this->GetOutput();

  // Cast the created distance-Image from itk::Image to the mitk::Image
  // that is our output.
  CastToMitkImage(distanceImg, resultImage);
}