예제 #1
0
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;
}
예제 #2
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);//显示结果图
}