ImageType::Pointer SBFilterUtils::ThresholdImage(ImageType::Pointer image, int lowerThreshold, int upperThreshold, int insideValue, int outsideValue)
{
	BinaryThresholdFilterType::Pointer thresholdFilter = BinaryThresholdFilterType::New();
	thresholdFilter->SetInput(image);
	thresholdFilter->SetLowerThreshold(lowerThreshold);
	thresholdFilter->SetUpperThreshold(upperThreshold);
	thresholdFilter->SetOutsideValue(outsideValue);
	thresholdFilter->SetInsideValue(insideValue);
	thresholdFilter->Update();
	
	return thresholdFilter->GetOutput();
}
void BinaryThresholdFilterDialog::on_pushButtonApply_clicked()
{
    ImageLayer *imageLayer = ImageLayer::instance();
    int insideValue = ui->spinBoxInsideValue->value();
    int outsideValue = ui->spinBoxOutsideValue->value();
    int lowerThreshold = ui->spinBoxLowerThreshold->value();
    int upperThreshold = ui->spinBoxUpperThreshold->value();
    imageLayer->resizeImageVector(2);

    typedef itk::BinaryThresholdImageFilter<ImageLayer::GrayImageType, ImageLayer::GrayImageType> BinaryThresholdFilterType;

    BinaryThresholdFilterType::Pointer binaryThresholdFilter = BinaryThresholdFilterType::New();
    binaryThresholdFilter->SetInsideValue(insideValue);
    binaryThresholdFilter->SetOutsideValue(outsideValue);
    binaryThresholdFilter->SetLowerThreshold(lowerThreshold);
    binaryThresholdFilter->SetUpperThreshold(upperThreshold);
    binaryThresholdFilter->SetInput(imageLayer->grayImagePointer(0));
    binaryThresholdFilter->Update();

    imageLayer->setGrayImage(1, binaryThresholdFilter->GetOutput());
}
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;
}
Example #4
0
void WholeCellSeg::SyntheticBoundaries(){

	typedef itk::RescaleIntensityImageFilter< UShortImageType, IntImageType > RescaleIOIntType;
	typedef itk::RescaleIntensityImageFilter< FltImageType, IntImageType > RescaleFltIntType;
	typedef itk::CastImageFilter< UShortImageType, IntImageType > CastUSIntType;
	typedef itk::CastImageFilter< IntImageType, UShortImageType > CastIntUSType;
	typedef itk::BinaryThresholdImageFilter< IntImageType, IntImageType > BinaryThresholdFilterType;
	typedef itk::BinaryThresholdImageFilter< FltImageType, IntImageType > BinaryThresholdFilterTypeFI;
	typedef itk::AndImageFilter< IntImageType, IntImageType, IntImageType > AndFilterType;
	typedef itk::SignedMaurerDistanceMapImageFilter< IntImageType, FltImageType > SignedMaurerDistanceMapFilterType;
	typedef itk::MorphologicalWatershedFromMarkersImageFilter< IntImageType, IntImageType > WatershedFilterType;
	typedef itk::ImageRegionIteratorWithIndex< UShortImageType > IteratorType;
	typedef itk::ImageRegionIteratorWithIndex< IntImageType > IteratorType1;
	
//Rescale and Threshold input label image 
	RescaleIOIntType::Pointer RescaleIOInt = RescaleIOIntType::New();
	RescaleIOInt->SetOutputMaximum( INT_MAX );
	RescaleIOInt->SetOutputMinimum( 0 );
	RescaleIOInt->SetInput( nuclab_inp );
	if( draw_real_bounds && remove_small_objs )
		RescaleIOInt->SetInput( nuclab_inp_cpy );
	else
		RescaleIOInt->SetInput( nuclab_inp );
	RescaleIOInt->Update();

	BinaryThresholdFilterType::Pointer binarythreshfilter = BinaryThresholdFilterType::New();
	binarythreshfilter->SetInsideValue( INT_MAX );
	binarythreshfilter->SetOutsideValue( 0 );
	binarythreshfilter->SetLowerThreshold( 1 );
	binarythreshfilter->SetUpperThreshold( INT_MAX );
	binarythreshfilter->SetInput( RescaleIOInt->GetOutput() );
	binarythreshfilter->Update();

//Distance map for synthetic boundaries around nuclei that do not have any marker around them
	SignedMaurerDistanceMapFilterType::Pointer distancemapfilter = SignedMaurerDistanceMapFilterType::New();
	distancemapfilter->SetInput(binarythreshfilter->GetOutput());
	distancemapfilter->SquaredDistanceOff();
	distancemapfilter->Update();

//Threshold the map to limit the max distance to the radius limit set by the user
	BinaryThresholdFilterTypeFI::Pointer binarythreshfilterfi = BinaryThresholdFilterTypeFI::New();
	binarythreshfilterfi->SetInsideValue( INT_MAX );
	binarythreshfilterfi->SetOutsideValue( 0 );
	binarythreshfilterfi->SetLowerThreshold( 1 );
	binarythreshfilterfi->SetUpperThreshold( radius_of_synth_bounds );
	binarythreshfilterfi->SetInput( distancemapfilter->GetOutput() );
	RescaleFltIntType::Pointer rescalefltint = RescaleFltIntType::New();
	rescalefltint->SetOutputMaximum( INT_MAX );
	rescalefltint->SetOutputMinimum( 0 );
	rescalefltint->SetInput( distancemapfilter->GetOutput() );
	AndFilterType::Pointer andfilter1 = AndFilterType::New();
	andfilter1->SetInput1( rescalefltint->GetOutput() );
	andfilter1->SetInput2( binarythreshfilterfi->GetOutput() );
	AndFilterType::Pointer andfilter2 = AndFilterType::New();
	andfilter2->SetInput1( andfilter1->GetOutput() );
	andfilter2->SetInput2( binarythreshfilterfi->GetOutput() );
	andfilter2->Update();

	CastUSIntType::Pointer castUSIntfilter = CastUSIntType::New();
	if( draw_real_bounds && remove_small_objs )
		castUSIntfilter->SetInput( nuclab_inp_cpy );
	else
		castUSIntfilter->SetInput( nuclab_inp );
	castUSIntfilter->Update();
	IntImageType::Pointer nuclab_inp_int = IntImageType::New();
	nuclab_inp_int = castUSIntfilter->GetOutput();

	IntImageType::Pointer image2=andfilter2->GetOutput();
	IteratorType1 pix_bufed2( image2, image2->GetRequestedRegion() );
	pix_bufed2.GoToBegin();
	IteratorType1 pix_bufed3( nuclab_inp_int, nuclab_inp_int->GetRequestedRegion() );
	pix_bufed3.GoToBegin();
	while( !pix_bufed2.IsAtEnd() || !pix_bufed3.IsAtEnd() ){
			if( !pix_bufed2.Get() )
				if( !pix_bufed3.Get() )
					pix_bufed2.Set( INT_MIN );
			++pix_bufed2; ++pix_bufed3;
	}

//Draw synthetic boundaries using the seeded Watershed algorithm
	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();

	if( draw_real_bounds ){
		UShortImageType::Pointer image1=castIntUSfilter->GetOutput();
		IteratorType pix_bufed( image1, image1->GetRequestedRegion() );
		pix_bufed.GoToBegin();
		IteratorType pix_bufed1( seg_im_out, seg_im_out->GetRequestedRegion() );
		pix_bufed1.GoToBegin();
		while( !pix_bufed1.IsAtEnd() ){
			if( !pix_bufed1.Get() )
				pix_bufed1.Set( pix_bufed.Get());
			++pix_bufed; ++pix_bufed1;
		}
	}
	else
		seg_im_out = castIntUSfilter->GetOutput();


/*	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( "dist_map.tif" );
	writer->SetInput( RescaleIntIO1->GetOutput() );//RescaleIntIO1--finalO/P
	writer->Update();
*/

	if( ( !remove_small_objs ) || ( draw_real_bounds && remove_small_objs )  )
		seg_done = 1;
}