Ejemplo n.º 1
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void Threshold::execute()
{
  std::stringstream ss;
  int err = 0;
  setErrorCondition(err);
  VoxelDataContainer* m = getVoxelDataContainer();
  if(NULL == m)
  {
    setErrorCondition(-999);
    notifyErrorMessage("The DataContainer Object was NULL", getErrorCondition());
    return;
  }
  setErrorCondition(0);
  int64_t totalPoints = m->getTotalPoints();
  size_t totalFields = m->getNumFieldTuples();
  size_t totalEnsembles = m->getNumEnsembleTuples();
  dataCheck(false, totalPoints, totalFields, totalEnsembles);
  if(m_OverwriteArray)
  {
    CREATE_NON_PREREQ_DATA(m, DREAM3D, CellData, ProcessedImageData, ss, ImageProcessing::DefaultPixelType, ImageProcessing::DefaultArrayType, 0, totalPoints, 1)
  }
  if (getErrorCondition() < 0)
  {
    return;
  }

  //get dims
  size_t udims[3] = {0,0,0};
  m->getDimensions(udims);
#if (CMP_SIZEOF_SIZE_T == 4)
  typedef int32_t DimType;
#else
  typedef int64_t DimType;
#endif
  DimType dims[3] = {
    static_cast<DimType>(udims[0]),
    static_cast<DimType>(udims[1]),
    static_cast<DimType>(udims[2]),
  };

    //wrap input as itk image
    ImageProcessing::DefaultImageType::Pointer inputImage=ITKUtilities::Dream3DtoITK(m, m_RawImageData);

    //define threshold filters
    typedef itk::BinaryThresholdImageFilter <ImageProcessing::DefaultImageType, ImageProcessing::DefaultImageType> BinaryThresholdImageFilterType;
    typedef itk::BinaryThresholdImageFilter <ImageProcessing::DefaultSliceType, ImageProcessing::DefaultSliceType> BinaryThresholdImageFilterType2D;

  if(m_Method>=0 && m_Method<=11)
  {
     //define hitogram generator (will make the same kind of histogram for 2 and 3d images
    typedef itk::Statistics::ImageToHistogramFilter<ImageProcessing::DefaultImageType> HistogramGenerator;

    //find threshold value w/ histogram
    itk::HistogramThresholdCalculator< HistogramGenerator::HistogramType, uint8_t >::Pointer calculator;

    typedef itk::HuangThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > HuangCalculatorType;
    typedef itk::IntermodesThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > IntermodesCalculatorType;
    typedef itk::IsoDataThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > IsoDataCalculatorType;
    typedef itk::KittlerIllingworthThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > KittlerIllingowrthCalculatorType;
    typedef itk::LiThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > LiCalculatorType;
    typedef itk::MaximumEntropyThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > MaximumEntropyCalculatorType;
    typedef itk::MomentsThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > MomentsCalculatorType;
    typedef itk::OtsuThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > OtsuCalculatorType;
    typedef itk::RenyiEntropyThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > RenyiEntropyCalculatorType;
    typedef itk::ShanbhagThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > ShanbhagCalculatorType;
    typedef itk::TriangleThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > TriangleCalculatorType;
    typedef itk::YenThresholdCalculator< HistogramGenerator::HistogramType, uint8_t > YenCalculatorType;

    switch(m_Method)
    {
      case 0:
        {
          calculator = HuangCalculatorType::New();
        }
        break;

      case 1:
        {
          calculator = IntermodesCalculatorType::New();
        }
        break;

      case 2:
        {
          calculator = IsoDataCalculatorType::New();
        }
        break;

      case 3:
        {
          calculator = KittlerIllingowrthCalculatorType::New();
        }
        break;

      case 4:
        {
          calculator = LiCalculatorType::New();
        }
        break;

      case 5:
        {
          calculator = MaximumEntropyCalculatorType::New();
        }
        break;

      case 6:
        {
          calculator = MomentsCalculatorType::New();
        }
        break;

      case 7:
        {
          calculator = OtsuCalculatorType::New();
        }
        break;

      case 8:
        {
          calculator = RenyiEntropyCalculatorType::New();
        }
        break;

      case 9:
        {
          calculator = ShanbhagCalculatorType::New();
        }
        break;

      case 10:
        {
          calculator = TriangleCalculatorType::New();
        }
        break;

      case 11:
        {
          calculator = YenCalculatorType::New();
        }
        break;
    }

    if(m_Slice)
    {
      //define 2d histogram generator
      typedef itk::Statistics::ImageToHistogramFilter<ImageProcessing::DefaultSliceType> HistogramGenerator2D;
      HistogramGenerator2D::Pointer histogramFilter2D = HistogramGenerator2D::New();

      //specify number of bins / bounds
      typedef HistogramGenerator2D::HistogramSizeType SizeType;
      SizeType size( 1 );
      size[0] = 255;
      histogramFilter2D->SetHistogramSize( size );
      histogramFilter2D->SetMarginalScale( 10.0 );
      HistogramGenerator2D::HistogramMeasurementVectorType lowerBound( 1 );
      HistogramGenerator2D::HistogramMeasurementVectorType upperBound( 1 );
      lowerBound[0] = 0;
      upperBound[0] = 256;
      histogramFilter2D->SetHistogramBinMinimum( lowerBound );
      histogramFilter2D->SetHistogramBinMaximum( upperBound );

      //wrap output buffer as image
      ImageProcessing::DefaultImageType::Pointer outputImage=ITKUtilities::Dream3DtoITK(m, m_ProcessedImageData);

      //loop over slices
      for(int i=0; i<dims[2]; i++)
      {
        //get slice
        ImageProcessing::DefaultSliceType::Pointer slice = ITKUtilities::ExtractSlice<ImageProcessing::DefaultPixelType>(inputImage, ImageProcessing::ZSlice, i);

        //find histogram
        histogramFilter2D->SetInput( slice );
        histogramFilter2D->Update();
        const HistogramGenerator::HistogramType * histogram = histogramFilter2D->GetOutput();

        //calculate threshold level
        calculator->SetInput(histogram);
        calculator->Update();
        const uint8_t thresholdValue = calculator->GetThreshold();

        //threshold
        BinaryThresholdImageFilterType2D::Pointer thresholdFilter = BinaryThresholdImageFilterType2D::New();
        thresholdFilter->SetInput(slice);
        thresholdFilter->SetLowerThreshold(thresholdValue);
        thresholdFilter->SetUpperThreshold(255);
        thresholdFilter->SetInsideValue(255);
        thresholdFilter->SetOutsideValue(0);
        thresholdFilter->Update();

        //copy back into volume
        ITKUtilities::SetSlice<ImageProcessing::DefaultPixelType>(outputImage, thresholdFilter->GetOutput(), ImageProcessing::ZSlice, i);
      }
    }
    else
    {
      //specify number of bins / bounds
      HistogramGenerator::Pointer histogramFilter = HistogramGenerator::New();
      typedef HistogramGenerator::HistogramSizeType SizeType;
      SizeType size( 1 );
      size[0] = 255;
      histogramFilter->SetHistogramSize( size );
      histogramFilter->SetMarginalScale( 10.0 );
      HistogramGenerator::HistogramMeasurementVectorType lowerBound( 1 );
      HistogramGenerator::HistogramMeasurementVectorType upperBound( 1 );
      lowerBound[0] = 0;
      upperBound[0] = 256;
      histogramFilter->SetHistogramBinMinimum( lowerBound );
      histogramFilter->SetHistogramBinMaximum( upperBound );

      //find histogram
      histogramFilter->SetInput( inputImage );
      histogramFilter->Update();
      const HistogramGenerator::HistogramType * histogram = histogramFilter->GetOutput();

      //calculate threshold level
      calculator->SetInput(histogram);
      calculator->Update();
      const uint8_t thresholdValue = calculator->GetThreshold();

      //threshold
      BinaryThresholdImageFilterType::Pointer thresholdFilter = BinaryThresholdImageFilterType::New();
      thresholdFilter->SetInput(inputImage);
      thresholdFilter->SetLowerThreshold(thresholdValue);
      thresholdFilter->SetUpperThreshold(255);
      thresholdFilter->SetInsideValue(255);
      thresholdFilter->SetOutsideValue(0);
      thresholdFilter->GetOutput()->GetPixelContainer()->SetImportPointer(m_ProcessedImageData, totalPoints, false);
      thresholdFilter->Update();
    }
  }
  else if(m_Method==12)//manual
  {
    //threshold
    BinaryThresholdImageFilterType::Pointer thresholdFilter = BinaryThresholdImageFilterType::New();
    thresholdFilter->SetInput(inputImage);
    thresholdFilter->SetLowerThreshold(m_ManualParameter);
    thresholdFilter->SetUpperThreshold(255);
    thresholdFilter->SetInsideValue(255);
    thresholdFilter->SetOutsideValue(0);
    thresholdFilter->GetOutput()->GetPixelContainer()->SetImportPointer(m_ProcessedImageData, totalPoints, false);
    thresholdFilter->Update();
  }
  /*
  else if(m_Method==13)//robust automatic
  {
    typedef itk::GradientMagnitudeImageFilter<ImageProcessing::DefaultImageType, ImageProcessing::DefaultImageType>  GradientMagnitudeType;
    typedef itk::GradientMagnitudeImageFilter<ImageProcessing::DefaultSliceType, ImageProcessing::DefaultSliceType>  GradientMagnitudeType2D;

    typedef itk::itkRobustAutomaticThresholdCalculator<ImageProcessing::DefaultImageType,ImageProcessing::DefaultImageType> SelectionType;
    typedef itk::itkRobustAutomaticThresholdCalculator<ImageProcessing::DefaultSliceType,ImageProcessing::DefaultSliceType> SelectionType2D;

    if(m_slice)
    {
      //wrap output buffer as image
      ImageProcessing::DefaultImageType::Pointer outputImage=ITKUtilities::Dream3DtoITK(m, m_ProcessedImageData);

      //loop over slices
      for(int i=0; i<dims[2]; i++)
      {
        //get slice
        ImageProcessing::DefaultSliceType::Pointer slice = ITKUtilities::ExtractSlice<ImageProcessing::DefaultPixelType>(inputImage, ImageProcessing::ZSlice, i);

        //find gradient
        GradientMagnitudeType2D::Pointer gradientFilter = GradientMagnitudeType2D::New();
        gradientFilter->setInput(slice);
        gradientFilter->Update();

        //calculate thershold
        SelectionType2D::Pointer calculatorFilter = SelectionType2D::New();
        calculatorFilter->SetInput(slice);
        calculatorFilter->SetGradientImage(gradientFilter->GetOutput());
        calculatorFilter->SetPow(m_ManualParameter);
        calculatorFilter->Update();
        const uint8_t thresholdValue = calculatorFilter->GetOutput();

        //threshold
        BinaryThresholdImageFilterType::Pointer thresholdFilter = BinaryThresholdImageFilterType::New();
        thresholdFilter->SetInput(inputImage);
        thresholdFilter->SetLowerThreshold(thresholdValue);
        thresholdFilter->SetUpperThreshold(255);
        thresholdFilter->SetInsideValue(255);
        thresholdFilter->SetOutsideValue(0);
        thresholdFilter->Update();

        //copy back into volume
        ITKUtilities::SetSlice<ImageProcessing::DefaultPixelType>(outputImage, thresholdFilter->GetOutput(), ImageProcessing::ZSlice, i);
      }
    }
    else
    {
      //find gradient
      GradientMagnitudeType::Pointer gradientFilter = GradientMagnitudeType::New();
      gradientFilter->setInput(inputImage);
      gradientFilter->Update();

      //calculate threshold
      SelectionType::Pointer calculatorFilter = SelectionType::New();
      calculatorFilter->SetInput(inputImage);
      calculatorFilter->SetGradientImage(gradientFilter->GetOutput());
      calculatorFilter->SetPow(m_ManualParameter);
      calculatorFilter->Update();
      const uint8_t thresholdValue = calculatorFilter->GetOutput();

      //threshold
      BinaryThresholdImageFilterType::Pointer thresholdFilter = BinaryThresholdImageFilterType::New();
      thresholdFilter->SetInput(inputImage);
      thresholdFilter->SetLowerThreshold(thresholdValue);
      thresholdFilter->SetUpperThreshold(255);
      thresholdFilter->SetInsideValue(255);
      thresholdFilter->SetOutsideValue(0);
      thresholdFilter->GetOutput()->GetPixelContainer()->SetImportPointer(m_ProcessedImageData, totalPoints, false);
      thresholdFilter->Update();
    }
  }
  */


  //array name changing/cleanup
  if(m_OverwriteArray)
  {
    m->removeCellData(m_SelectedCellArrayName);
    bool check = m->renameCellData(m_ProcessedImageDataArrayName, m_SelectedCellArrayName);
  }

  /* Let the GUI know we are done with this filter */
   notifyStatusMessage("Complete");
}
Ejemplo n.º 2
0
int main( int argc, char* argv[] )
{
    if( argc != 3 )
    {
        std::cerr << "Usage: "<< std::endl;
        std::cerr << argv[0];
        std::cerr << " <InputFileName> n";
        std::cerr << std::endl;
        return EXIT_FAILURE;
    }



    int operations = atoi(argv[2]);
    //sscanf(&operations,"%d",argv[2]);
    //printf("%d\n", operations);

    itk::TimeProbe itkClock;
    double t0 = 0.0;
    double tf = 0.0;

    itk::MultiThreader::SetGlobalDefaultNumberOfThreads(1);

    // Loading file
    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName( argv[1] );
    reader->Update();
    ImageType::Pointer image = reader->GetOutput();

#ifdef GPU
    GPUReaderType::Pointer gpureader = GPUReaderType::New();
    gpureader->SetFileName( argv[1] );
    gpureader->Update();
    GPUImageType::Pointer gpuImage = gpureader->GetOutput();
#endif


    saveFile((char*) "/tmp/itk_input.dcm", image);

    // Allocate output image
    ImageType::Pointer output = ImageType::New();
    ImageType::RegionType region = image->GetBufferedRegion();
    output->SetRegions( region );
    output->SetOrigin(  image->GetOrigin()  );
    output->SetSpacing( image->GetSpacing() );
    output->Allocate();


    // Negative
    typedef itk::UnaryFunctorImageFilter<ImageType,ImageType,
                  Negate<ImageType::PixelType,ImageType::PixelType> > NegateImageFilterType;
 
    NegateImageFilterType::Pointer negateFilter = NegateImageFilterType::New();

    negateFilter = NegateImageFilterType::New();
    negateFilter->SetInput(image);
#ifndef GPU_only
    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    {
      negateFilter->Modified();
      negateFilter->Update();    
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d negative: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;
#endif
    // Saving Not result
    saveFile((char*) "/tmp/itk_not.dcm", negateFilter->GetOutput());


#ifdef GPU
    // GPU Negative
    typedef itk::GPUUnaryFunctorImageFilter<ImageType,ImageType,
                  Negate<ImageType::PixelType,ImageType::PixelType> > GPUNegateImageFilterType;
 
    GPUNegateImageFilterType::Pointer gpuNegateFilter = GPUNegateImageFilterType::New();
    gpuNegateFilter->SetInput(gpureader->GetOutput());
    gpuNegateFilter->Update();    
    // Saving Not result
    //saveFile("/tmp/itk_gpu_not.dcm", gpuNegateFilter->GetOutput());
#endif

    // Common Threshold
    int lowerThreshold = 100;
    int upperThreshold = 200;


    // Threshold
    typedef itk::BinaryThresholdImageFilter <ImageType, ImageType>
       BinaryThresholdImageFilterType;
    
    BinaryThresholdImageFilterType::Pointer thresholdFilter
      = BinaryThresholdImageFilterType::New();

    thresholdFilter = BinaryThresholdImageFilterType::New();
    thresholdFilter->SetInput(reader->GetOutput());
    thresholdFilter->SetLowerThreshold(lowerThreshold);
    thresholdFilter->SetUpperThreshold(upperThreshold);
    thresholdFilter->SetInsideValue(255);
    thresholdFilter->SetOutsideValue(0);
#ifndef GPU_only
    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    {
	thresholdFilter->Modified();
	thresholdFilter->Update();
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d threshold: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;
    // Saving Threshold result
    saveFile((char*) "/tmp/itk_thresh.dcm", thresholdFilter->GetOutput());
#endif


#ifdef GPU
    // GPU Threshold

    typedef itk::GPUBinaryThresholdImageFilter <GPUImageType, GPUImageType> 
			GPUBinaryThresholdImageFilterType;
    
    GPUBinaryThresholdImageFilterType::Pointer gpuThresholdFilter
      = GPUBinaryThresholdImageFilterType::New();

    gpuThresholdFilter->SetInput(gpureader->GetOutput());
    gpuThresholdFilter->SetLowerThreshold(lowerThreshold);
    gpuThresholdFilter->SetUpperThreshold(upperThreshold);
    gpuThresholdFilter->SetInsideValue(255);
    gpuThresholdFilter->SetOutsideValue(0);

    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    {
      gpuThresholdFilter->Modified();
      gpuThresholdFilter->Update();
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d GPU threshold: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;
    // Saving GPU Threshold result
    gpuThresholdFilter->GetOutput()->UpdateBuffers();
    saveFile((char*) "/tmp/itk_gpu_thresh.dcm", gpuThresholdFilter->GetOutput());
#endif

    // Mean
    typedef itk::MeanImageFilter< ImageType, ImageType > MeanFilterType;
    MeanFilterType::Pointer meanFilter = MeanFilterType::New();

    meanFilter = MeanFilterType::New();
    meanFilter->SetInput( image );
    meanFilter->SetRadius( 1 );
#ifndef GPU_only
    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    {
       meanFilter->Modified();
       meanFilter->Update();
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d mean blur: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;
    // Saving Convolution result
    saveFile((char*) "/tmp/itk_mean3x3.dcm", meanFilter->GetOutput());
#endif

    // Binomial Blur (aproximation of gaussian blur)
    typedef itk::BinomialBlurImageFilter<ImageType, ImageType> BinomialBlurImageFilterType;
 
    int repetitions = 1;
    BinomialBlurImageFilterType::Pointer blurFilter = BinomialBlurImageFilterType::New();

    blurFilter = BinomialBlurImageFilterType::New();
    blurFilter->SetInput( reader->GetOutput() );
    blurFilter->SetRepetitions( repetitions );
#ifndef GPU_only
    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    {
      blurFilter->Modified();
      blurFilter->Update();
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d blur: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;
    // Saving Blur result
    saveFile((char*) "/tmp/itk_blur.dcm", blurFilter->GetOutput());
#endif


#ifdef GPU
    // GPU Blur
    typedef itk::BoxImageFilter< GPUImageType, GPUImageType > BoxImageFilterType;
    typedef itk::GPUBoxImageFilter< GPUImageType, GPUImageType, BoxImageFilterType > GPUBoxImageFilterType;

    GPUBoxImageFilterType::Pointer GPUBlurFilter = GPUBoxImageFilterType::New();

	//ImageType::SizeType indexRadius;
	//indexRadius[0] = 2;
	//indexRadius[1] = 2;
	//indexRadius[2] = 2;

    GPUBlurFilter->SetInput(gpureader->GetOutput());
	//GPUBlurFilter->SetRadius(indexRadius);
    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    {
        GPUBlurFilter->Update();
        GPUBlurFilter->Modified();
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d gpu blur: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;
    GPUBlurFilter->GetOutput()->UpdateBuffers();
    // Saving GPU Blur result
    saveFile((char*) "/tmp/itk_gpu_blur.dcm", GPUBlurFilter->GetOutput());

#endif


    //Erosion Common
    typedef itk::BinaryBallStructuringElement<
      ImageType::PixelType, 3>                  StructuringElementType;
    typedef itk::GrayscaleErodeImageFilter <ImageType, ImageType, StructuringElementType>
      GrayscaleErodeImageFilterType;
    unsigned int radius;

    // Erosion 3x3
    StructuringElementType structuringElement3x3;
    radius = 1;
    structuringElement3x3.SetRadius(radius);
    structuringElement3x3.CreateStructuringElement();

    GrayscaleErodeImageFilterType::Pointer erodeFilter3x3;

    erodeFilter3x3= GrayscaleErodeImageFilterType::New();
    erodeFilter3x3->SetInput(reader->GetOutput());
    erodeFilter3x3->SetKernel(structuringElement3x3);
#ifndef GPU_only
    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    {
        erodeFilter3x3->Modified();
        erodeFilter3x3->Update();
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d erosion 3x3: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;

    // Saving Erosion result
    saveFile((char*) "/tmp/itk_erode3x3.dcm", erodeFilter3x3->GetOutput());
#endif

    // Erosion 5x5
    StructuringElementType structuringElement5x5;
    radius = 2;
    structuringElement5x5.SetRadius(radius);
    structuringElement5x5.CreateStructuringElement();

    GrayscaleErodeImageFilterType::Pointer erodeFilter5x5;

    erodeFilter5x5 = GrayscaleErodeImageFilterType::New();
    erodeFilter5x5->SetInput(reader->GetOutput());
    erodeFilter5x5->SetKernel(structuringElement5x5);
#ifndef GPU_only
    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    {
      erodeFilter5x5->Modified();
      erodeFilter5x5->Update();
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d erosion 5x5: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;

    // Saving Erosion result
    saveFile((char*) "/tmp/itk_erode5x5.dcm", erodeFilter5x5->GetOutput());
#endif

    // Copy
    typedef itk::ImageDuplicator< ImageType > DuplicatorType;
    DuplicatorType::Pointer duplicator;

    duplicator = DuplicatorType::New();
    duplicator->SetInputImage(image);
#ifndef GPU_only
    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    { 
       duplicator->Modified();
       duplicator->Update();
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d copias cpu: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;
    // Saving Copy result
    saveFile((char*) "/tmp/itk_copy.dcm", duplicator->GetOutput());
#endif

    // Convolution common
    typedef itk::ConvolutionImageFilter<ImageType> ConvolutionImageFilterType;

    ConvolutionImageFilterType::Pointer convolutionFilter;

    convolutionFilter = ConvolutionImageFilterType::New();
    convolutionFilter->SetInput(reader->GetOutput());
    int convWidth;

    // Convolution 3x3
    ImageType::Pointer kernel3x3 = ImageType::New();
    convWidth = 3;
    CreateKernel(kernel3x3, convWidth);

    convolutionFilter->SetKernelImage(kernel3x3);
#ifndef GPU_only
    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    {  
       convolutionFilter->Modified();
       convolutionFilter->Update();
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d convolucoes 3x3 cpu: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;
    // Saving Convolution result
    saveFile((char*) "/tmp/itk_convolution3x3.dcm", convolutionFilter->GetOutput());
#endif

    // Convolution 5x5
    ImageType::Pointer kernel5x5 = ImageType::New();
    convWidth = 5;
    CreateKernel(kernel5x5, convWidth);

    convolutionFilter->SetKernelImage(kernel5x5);
#ifndef GPU_only
    itkClock.Start();
    TimerStart();
    for(int n = 0; n < operations; n++)
    {  
       convolutionFilter->Modified();
       convolutionFilter->Update();
    }
    itkClock.Stop();
    printf("Tempo gasto para fazer %d convolucoes 5x5 cpu: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;
    // Saving Convolution result
    saveFile((char*) "/tmp/itk_convolution5x5.dcm", convolutionFilter->GetOutput());
#endif

#ifdef GPU

    // GPU Mean
    typedef itk::GPUMeanImageFilter<GPUImageType, GPUImageType> GPUMeanFilterType;
	GPUMeanFilterType::Pointer GPUMean = GPUMeanFilterType::New();
	GPUMean->SetInput(gpureader->GetOutput());
	GPUMean->SetRadius( 1 );
	TimerStart();
	for(int n = 0; n < operations; n++)
	{
	   GPUMean->Update();
	   GPUMean->Modified();
	}
    itkClock.Stop();
    printf("Tempo gasto para fazer %d GPU mean blur: %s\n",operations, getTimeElapsedInSeconds());
    tf = itkClock.GetTotal();
    std::cout << "My: "    << (tf - t0) << std::endl;
    t0 = tf;
	GPUMean->GetOutput()->UpdateBuffers();
    saveFile((char*) "/tmp/itk_gpu_blurmean.dcm", GPUMean->GetOutput());
#endif

    // Visualize
    /*
    QuickView viewer;
    viewer.AddImage<ImageType>(
      image,true,
      itksys::SystemTools::GetFilenameName(argv[1]));  
    std::stringstream desc;
    desc << "ITK QuickView: " 
         << argv[1];
    viewer.Visualize();
    */

    // Saving input image as is
    saveFile((char*) "/tmp/itk_input.dcm", image);


    return EXIT_SUCCESS;
}