// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- 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"); }
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; }
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; }
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; }