Пример #1
0
ImageType::Pointer SBFilterUtils::GaussianSmoothImage(ImageType::Pointer image, float variance) {
	
	GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
	gaussianFilter->SetInput(image);
	gaussianFilter->SetVariance(variance);
	gaussianFilter->Update();

	CastFilterType::Pointer castFilter = CastFilterType::New();
	castFilter->SetInput(gaussianFilter->GetOutput());
	castFilter->Update();

	return castFilter->GetOutput();
}
bool VolumeProcess::RunGaussianSmoothing(float varX, float varY, float varZ, float maxErr)
{  //by xiao liang
   typedef itk::DiscreteGaussianImageFilter< ImageType, FloatImageType3D > GaussianFilterType;
   GaussianFilterType::Pointer GaussianFilter =  GaussianFilterType::New();
   GaussianFilter->SetInput(m_outputImage);
   //GaussianFilter->SetFilterDimensionality(3);
   GaussianFilterType::ArrayType maxErrTypeValue;
   maxErrTypeValue.Fill(maxErr);
   GaussianFilter->SetMaximumError( maxErrTypeValue );

   GaussianFilterType::ArrayType variance;
   variance[0] = varX;
   variance[1] = varY;
   variance[2] = varZ;
   GaussianFilter->SetVariance(variance);
   //GaussianFilter->SetMaximumKernelWidth(maxKernalWidth);
   try
    {
		GaussianFilter->Update();
    }
   catch( itk::ExceptionObject & err )
	{
		std::cerr << "ITK FILTER ERROR: " << err << std::endl ;
		return false;
	}
	m_outputImage = RescaleFloatToImageType(GaussianFilter->GetOutput());
	if(debug)
		std::cerr << "GaussianFilter Filter Done" << std::endl;
	return true;
}
VolumeVisualizationImagePreprocessor::CTImage::Pointer 
VolumeVisualizationImagePreprocessor::Gaussian(CTImage::Pointer src)
{
  VVP_INFO << "Gaussian...";

  typedef itk::DiscreteGaussianImageFilter< CTImage, CTImage>					GaussianFilterType;

  GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
  gaussianFilter->SetInput( src );
  gaussianFilter->SetVariance( 1 );
  //   gaussianFilter->SetMaximumError( 0.1 );

  gaussianFilter->SetMaximumKernelWidth ( 8 ); 
  gaussianFilter->UpdateLargestPossibleRegion();
  
  CTImage::Pointer dst = gaussianFilter->GetOutput(); 
  dst->DisconnectPipeline();

  return dst;

}
bool ShowSegmentationAsSmoothedSurface::ThreadedUpdateFunction()
{
  Image::Pointer image;
  GetPointerParameter("Input", image);

  float smoothing;
  GetParameter("Smoothing", smoothing);

  float decimation;
  GetParameter("Decimation", decimation);

  float closing;
  GetParameter("Closing", closing);

  int timeNr = 0;
  GetParameter("TimeNr", timeNr);

  if (image->GetDimension() == 4)
    MITK_INFO << "CREATING SMOOTHED POLYGON MODEL (t = " << timeNr << ')';
  else
    MITK_INFO << "CREATING SMOOTHED POLYGON MODEL";

  MITK_INFO << "  Smoothing  = " << smoothing;
  MITK_INFO << "  Decimation = " << decimation;
  MITK_INFO << "  Closing    = " << closing;

  Geometry3D::Pointer geometry = dynamic_cast<Geometry3D *>(image->GetGeometry()->Clone().GetPointer());

  // Make ITK image out of MITK image

  typedef itk::Image<unsigned char, 3> CharImageType;
  typedef itk::Image<unsigned short, 3> ShortImageType;
  typedef itk::Image<float, 3> FloatImageType;

  if (image->GetDimension() == 4)
  {
    ImageTimeSelector::Pointer imageTimeSelector = ImageTimeSelector::New();
    imageTimeSelector->SetInput(image);
    imageTimeSelector->SetTimeNr(timeNr);
    imageTimeSelector->UpdateLargestPossibleRegion();
    image = imageTimeSelector->GetOutput(0);
  }

  ImageToItk<CharImageType>::Pointer imageToItkFilter = ImageToItk<CharImageType>::New();

  try
  {
    imageToItkFilter->SetInput(image);
  }
  catch (const itk::ExceptionObject &e)
  {
    // Most probably the input image type is wrong. Binary images are expected to be
    // >unsigned< char images.
    MITK_ERROR << e.GetDescription() << endl;
    return false;
  }

  imageToItkFilter->Update();

  CharImageType::Pointer itkImage = imageToItkFilter->GetOutput();

  // Get bounding box and relabel

  MITK_INFO << "Extracting VOI...";

  int imageLabel = 1;
  bool roiFound = false;

  CharImageType::IndexType minIndex;
  minIndex.Fill(numeric_limits<CharImageType::IndexValueType>::max());

  CharImageType::IndexType maxIndex;
  maxIndex.Fill(numeric_limits<CharImageType::IndexValueType>::min());

  itk::ImageRegionIteratorWithIndex<CharImageType> iter(itkImage, itkImage->GetLargestPossibleRegion());

  for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter)
  {
    if (iter.Get() == imageLabel)
    {
      roiFound = true;
      iter.Set(1);

      CharImageType::IndexType currentIndex = iter.GetIndex();

      for (unsigned int dim = 0; dim < 3; ++dim)
      {
        minIndex[dim] = min(currentIndex[dim], minIndex[dim]);
        maxIndex[dim] = max(currentIndex[dim], maxIndex[dim]);
      }
    }
    else
    {
      iter.Set(0);
    }
  }

  if (!roiFound)
  {
    ProgressBar::GetInstance()->Progress(8);
    MITK_ERROR << "Didn't found segmentation labeled with " << imageLabel << "!" << endl;
    return false;
  }

  ProgressBar::GetInstance()->Progress(1);

  // Extract and pad bounding box

  typedef itk::RegionOfInterestImageFilter<CharImageType, CharImageType> ROIFilterType;

  ROIFilterType::Pointer roiFilter = ROIFilterType::New();
  CharImageType::RegionType region;
  CharImageType::SizeType size;

  for (unsigned int dim = 0; dim < 3; ++dim)
  {
    size[dim] = maxIndex[dim] - minIndex[dim] + 1;
  }

  region.SetIndex(minIndex);
  region.SetSize(size);

  roiFilter->SetInput(itkImage);
  roiFilter->SetRegionOfInterest(region);
  roiFilter->ReleaseDataFlagOn();
  roiFilter->ReleaseDataBeforeUpdateFlagOn();

  typedef itk::ConstantPadImageFilter<CharImageType, CharImageType> PadFilterType;

  PadFilterType::Pointer padFilter = PadFilterType::New();
  const PadFilterType::SizeValueType pad[3] = { 10, 10, 10 };

  padFilter->SetInput(roiFilter->GetOutput());
  padFilter->SetConstant(0);
  padFilter->SetPadLowerBound(pad);
  padFilter->SetPadUpperBound(pad);
  padFilter->ReleaseDataFlagOn();
  padFilter->ReleaseDataBeforeUpdateFlagOn();
  padFilter->Update();

  CharImageType::Pointer roiImage = padFilter->GetOutput();

  roiImage->DisconnectPipeline();
  roiFilter = nullptr;
  padFilter = nullptr;

  // Correct origin of real geometry (changed by cropping and padding)

  typedef Geometry3D::TransformType TransformType;

  TransformType::Pointer transform = TransformType::New();
  TransformType::OutputVectorType translation;

  for (unsigned int dim = 0; dim < 3; ++dim)
    translation[dim] = (int)minIndex[dim] - (int)pad[dim];

  transform->SetIdentity();
  transform->Translate(translation);
  geometry->Compose(transform, true);

  ProgressBar::GetInstance()->Progress(1);

  // Median

  MITK_INFO << "Median...";

  typedef itk::BinaryMedianImageFilter<CharImageType, CharImageType> MedianFilterType;

  MedianFilterType::Pointer medianFilter = MedianFilterType::New();
  CharImageType::SizeType radius = { 0 };

  medianFilter->SetRadius(radius);
  medianFilter->SetBackgroundValue(0);
  medianFilter->SetForegroundValue(1);
  medianFilter->SetInput(roiImage);
  medianFilter->ReleaseDataFlagOn();
  medianFilter->ReleaseDataBeforeUpdateFlagOn();
  medianFilter->Update();

  ProgressBar::GetInstance()->Progress(1);

  // Intelligent closing

  MITK_INFO << "Intelligent closing...";

  unsigned int surfaceRatio = (unsigned int)((1.0f - closing) * 100.0f);

  typedef itk::IntelligentBinaryClosingFilter<CharImageType, ShortImageType> ClosingFilterType;

  ClosingFilterType::Pointer closingFilter = ClosingFilterType::New();

  closingFilter->SetInput(medianFilter->GetOutput());
  closingFilter->ReleaseDataFlagOn();
  closingFilter->ReleaseDataBeforeUpdateFlagOn();
  closingFilter->SetSurfaceRatio(surfaceRatio);
  closingFilter->Update();

  ShortImageType::Pointer closedImage = closingFilter->GetOutput();

  closedImage->DisconnectPipeline();
  roiImage = nullptr;
  medianFilter = nullptr;
  closingFilter = nullptr;

  ProgressBar::GetInstance()->Progress(1);

  // Gaussian blur

  MITK_INFO << "Gauss...";

  typedef itk::BinaryThresholdImageFilter<ShortImageType, FloatImageType> BinaryThresholdToFloatFilterType;

  BinaryThresholdToFloatFilterType::Pointer binThresToFloatFilter = BinaryThresholdToFloatFilterType::New();

  binThresToFloatFilter->SetInput(closedImage);
  binThresToFloatFilter->SetLowerThreshold(1);
  binThresToFloatFilter->SetUpperThreshold(1);
  binThresToFloatFilter->SetInsideValue(100);
  binThresToFloatFilter->SetOutsideValue(0);
  binThresToFloatFilter->ReleaseDataFlagOn();
  binThresToFloatFilter->ReleaseDataBeforeUpdateFlagOn();

  typedef itk::DiscreteGaussianImageFilter<FloatImageType, FloatImageType> GaussianFilterType;

  // From the following line on, IntelliSense (VS 2008) is broken. Any idea how to fix it?
  GaussianFilterType::Pointer gaussFilter = GaussianFilterType::New();

  gaussFilter->SetInput(binThresToFloatFilter->GetOutput());
  gaussFilter->SetUseImageSpacing(true);
  gaussFilter->SetVariance(smoothing);
  gaussFilter->ReleaseDataFlagOn();
  gaussFilter->ReleaseDataBeforeUpdateFlagOn();

  typedef itk::BinaryThresholdImageFilter<FloatImageType, CharImageType> BinaryThresholdFromFloatFilterType;

  BinaryThresholdFromFloatFilterType::Pointer binThresFromFloatFilter = BinaryThresholdFromFloatFilterType::New();

  binThresFromFloatFilter->SetInput(gaussFilter->GetOutput());
  binThresFromFloatFilter->SetLowerThreshold(50);
  binThresFromFloatFilter->SetUpperThreshold(255);
  binThresFromFloatFilter->SetInsideValue(1);
  binThresFromFloatFilter->SetOutsideValue(0);
  binThresFromFloatFilter->ReleaseDataFlagOn();
  binThresFromFloatFilter->ReleaseDataBeforeUpdateFlagOn();
  binThresFromFloatFilter->Update();

  CharImageType::Pointer blurredImage = binThresFromFloatFilter->GetOutput();

  blurredImage->DisconnectPipeline();
  closedImage = nullptr;
  binThresToFloatFilter = nullptr;
  gaussFilter = nullptr;

  ProgressBar::GetInstance()->Progress(1);

  // Fill holes

  MITK_INFO << "Filling cavities...";

  typedef itk::ConnectedThresholdImageFilter<CharImageType, CharImageType> ConnectedThresholdFilterType;

  ConnectedThresholdFilterType::Pointer connectedThresFilter = ConnectedThresholdFilterType::New();

  CharImageType::IndexType corner;

  corner[0] = 0;
  corner[1] = 0;
  corner[2] = 0;

  connectedThresFilter->SetInput(blurredImage);
  connectedThresFilter->SetSeed(corner);
  connectedThresFilter->SetLower(0);
  connectedThresFilter->SetUpper(0);
  connectedThresFilter->SetReplaceValue(2);
  connectedThresFilter->ReleaseDataFlagOn();
  connectedThresFilter->ReleaseDataBeforeUpdateFlagOn();

  typedef itk::BinaryThresholdImageFilter<CharImageType, CharImageType> BinaryThresholdFilterType;

  BinaryThresholdFilterType::Pointer binThresFilter = BinaryThresholdFilterType::New();

  binThresFilter->SetInput(connectedThresFilter->GetOutput());
  binThresFilter->SetLowerThreshold(0);
  binThresFilter->SetUpperThreshold(0);
  binThresFilter->SetInsideValue(50);
  binThresFilter->SetOutsideValue(0);
  binThresFilter->ReleaseDataFlagOn();
  binThresFilter->ReleaseDataBeforeUpdateFlagOn();

  typedef itk::AddImageFilter<CharImageType, CharImageType, CharImageType> AddFilterType;

  AddFilterType::Pointer addFilter = AddFilterType::New();

  addFilter->SetInput1(blurredImage);
  addFilter->SetInput2(binThresFilter->GetOutput());
  addFilter->ReleaseDataFlagOn();
  addFilter->ReleaseDataBeforeUpdateFlagOn();
  addFilter->Update();

  ProgressBar::GetInstance()->Progress(1);

  // Surface extraction

  MITK_INFO << "Surface extraction...";

  Image::Pointer filteredImage = Image::New();
  CastToMitkImage(addFilter->GetOutput(), filteredImage);

  filteredImage->SetGeometry(geometry);

  ImageToSurfaceFilter::Pointer imageToSurfaceFilter = ImageToSurfaceFilter::New();

  imageToSurfaceFilter->SetInput(filteredImage);
  imageToSurfaceFilter->SetThreshold(50);
  imageToSurfaceFilter->SmoothOn();
  imageToSurfaceFilter->SetDecimate(ImageToSurfaceFilter::NoDecimation);

  m_Surface = imageToSurfaceFilter->GetOutput(0);

  ProgressBar::GetInstance()->Progress(1);

  // Mesh decimation

  if (decimation > 0.0f && decimation < 1.0f)
  {
    MITK_INFO << "Quadric mesh decimation...";

    vtkQuadricDecimation *quadricDecimation = vtkQuadricDecimation::New();
    quadricDecimation->SetInputData(m_Surface->GetVtkPolyData());
    quadricDecimation->SetTargetReduction(decimation);
    quadricDecimation->AttributeErrorMetricOn();
    quadricDecimation->GlobalWarningDisplayOff();
    quadricDecimation->Update();

    vtkCleanPolyData* cleaner = vtkCleanPolyData::New();
    cleaner->SetInputConnection(quadricDecimation->GetOutputPort());
    cleaner->PieceInvariantOn();
    cleaner->ConvertLinesToPointsOn();
    cleaner->ConvertStripsToPolysOn();
    cleaner->PointMergingOn();
    cleaner->Update();

    m_Surface->SetVtkPolyData(cleaner->GetOutput());
  }

  ProgressBar::GetInstance()->Progress(1);

  // Compute Normals

  vtkPolyDataNormals* computeNormals = vtkPolyDataNormals::New();
  computeNormals->SetInputData(m_Surface->GetVtkPolyData());
  computeNormals->SetFeatureAngle(360.0f);
  computeNormals->FlipNormalsOff();
  computeNormals->Update();

  m_Surface->SetVtkPolyData(computeNormals->GetOutput());

  return true;
}
void QmitkBasicImageProcessing::StartButtonClicked()
{
  if(!m_SelectedImageNode->GetNode()) return;

  this->BusyCursorOn();

  mitk::Image::Pointer newImage;

  try
  {
    newImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData());
  }
  catch ( std::exception &e )
  {
  QString exceptionString = "An error occured during image loading:\n";
  exceptionString.append( e.what() );
    QMessageBox::warning( NULL, "Basic Image Processing", exceptionString , QMessageBox::Ok, QMessageBox::NoButton );
    this->BusyCursorOff();
    return;
  }

  // check if input image is valid, casting does not throw exception when casting from 'NULL-Object'
  if ( (! newImage) || (newImage->IsInitialized() == false) )
  {
    this->BusyCursorOff();

    QMessageBox::warning( NULL, "Basic Image Processing", "Input image is broken or not initialized. Returning.", QMessageBox::Ok, QMessageBox::NoButton );
    return;
  }

  // check if operation is done on 4D a image time step
  if(newImage->GetDimension() > 3)
  {
    mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
    timeSelector->SetInput(newImage);
    timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() );
    timeSelector->Update();
    newImage = timeSelector->GetOutput();
  }



  // check if image or vector image
  ImageType::Pointer itkImage = ImageType::New();
  VectorImageType::Pointer itkVecImage = VectorImageType::New();

  int isVectorImage = newImage->GetPixelType().GetNumberOfComponents();

  if(isVectorImage > 1)
  {
    CastToItkImage( newImage, itkVecImage );
  }
  else
  {
    CastToItkImage( newImage, itkImage );
  }

  std::stringstream nameAddition("");

  int param1 = m_Controls->sbParam1->value();
  int param2 = m_Controls->sbParam2->value();
  double dparam1 = m_Controls->dsbParam1->value();
  double dparam2 = m_Controls->dsbParam2->value();
  double dparam3 = m_Controls->dsbParam3->value();

  try{

  switch (m_SelectedAction)
  {

  case GAUSSIAN:
    {
      GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
      gaussianFilter->SetInput( itkImage );
      gaussianFilter->SetVariance( param1 );
      gaussianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(gaussianFilter->GetOutput())->Clone();
      nameAddition << "_Gaussian_var_" << param1;
      std::cout << "Gaussian filtering successful." << std::endl;
      break;
    }

  case MEDIAN:
    {
      MedianFilterType::Pointer medianFilter = MedianFilterType::New();
      MedianFilterType::InputSizeType size;
      size.Fill(param1);
      medianFilter->SetRadius( size );
      medianFilter->SetInput(itkImage);
      medianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(medianFilter->GetOutput())->Clone();
      nameAddition << "_Median_radius_" << param1;
      std::cout << "Median Filtering successful." << std::endl;
      break;
    }

  case TOTALVARIATION:
    {
      if(isVectorImage > 1)
      {
        VectorTotalVariationFilterType::Pointer TVFilter
          = VectorTotalVariationFilterType::New();
        TVFilter->SetInput( itkVecImage.GetPointer() );
        TVFilter->SetNumberIterations(param1);
        TVFilter->SetLambda(double(param2)/1000.);
        TVFilter->UpdateLargestPossibleRegion();

        newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
      }
      else
      {
        ImagePTypeToFloatPTypeCasterType::Pointer floatCaster = ImagePTypeToFloatPTypeCasterType::New();
        floatCaster->SetInput( itkImage );
        floatCaster->Update();
        FloatImageType::Pointer fImage = floatCaster->GetOutput();

        TotalVariationFilterType::Pointer TVFilter
          = TotalVariationFilterType::New();
        TVFilter->SetInput( fImage.GetPointer() );
        TVFilter->SetNumberIterations(param1);
        TVFilter->SetLambda(double(param2)/1000.);
        TVFilter->UpdateLargestPossibleRegion();

        newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
      }

      nameAddition << "_TV_Iter_" << param1 << "_L_" << param2;
      std::cout << "Total Variation Filtering successful." << std::endl;
      break;
    }

  case DILATION:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      DilationFilterType::Pointer dilationFilter = DilationFilterType::New();
      dilationFilter->SetInput( itkImage );
      dilationFilter->SetKernel( binaryBall );
      dilationFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(dilationFilter->GetOutput())->Clone();
      nameAddition << "_Dilated_by_" << param1;
      std::cout << "Dilation successful." << std::endl;
      break;
    }

  case EROSION:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      ErosionFilterType::Pointer erosionFilter = ErosionFilterType::New();
      erosionFilter->SetInput( itkImage );
      erosionFilter->SetKernel( binaryBall );
      erosionFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(erosionFilter->GetOutput())->Clone();
      nameAddition << "_Eroded_by_" << param1;
      std::cout << "Erosion successful." << std::endl;
      break;
    }

  case OPENING:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      OpeningFilterType::Pointer openFilter = OpeningFilterType::New();
      openFilter->SetInput( itkImage );
      openFilter->SetKernel( binaryBall );
      openFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(openFilter->GetOutput())->Clone();
      nameAddition << "_Opened_by_" << param1;
      std::cout << "Opening successful." << std::endl;
      break;
    }

  case CLOSING:
    {
      BallType binaryBall;
      binaryBall.SetRadius( param1 );
      binaryBall.CreateStructuringElement();

      ClosingFilterType::Pointer closeFilter = ClosingFilterType::New();
      closeFilter->SetInput( itkImage );
      closeFilter->SetKernel( binaryBall );
      closeFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(closeFilter->GetOutput())->Clone();
      nameAddition << "_Closed_by_" << param1;
      std::cout << "Closing successful." << std::endl;
      break;
    }

  case GRADIENT:
    {
      GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
      gradientFilter->SetInput( itkImage );
      gradientFilter->SetSigma( param1 );
      gradientFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(gradientFilter->GetOutput())->Clone();
      nameAddition << "_Gradient_sigma_" << param1;
      std::cout << "Gradient calculation successful." << std::endl;
      break;
    }

  case LAPLACIAN:
    {
      // the laplace filter requires a float type image as input, we need to cast the itkImage
      // to correct type
      ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
      caster->SetInput( itkImage );
      caster->Update();
      FloatImageType::Pointer fImage = caster->GetOutput();

      LaplacianFilterType::Pointer laplacianFilter = LaplacianFilterType::New();
      laplacianFilter->SetInput( fImage );
      laplacianFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(laplacianFilter->GetOutput())->Clone();
      nameAddition << "_Second_Derivative";
      std::cout << "Laplacian filtering successful." << std::endl;
      break;
    }

  case SOBEL:
    {
      // the sobel filter requires a float type image as input, we need to cast the itkImage
      // to correct type
      ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
      caster->SetInput( itkImage );
      caster->Update();
      FloatImageType::Pointer fImage = caster->GetOutput();

      SobelFilterType::Pointer sobelFilter = SobelFilterType::New();
      sobelFilter->SetInput( fImage );
      sobelFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(sobelFilter->GetOutput())->Clone();
      nameAddition << "_Sobel";
      std::cout << "Edge Detection successful." << std::endl;
      break;
    }

  case THRESHOLD:
    {
      ThresholdFilterType::Pointer thFilter = ThresholdFilterType::New();
      thFilter->SetLowerThreshold(param1 < param2 ? param1 : param2);
      thFilter->SetUpperThreshold(param2 > param1 ? param2 : param1);
      thFilter->SetInsideValue(1);
      thFilter->SetOutsideValue(0);
      thFilter->SetInput(itkImage);
      thFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(thFilter->GetOutput())->Clone();
      nameAddition << "_Threshold";
      std::cout << "Thresholding successful." << std::endl;
      break;
    }

  case INVERSION:
    {
      InversionFilterType::Pointer invFilter = InversionFilterType::New();
      mitk::ScalarType min = newImage->GetScalarValueMin();
      mitk::ScalarType max = newImage->GetScalarValueMax();
      invFilter->SetMaximum( max + min );
      invFilter->SetInput(itkImage);
      invFilter->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(invFilter->GetOutput())->Clone();
      nameAddition << "_Inverted";
      std::cout << "Image inversion successful." << std::endl;
      break;
    }

  case DOWNSAMPLING:
    {
      ResampleImageFilterType::Pointer downsampler = ResampleImageFilterType::New();
      downsampler->SetInput( itkImage );

      NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
      downsampler->SetInterpolator( interpolator );

      downsampler->SetDefaultPixelValue( 0 );

      ResampleImageFilterType::SpacingType spacing = itkImage->GetSpacing();
      spacing *= (double) param1;
      downsampler->SetOutputSpacing( spacing );

      downsampler->SetOutputOrigin( itkImage->GetOrigin() );
      downsampler->SetOutputDirection( itkImage->GetDirection() );

      ResampleImageFilterType::SizeType size = itkImage->GetLargestPossibleRegion().GetSize();
      for ( int i = 0; i < 3; ++i )
      {
        size[i] /= param1;
      }
      downsampler->SetSize( size );
      downsampler->UpdateLargestPossibleRegion();

      newImage = mitk::ImportItkImage(downsampler->GetOutput())->Clone();
      nameAddition << "_Downsampled_by_" << param1;
      std::cout << "Downsampling successful." << std::endl;
      break;
    }

  case FLIPPING:
    {
      FlipImageFilterType::Pointer flipper = FlipImageFilterType::New();
      flipper->SetInput( itkImage );
      itk::FixedArray<bool, 3> flipAxes;
      for(int i=0; i<3; ++i)
      {
        if(i == param1)
        {
          flipAxes[i] = true;
        }
        else
        {
          flipAxes[i] = false;
        }
      }
      flipper->SetFlipAxes(flipAxes);
      flipper->UpdateLargestPossibleRegion();
      newImage = mitk::ImportItkImage(flipper->GetOutput())->Clone();
      std::cout << "Image flipping successful." << std::endl;
      break;
    }

  case RESAMPLING:
    {
      std::string selectedInterpolator;
      ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New();
      switch (m_SelectedInterpolation)
      {
      case LINEAR:
        {
          LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Linear";
          break;
        }
      case NEAREST:
        {
          NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Nearest";
          break;
        }
      default:
        {
          LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
          resampler->SetInterpolator(interpolator);
          selectedInterpolator = "Linear";
          break;
        }
      }
      resampler->SetInput( itkImage );
      resampler->SetOutputOrigin( itkImage->GetOrigin() );

      ImageType::SizeType input_size = itkImage->GetLargestPossibleRegion().GetSize();
      ImageType::SpacingType input_spacing = itkImage->GetSpacing();

      ImageType::SizeType output_size;
      ImageType::SpacingType output_spacing;

      output_size[0] = input_size[0] * (input_spacing[0] / dparam1);
      output_size[1] = input_size[1] * (input_spacing[1] / dparam2);
      output_size[2] = input_size[2] * (input_spacing[2] / dparam3);
      output_spacing [0] = dparam1;
      output_spacing [1] = dparam2;
      output_spacing [2] = dparam3;

      resampler->SetSize( output_size );
      resampler->SetOutputSpacing( output_spacing );
      resampler->SetOutputDirection( itkImage->GetDirection() );

      resampler->UpdateLargestPossibleRegion();

      ImageType::Pointer resampledImage = resampler->GetOutput();

      newImage = mitk::ImportItkImage( resampledImage );
      nameAddition << "_Resampled_" << selectedInterpolator;
      std::cout << "Resampling successful." << std::endl;
      break;
    }


  case RESCALE:
    {
      FloatImageType::Pointer floatImage = FloatImageType::New();
      CastToItkImage( newImage, floatImage );
      itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::Pointer filter = itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::New();
      filter->SetInput(0, floatImage);
      filter->SetOutputMinimum(dparam1);
      filter->SetOutputMaximum(dparam2);
      filter->Update();
      floatImage = filter->GetOutput();

      newImage = mitk::Image::New();
      newImage->InitializeByItk(floatImage.GetPointer());
      newImage->SetVolume(floatImage->GetBufferPointer());
      nameAddition << "_Rescaled";
      std::cout << "Rescaling successful." << std::endl;

      break;
    }

  default:
    this->BusyCursorOff();
    return;
  }
  }
  catch (...)
  {
    this->BusyCursorOff();
    QMessageBox::warning(NULL, "Warning", "Problem when applying filter operation. Check your input...");
    return;
  }

  newImage->DisconnectPipeline();

  // adjust level/window to new image
  mitk::LevelWindow levelwindow;
  levelwindow.SetAuto( newImage );
  mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
  levWinProp->SetLevelWindow( levelwindow );

  // compose new image name
  std::string name = m_SelectedImageNode->GetNode()->GetName();
  if (name.find(".pic.gz") == name.size() -7 )
  {
    name = name.substr(0,name.size() -7);
  }
  name.append( nameAddition.str() );

  // create final result MITK data storage node
  mitk::DataNode::Pointer result = mitk::DataNode::New();
  result->SetProperty( "levelwindow", levWinProp );
  result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) );
  result->SetData( newImage );

  // for vector images, a different mapper is needed
  if(isVectorImage > 1)
  {
    mitk::VectorImageMapper2D::Pointer mapper =
      mitk::VectorImageMapper2D::New();
    result->SetMapper(1,mapper);
  }

  // reset GUI to ease further processing
