Esempio n. 1
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void Watershed::execute()
{
  //int err = 0;
  dataCheck();
  if(getErrorCondition() < 0) { return; }

  DataContainer::Pointer m = getDataContainerArray()->getDataContainer(getSelectedCellArrayPath().getDataContainerName());
  QString attrMatName = getSelectedCellArrayPath().getAttributeMatrixName();

  //wrap m_RawImageData as itk::image
  ImageProcessing::DefaultImageType::Pointer inputImage = ITKUtilitiesType::CreateItkWrapperForDataPointer(m, attrMatName, m_SelectedCellArray);

  //create gradient magnitude filter
  notifyStatusMessage(getHumanLabel(), "Calculating Gradient Magnitude");
  typedef itk::GradientMagnitudeImageFilter<ImageProcessing::DefaultImageType, ImageProcessing::DefaultImageType >  GradientMagnitudeImageFilterType;
  GradientMagnitudeImageFilterType::Pointer gradientMagnitudeImageFilter = GradientMagnitudeImageFilterType::New();
  gradientMagnitudeImageFilter->SetInput(inputImage);
  gradientMagnitudeImageFilter->Update();

  //watershed image
  notifyStatusMessage(getHumanLabel(), "Watershedding");
  typedef itk::WatershedImageFilter<ImageProcessing::DefaultImageType> WatershedFilterType;
  WatershedFilterType::Pointer watershed = WatershedFilterType::New();
  watershed->SetThreshold(m_Threshold);
  watershed->SetLevel(m_Level);
  watershed->SetInput(gradientMagnitudeImageFilter->GetOutput());

  //execute filter
  try
  {
    watershed->Update();
  }
  catch( itk::ExceptionObject& err )
  {
    setErrorCondition(-5);
    QString ss = QObject::tr("Failed to execute itk::GradientMagnitudeImageFilter filter. Error Message returned from ITK:\n   %1").arg(err.GetDescription());
    notifyErrorMessage(getHumanLabel(), ss, getErrorCondition());
  }

  //get output and copy to grainids
  typedef itk::Image<unsigned long, ImageProcessing::ImageDimension>   WatershedImageType;
  WatershedImageType::Pointer output = watershed->GetOutput();
  WatershedImageType::RegionType filterRegion = output->GetLargestPossibleRegion();
  typedef itk::ImageRegionConstIterator<itk::Image<unsigned long, ImageProcessing::ImageDimension> > WatershedIteratorType;
  WatershedIteratorType it(output, filterRegion);
  it.GoToBegin();
  int index = 0;
  while(!it.IsAtEnd())
  {
    m_FeatureIds[index] = it.Get();
    ++it;
    ++index;
  }


  /* Let the GUI know we are done with this filter */
  notifyStatusMessage(getHumanLabel(), "Complete");
}
Esempio n. 2
0
int
main(int argc, char* argv[])
{
	boost::filesystem::path inputFile;
	boost::filesystem::path outputFile;

	Algorithm algorithm;
	std::string algorithmName;

	po::options_description desc("Allowed options");
	desc.add_options()
		("help", "produce help message")
		("input,i", po::value<boost::filesystem::path>(&inputFile), "input file")
		("algorithm,a", po::value<std::string>(&algorithmName)->default_value("itk-implementation"), "itk-implementation")
		("output,o", po::value<boost::filesystem::path>(&outputFile), "output mask file")
		;

	po::variables_map vm;
	po::store(po::parse_command_line(argc, argv, desc), vm);
	po::notify(vm);

	algorithm = getAlgorithmFromString(algorithmName);

	if (vm.count("help")) {
		std::cout << desc << "\n";
		return 1;
	}

	if (vm.count("input") == 0) {
		std::cout << "Missing input filename\n" << desc << "\n";
		return 1;
	}

	if (vm.count("output") == 0) {
		std::cout << "Missing output filename\n" << desc << "\n";
		return 1;
	}

	typedef itk::ImageFileReader<ImageType>  ImageReaderType;

	BOOST_LOG_TRIVIAL(info) << "Loading inputs ...";
	ImageReaderType::Pointer imageReader = ImageReaderType::New();
	imageReader->SetFileName(inputFile.string());
	imageReader->Update();

	ImageType::Pointer image = imageReader->GetOutput();

	LabeledImageType::Pointer outputImage;

	switch (algorithm) {
	case Algorithm::ItkImplementation: {
		BOOST_LOG_TRIVIAL(info) << "Running ITK version of watershed transformation ...";
			WatershedFilterType::Pointer filter = WatershedFilterType::New();
			filter->SetInput(image);
			filter->MarkWatershedLineOff();

			boost::timer::cpu_timer computationTimer;
			computationTimer.start();
			filter->Update();
			BOOST_LOG_TRIVIAL(info) << "Computation time: " << computationTimer.format(9, "%w");

			outputImage = filter->GetOutput();
		}
		break;
	default:
		BOOST_LOG_TRIVIAL(info) << "Allocating output ...";
		outputImage = LabeledImageType::New();
		outputImage->SetRegions(image->GetLargestPossibleRegion());
		outputImage->Allocate();
		outputImage->SetSpacing(image->GetSpacing());
		BOOST_LOG_TRIVIAL(info) << "Running CUDA version of watershed transformation (topographical distance)...";
		boost::timer::cpu_timer computationTimer;
		computationTimer.start();
		watershedTransformation2(
			cugip::const_view(*(image.GetPointer())),
			cugip::view(*(outputImage.GetPointer())),
			Options()
			);
		BOOST_LOG_TRIVIAL(info) << "Computation time: " << computationTimer.format(9, "%w");
		//BOOST_LOG_TRIVIAL(error) << "Unknown algorithm";
	}

	BOOST_LOG_TRIVIAL(info) << "Saving output `" << outputFile << "` ...";
	WriterType::Pointer writer = WriterType::New();
	writer->SetFileName(outputFile.string());
	writer->SetInput(outputImage);
	try {
		writer->Update();
	} catch (itk::ExceptionObject & error) {
		std::cerr << "Error: " << error << std::endl;
		return EXIT_FAILURE;
	}

	return 0;
}
Esempio n. 3
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;
}
Esempio n. 4
0
void WholeCellSeg::RealBoundaries(){
	int size1=cyt_im_inp->GetLargestPossibleRegion().GetSize()[0];
	int size2=cyt_im_inp->GetLargestPossibleRegion().GetSize()[1];

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

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

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

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

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


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

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

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

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

	free( NUC_IM );
	free( bin_Image );

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

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

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

	free( INP_IM_2D );

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

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

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

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

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

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

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

	for(int j=size2-1; j>=0; j--)
		for(int i=0; i<size1; i++){
			OP(i,j)=(pix_bufed3.Get());
			++pix_bufed3;
		}
*/
	if( !remove_small_objs )
		seg_done = 1;
}