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; }
void Preprocess::OtsuBinarize(int num_thresholds, int num_in_foreground, bool fgrnd_dark) { //Create histogram: typedef itk::Statistics::ScalarImageToHistogramGenerator< ImageType3D > HistogramGeneratorType; typedef HistogramGeneratorType::HistogramType HistogramType; HistogramGeneratorType::Pointer histoGenerator = HistogramGeneratorType::New(); histoGenerator->SetNumberOfBins( 256 ); histoGenerator->SetInput( myImg ); try { histoGenerator->Compute(); } catch( itk::ExceptionObject & excep ) { std::cerr << " Histogram Computation: exception caught !" << std::endl; std::cerr << excep << std::endl; return; } //Estimate thresholds: typedef itk::OtsuMultipleThresholdsCalculator< HistogramType > CalculatorType; CalculatorType::Pointer calculator = CalculatorType::New(); calculator->SetNumberOfThresholds( num_thresholds ); calculator->SetInputHistogram( histoGenerator->GetOutput() ); try { calculator->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << " Otsu Computation: exception caught !" << std::endl; std::cerr << excep << std::endl; return; } const CalculatorType::OutputType &thresholdVector = calculator->GetOutput(); //Estimate Binarization thresholds: PixelType lowerThreshold,upperThreshold; if( fgrnd_dark ) //Do I want to make the foregound of the binary dark: { CalculatorType::OutputType::const_iterator itNum = thresholdVector.end(); for( int i=0; i<(num_thresholds-num_in_foreground+1); ++i ) --itNum; upperThreshold = static_cast<PixelType>(*itNum); lowerThreshold = itk::NumericTraits<PixelType>::min(); } else { CalculatorType::OutputType::const_iterator itNum = thresholdVector.begin(); for( int i=0; i<(num_thresholds-num_in_foreground); ++i ) ++itNum; lowerThreshold = static_cast<PixelType>(*itNum); upperThreshold = itk::NumericTraits<PixelType>::max(); } //std::cerr << "Binarization Thresholds: " << lowerThreshold << " " << upperThreshold << std::endl; typedef itk::BinaryThresholdImageFilter< ImageType3D, ImageType3D > ThreshFilterType; ThreshFilterType::Pointer threshfilter = ThreshFilterType::New(); threshfilter->SetOutsideValue( 0 ); threshfilter->SetInsideValue( (int)itk::NumericTraits<PixelType>::max() ); threshfilter->SetInput( myImg ); threshfilter->SetLowerThreshold( lowerThreshold ); threshfilter->SetUpperThreshold( upperThreshold ); try { threshfilter->Update(); } catch( itk::ExceptionObject & excep ) { std::cerr << " Threshold: exception caught !" << std::endl; std::cerr << excep << std::endl; return; } myImg = threshfilter->GetOutput(); }
USImageType::PixelType returnthresh( itk::SmartPointer<USImageType> input_image, int num_bin_levs, int num_in_fg ){ //Instantiate the different image and filter types that will be used typedef itk::ImageRegionConstIterator< USImageType > ConstIteratorType; typedef itk::Statistics::Histogram< float > HistogramType; typedef itk::OtsuMultipleThresholdsCalculator< HistogramType > CalculatorType; std::cout<<"Starting threshold computation\n"; //Create a temporary histogram container: const int numBins = itk::NumericTraits<USImageType::PixelType>::max(); double *tempHist; tempHist = (double*) malloc( sizeof(double) * numBins ); for(USImageType::PixelType i=0; i<numBins; ++i) tempHist[i] = 0; USImageType::PixelType maxval = itk::NumericTraits<USImageType::PixelType>::ZeroValue(); USImageType::PixelType minval = itk::NumericTraits<USImageType::PixelType>::max(); //Populate the histogram (assume pixel type is actually is some integer type): ConstIteratorType it( input_image, input_image->GetRequestedRegion() ); for ( it.GoToBegin(); !it.IsAtEnd(); ++it ){ USImageType::PixelType pix = it.Get(); ++tempHist[pix]; if( pix > maxval ) maxval = pix; if( pix < minval ) minval = pix; } //return max of type if there is no variation in the staining if( (maxval-minval)<3 ) return itk::NumericTraits<USImageType::PixelType>::max(); const USImageType::PixelType numBinsPresent = maxval+1; //Find max value in the histogram double floatIntegerMax = itk::NumericTraits<USImageType::PixelType>::max(); double max = 0.0; for(USImageType::PixelType i=0; i<numBinsPresent; ++i) if( tempHist[i] > max ) max = tempHist[i]; double scaleFactor = 1; if(max >= floatIntegerMax) scaleFactor = floatIntegerMax / max; HistogramType::Pointer histogram = HistogramType::New() ; // initialize histogram HistogramType::SizeType size; HistogramType::MeasurementVectorType lowerBound; HistogramType::MeasurementVectorType upperBound; lowerBound.SetSize(1); upperBound.SetSize(1); size.SetSize(1); lowerBound.Fill(0.0); upperBound.Fill((double)maxval); size.Fill(numBinsPresent); histogram->SetMeasurementVectorSize(1); histogram->Initialize(size, lowerBound, upperBound ) ; USImageType::PixelType i=0; for (HistogramType::Iterator iter = histogram->Begin(); iter != histogram->End(); ++iter ){ float norm_freq = (float)(tempHist[i] * scaleFactor); iter.SetFrequency(norm_freq); ++i; } std::cout<<"Histogram computed\n"; CalculatorType::Pointer calculator = CalculatorType::New(); calculator->SetNumberOfThresholds( num_bin_levs ); calculator->SetInputHistogram( histogram ); calculator->Update(); const CalculatorType::OutputType &thresholdVector = calculator->GetOutput(); CalculatorType::OutputType::const_iterator itNum = thresholdVector.begin(); float thresh; for(USImageType::PixelType i=0; i < num_in_fg; ++itNum, ++i) thresh = (static_cast<float>(*itNum)); std::cout<<"Threshold computed: "<<thresh<<std::endl; return (USImageType::PixelType)(thresh+0.5); }