//  this->ResetOneImageOpPanel();

  // add new image to data storage and set as active to ease further processing
  GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() );
  if ( m_Controls->cbHideOrig->isChecked() == true )
    m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
  // TODO!! m_Controls->m_ImageSelector1->SetSelectedNode(result);

  // show the results
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  this->BusyCursorOff();
}
Пример #6
0
int main(int argc, char* argv[])
{
  mitkCommandLineParser parser;

  parser.setTitle("DmriDenoising");
  parser.setCategory("Preprocessing Tools");
  parser.setDescription("dMRI denoising tool");
  parser.setContributor("MIC");

  parser.setArgumentPrefix("--", "-");

  parser.beginGroup("1. Mandatory arguments:");
  parser.addArgument("", "i", mitkCommandLineParser::String, "Input:", "input image", us::Any(), false, false, false, mitkCommandLineParser::Input);
  parser.addArgument("", "o", mitkCommandLineParser::String, "Output:", "output image", us::Any(), false, false, false, mitkCommandLineParser::Output);
  parser.addArgument("type", "", mitkCommandLineParser::Int, "Type:", "0 (TotalVariation), 1 (Gauss), 2 (NLM)", 0);
  parser.endGroup();

  parser.beginGroup("2. Total variation parameters:");
  parser.addArgument("tv_iterations", "", mitkCommandLineParser::Int, "Iterations:", "", 1);
  parser.addArgument("lambda", "", mitkCommandLineParser::Float, "Lambda:", "", 0.1);
  parser.endGroup();

  parser.beginGroup("3. Gauss parameters:");
  parser.addArgument("variance", "", mitkCommandLineParser::Float, "Variance:", "", 1.0);
  parser.endGroup();

  parser.beginGroup("4. NLM parameters:");
  parser.addArgument("nlm_iterations", "", mitkCommandLineParser::Int, "Iterations:", "", 4);
  parser.addArgument("sampling_radius", "", mitkCommandLineParser::Int, "Sampling radius:", "", 4);
  parser.addArgument("patch_radius", "", mitkCommandLineParser::Int, "Patch radius:", "", 1);
  parser.addArgument("num_patches", "", mitkCommandLineParser::Int, "Num. patches:", "", 10);
  parser.endGroup();

  std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
  if (parsedArgs.size()==0)
    return EXIT_FAILURE;

  // mandatory arguments
  std::string imageName = us::any_cast<std::string>(parsedArgs["i"]);
  std::string outImage = us::any_cast<std::string>(parsedArgs["o"]);

  int type = 0;
  if (parsedArgs.count("type"))
    type = us::any_cast<int>(parsedArgs["type"]);

  int tv_iterations = 1;
  if (parsedArgs.count("tv_iterations"))
    tv_iterations = us::any_cast<int>(parsedArgs["tv_iterations"]);

  float lambda = 0.1;
  if (parsedArgs.count("lambda"))
    lambda = us::any_cast<float>(parsedArgs["lambda"]);

  float variance = 1.0;
  if (parsedArgs.count("variance"))
    variance = us::any_cast<float>(parsedArgs["variance"]);

  int nlm_iterations = 4;
  if (parsedArgs.count("nlm_iterations"))
    nlm_iterations = us::any_cast<int>(parsedArgs["nlm_iterations"]);

  int sampling_radius = 4;
  if (parsedArgs.count("sampling_radius"))
    sampling_radius = us::any_cast<int>(parsedArgs["sampling_radius"]);

  int patch_radius = 1;
  if (parsedArgs.count("patch_radius"))
    patch_radius = us::any_cast<int>(parsedArgs["patch_radius"]);

  int num_patches = 10;
  if (parsedArgs.count("num_patches"))
    num_patches = us::any_cast<int>(parsedArgs["num_patches"]);

  try
  {
    mitk::PreferenceListReaderOptionsFunctor functor = mitk::PreferenceListReaderOptionsFunctor({"Diffusion Weighted Images"}, {});
    mitk::Image::Pointer input_image = mitk::IOUtil::Load<mitk::Image>(imageName, &functor);

    typedef short                                                                         DiffusionPixelType;
    typedef itk::VectorImage<DiffusionPixelType, 3>                                       DwiImageType;
    typedef itk::Image<DiffusionPixelType, 3>                                             DwiVolumeType;
    typedef itk::DiscreteGaussianImageFilter < DwiVolumeType, DwiVolumeType >             GaussianFilterType;
    typedef itk::PatchBasedDenoisingImageFilter < DwiVolumeType, DwiVolumeType >          NlmFilterType;
    typedef itk::VectorImageToImageFilter < DiffusionPixelType >                          ExtractFilterType;
    typedef itk::ComposeImageFilter < itk::Image<DiffusionPixelType, 3> >                 ComposeFilterType;

    if (!mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage(input_image))
      mitkThrow() << "Input is not a diffusion-weighted image!";

    DwiImageType::Pointer itkVectorImagePointer = mitk::DiffusionPropertyHelper::GetItkVectorImage(input_image);

    mitk::Image::Pointer denoised_image = nullptr;

    switch (type)
    {
    case 0:
    {
      ComposeFilterType::Pointer composer = ComposeFilterType::New();
      for (unsigned int i=0; i<itkVectorImagePointer->GetVectorLength(); ++i)
      {
        ExtractFilterType::Pointer extractor = ExtractFilterType::New();
        extractor->SetInput( itkVectorImagePointer );
        extractor->SetIndex( i );
        extractor->Update();
        DwiVolumeType::Pointer gradient_volume = extractor->GetOutput();
        itk::TotalVariationDenoisingImageFilter< DwiVolumeType, DwiVolumeType >::Pointer filter = itk::TotalVariationDenoisingImageFilter< DwiVolumeType, DwiVolumeType >::New();
        filter->SetInput(gradient_volume);
        filter->SetLambda(lambda);
        filter->SetNumberIterations(tv_iterations);
        filter->Update();
        composer->SetInput(i, filter->GetOutput());
      }
      composer->Update();
      denoised_image = mitk::GrabItkImageMemory(composer->GetOutput());
      break;
    }
    case 1:
    {
      ExtractFilterType::Pointer extractor = ExtractFilterType::New();
      extractor->SetInput( itkVectorImagePointer );
      ComposeFilterType::Pointer composer = ComposeFilterType::New();
      for (unsigned int i = 0; i < itkVectorImagePointer->GetVectorLength(); ++i)
      {
        extractor->SetIndex(i);
        extractor->Update();
        GaussianFilterType::Pointer filter = GaussianFilterType::New();
        filter->SetVariance(variance);
        filter->SetInput(extractor->GetOutput());
        filter->Update();
        composer->SetInput(i, filter->GetOutput());
      }
      composer->Update();
      denoised_image = mitk::GrabItkImageMemory(composer->GetOutput());
      break;
    }
    case 2:
    {
      typedef itk::Statistics::GaussianRandomSpatialNeighborSubsampler< NlmFilterType::PatchSampleType, DwiVolumeType::RegionType > SamplerType;
      // sampling the image to find similar patches
      SamplerType::Pointer sampler = SamplerType::New();
      sampler->SetRadius( sampling_radius );
      sampler->SetVariance( sampling_radius*sampling_radius );
      sampler->SetNumberOfResultsRequested( num_patches );

      MITK_INFO << "Starting NLM denoising";
      ExtractFilterType::Pointer extractor = ExtractFilterType::New();
      extractor->SetInput( itkVectorImagePointer );
      ComposeFilterType::Pointer composer = ComposeFilterType::New();
      for (unsigned int i = 0; i < itkVectorImagePointer->GetVectorLength(); ++i)
      {
        extractor->SetIndex(i);
        extractor->Update();
        NlmFilterType::Pointer filter = NlmFilterType::New();
        filter->SetInput(extractor->GetOutput());
        filter->SetPatchRadius(patch_radius);
        filter->SetNoiseModel(NlmFilterType::RICIAN);
        filter->UseSmoothDiscPatchWeightsOn();
        filter->UseFastTensorComputationsOn();

        filter->SetNumberOfIterations(nlm_iterations);
        filter->SetSmoothingWeight( 1 );
        filter->SetKernelBandwidthEstimation(true);

        filter->SetSampler( sampler );
        filter->Update();
        composer->SetInput(i, filter->GetOutput());
        MITK_INFO << "Gradient " << i << " finished";
      }
      composer->Update();
      denoised_image = mitk::GrabItkImageMemory(composer->GetOutput());
      break;
    }
    }

    mitk::DiffusionPropertyHelper::SetGradientContainer(denoised_image, mitk::DiffusionPropertyHelper::GetGradientContainer(input_image));
    mitk::DiffusionPropertyHelper::SetReferenceBValue(denoised_image, mitk::DiffusionPropertyHelper::GetReferenceBValue(input_image));
    mitk::DiffusionPropertyHelper::InitializeImage( denoised_image );

    std::string ext = itksys::SystemTools::GetFilenameExtension(outImage);
    if (ext==".nii" || ext==".nii.gz")
      mitk::IOUtil::Save(denoised_image, "DWI_NIFTI", outImage);
    else
      mitk::IOUtil::Save(denoised_image, outImage);
  }
  catch (itk::ExceptionObject e)
  {
    std::cout << e;
    return EXIT_FAILURE;
  }
  catch (std::exception e)
  {
    std::cout << e.what();
    return EXIT_FAILURE;
  }
  catch (...)
  {
    std::cout << "ERROR!?!";
    return EXIT_FAILURE;
  }
  return EXIT_SUCCESS;
}
Пример #7
0
void WholeCellSeg::RealBoundaries(){
	int size1=cyt_im_inp->GetLargestPossibleRegion().GetSize()[0];
	int size2=cyt_im_inp->GetLargestPossibleRegion().GetSize()[1];

	typedef itk::SmoothingRecursiveGaussianImageFilter< UShortImageType, UShortImageType > GaussianFilterType;
	typedef itk::GradientMagnitudeImageFilter< UShortImageType, UShortImageType > GradientMagnitudeType;
	typedef itk::RescaleIntensityImageFilter< UShortImageType, FltImageType > RescaleUSFltType;
	typedef itk::CastImageFilter< UShortImageType, IntImageType > CastUSIntType;
	typedef itk::CastImageFilter< IntImageType, UShortImageType > CastIntUSType;
	typedef itk::ImageRegionIteratorWithIndex< IntImageType > IteratorType1;
	typedef itk::ImageRegionConstIterator< FltImageType > ConstIteratorType1;
	typedef itk::ImageRegionConstIterator< UShortImageType > ConstIteratorType;
	typedef itk::MorphologicalWatershedFromMarkersImageFilter< IntImageType, IntImageType > WatershedFilterType;

//Get gradient image from cytoplasm image
	GaussianFilterType::Pointer  gaussianfilter = GaussianFilterType::New();
	gaussianfilter->SetSigma( 1.25 );
	gaussianfilter->SetInput( cyt_im_inp );
	gaussianfilter->Update();
	GradientMagnitudeType::Pointer gradmagfilter = GradientMagnitudeType::New();
	gradmagfilter->SetInput( gaussianfilter->GetOutput() );
	gradmagfilter->Update();

//Rescale image
	RescaleUSFltType::Pointer rescaleusflt = RescaleUSFltType::New();
	rescaleusflt->SetOutputMaximum( scaling );
	rescaleusflt->SetOutputMinimum( 1 );
	rescaleusflt->SetInput( gradmagfilter->GetOutput() );
	rescaleusflt->Update();

//Get the rescaled gradient image from ITK into an array of known size and indexing system
	float *INP_IM_2D;
	FltImageType::Pointer grad_img = FltImageType::New();
	grad_img = rescaleusflt->GetOutput();
	INP_IM_2D = (float *) malloc (size1*size2*sizeof(float));
	if ( INP_IM_2D == NULL ){
		std::cerr << "Unable to allocate memory for 2D Gradient Image";
		return;
	}
	ConstIteratorType1 pix_buf( grad_img, grad_img->GetRequestedRegion() );
	itk::IndexValueType ind=0;
	for ( pix_buf.GoToBegin(); !pix_buf.IsAtEnd(); ++pix_buf, ++ind )
		INP_IM_2D[ind] = ( pix_buf.Get() );
	//int testing=0;

	if( use_mem_img ){
		GaussianFilterType::Pointer  gaussianfilter1 = GaussianFilterType::New();
		gaussianfilter1->SetSigma( 1.25 );
		gaussianfilter1->SetInput( mem_im_inp );
		gaussianfilter1->Update();
		GradientMagnitudeType::Pointer gradmagfilter1 = GradientMagnitudeType::New();
		gradmagfilter1->SetInput( gaussianfilter1->GetOutput() );
		gradmagfilter1->Update();
		RescaleUSFltType::Pointer rescaleusflt1 = RescaleUSFltType::New();
		rescaleusflt1->SetOutputMaximum( scaling );
		rescaleusflt1->SetOutputMinimum( 1 );
		rescaleusflt1->SetInput( gradmagfilter1->GetOutput() );
		rescaleusflt1->Update();
		FltImageType::Pointer grad_img1 = FltImageType::New();
		grad_img1 = rescaleusflt1->GetOutput();
		float *INP_IM_2D1;
		INP_IM_2D1 = (float *) malloc (size1*size2*sizeof(float));
		if ( INP_IM_2D1 == NULL ){
			std::cerr << "Unable to allocate memory for 2D Membrane Image";
			return;
		}
		ConstIteratorType1 pix_buf2( grad_img1, grad_img1->GetRequestedRegion() );
		ind=0;
		for ( pix_buf2.GoToBegin(); !pix_buf2.IsAtEnd(); ++pix_buf2, ++ind )
			INP_IM_2D1[ind]=(pix_buf2.Get());
		for(itk::SizeValueType j=0; j<size2; j++)
			for(itk::SizeValueType i=0; i<size1; i++)
				inp_im_2D(i,j) = (inp_im_2D(i,j)/mem_scaling)*(inp_im_2D1(i,j)*mem_scaling);
		free( INP_IM_2D1 );
	}


//Get the nucleus label image from ITK into an array of known size and indexing system
	unsigned short *NUC_IM;
	NUC_IM = (unsigned short *) malloc (size1*size2*sizeof(unsigned short));
	if ( NUC_IM == NULL ){
		std::cerr << "Unable to allocate memory for Nucleus Label Image";
		return;
	}
	ConstIteratorType pix_buf2( nuclab_inp, nuclab_inp->GetRequestedRegion() );
	ind=0;
	for ( pix_buf2.GoToBegin(); !pix_buf2.IsAtEnd(); ++pix_buf2, ++ind )
		NUC_IM[ind]=(pix_buf2.Get());

//allocate memory for the gradient weighted distance map
	float *GRAD_IMW;
	GRAD_IMW = (float *) malloc ((size1+2)*(size2+2)*sizeof(float));
	if ( GRAD_IMW == NULL ){
		std::cerr << "Unable to allocate memory for Gradient Weighted Distance Image";
		return;
	}

//Create Gradient Weighted Distance Map
	float flt_mini = -1*FLT_MAX;
	for(itk::SizeValueType i=0; i<size1; i++)
		for(itk::SizeValueType j=0; j<size2; j++){
			if(!nuc_im(i,j)) grad_imw(i+1,j+1) = FLT_MAX;
			else grad_imw(i+1,j+1)=0;
		}

	for(itk::SizeValueType i=0; i<size1; i++)
		for(itk::SizeValueType j=0; j<size2; j++)
			if(!BIN_Image(i,j)) grad_imw(i+1,j+1)=flt_mini;

	free( NUC_IM );
	free( bin_Image );

	for(itk::SizeValueType i=0; i<(size1+2); i++){
		grad_imw(i,0)=flt_mini;
		grad_imw(i,size2+1)=flt_mini;
	}

	for(itk::SizeValueType i=0; i<(size2+2); i++){
		grad_imw(0,i)=flt_mini;
		grad_imw(size1+1,i)=flt_mini;
	}

	int ok;
 	ok = gradient_enhanced_distance_map( INP_IM_2D, GRAD_IMW, size1, size2);

	free( INP_IM_2D );

//Getting gradient weighted distance map into ITK array
	IntImageType::Pointer image2;
	image2 = IntImageType::New();
	IntImageType::PointType origint;
	origint[0] = 0;
	origint[1] = 0;
	image2->SetOrigin( origint );

	IntImageType::IndexType startt;
	startt[0] = 0;  // first index on X
	startt[1] = 0;  // first index on Y
	IntImageType::SizeType  sizet;
	sizet[0] = size1;  // size along X
	sizet[1] = size2;  // size along Y
	IntImageType::RegionType regiont;
	regiont.SetSize( sizet );
	regiont.SetIndex( startt );
	image2->SetRegions( regiont );
	image2->Allocate();
	image2->FillBuffer(0);
	image2->Update();
	//copy the output image into the ITK image
	IteratorType1 iteratort(image2,image2->GetRequestedRegion());
	for(itk::SizeValueType j=0; j<size2; j++){
		for(itk::SizeValueType i=0; i<size1; i++){
			iteratort.Set(grad_imw(i+1,j+1));
			++iteratort;
		}
	}
	free( GRAD_IMW );

	CastUSIntType::Pointer castUSIntfilter = CastUSIntType::New();
	castUSIntfilter->SetInput( nuclab_inp );
	castUSIntfilter->Update();
	IntImageType::Pointer nuclab_inp_int = IntImageType::New();
	nuclab_inp_int = castUSIntfilter->GetOutput();

//Seeded watershed to get the cytoplasm regions
	WatershedFilterType::Pointer watershedfilter = WatershedFilterType::New();
	watershedfilter->SetInput1( image2 );
	watershedfilter->SetInput2( nuclab_inp_int );
	watershedfilter->SetMarkWatershedLine( 1 );
	watershedfilter->Update();

	CastIntUSType::Pointer castIntUSfilter = CastIntUSType::New();
	castIntUSfilter->SetInput( watershedfilter->GetOutput() );
	castIntUSfilter->Update();
	seg_im_out = castIntUSfilter->GetOutput();

//Write the output for testing
/*	IteratorType1 pix_bufed33( image2, image2->GetRequestedRegion() );
	pix_bufed33.GoToBegin();
	while( !pix_bufed33.IsAtEnd() ){
		if( 0 > pix_bufed33.Get() )
			pix_bufed33.Set(0);
		++pix_bufed33;
	}
	typedef itk::RescaleIntensityImageFilter< IntImageType, UShortImageType  > RescaleIntIOType;
	RescaleIntIOType::Pointer RescaleIntIO1 = RescaleIntIOType::New();
	RescaleIntIO1->SetOutputMaximum( USHRT_MAX );
	RescaleIntIO1->SetOutputMinimum( 0 );
	RescaleIntIO1->SetInput( image2 ); //watershedfilter->GetOutput() image1
	RescaleIntIO1->Update();
	typedef itk::ImageFileWriter< UShortImageType > WriterType;
	WriterType::Pointer writer = WriterType::New();
	writer->SetFileName( "grad_wts.tif" );
	writer->SetInput( RescaleIntIO1->GetOutput() );//RescaleIntIO1--finalO/P
	writer->Update();
*/

//Get Array into IDL
/*	IntImageType::Pointer image_fin = IntImageType::New();
	image_fin = watershedfilter->GetOutput();
	ConstIteratorType3 pix_bufed3( image_fin, image_fin->GetRequestedRegion() );
	pix_bufed3.GoToBegin();

	for(int j=size2-1; j>=0; j--)
		for(int i=0; i<size1; i++){
			OP(i,j)=(pix_bufed3.Get());
			++pix_bufed3;
		}
*/
	if( !remove_small_objs )
		seg_done = 1;
}
unsigned int Initialisation::houghTransformCircles(ImageType2D* im, unsigned int numberOfCircles, double** center_result, double* radius_result, double* accumulator_result, double meanRadius, double valPrint)
{
	MinMaxCalculatorType::Pointer minMaxCalculator = MinMaxCalculatorType::New();
	minMaxCalculator->SetImage(im);
	minMaxCalculator->ComputeMaximum();
	minMaxCalculator->ComputeMinimum();
	ImageType2D::PixelType maxIm = minMaxCalculator->GetMaximum(), minIm = minMaxCalculator->GetMinimum();
	double val_Print = maxIm;
    
    double min_radius = meanRadius-3.0;
    if (min_radius < 0) min_radius = 0;
	
	HoughCirclesFilter::Pointer houghfilter = HoughCirclesFilter::New();
	houghfilter->SetInput(im);
	houghfilter->SetMinimumRadius(min_radius);
	houghfilter->SetMaximumRadius(meanRadius+3.0);
	houghfilter->SetSigmaGradient(2);
	houghfilter->SetGradientFactor(valPrint*typeImageFactor_);
	houghfilter->SetSweepAngle(M_PI/180.0*5.0);
	houghfilter->SetThreshold((maxIm-minIm)/20.0);
	houghfilter->Update();
	
    
	const double nPI = 4.0 * vcl_atan( 1.0 );
	ImageType2D::IndexType index;
    
	ImageType2D::Pointer m_Accumulator= houghfilter->GetOutput();
    
	ImageType2D::Pointer m_RadiusImage= houghfilter->GetRadiusImage();
    
	/** Blur the accumulator in order to find the maximum */
	ImageType2D::Pointer m_PostProcessImage = ImageType2D::New();
	GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
	gaussianFilter->SetInput(m_Accumulator);
	double variance[2];
	variance[0]=10;
	variance[1]=10;
	gaussianFilter->SetVariance(variance);
	gaussianFilter->SetMaximumError(.01f);
	gaussianFilter->Update();
	m_PostProcessImage = gaussianFilter->GetOutput();
    
	ImageType2D::SizeType bound = m_PostProcessImage->GetLargestPossibleRegion().GetSize();
    
	itk::ImageRegionIterator<ImageType2D> it_output(im,im->GetLargestPossibleRegion());
	itk::ImageRegionIterator<ImageType2D> it_input(m_PostProcessImage,m_PostProcessImage->GetLargestPossibleRegion());
    
    
	/** Set the disc ratio */
	double discRatio = 1.1;
    
	/** Search for maxima */
	unsigned int circles=0, maxIteration=100, it=0;
	do{
		it++;
		minMaxCalculator->SetImage(m_PostProcessImage);
		minMaxCalculator->ComputeMaximum();
		ImageType2D::PixelType max = minMaxCalculator->GetMaximum();
        
		it_output.GoToBegin();
		for(it_input.GoToBegin();!it_input.IsAtEnd();++it_input)
		{
			if(it_input.Get() == max)
			{
				it_output.Set(val_Print);
				index = it_output.GetIndex();
				double radius2 = m_RadiusImage->GetPixel(index);
				if (index[0]!=0 && index[0]!=bound[0]-1 && index[1]!=0 && index[1]!=bound[1]-1)
				{
					center_result[circles][0] = it_output.GetIndex()[0];
					center_result[circles][1] = it_output.GetIndex()[1];
					radius_result[circles] = radius2;
					accumulator_result[circles] = m_PostProcessImage->GetPixel(index);
                    
					// Draw the circle
					for(double angle = 0; angle <= 2 * nPI; angle += nPI / 1000)
					{
						index[0] = (long int)(it_output.GetIndex()[0] + radius2 * cos(angle));
						index[1] = (long int)(it_output.GetIndex()[1] + radius2 * sin(angle));
						if (index[0]>=0 && index[0]<bound[0] && index[1]>=0 && index[1]<bound[1])
							im->SetPixel(index,val_Print);
                        
						// Remove the maximum from the accumulator
						for(double length = 0; length < discRatio*radius2;length+=1)
						{
							index[0] = (long int)(it_output.GetIndex()[0] + length * cos(angle));
							index[1] = (long int)(it_output.GetIndex()[1] + length* sin(angle));
							if (index[0]>=0 && index[0]<bound[0] && index[1]>=0 && index[1]<bound[1])
								m_PostProcessImage->SetPixel(index,0);
						}
					}
					circles++;
					if(circles == numberOfCircles) break;
				}
				else
				{
					// Draw the circle
					for(double angle = 0; angle <= 2 * nPI; angle += nPI / 1000)
					{
						// Remove the maximum from the accumulator
						for(double length = 0; length < discRatio*radius2;length+=1)
						{
							index[0] = (long int)(it_output.GetIndex()[0] + length * cos(angle));
							index[1] = (long int)(it_output.GetIndex()[1] + length* sin(angle));
							if (index[0]>=0 && index[0]<bound[0] && index[1]>=0 && index[1]<bound[1])
								m_PostProcessImage->SetPixel(index,0);
						}
					}
				}
				minMaxCalculator->SetImage(m_PostProcessImage);
				minMaxCalculator->ComputeMaximum();
				max = minMaxCalculator->GetMaximum();
			}
			++it_output;
		}
	}
	while(circles<numberOfCircles && it<=maxIteration);
    
	return circles;
}
void QAngioSubstractionExtension::computeAutomateSingleImage()
{
    QApplication::setOverrideCursor(Qt::WaitCursor);
    const    unsigned int          Dimension = 2;
    typedef  Volume::ItkPixelType  PixelType;

    typedef itk::Image< PixelType, Dimension >  FixedImageType;
    typedef itk::Image< PixelType, Dimension >  MovingImageType;
    typedef   float     InternalPixelType;
    typedef itk::Image< InternalPixelType, Dimension > InternalImageType;

    typedef itk::TranslationTransform< double, Dimension > TransformType;
    typedef itk::GradientDescentOptimizer                  OptimizerType;
    typedef itk::LinearInterpolateImageFunction< 
                                    InternalImageType,
                                    double             > InterpolatorType;
    typedef itk::ImageRegistrationMethod< 
                                    InternalImageType, 
                                    InternalImageType >  RegistrationType;
    typedef itk::MutualInformationImageToImageMetric< 
                                          InternalImageType, 
                                          InternalImageType >    MetricType;

    TransformType::Pointer      transform     = TransformType::New();
    OptimizerType::Pointer      optimizer     = OptimizerType::New();
    InterpolatorType::Pointer   interpolator  = InterpolatorType::New();
    RegistrationType::Pointer   registration  = RegistrationType::New();

    registration->SetOptimizer(optimizer);
    registration->SetTransform(transform);
    registration->SetInterpolator(interpolator);

    MetricType::Pointer         metric        = MetricType::New();
    registration->SetMetric(metric);
    metric->SetFixedImageStandardDeviation(0.4);
    metric->SetMovingImageStandardDeviation(0.4);
    metric->SetNumberOfSpatialSamples(50);

    typedef itk::ExtractImageFilter< Volume::ItkImageType, FixedImageType > FilterType;
    
    FilterType::Pointer extractFixedImageFilter = FilterType::New();
    Volume::ItkImageType::RegionType inputRegion = m_mainVolume->getItkData()->GetLargestPossibleRegion();
    Volume::ItkImageType::SizeType size = inputRegion.GetSize();
    //Dividim la mida per dos per tal de quedar-nos només amb la part central
    // ja que si no ens registre el background
    size[0] = size[0] / 2;
    size[1] = size[1] / 2;
    size[2] = 0;
    Volume::ItkImageType::IndexType start = inputRegion.GetIndex();
    const unsigned int sliceReference = m_imageSelectorSpinBox->value();
    //comencem a un quart de la imatge
    start[0] = size[0] / 2;
    start[1] = size[1] / 2;
    start[2] = sliceReference;
    Volume::ItkImageType::RegionType desiredRegion;
    desiredRegion.SetSize(size);
    desiredRegion.SetIndex(start);
    extractFixedImageFilter->SetExtractionRegion(desiredRegion);
    extractFixedImageFilter->SetInput(m_mainVolume->getItkData());
    extractFixedImageFilter->Update();

    FilterType::Pointer extractMovingImageFilter = FilterType::New();
    Volume::ItkImageType::IndexType startMoving = inputRegion.GetIndex();
    const unsigned int sliceNumber = m_2DView_1->getViewer()->getCurrentSlice();
    startMoving[0] = size[0] / 2;
    startMoving[1] = size[1] / 2;
    startMoving[2] = sliceNumber;
    Volume::ItkImageType::RegionType desiredMovingRegion;
    desiredMovingRegion.SetSize(size);
    desiredMovingRegion.SetIndex(startMoving);
    extractMovingImageFilter->SetExtractionRegion(desiredMovingRegion);
    extractMovingImageFilter->SetInput(m_mainVolume->getItkData());
    extractMovingImageFilter->Update();

    typedef itk::NormalizeImageFilter< 
                                FixedImageType, 
                                InternalImageType 
                                        > FixedNormalizeFilterType;

    typedef itk::NormalizeImageFilter< 
                                MovingImageType, 
                                InternalImageType 
                                              > MovingNormalizeFilterType;

    FixedNormalizeFilterType::Pointer fixedNormalizer = 
                                            FixedNormalizeFilterType::New();

    MovingNormalizeFilterType::Pointer movingNormalizer =
                                            MovingNormalizeFilterType::New();
    typedef itk::DiscreteGaussianImageFilter<
                                      InternalImageType, 
                                      InternalImageType
                                                    > GaussianFilterType;

    GaussianFilterType::Pointer fixedSmoother  = GaussianFilterType::New();
    GaussianFilterType::Pointer movingSmoother = GaussianFilterType::New();

    fixedSmoother->SetVariance(2.0);
    movingSmoother->SetVariance(2.0);
    fixedNormalizer->SetInput(extractFixedImageFilter->GetOutput());
    movingNormalizer->SetInput(extractMovingImageFilter->GetOutput());

    fixedSmoother->SetInput(fixedNormalizer->GetOutput());
    movingSmoother->SetInput(movingNormalizer->GetOutput());

    registration->SetFixedImage(fixedSmoother->GetOutput());
    registration->SetMovingImage(movingSmoother->GetOutput());

    fixedNormalizer->Update();
    registration->SetFixedImageRegion(
       fixedNormalizer->GetOutput()->GetBufferedRegion());

    typedef RegistrationType::ParametersType ParametersType;
    ParametersType initialParameters(transform->GetNumberOfParameters());

    initialParameters[0] = 0.0;  // Initial offset in mm along X
    initialParameters[1] = 0.0;  // Initial offset in mm along Y

    registration->SetInitialTransformParameters(initialParameters);

    optimizer->SetLearningRate(20.0);
    optimizer->SetNumberOfIterations(200);
    optimizer->MaximizeOn();

    try 
    { 
        registration->Update();
    } 
    catch(itk::ExceptionObject & err) 
    { 
        std::cout << "ExceptionObject caught !" << std::endl; 
        std::cout << err << std::endl; 
        return;
    } 

    ParametersType finalParameters = registration->GetLastTransformParameters();

    double TranslationAlongX = finalParameters[0];
    double TranslationAlongY = finalParameters[1];

    // Print out results
    //
    DEBUG_LOG(QString("Result = "));
    DEBUG_LOG(QString(" Translation X = %1").arg(TranslationAlongX));
    DEBUG_LOG(QString(" Translation Y = %1").arg(TranslationAlongY));
    DEBUG_LOG(QString(" Iterations    = %1").arg(optimizer->GetCurrentIteration()));
    DEBUG_LOG(QString(" Metric value  = %1").arg(optimizer->GetValue()));
    double spacing[3];
    m_mainVolume->getSpacing(spacing);
    DEBUG_LOG(QString(" Translation X (in px) = %1").arg(TranslationAlongX / spacing[0]));
    DEBUG_LOG(QString(" Translation Y (in px) = %1").arg(TranslationAlongY / spacing[1]));

    //Actualitzem les dades de la transdifference tool
    m_toolManager->triggerTool("TransDifferenceTool");
    TransDifferenceTool* tdTool = static_cast<TransDifferenceTool*> (m_2DView_2->getViewer()->getToolProxy()->getTool("TransDifferenceTool"));
    if(m_tdToolData == 0){
        m_tdToolData = static_cast<TransDifferenceToolData*> (tdTool->getToolData());
    }
    if(m_tdToolData->getInputVolume() != m_mainVolume){
        m_tdToolData->setInputVolume(m_mainVolume);
    }
    tdTool->setSingleDifferenceImage(TranslationAlongX / spacing[0],TranslationAlongY / spacing[1]);
    m_toolManager->triggerTool("SlicingTool");
    

/*    typedef itk::Image< PixelType, Dimension >  FixedImageType;
    typedef itk::Image< PixelType, Dimension >  MovingImageType;
    typedef itk::TranslationTransform< double, Dimension > TransformType;
    typedef itk::RegularStepGradientDescentOptimizer       OptimizerType;
    typedef itk::MattesMutualInformationImageToImageMetric< 
                                          FixedImageType, 
                                          MovingImageType >    MetricType;
    typedef itk:: LinearInterpolateImageFunction< 
                                    MovingImageType,
                                    double          >    InterpolatorType;
    typedef itk::ImageRegistrationMethod< 
                                    FixedImageType, 
                                    MovingImageType >    RegistrationType;

    MetricType::Pointer         metric        = MetricType::New();
    TransformType::Pointer      transform     = TransformType::New();
    OptimizerType::Pointer      optimizer     = OptimizerType::New();
    InterpolatorType::Pointer   interpolator  = InterpolatorType::New();
    RegistrationType::Pointer   registration  = RegistrationType::New();

    registration->SetMetric(metric);
    registration->SetOptimizer(optimizer);
    registration->SetTransform(transform);
    registration->SetInterpolator(interpolator);

    metric->SetNumberOfHistogramBins(50);
    metric->SetNumberOfSpatialSamples(10000);

    typedef itk::ExtractImageFilter< Volume::ItkImageType, FixedImageType > FilterType;
    
    FilterType::Pointer extractFixedImageFilter = FilterType::New();
    Volume::ItkImageType::RegionType inputRegion = m_mainVolume->getItkData()->GetLargestPossibleRegion();
    Volume::ItkImageType::SizeType size = inputRegion.GetSize();
    //Dividim la mida per dos per tal de quedar-nos només amb la part central
    // ja que si no ens registre el background
    size[0] = size[0] / 2;
    size[1] = size[1] / 2;
    size[2] = 0;
    Volume::ItkImageType::IndexType start = inputRegion.GetIndex();
    const unsigned int sliceReference = m_imageSelectorSpinBox->value();
    //comencem a un quart de la imatge
    start[0] = size[0] / 2;
    start[1] = size[1] / 2;
    start[2] = sliceReference;
    Volume::ItkImageType::RegionType desiredRegion;
    desiredRegion.SetSize(size);
    desiredRegion.SetIndex(start);
    extractFixedImageFilter->SetExtractionRegion(desiredRegion);
    extractFixedImageFilter->SetInput(m_mainVolume->getItkData());
    extractFixedImageFilter->Update();

    FilterType::Pointer extractMovingImageFilter = FilterType::New();
    Volume::ItkImageType::IndexType startMoving = inputRegion.GetIndex();
    const unsigned int sliceNumber = m_2DView_1->getViewer()->getCurrentSlice();
    startMoving[0] = size[0] / 2;
    startMoving[1] = size[1] / 2;
    startMoving[2] = sliceNumber;
    Volume::ItkImageType::RegionType desiredMovingRegion;
    desiredMovingRegion.SetSize(size);
    desiredMovingRegion.SetIndex(startMoving);
    extractMovingImageFilter->SetExtractionRegion(desiredMovingRegion);
    extractMovingImageFilter->SetInput(m_mainVolume->getItkData());
    extractMovingImageFilter->Update();

    registration->SetFixedImage(extractFixedImageFilter->GetOutput());
    registration->SetMovingImage(extractMovingImageFilter->GetOutput());

    typedef RegistrationType::ParametersType ParametersType;
    ParametersType initialParameters(transform->GetNumberOfParameters());

    //Potser seria millor posar la transformada que té actualment
    initialParameters[0] = 0.0;  // Initial offset in mm along X
    initialParameters[1] = 0.0;  // Initial offset in mm along Y

    registration->SetInitialTransformParameters(initialParameters);

    optimizer->SetMaximumStepLength(4.00);  
    optimizer->SetMinimumStepLength(0.005);

    optimizer->SetNumberOfIterations(200);

    try 
    { 
        registration->StartRegistration(); 
    } 
    catch(itk::ExceptionObject & err) 
    { 
        DEBUG_LOG(QString("ExceptionObject caught !"));
        std::cout<<err<<std::endl;
        return;
    } 
    ParametersType finalParameters = registration->GetLastTransformParameters();

    const double TranslationAlongX = finalParameters[0];
    const double TranslationAlongY = finalParameters[1];

    const unsigned int numberOfIterations = optimizer->GetCurrentIteration();

    const double bestValue = optimizer->GetValue();

    DEBUG_LOG(QString("Result = "));
    DEBUG_LOG(QString(" Translation X = %1").arg(TranslationAlongX));
    DEBUG_LOG(QString(" Translation Y = %1").arg(TranslationAlongY));
    DEBUG_LOG(QString(" Iterations    = %1").arg(numberOfIterations));
    DEBUG_LOG(QString(" Metric value  = %1").arg(bestValue));

    typedef  unsigned char  OutputPixelType;
    typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
    typedef itk::RescaleIntensityImageFilter< FixedImageType, FixedImageType > RescaleFilterType;
    typedef itk::ResampleImageFilter< 
                            FixedImageType, 
                            FixedImageType >    ResampleFilterType;
    typedef itk::CastImageFilter< 
                        FixedImageType,
                        OutputImageType > CastFilterType;
    typedef itk::ImageFileWriter< OutputImageType >  WriterType;

    WriterType::Pointer      writer =  WriterType::New();
    CastFilterType::Pointer  caster =  CastFilterType::New();
    ResampleFilterType::Pointer resample = ResampleFilterType::New();
    RescaleFilterType::Pointer rescaler = RescaleFilterType::New();

    rescaler->SetOutputMinimum(0);
    rescaler->SetOutputMaximum(255);

    TransformType::Pointer finalTransform = TransformType::New();
    finalTransform->SetParameters(finalParameters);
    resample->SetTransform(finalTransform);
    resample->SetSize(extractMovingImageFilter->GetOutput()->GetLargestPossibleRegion().GetSize());
    resample->SetOutputOrigin(extractMovingImageFilter->GetOutput()->GetOrigin());
    resample->SetOutputSpacing(extractMovingImageFilter->GetOutput()->GetSpacing());
    resample->SetDefaultPixelValue(100);

    writer->SetFileName("prova.jpg");

    rescaler->SetInput(extractMovingImageFilter->GetOutput());
    resample->SetInput(rescaler->GetOutput());
    caster->SetInput(resample->GetOutput());
    writer->SetInput(caster->GetOutput());
    writer->Update();
*/

    QApplication::restoreOverrideCursor();

}