Beispiel #1
0
bool DilationFilter::execute() {
	ImagePtr input = this->getCopiedInputImage();
	if (!input)
		return false;

	double radius = this->getDilationRadiusOption(mCopiedOptions)->getValue();

	// Convert radius in mm to radius in voxels for the structuring element
	Eigen::Array3d spacing = input->getSpacing();
	itk::Size<3> radiusInVoxels;
	radiusInVoxels[0] = radius/spacing(0);
	radiusInVoxels[1] = radius/spacing(1);
	radiusInVoxels[2] = radius/spacing(2);

	itkImageType::ConstPointer itkImage = AlgorithmHelper::getITKfromSSCImage(input);

	// Create structuring element
	typedef itk::BinaryBallStructuringElement<unsigned char,3> StructuringElementType;
    StructuringElementType structuringElement;
    structuringElement.SetRadius(radiusInVoxels);
    structuringElement.CreateStructuringElement();

	// Dilation
	typedef itk::BinaryDilateImageFilter<itkImageType, itkImageType, StructuringElementType> dilateFilterType;
	dilateFilterType::Pointer dilationFilter = dilateFilterType::New();
	dilationFilter->SetInput(itkImage);
	dilationFilter->SetKernel(structuringElement);
	dilationFilter->SetDilateValue(1);
	dilationFilter->Update();
	itkImage = dilationFilter->GetOutput();

	//Convert ITK to VTK
	itkToVtkFilterType::Pointer itkToVtkFilter = itkToVtkFilterType::New();
	itkToVtkFilter->SetInput(itkImage);
	itkToVtkFilter->Update();

	vtkImageDataPtr rawResult = vtkImageDataPtr::New();
	rawResult->DeepCopy(itkToVtkFilter->GetOutput());

	vtkImageCastPtr imageCast = vtkImageCastPtr::New();
	imageCast->SetInputData(rawResult);
	imageCast->SetOutputScalarTypeToUnsignedChar();
	imageCast->Update();
	rawResult = imageCast->GetOutput();

	// TODO: possible memory problem here - check debug mem system of itk/vtk

	mRawResult =  rawResult;

	BoolPropertyPtr generateSurface = this->getGenerateSurfaceOption(mCopiedOptions);
	if (generateSurface->getValue())
	{
        double threshold = 1;/// because the segmented image is 0..1
        mRawContour = ContourFilter::execute(mRawResult, threshold);
	}

    return true;
}
Beispiel #2
0
void Preprocess::ClosingFilter( int radius )
{
	typedef itk::BinaryBallStructuringElement<PixelType,3> StructuringElementType;
	typedef itk::GrayscaleMorphologicalClosingImageFilter<ImageType3D, ImageType3D, StructuringElementType > FilterType;
	FilterType::Pointer close = FilterType::New();
	StructuringElementType structuringElement;
	structuringElement.CreateStructuringElement();
	structuringElement.SetRadius(radius);
	close->SetKernel( structuringElement );	 
	close->SetInput(myImg);
	try
	{
		close->Update();
	}
	catch( itk::ExceptionObject & err )
	{
		std::cerr << "Exception caught: " << err << std::endl;
	}
	myImg = close->GetOutput();
}
void LidarSegmentationWidget::on_btnErodeSources_clicked()
{
  Mask::Pointer sourcesImage = Mask::New();
  sourcesImage->SetRegions(this->ImageRegion);
  ITKHelpers::IndicesToBinaryImage(this->Sources, sourcesImage);

  typedef itk::BinaryBallStructuringElement<Mask::PixelType,2> StructuringElementType;
  StructuringElementType structuringElementBig;
  structuringElementBig.SetRadius(3);
  structuringElementBig.CreateStructuringElement();

  typedef itk::BinaryErodeImageFilter<Mask, Mask, StructuringElementType> BinaryErodeImageFilterType;

  BinaryErodeImageFilterType::Pointer erodeFilter = BinaryErodeImageFilterType::New();
  erodeFilter->SetInput(sourcesImage);
  erodeFilter->SetKernel(structuringElementBig);
  erodeFilter->Update();

  //this->Sources.clear();

  this->Sources = ITKHelpers::GetNonZeroPixels(erodeFilter->GetOutput());

  UpdateSelections();
}
void TrainPipeline::Train(){
    int limitValue = 0;
    int label = NULL;
    FILE* resultFile;
    ProgressBar progressBar;
    //string resultFileName = "results.txt";
    resultFile = fopen(this -> resultFileName.c_str(), "w");
    FileHandler* fileHandler = new FileHandler(dirName);
    //fprintf(resultFile, "%d\n" , fileHandler -> GetNumberOfFiles());
    for (int cont = 0; cont < fileHandler -> GetNumberOfFiles(); cont++) {
            
/* --------------------------------------- IMAGE CONVERTING --------------------------------------------- */
            
    RGBReaderType::Pointer rgbReader = RGBReaderType::New();
    rgbReader -> SetFileName(fileHandler -> GetFiles()[cont]);
    //rgbReader -> SetFileName("img/Im148_0.tif"); // teste uma imagem
    //label = descobreLabel("img/Im148_0.tif");
    LabelFinder* labelFinder = new LabelFinder(fileHandler -> GetFiles()[cont]);
    label = labelFinder -> GetLabel();
    //label = descobreLabel(fileHandler -> GetFiles()[cont]);
    rgbReader -> SetFileName(fileHandler -> GetFiles()[cont]);
    GrayscaleFilterType::Pointer grayscaleFilter = GrayscaleFilterType::New();
    grayscaleFilter -> SetInput(rgbReader -> GetOutput());
    GrayscaleImageType::Pointer grayScaleImage = grayscaleFilter -> GetOutput();
    grayscaleFilter -> Update();
            
/* ------------------------------------------------------------------------------------------------------ */
     
/* ------------------------------------------- OPENING MORPHOLOGY -------------------------------------------- */
        
    StructuringElementType structuringElementOpen;
    structuringElementOpen.SetRadius(5);
    structuringElementOpen.CreateStructuringElement();
    OpeningMorphologyType::Pointer openingFilter = OpeningMorphologyType::New();
    openingFilter -> SetInput(grayscaleFilter -> GetOutput());
    openingFilter -> SetKernel(structuringElementOpen);
    //stringstream imageOutOpen;
    //imageOutOpen << "open_" << imageName;
    //cout  << "imageName : " << imageOutOpen.str() << endl;
    //WriterType::Pointer writerOpen = WriterType::New();
    //writerOpen -> SetFileName(imageOutOpen.str());
    //writerOpen -> SetInput(openingFilter -> GetOutput());
    //writerOpen -> Update();
        
/* ------------------------------------------------------------------------------------------------------ */
        
/* ------------------------------------------- FIND THRESHOLD VALUE -------------------------------------- */
        
    Optimalthreshold* optimalThreshold = new Optimalthreshold(openingFilter -> GetOutput());
    //Optimalthreshold* optimalThreshold = new Optimalthreshold(grayscaleFilter -> GetOutput());
    limitValue = optimalThreshold -> GetOutput();
    //cout << "Valor Limiar : " << limitValue << endl;
    ThresholdFilter::Pointer thresholdFilter = ThresholdFilter::New();
    thresholdFilter -> SetInput(grayscaleFilter -> GetOutput());
    thresholdFilter -> SetOutsideValue(255);
    thresholdFilter -> SetUpper(optimalThreshold -> GetOutput()); // valor aleatorio
    thresholdFilter -> SetLower(0);
    thresholdFilter -> Update();
    GrayscaleImageType::Pointer thresholdImage = GrayscaleImageType::New();
    thresholdImage = thresholdFilter -> GetOutput();
    thresholdImage -> Update();
        
/* ------------------------------------------------------------------------------------------------------ */
            
/* ---------------------------------------- REGION GROWING ---------------------------------------------- */
            
    NeighborhoodConnectedFilterType::Pointer regionGrow = NeighborhoodConnectedFilterType::New();
    float lower = 0;
    float upper = optimalThreshold -> GetOutput();
    regionGrow->SetLower(lower);
    regionGrow->SetUpper(upper);
    regionGrow->SetReplaceValue(255);
    regionGrow->SetInput(grayscaleFilter -> GetOutput());
            
    for (int x = 5; x < 250; x += 5) {
        GrayscaleImageType::IndexType seed1;
        seed1[0] = x;
        seed1[1] = 0;
        regionGrow->AddSeed(seed1);
        GrayscaleImageType::IndexType seed2;
        seed2[0] = x;
        seed2[1] = 255;
        regionGrow->AddSeed(seed2);
    }
    for (int y = 0; y < 250; y += 5) {
        GrayscaleImageType::IndexType seed1;
        seed1[0] = 255;
        seed1[1] = y;
        regionGrow->AddSeed(seed1);
        GrayscaleImageType::IndexType seed2;
        seed2[0] = 0;
        seed2[1] = y;
        regionGrow->AddSeed(seed2);
    }
            
/* ------------------------------------------------------------------------------------------------------ */
            
/* --------------------------------------------- OR IMAGEFILTER ----------------------------------------- */
            
    OrFilterType::Pointer orFilter = OrFilterType::New();
    orFilter -> SetInput(0, thresholdImage);
    orFilter -> SetInput(1, regionGrow -> GetOutput());
    orFilter -> Update();
        
/* ------------------------------------------------------------------------------------------------------- */
            
/* --------------------------------------------- DATA COLLECT -------------------------------------------- */
        
    //DataCollector* dataCollector = new DataCollector(dilateFilter -> GetOutput());
    DataCollector* dataCollector = new DataCollector(orFilter -> GetOutput());
        
        
/* ------------------------------------------------------------------------------------------------------- */
            
/* ------------------------------------------ GENERATE RESULTS ------------------------------------------- *
        
        stringstream imageOut;
        imageOut << "out/" << fileHandler -> GetFiles()[cont].substr(dirName.length() , (fileHandler -> GetFiles()[cont].length() - dirName.length()));
        cout  << "imageName : " << imageOut.str() << endl;
        cout << "==============================================================================" << endl << endl;
        WriterType::Pointer writer = WriterType::New();
        writer -> SetFileName(imageOut.str());
        writer -> SetInput(orFilter -> GetOutput());
        writer -> Update();
            
/* ------------------------------------------------------------------------------------------------------- */
        if(dataCollector -> GetPxCount() == 0){
            //fprintf(resultFile,"%d , %d , %d , %d\n",limitValue * 2 , dataCollector -> GetPxCount() , dataCollector -> GetCellAvrage() , label);
            fprintf(resultFile,"%d , %d , %d , %d\n",limitValue * 2 , dataCollector -> GetCellAvrage() , dataCollector -> GetAberration() , label);
        }else{
            //fprintf(resultFile,"%d , %d , %d , %d\n",limitValue , dataCollector -> GetPxCount() / 100 , dataCollector -> GetCellAvrage() , label);
            fprintf(resultFile,"%d , %d , %d , %d\n",limitValue , dataCollector -> GetCellAvrage() , dataCollector -> GetAberration() , label);
        }
        //cout << "tot : " << fileHandler -> GetNumberOfFiles() << " | inc : " <<  (100 / (float) fileHandler -> GetNumberOfFiles()) << endl;
        progressBar.update(100 / (float) fileHandler -> GetNumberOfFiles());
        progressBar.print();
        //cout << "Processado  " << cont + 1 << " de " << fileHandler -> GetNumberOfFiles() << endl;
    }
    fclose(resultFile);
    
/* -------------------------------------------------------------------------------------------------------- */
    
        cout << "TREINAMENTO CONCLUIDO" << endl;

}
float
rich_cell::
compute_average_intensity( ImageType::Pointer intensity_image, LabelImageType::ConstPointer label_image, int dist_interior, int dist_exterior)
{
  float sum_interior = 0;
  float sum_exterior = 0;
  int count_interior = 0;
  int count_exterior = 0;

  if (dist_exterior < dist_interior) { // the entire segmented area is taken
    for (unsigned int b = 0; b<all_points_.size(); b++) {
      vnl_vector_fixed< float, 3 > const & pt = all_points_[b];
      ImageType::IndexType pos;
      pos[0] = pt[0];
      pos[1] = pt[1];
      pos[2] = pt[2];
      sum_interior += intensity_image->GetPixel(pos);
    }

    return sum_interior/all_points_.size();
  }
   
  RegionType region = bounding_box_;
  if (dist_interior < 0) { //erode the mask 
    // Generate a mask image of the cell region. Erode the region by
    // r_interior
    RegionType::SizeType size = region.GetSize();
    RegionType::IndexType start={{0,0,0}};
    ImageType::Pointer cropped_mask = ImageType::New(); 
    RegionType mask_region;
    mask_region.SetIndex( start );
    mask_region.SetSize( size );
    cropped_mask->SetRegions( mask_region );
    cropped_mask->Allocate();
    cropped_mask->FillBuffer(0);
    LabelConstRegionIteratorType it1( label_image, region);
    RegionIteratorType it2( cropped_mask, mask_region );
    for (it1.GoToBegin(), it2.GoToBegin(); !it1.IsAtEnd(); ++it1, ++it2) {
      if (it1.Get() == label_)
        it2.Set( 255 );
    }
      
    ImageType::Pointer eroded_mask;
    ErodeFilterType::Pointer f_erode = ErodeFilterType::New();
    SubFilterType::Pointer f_sub = SubFilterType::New();
    StructuringElementType  structuringElement;
    structuringElement.SetRadius( -dist_interior );
    structuringElement.CreateStructuringElement();
    f_erode->SetKernel( structuringElement );
    f_erode->SetInput(cropped_mask);
    f_sub->SetInput1( cropped_mask  );
    f_sub->SetInput2( f_erode->GetOutput() );
    try {
      f_sub->Update();
    }
    catch (itk::ExceptionObject & e) {
      std::cerr << "Exception in SubFilter: " << e << std::endl;
      exit(0);
    }
    eroded_mask = f_sub->GetOutput();
      
    // Sum the signal in the eroded region only
    ConstRegionIteratorType it3( eroded_mask, mask_region );
    ConstRegionIteratorType it4( intensity_image, region);
    for (it3.GoToBegin(), it4.GoToBegin(); !it3.IsAtEnd(); ++it1, ++it3, ++it4) {
      if (it3.Get() > 0) {
        sum_interior += it4.Get();
        count_interior ++;
      }
    }
  }
  if (dist_exterior > 0) { //dilate the mask
    // enlarge the bounding box by r on each side.
    RegionType::SizeType image_size = intensity_image->GetLargestPossibleRegion().GetSize();
    RegionType::SizeType size = region.GetSize();
    RegionType::IndexType start = region.GetIndex();
    RegionType::IndexType end;
    end[0] = vnl_math_min(start[0]+size[0]+dist_exterior, image_size[0]);
    end[1] = vnl_math_min(start[1]+size[1]+dist_exterior, image_size[1]);
    end[2] = vnl_math_min(start[2]+size[2]+dist_exterior, image_size[2]);
    start[0] = vnl_math_max(int(start[0]-dist_exterior), 0);
    start[1] = vnl_math_max(int(start[1]-dist_exterior), 0);
    start[2] = vnl_math_max(int(start[2]-dist_exterior), 0);
    
    size[0] = end[0] - start[0];
    size[1] = end[1] - start[1];
    size[2] = end[2] - start[2];
    region.SetSize( size );
    region.SetIndex( start );
    
    // Generate a mask image of the region just found. Dilate the
    // region defined by the segmentation by r. 
    ImageType::Pointer cropped_mask = ImageType::New(); 
    RegionType mask_region;
    start[0] = start[1] = start[2] = 0;
    mask_region.SetIndex( start );
    mask_region.SetSize( size );
    cropped_mask->SetRegions( mask_region );
    cropped_mask->Allocate();
    cropped_mask->FillBuffer(0);
    LabelConstRegionIteratorType it1( label_image, region);
    RegionIteratorType it2( cropped_mask, mask_region );
    for (it1.GoToBegin(), it2.GoToBegin(); !it1.IsAtEnd(); ++it1, ++it2) {
      if (it1.Get() == label_)
        it2.Set( 255 );
    }
    ImageType::Pointer dilated_mask;
    DilateFilterType::Pointer f_dilate = DilateFilterType::New();
    SubFilterType::Pointer f_sub = SubFilterType::New();
    StructuringElementType  structuringElement;
    structuringElement.SetRadius( dist_exterior );
    structuringElement.CreateStructuringElement();
    f_dilate->SetKernel( structuringElement );
    f_dilate->SetInput(cropped_mask);
    f_sub->SetInput1( f_dilate->GetOutput() );
    f_sub->SetInput2( cropped_mask );
    
    try {
      f_sub->Update();
    }
    catch (itk::ExceptionObject & e) {
      std::cerr << "Exception in SubFilter: " << e << std::endl;
      exit(0);
    }
    dilated_mask = f_sub->GetOutput();
    
    // Sum the signal in the dilated region only
    ConstRegionIteratorType it3( dilated_mask, mask_region );
    ConstRegionIteratorType it4( intensity_image, region);
    for (it3.GoToBegin(), it4.GoToBegin(); !it3.IsAtEnd(); ++it1, ++it3, ++it4) {
      if (it3.Get() > 0) {
        sum_exterior += it4.Get();
        count_exterior ++;
      }
    }
  }
  
  // average the interior and exterior signals
  return (sum_interior+sum_exterior)/float(count_interior+count_exterior);
}
void udgPerfusionEstimator<TPerfuImage,TMaskImage, TTransform>::ComputeEstimation()
{

  if(m_perfuImage.IsNull()){
    std::cout<<"Not Perfusion Image defined"<<std::endl;
    return;
    }


  if(m_ventricleMask.IsNull()){
    std::cout<<"Not Ventricle Mask Image defined"<<std::endl;
    return;
    }

  if(m_strokeMask.IsNull()){
    std::cout<<"Not Stroke Mask Image defined"<<std::endl;
    return;
    }

  if(m_Transform.IsNull()){
    std::cout<<"Not Transform defined"<<std::endl;
    return;
    }

  m_estimatedImage = PerfuImageType::New();
  m_estimatedImage->SetRegions( m_perfuImage->GetLargestPossibleRegion() );
  m_estimatedImage->SetSpacing( m_perfuImage->GetSpacing() );
  m_estimatedImage->SetOrigin( m_perfuImage->GetOrigin() );
  m_estimatedImage->Allocate();

  //Definim la regi�molt probablement infartada
  typename MaskImageType::Pointer m_strokeInfluence = MaskImageType::New();
  m_strokeInfluence->SetRegions( m_strokeMask->GetLargestPossibleRegion() );
  m_strokeInfluence->SetSpacing( m_strokeMask->GetSpacing() );
  m_strokeInfluence->SetOrigin( m_strokeMask->GetOrigin() );
  m_strokeInfluence->Allocate();

  typename DilateFilterType::Pointer binaryDilate = DilateFilterType::New();
  binaryDilate->SetDilateValue( 255 );	//suposem que el valor alt ser�255
  StructuringElementType structuringElementDilate;
  structuringElementDilate.SetRadius( 2 ); // 3x3 structuring element
  structuringElementDilate.CreateStructuringElement();

  binaryDilate->SetKernel( structuringElementDilate );

  binaryDilate->SetInput( m_strokeMask );
  binaryDilate->Update();
  m_strokeInfluence = binaryDilate->GetOutput();

  //Fi regi�molt probablement infartada




      typename ResampleFilterType::Pointer resample = ResampleFilterType::New();

      typename TransformType::Pointer inverse = TransformType::New();
      if (!m_Transform->GetInverse( inverse ))
      {
          std::cout<<"ERROR! udgPerfusionEstimator<TPerfuImage,TMaskImage, TTransform>::ComputeEstimation() No hi ha inversa!"<<std::endl;
      }

      resample->SetTransform( inverse );
      resample->SetInput( m_ventricleMask);
      resample->SetSize( m_perfuImage->GetLargestPossibleRegion().GetSize() );
      resample->SetOutputOrigin(  m_perfuImage->GetOrigin() );
      resample->SetOutputSpacing( m_perfuImage->GetSpacing() );
      resample->SetDefaultPixelValue( 0 );
      resample->SetInterpolator( m_InterpolatorVentricle );

      resample->Update();

      Ventricles = resample->GetOutput();


      typename ResampleFilterType::Pointer resample2 = ResampleFilterType::New();

      resample2->SetTransform( inverse );
      resample2->SetInput( m_strokeInfluence);
      resample2->SetSize( m_perfuImage->GetLargestPossibleRegion().GetSize() );
      resample2->SetOutputOrigin(  m_perfuImage->GetOrigin() );
      resample2->SetOutputSpacing( m_perfuImage->GetSpacing() );
      resample2->SetDefaultPixelValue( 0 );
      resample2->SetInterpolator( m_InterpolatorStroke );

      resample2->Update();

      //Creem les finestres mostrant les imatges registrades

      Stroke = resample2->GetOutput();



  PerfuIteratorType estimatedIt(m_estimatedImage, m_estimatedImage->GetBufferedRegion());

  PerfuIteratorType perfuIt(m_perfuImage, m_perfuImage->GetBufferedRegion());
  PerfuIteratorType VentIt(Ventricles, Ventricles->GetBufferedRegion());
  PerfuIteratorType StkIt(Stroke, Stroke->GetBufferedRegion());

  RadiusNeighborType radius;
  radius.Fill(2);

  m_InterpolatorVentricle->SetInputImage( m_ventricleMask );
  m_InterpolatorStroke->SetInputImage( m_strokeInfluence );

  PerfuPointType inputPoint;
  PerfuPixelType perfuValue;
  PerfuPixelType VentValue;
  PerfuPixelType StkValue;
  typename PerfuImageType::IndexType index;

  MaskPointType transformedPoint;

  perfuIt.GoToBegin();
  VentIt.GoToBegin();
  StkIt.GoToBegin();
  estimatedIt.GoToBegin();
  ++perfuIt;
  ++VentIt;
  ++StkIt;
  ++estimatedIt;
    while (!perfuIt.IsAtEnd())
    {
        perfuValue = perfuIt.Value();

//         if(perfuValue == 0) // ((maskValue == m_insideValue)&&(perfuValue == 0))
        if ( perfuValue < 32 ) // ((maskValue == m_insideValue)&&(perfuValue == 0))
        {   //és a dir, és un punt negre
            index = perfuIt.GetIndex();
            m_perfuImage->TransformIndexToPhysicalPoint(index, inputPoint);

            transformedPoint = m_Transform->TransformPoint(inputPoint); //transformed point és el punt corresponent en difusió
            if (m_InterpolatorVentricle->IsInsideBuffer(transformedPoint))
            {
//                m_Interpolator->SetInputImage( m_ventricleMask );
                //const RealType VentriclemaskValue = m_InterpolatorVentricle->Evaluate(transformedPoint);
                VentValue = VentIt.Value();

//                if(VentriclemaskValue!=0)
                if(VentValue!=0)
                {
                    estimatedIt.Set(0);//estimatedIt.Set(1);
                }
                else
                {
                    /*
                    const RealType strokemaskValue = m_InterpolatorStroke->Evaluate(transformedPoint);
                    if(strokemaskValue!=0){
                        estimatedIt.Set(1);//estimatedIt.Set(255);
                    }
                    */
                    StkValue = StkIt.Value();
                    if(StkValue != 0)
                    {
                        estimatedIt.Set(255);
                    }
                    else
                    {
                        estimatedIt.Set(0);
                    }
                }
            }
        }
        else
        {
            estimatedIt.Set( perfuValue );  //estimatedIt.Set( perfuValue );
        }
        ++perfuIt;
        ++VentIt;
        ++StkIt;
        ++estimatedIt;
    }

    //Aqu�determinem els punts que no s� ni infart ni ventricle, fent una mitjana dels valors veins
    //La imatge s'actualitza sobre ella mateixa, per�no sembla que aix�hagi de portar problemes
 /*
  double med, cont;
  PerfuNeighborIteratorType perfuNeighborIt(radius, m_estimatedImage,  m_estimatedImage->GetBufferedRegion());

  perfuNeighborIt.GoToBegin();
  perfuIt.GoToBegin();
  estimatedIt.GoToBegin();
  ++perfuNeighborIt;
  ++estimatedIt;
  while (!estimatedIt.IsAtEnd())
  {
	  perfuValue = estimatedIt.Get();

    if (perfuValue == 0)    //� a dir, � un punt negre
	  {
      med=0;
		  cont=0;

		  for (unsigned int i = 0; i < perfuNeighborIt.Size(); i++)
		  {
		    if ( perfuNeighborIt.GetPixel(i) != 0 && perfuNeighborIt.GetPixel(i)<1000 )
		    {
		      med += perfuNeighborIt.GetPixel(i);
		      cont ++;
			  }
		  }
		  estimatedIt.Set(static_cast<PerfuPixelType> (med/cont));
	  }
	  ++perfuNeighborIt;
    ++estimatedIt;
  }
  */
  //Suavitzem la sortida --> S'hauria de fer per�d�a errors
/*
  typename SmoothingFilterType::Pointer smoothFilter = SmoothingFilterType::New();
//  smoothFilter->SetInput(m_estimatedImage);
  smoothFilter->SetInput(m_perfuImage);


//  smoothFilter->SetNumberOfIterations(5);
//  smoothFilter->SetTimeStep(0.0625);
//  smoothFilter->SetConductanceParameter(1);

//std::cout<<"hola 1"<<std::endl;

  smoothFilter->SetVariance(1);
  smoothFilter->SetMaximumKernelWidth(6);


  //smoothFilter->Update();

  RescaleFilterType::Pointer rescaler = RescaleFilterType::New();

  rescaler->SetOutputMinimum(   0 );
  rescaler->SetOutputMaximum( 255 );
//std::cout<<"hola 2"<<std::endl;

  rescaler->SetInput(smoothFilter->GetOutput());
  rescaler->Update();
//std::cout<<"hola 3"<<std::endl;

  m_estimatedImage = rescaler->GetOutput();
  */
}
void myVtkInteractorStyleImage3D::RemoveLeaks(){
	boost::mutex::scoped_lock scoped_lock(_canSegment_mutex);
	if (!_foundLeaks){
		cout << "Final segmentation had no leaks!" << endl;
		vtkSmartPointer<vtkNIFTIImageWriter> niw = vtkSmartPointer<vtkNIFTIImageWriter>::New();
		vtkStructuredPoints* saveMat = vtkStructuredPoints::New();
		cout << "At filtering." << endl;
		saveMat->DeepCopy(_selection);
		vtkUnsignedShortArray* scalars = (vtkUnsignedShortArray*)(saveMat->GetPointData()->GetScalars());
		for (int i = 0; i < saveMat->GetNumberOfPoints(); i++){
			if (scalars->GetValue(i) == BACKGROUND){
				scalars->SetValue(i, NOT_ACTIVE);
			}
		}
		scalars->Modified();
		//dilate:
		cout << "at dilation" << endl;
		vtkSmartPointer<vtkImageDilateErode3D> dilateErode =
			vtkSmartPointer<vtkImageDilateErode3D>::New();
		dilateErode->SetInputData(saveMat);
		dilateErode->SetDilateValue(FOREGROUND);
		dilateErode->SetErodeValue(NOT_ACTIVE);
		dilateErode->SetKernelSize(DILATION_ST_SIZE, DILATION_ST_SIZE, 1);
		dilateErode->ReleaseDataFlagOff();
		dilateErode->Update();
		cout << "finished dilation" << endl;

		cout << "Saving..." << endl;
		niw->SetInputData(dilateErode->GetOutput());
		niw->SetFileName("correctedImage.nii.gz");
		niw->Write();
		cout << "Final segmentation was saved successfully!" << endl;
		return;
	}
	cout << "Started fixing mesh!" << endl;
	typedef double PixelType;
	typedef unsigned short SegPixelType;
	const unsigned char dim = 3;

	typedef itk::Image<PixelType, dim> ImageType;
	typedef itk::Image<SegPixelType, dim> SegImageType;

	MeshLeaksCorrector mlc;
	ImageType::Pointer inputImage = mlc.read3DImage<ImageType>(_inputName.c_str());
	cout << "Image reading done." << endl;
	typedef itk::GradientMagnitudeImageFilter<ImageType, ImageType> GradientFilterType;
	GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
	gradientFilter->SetInput(inputImage);
	gradientFilter->Update();
	ImageType::Pointer gradientInputImage = gradientFilter->GetOutput();

	cout << "Produced gradient image" << endl;
	typedef itk::ImageRegionIterator<ImageType> IteratorType;
	typedef itk::ImageRegionIterator<SegImageType> SegIteratorType;

	IteratorType gradIt(gradientFilter->GetOutput(), gradientFilter->GetOutput()->GetLargestPossibleRegion());
	cout << "GradIt" << endl;
	vtkPolyDataMapper* mapper = (vtkPolyDataMapper*)(this->GetDefaultRenderer()->GetActors()->GetLastActor()->GetMapper());
	vtkSmartPointer<vtkPolyData> vtkSegImage = vtkSmartPointer<vtkPolyData>::New();
	vtkSegImage->DeepCopy(mapper->GetInput());
	vtkSegImage->GetPointData()->SetScalars(NULL);

	cout << "Extracted mesh from actor" << endl;

	vtkSmartPointer<vtkSmoothPolyDataFilter> smoother = vtkSmoothPolyDataFilter::New();
	smoother->SetInputData(vtkSegImage);
	smoother->SetNumberOfIterations(MESH_SMOOTH_ITERATIONS);
	smoother->Update();
	vtkSmartPointer<vtkPolyData> mesh = smoother->GetOutput();
	cout << "Mesh smoothed" << endl;
	typedef itk::ImageToVTKImageFilter<ImageType> ConverterType;
	ConverterType::Pointer gradientConverter = ConverterType::New();
	gradientConverter->SetInput(inputImage);
	gradientConverter->Update();
	vtkSmartPointer<vtkImageData> vtkGradientImage = gradientConverter->GetOutput();

	cout << "Read CT image" << endl;

	vtkSmartPointer<vtkProbeFilter> probeFilter = vtkProbeFilter::New();
	probeFilter->SetSourceData(vtkGradientImage);
	probeFilter->SetInputData(mesh);
	probeFilter->Update();

	cout << "Probe finished" << endl;
	vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkGeometryFilter::New();
	geometryFilter->SetInputData(probeFilter->GetOutput());
	geometryFilter->Update();
	vtkSmartPointer<vtkPolyData> gradientMesh = geometryFilter->GetOutput();

	cout << "Geometric filter finished" << endl;

	vtkSmartPointer<vtkPolyData> minCurvatureMesh = mlc.polyDataToMinCurvature(mapper->GetInput());
	cout << "mlc.minCurv finished" << endl;

	//just temporary - don't forget to delete
	vtkSmartPointer<vtkPolyData> maxCurvatureMesh = mlc.polyDataToMaxCurvature(mapper->GetInput());
	//  --- up to here
	cout << "mlc.maaxCurv finished" << endl;
	vtkSmartPointer<vtkPolyData> minCutMeshLeaks = mlc.minCut(minCurvatureMesh, mapper->GetInput(), gradientMesh, MIN_CURVATURE_TAG, 1.0f);
	cout << "minCut finished" << endl;
	vtkSmartPointer<vtkPolyData> minCutMeshInteriorLeaks = mlc.minCut(maxCurvatureMesh, mapper->GetInput(), gradientMesh, MAX_CURVATURE_TAG, 1.0f);
	cout << "minCut Interior finished" << endl;
	vtkSmartPointer<vtkPolyData> minCutMesh = mlc.minCutConjunction(minCutMeshLeaks, minCutMeshInteriorLeaks);
	cout << "Conjunction finished" << endl;
	mlc.attributeDilation(minCutMesh, ATTRIBUTE_DILATION_RADIUS);
	cout << "dilation finished" << endl;
	vtkSmartPointer<vtkPolyData> correctedMesh1 = mlc.laplaceInterpolation(minCutMesh);
	cout << "laplace finished" << endl;
	vtkSmartPointer<vtkPolyDataNormals> normals = vtkPolyDataNormals::New();
	normals->SetInputData(correctedMesh1);
	normals->FlipNormalsOn();
	normals->Update();
	vtkSmartPointer<vtkPolyData> correctedMesh = normals->GetOutput();
	cout << "Finished fixing mesh! Wow...." << endl;
	cout << "Writing mesh to file! laplaceMesh.vtk" << endl;
	mlc.writePolyData(correctedMesh, "laplaceMesh.vtk");
	vtkSmartPointer<vtkDecimatePro> decimateFilter = vtkDecimatePro::New();
	decimateFilter->SetInputData(correctedMesh);
	decimateFilter->SetTargetReduction(DECIMATION_FACTOR);
	decimateFilter->PreserveTopologyOn();
	decimateFilter->Update();
	vtkSmartPointer<vtkPolyData> decimatedMesh = decimateFilter->GetOutput();
	cout << "Writing mesh to file! decimatedMesh.vtk" << endl;
	mlc.writePolyData(decimatedMesh, "decimatedMesh.vtk");
	//2.5D NEW code
	//Seg input image is the selection_structured_points. (upcast to vtkImageData)
	typedef itk::VTKImageToImageFilter<SegImageType> SegConverterType;
	SegConverterType::Pointer converter = SegConverterType::New();
	cout << "bedug 1" << endl;
	// selection is not NULL (checked...)
	cout << "this->_selection->GetScalarType(): " << this->_selection->GetScalarType() << endl;
	if (this->_selection->GetScalarType() == VTK_INT){
		cout << "I have INTs instead of shorts for some reason!" << endl;
	}
	converter->SetInput(this->_selection);
	cout << "deb 5" << endl;
	converter->Update(); // 
	cout << "bedug 2" << endl;
	SegImageType::Pointer segInputImage = converter->GetOutput();
	cout << "bedug 3" << endl;
	SegImageType::Pointer outputContourImage = mlc.sampleMeshOnImage<SegImageType>(decimatedMesh, segInputImage);
	cout << "bedug 4" << endl;
	vtkSmartPointer<vtkDecimatePro> decimateFilter2 = vtkDecimatePro::New();
	decimateFilter2->SetInputData(mapper->GetInput());
	decimateFilter2->SetTargetReduction(DECIMATION_FACTOR);
	decimateFilter2->PreserveTopologyOn();
	decimateFilter2->Update();
	SegImageType::Pointer seedInputImage = mlc.sampleMeshOnImage<SegImageType>(decimateFilter2->GetOutput(), segInputImage);
	cout << "bedug 5" << endl;
	SegImageType::Pointer outputImage = mlc.correctImage<SegImageType>(segInputImage, seedInputImage, outputContourImage, _numTumors);

	//Here we should dilate:
	cout << "at dilation" << endl;
	typedef itk::BinaryBallStructuringElement<SegPixelType,3> StructuringElementType;
	StructuringElementType structuringElement;
	structuringElement.SetRadius(DILATION_ST_SIZE);
	structuringElement.CreateStructuringElement();

	typedef itk::BinaryDilateImageFilter<SegImageType, SegImageType, StructuringElementType>
		BinaryDilateImageFilterType;

	BinaryDilateImageFilterType::Pointer dilateFilter
		= BinaryDilateImageFilterType::New();
	dilateFilter->SetInput(outputImage);
	dilateFilter->SetKernel(structuringElement);
	dilateFilter->Update();
	outputImage = dilateFilter->GetOutput();
	cout << "finished dilation" << endl;

	//dilation end.

	typedef itk::ImageFileWriter<SegImageType> WriterType;
	WriterType::Pointer writer = WriterType::New();
	cout << "bedug 6" << endl;
	writer->SetInput(outputImage);
	cout << "Writing mesh to file! correctedImage.nii.gz" << endl;
	writer->SetFileName("correctedImage.nii.gz");
	try{
		writer->Update();
	}
	catch (itk::ExceptionObject & excp)
	{
		std::cerr << "writing input image exception thrown" << std::endl;
		std::cerr << excp << std::endl;
		exit(1);
	}

	typedef itk::ImageToVTKImageFilter<SegImageType> SegInvConverterType;
	SegInvConverterType::Pointer correctionConverter = SegInvConverterType::New();
	cout << "bedug 7" << endl;
	correctionConverter->SetInput(outputImage);
	correctionConverter->Update();
	vtkSmartPointer<vtkImageData> vtkCorrectedImage = correctionConverter->GetOutput();
	vtkUnsignedShortArray* scalars = (vtkUnsignedShortArray*)(vtkCorrectedImage->GetPointData()->GetScalars());
	vtkUnsignedShortArray* selection_scalars = (vtkUnsignedShortArray*)(_selection->GetPointData()->GetScalars());
	for (int i = 0; i < _selection->GetNumberOfPoints(); i++){	
		if (scalars->GetValue(i) != NOT_ACTIVE){
			//cout << scalars->GetValue(i) << endl;
			selection_scalars->SetValue(i, FOREGROUND);
		}
		else{
			selection_scalars->SetValue(i, NOT_ACTIVE);
		}
	}
	selection_scalars->Modified();
	this->_selection->Modified();

	cout << "bedug 8" << endl;
	vtkSmartPointer<vtkPolyData> outputMesh = mlc.createAndSmoothSurface(vtkCorrectedImage, 50);

	vtkUnsignedShortArray* meshScalars = vtkUnsignedShortArray::New();// (vtkUnsignedShortArray*)(outputMesh->GetPointData()->GetScalars());
	meshScalars->SetNumberOfComponents(1);
	meshScalars->SetNumberOfTuples(outputMesh->GetNumberOfPoints());
	cout <<"outputMesh->GetNumberOfPoints()"<< outputMesh->GetNumberOfPoints() << endl;
	for (int i = 0; i < outputMesh->GetNumberOfPoints(); i++){
		meshScalars->SetValue(i, NOT_ACTIVE);
	}
	meshScalars->SetName("mesh_colors");
	meshScalars->Modified(); 
	outputMesh->GetPointData()->RemoveArray("mesh_colors");
	outputMesh->GetPointData()->SetScalars(meshScalars);
	outputMesh->GetPointData()->Modified();
	cout << "output values: " << meshScalars->GetValue(0) << endl;
	mapper->GetInput()->DeepCopy(outputMesh);
	mapper->Modified();
	cout << "We won!" << endl;
}
void WholeCellSeg::BinarizationForRealBounds(){
	if( !nuc_im_set || !cyt_im_set ){
		std::cerr<<"Complete segmenting nuclei and set input imge before starting segmentation\n";
		return;
	}

	itk::SizeValueType size1=cyt_im_inp->GetLargestPossibleRegion().GetSize()[0];
	itk::SizeValueType size2=cyt_im_inp->GetLargestPossibleRegion().GetSize()[1];

	if( ( size1 != nuclab_inp->GetLargestPossibleRegion().GetSize()[0] ) ||
      	    ( size2 != nuclab_inp->GetLargestPossibleRegion().GetSize()[1] ) )
	{
		std::cerr<<"The input images must be of the same size\n";
		return;
	}

	typedef unsigned short int UShortPixelType;

	typedef itk::ImageRegionIteratorWithIndex< UShortImageType > IteratorType;
	typedef itk::ImageRegionConstIterator< UShortImageType > ConstIteratorType;

	typedef itk::Statistics::ScalarImageToHistogramGenerator< IntImageType > ScalarImageToHistogramGeneratorType;
	typedef ScalarImageToHistogramGeneratorType::HistogramType HistogramType;
	typedef itk::OtsuMultipleThresholdsCalculator< HistogramType > CalculatorType;
	typedef itk::RescaleIntensityImageFilter< UShortImageType, IntImageType > RescaleUsIntType;
	typedef itk::RescaleIntensityImageFilter< UShortImageType, UShortImageType > RescaleUsUsType;
	typedef itk::BinaryThresholdImageFilter< IntImageType, UShortImageType >  ThreshFilterType;
	typedef itk::BinaryThresholdImageFilter< UShortImageType, UShortImageType >  ThresholdFilterType;
	typedef itk::OrImageFilter< UShortImageType, UShortImageType, UShortImageType > OrFilterType;
 	typedef itk::BinaryBallStructuringElement< UShortPixelType, 2 > StructuringElementType;
	typedef itk::BinaryErodeImageFilter< UShortImageType, UShortImageType, StructuringElementType > ErodeFilterType;
	typedef itk::BinaryDilateImageFilter< UShortImageType, UShortImageType, StructuringElementType > DilateFilterType;

	unsigned char *in_Image;
	itk::SizeValueType ind=0;

//Call Yousef's binarization method if the number of bin levels is < 2
	if( num_levels < 2 ){
		bin_Image = (unsigned short *) malloc (size1*size2*sizeof(unsigned short));
		for(itk::SizeValueType j=0; j<size2; ++j)
			for(itk::SizeValueType i=0; i<size1; ++i)
				BIN_Image(i,j)=255;
		in_Image = (unsigned char *) malloc (size1*size2);
		if( ( in_Image == NULL ) || ( bin_Image == NULL ) ){
			std::cerr << "Memory allocation for binarization of image failed\n";
			return;
		}

		RescaleUsUsType::Pointer rescaleususfilter = RescaleUsUsType::New();
		rescaleususfilter->SetInput( cyt_im_inp );
		rescaleususfilter->SetOutputMaximum( itk::NumericTraits<unsigned char>::max() );
		rescaleususfilter->SetOutputMinimum( 0 );
		rescaleususfilter->Update();
		UShortImageType::Pointer resc_cyt_im = UShortImageType::New();
		resc_cyt_im = rescaleususfilter->GetOutput();
		ConstIteratorType pix_buf1( resc_cyt_im, resc_cyt_im->GetRequestedRegion() );
		for ( pix_buf1.GoToBegin(); !pix_buf1.IsAtEnd(); ++pix_buf1, ++ind )
		in_Image[ind]=(unsigned char)(pix_buf1.Get());

		int ok = 0;
		ok = Cell_Binarization_2D(in_Image,bin_Image, size1, size2, shift_bin);
		free( in_Image );

		if( !ok ){
			std::cerr<<"Binarization Failed\n";
			return;
		}

//copy the output binary image into the ITK image
		intermediate_bin_im_out = UShortImageType::New();
		UShortImageType::PointType origin;
		origin[0] = 0;
		origin[1] = 0;
		intermediate_bin_im_out->SetOrigin( origin );

		UShortImageType::IndexType start;
		start[0] = 0;  // first index on X
		start[1] = 0;  // first index on Y
		UShortImageType::SizeType  size;
		size[0] = size1;  // size along X
		size[1] = size2;  // size along Y

		UShortImageType::RegionType region;
		region.SetSize( size );
		region.SetIndex( start );

		intermediate_bin_im_out->SetRegions( region );
		intermediate_bin_im_out->Allocate();
		intermediate_bin_im_out->FillBuffer(0);
		intermediate_bin_im_out->Update();

		itk::SizeValueType dum,dum1;
		dum = 0;
		dum1 = USHRT_MAX;

		//unsigned int asd,asd1; asd=0; asd1=0;
		IteratorType iterator ( intermediate_bin_im_out, intermediate_bin_im_out->GetRequestedRegion() );
		for(itk::SizeValueType i=0; i < (size1*size2); ++i){
			if( bin_Image[i] )
			iterator.Set( dum1 );
			else
			iterator.Set( dum );
			++iterator;
		}
	}
//Call multi level binarization method if the number of bin levels is >= 2
	else{
		RescaleUsIntType::Pointer rescaleusintfilter = RescaleUsIntType::New();
		ScalarImageToHistogramGeneratorType::Pointer scalarImageToHistogramGenerator = ScalarImageToHistogramGeneratorType::New();
		rescaleusintfilter->SetInput( cyt_im_inp );
		rescaleusintfilter->SetOutputMaximum( itk::NumericTraits<unsigned short>::max() );
		rescaleusintfilter->SetOutputMinimum( 0 );
		rescaleusintfilter->Update();

		ThreshFilterType::Pointer threshfilter = ThreshFilterType::New();
		CalculatorType::Pointer calculator = CalculatorType::New();
		scalarImageToHistogramGenerator->SetNumberOfBins( 255 );
		calculator->SetNumberOfThresholds( num_levels );
		threshfilter->SetOutsideValue( (int)0 );
		threshfilter->SetInsideValue( (int)USHRT_MAX );
		scalarImageToHistogramGenerator->SetInput( rescaleusintfilter->GetOutput() );
		scalarImageToHistogramGenerator->Compute();
		calculator->SetInputHistogram( scalarImageToHistogramGenerator->GetOutput() );
		threshfilter->SetInput( rescaleusintfilter->GetOutput() );
		calculator->Update();
		const CalculatorType::OutputType &thresholdVector = calculator->GetOutput();
		CalculatorType::OutputType::const_iterator itNum = thresholdVector.begin();
		int lowerThreshold,upperThreshold;

		for( int i=0; i<(num_levels-num_levels_incl); ++i ) ++itNum;
		lowerThreshold = static_cast<unsigned short>(*itNum);
		upperThreshold = itk::NumericTraits<unsigned short>::max();

		threshfilter->SetLowerThreshold( lowerThreshold );
		threshfilter->SetUpperThreshold( upperThreshold );
		threshfilter->Update();

		intermediate_bin_im_out = UShortImageType::New();
		intermediate_bin_im_out = threshfilter->GetOutput();
	}

//Fill holes left by the nuclei
	ThresholdFilterType::Pointer binarythreshfilter = ThresholdFilterType::New();
	binarythreshfilter->SetInsideValue( USHRT_MAX );
	binarythreshfilter->SetOutsideValue( 0 );
	binarythreshfilter->SetLowerThreshold( 1 );
	binarythreshfilter->SetUpperThreshold( USHRT_MAX );
	binarythreshfilter->SetInput( nuclab_inp );
	OrFilterType::Pointer orfilter = OrFilterType::New();
	orfilter->SetInput1( binarythreshfilter->GetOutput() );
	orfilter->SetInput2( intermediate_bin_im_out );
//dialate and erode
	ErodeFilterType::Pointer  binaryErode  = ErodeFilterType::New();
	DilateFilterType::Pointer binaryDilate = DilateFilterType::New();
	StructuringElementType  structuringElement;
	structuringElement.SetRadius( 3 );  // 3x3 structuring element
	structuringElement.CreateStructuringElement();
	binaryErode->SetKernel( structuringElement );
	binaryErode->SetErodeValue( USHRT_MAX );
	binaryDilate->SetDilateValue( USHRT_MAX );
	binaryDilate->SetKernel( structuringElement );
	binaryErode->SetInput( binaryDilate->GetOutput() );
	binaryDilate->SetInput( orfilter->GetOutput() );
//erode and dialate
	ErodeFilterType::Pointer  binaryErode1  = ErodeFilterType::New();
	DilateFilterType::Pointer binaryDilate1 = DilateFilterType::New();
	binaryErode1->SetKernel(  structuringElement );
	binaryErode1->SetErodeValue( USHRT_MAX );
	binaryDilate1->SetDilateValue( USHRT_MAX );
	binaryDilate1->SetKernel( structuringElement );
	binaryErode1->SetInput( binaryErode->GetOutput() );
	binaryDilate1->SetInput( binaryErode1->GetOutput() );
	binaryDilate1->Update();
//Get pointer to the final binary image and return it to calling function
	UShortImageType::Pointer image_bin = UShortImageType::New();
	image_bin = binaryDilate1->GetOutput();
	bin_im_out = image_bin;
	bin_done = 1;

//Update bin array
	ind=0;
	if( draw_real_bounds ){
		ConstIteratorType pix_buf3( bin_im_out, bin_im_out->GetRequestedRegion() );
		for ( pix_buf3.GoToBegin(); !pix_buf3.IsAtEnd(); ++pix_buf3, ++ind )
		bin_Image[ind]=(pix_buf3.Get());
	}else
		free( bin_Image );
/*
	typedef itk::ImageFileWriter< UShortImageType > WriterType;
	WriterType::Pointer writer = WriterType::New();
	writer->SetFileName( "bin_info.tif" );
	writer->SetInput( bin_im_out );//RescaleIntIO1--finalO/P
	writer->Update();
*/
	return;
}
Beispiel #9
0
//腐蚀操作
void segmentation::erosionOperation()//未用到
{
    const unsigned int Dimension = 3;
    typedef unsigned char   InputPixelType;
    typedef unsigned char   OutputPixelType;
    typedef itk::Image< InputPixelType,  Dimension >   InputImageType;
    typedef itk::Image< OutputPixelType, Dimension >   OutputImageType;
    typedef itk::ImageFileReader< InputImageType  >  ReaderType;
    typedef itk::ImageFileWriter< OutputImageType >  WriterType;
    typedef itk::BinaryThresholdImageFilter< InputImageType, InputImageType >  ThresholdFilterType;
    typedef itk::BinaryBallStructuringElement< 
        InputPixelType,
        Dimension  >             StructuringElementType;
    typedef itk::BinaryErodeImageFilter<
        InputImageType, 
        OutputImageType,
        StructuringElementType >  ErodeFilterType;
    ReaderType::Pointer reader = ReaderType::New();
    WriterType::Pointer writerErosion  = WriterType::New();
    ThresholdFilterType::Pointer thresholder = ThresholdFilterType::New();
    ErodeFilterType::Pointer  binaryErode  = ErodeFilterType::New();
    StructuringElementType  structuringElementErosion;
    reader->SetFileName( initFileName );//读入二值图
    reader->Update();
    InputImageType::Pointer inputImage = InputImageType::New();
    InputImageType::IndexType voxelIndex;
    inputImage = reader->GetOutput();
    InputImageType::SizeType imgSize = inputImage->GetLargestPossibleRegion().GetSize();
    long vol = 0;
    unsigned char temp;
    float r;
    for(int z = 0; z < imgSize[2]; z++)
        for(int y = 0; y < imgSize[1]; y++)
            for(int x = 0; x < imgSize[0]; x++)
            {
                voxelIndex[0] = x;
                voxelIndex[1] = y;
                voxelIndex[2] = z;
                temp = inputImage->GetPixel(voxelIndex);
                if(temp == 255)// 255 for PED
                    vol += 1;
            }
            r = pow((3 * vol) / (4 * PI), (1.0 / 3)) ;
            r = r / 20;//experiment data
            structuringElementErosion.SetRadius( r );  // 3x3 structuring element
            structuringElementErosion.CreateStructuringElement();
            binaryErode->SetKernel(  structuringElementErosion );
            //文件前缀名
            filePrefix = inputFileName;//char* to string
            filePrefix = filePrefix.substr(0, filePrefix.length() - 4);
            string erosionFileName;
            erosionFileName = filePrefix + "_erosionResult.mhd";
            strcpy(outputFileName, erosionFileName.c_str());//string to char*
            writerErosion->SetFileName(outputFileName);
            const InputPixelType lowerThreshold = 255;
            const InputPixelType upperThreshold = 255;
            thresholder->SetInput( reader->GetOutput() );
            InputPixelType background =   0;
            InputPixelType foreground = 255;
            thresholder->SetOutsideValue( background );
            thresholder->SetInsideValue(  foreground );
            thresholder->SetLowerThreshold( lowerThreshold );
            thresholder->SetUpperThreshold( upperThreshold );
            binaryErode->SetInput( thresholder->GetOutput() );
            binaryErode->SetErodeValue( foreground );
            writerErosion->SetInput( binaryErode->GetOutput() );
            writerErosion->Update();
            //binaryErode->GetOutput()->GetPixel(index);//获取像素值失败

            //腐蚀结果叠加到原图
            typedef itk::Image< unsigned short,  Dimension >   OriginalImageType;
            typedef itk::ImageFileReader<OriginalImageType>OriginalReaderType;
            OriginalReaderType::Pointer orignalImgreader = OriginalReaderType::New();
            OriginalImageType::Pointer originalImage = OriginalImageType::New();
            OriginalReaderType::IndexType originalImgVoxelIndex;
            reader->SetFileName(outputFileName);//读入腐蚀结果图像
            reader->Update();
            inputImage = reader->GetOutput();
            orignalImgreader->SetFileName(inputFileName);//读入原图像
            orignalImgreader->Update();
            originalImage = orignalImgreader->GetOutput();
            for(int z = 0; z < imgSize[2]; z++)
                for(int y = 0; y < imgSize[1]; y++)
                    for(int x = 0; x < imgSize[0]; x++)
                    {
                        voxelIndex[0] = x;
                        voxelIndex[1] = y;
                        voxelIndex[2] = z;
                        originalImgVoxelIndex[0] = x;
                        originalImgVoxelIndex[1] = y;
                        originalImgVoxelIndex[2] = z;
                        temp = inputImage->GetPixel(voxelIndex);
                        if(temp == 255)
                            originalImage->SetPixel(originalImgVoxelIndex, 65535);
                    }
                    //输出结果
                    typedef itk::ImageFileWriter<OriginalImageType>NewWriterType;
                    NewWriterType::Pointer writer = NewWriterType::New();
                    //文件前缀名
                    filePrefix = inputFileName;//char* to string
                    filePrefix = filePrefix.substr(0, filePrefix.length() - 4);
                    filePrefix = filePrefix + "_refinedResult.mhd";
                    strcpy(outputFileName, filePrefix.c_str());//string to char*
                    writer->SetFileName(outputFileName);
                    writer->SetInput(originalImage);
                    writer->Update();

                    emit returnInternalFileName(initResultFileName);//更新原视图
                    emit returnOutputFileName(outputFileName);//显示结果图
}
void LidarSegmentationWidget::GenerateNeighborSinks()
{
  Mask::Pointer sourcesImage = Mask::New();
  sourcesImage->SetRegions(this->ImageRegion);
  ITKHelpers::IndicesToBinaryImage(this->Sources, sourcesImage);
  ITKHelpers::WriteImage(sourcesImage.GetPointer(), "sourcesImage.png");
  
  // Dilate the mask
  std::cout << "Dilating mask..." << std::endl;
  typedef itk::BinaryBallStructuringElement<Mask::PixelType, 2> StructuringElementType;
  StructuringElementType structuringElement;
  structuringElement.SetRadius(1);
  structuringElement.CreateStructuringElement();

  typedef itk::BinaryDilateImageFilter<Mask, Mask, StructuringElementType> BinaryDilateImageFilterType;

  BinaryDilateImageFilterType::Pointer dilateFilter = BinaryDilateImageFilterType::New();
  dilateFilter->SetInput(sourcesImage);
  dilateFilter->SetKernel(structuringElement);
  dilateFilter->Update();

  // Binary XOR the images to get the difference image
  //std::cout << "XORing masks..." << std::endl;
  typedef itk::XorImageFilter<Mask> XorImageFilterType;

  XorImageFilterType::Pointer xorFilter = XorImageFilterType::New();
  xorFilter->SetInput1(dilateFilter->GetOutput());
  xorFilter->SetInput2(sourcesImage);
  xorFilter->Update();

  ITKHelpers::WriteImage(xorFilter->GetOutput(), "boundaryOfSegmentation.png");
  
  // Iterate over the border pixels. If the closest pixel in the original segmentation has
  // a depth greater than a threshold, mark it as a new sink. Else, do not.
  std::cout << "Determining which boundary pixels should be declared background..." << std::endl;
  //std::cout << "There should be " << Helpers::CountNonZeroPixels(xorFilter->GetOutput())
  //          << " considered." << std::endl;
  typedef std::vector<itk::Index<2> > VectorOfPixelsType;
  VectorOfPixelsType newSinks;

  typedef itk::VectorIndexSelectionCastImageFilter<ImageType, FloatScalarImageType> IndexSelectionType;
  IndexSelectionType::Pointer indexSelectionFilter = IndexSelectionType::New();
  indexSelectionFilter->SetIndex(3);
  indexSelectionFilter->SetInput(this->Image);
  indexSelectionFilter->Update();
  
  FloatScalarImageType::Pointer depthImage = indexSelectionFilter->GetOutput();

  //float sameObjectThreshold = 0.1f;

  VectorOfPixelsType consideredPixels;

  itk::ImageRegionIterator<Mask> imageIterator(xorFilter->GetOutput(),
                                               xorFilter->GetOutput()->GetLargestPossibleRegion());
  while(!imageIterator.IsAtEnd())
    {
    if(imageIterator.Get()) // If the current pixel is in question
      {
      consideredPixels.push_back(imageIterator.GetIndex());
      }
    ++imageIterator;
    }

  std::cout << "There are " << consideredPixels.size() << " potential new sink pixels." << std::endl;
  
  for(VectorOfPixelsType::const_iterator iter = consideredPixels.begin(); iter != consideredPixels.end(); ++iter)
    {
    //std::cout << "Considering pixel " << consideredCounter << " (index "
    //          << imageIterator.GetIndex() << ")" << std::endl;
    ImageType::PixelType currentPixel = this->Image->GetPixel(*iter);

    unsigned int radius = this->txtBackgroundCheckRadius->text().toUInt();
    ImageType::RegionType desiredRegion = ITKHelpers::GetRegionInRadiusAroundPixel(*iter, radius);
    //std::cout << "desiredRegion: " << desiredRegion << std::endl;
    
    itk::ImageRegionIterator<Mask> sourcesImageIterator(sourcesImage, desiredRegion);
    
    std::vector<float> nonForegroundDepths;
    std::vector<float> foregroundDepths;
    while(!sourcesImageIterator.IsAtEnd())
      {
      if(sourcesImageIterator.Get())
        {
        foregroundDepths.push_back(depthImage->GetPixel(sourcesImageIterator.GetIndex()));
        }
      else
        {
        nonForegroundDepths.push_back(depthImage->GetPixel(sourcesImageIterator.GetIndex()));
        }
      ++sourcesImageIterator;
      }

    if(nonForegroundDepths.size() < 1)
    {
    }
    
    float nonForegroundMedian = Helpers::VectorMedian(nonForegroundDepths);
    float foregroundMedian = Helpers::VectorMedian(foregroundDepths);

    float difference = fabs(foregroundMedian - nonForegroundMedian);

    if(difference > this->txtBackgroundThreshold->text().toFloat())
      {
      //std::cout << "Difference was " << difference << " so this is a sink pixel." << std::endl;
      newSinks.push_back(*iter);
      }
    else
      {
      //std::cout << "Difference was " << difference << " so this is NOT a sink pixel." << std::endl;
      }
    } // end loop over considered pixels
  
  unsigned char blue[3] = {0, 0, 255};
//   ImageType::PixelType blue(3);
//   blue[0] = 0;
//   blue[1] = 0;
//   blue[2] = 255;
  
  ITKVTKHelpers::SetPixels(this->SourceSinkImageData.GetPointer(), consideredPixels, blue);
  this->SourceSinkImageData->Modified();
  this->Refresh();
  
  // Save the new sink pixels for inspection
  UnsignedCharScalarImageType::Pointer newSinksImage = UnsignedCharScalarImageType::New();
  newSinksImage->SetRegions(this->Image->GetLargestPossibleRegion());
  newSinksImage->Allocate();

  ITKHelpers::IndicesToBinaryImage(newSinks, newSinksImage);
  ITKHelpers::WriteImage(newSinksImage.GetPointer(), "newSinks.png");

  //std::cout << "Out of " << consideredCounter << " pixels considered, "
  //          << backgroundCounter << " were declared background." << std::endl;
  // Set the new sinks
  std::cout << "Setting " << newSinks.size() << " new sinks." << std::endl;

  // Modify the list of sinks so it can be retrieved by the MainWindow after the segmentation is finished
  this->Sinks.insert(this->Sinks.end(), newSinks.begin(), newSinks.end());

  UpdateSelections();
}