Ejemplo n.º 1
0
int runGrAnisDiff(unsigned char* imgIn, int r, int c, int z, int iter, int timeStep, int comductance)
{
	
	//pixel types
	typedef unsigned char InputPixelType;
	typedef float OutputPixelType;
	typedef itk::Image< InputPixelType, 3 > InputImageType;
	typedef itk::Image< OutputPixelType, 3 > OutputImageType;
	
	//create an ITK image from the input image
	OutputImageType::Pointer im;
	im = OutputImageType::New();
	OutputImageType::PointType origin;
    origin[0] = 0.; 
    origin[1] = 0.;    
	origin[2] = 0.;    
    im->SetOrigin( origin );

    OutputImageType::IndexType start;
    start[0] =   0;  // first index on X
    start[1] =   0;  // first index on Y    
	start[2] =   0;  // first index on Z    
    OutputImageType::SizeType  size;
    size[0]  = c;  // size along X
    size[1]  = r;  // size along Y
	size[2]  = z;  // size along Z
  
    OutputImageType::RegionType region;
    region.SetSize( size );
    region.SetIndex( start );
    
 //   double spacing[3];
	//spacing[0] = 1; //spacing along x
	//spacing[1] = 1; //spacing along y
	//spacing[2] = sampl_ratio; //spacing along z

    im->SetRegions( region );
	//im->SetSpacing(spacing);
    im->Allocate();
    im->FillBuffer(0);
	im->Update();	
	
	//copy the input image into the ITK image
	typedef itk::ImageRegionIteratorWithIndex< OutputImageType > IteratorType;
	IteratorType iterator1(im,im->GetRequestedRegion());
	
	for(int i=0; i<r*c*z; i++)
	{					
		iterator1.Set((float)imgIn[i]);
		++iterator1;		
	}

	//apply gradient anisotropic diffusion
	typedef itk::GradientAnisotropicDiffusionImageFilter< OutputImageType, OutputImageType > FilterType;
	FilterType::Pointer filter = FilterType::New();
	filter->SetInput( im );

	filter->SetNumberOfIterations( iter );
	filter->SetTimeStep( timeStep );
	filter->SetConductanceParameter( comductance );

	try
	{
		filter->Update();
	}
	catch( itk::ExceptionObject & err ) 
    { 
		std::cerr << err << std::endl;
		return 0;
	}

	typedef itk::RescaleIntensityImageFilter< OutputImageType, InputImageType > RescaleFilterType;

	RescaleFilterType::Pointer rescaler = RescaleFilterType::New();
	rescaler->SetOutputMinimum(   0 );
	rescaler->SetOutputMaximum( 255 );
	rescaler->SetInput( filter->GetOutput() );
	rescaler->Update();

	//overwrite the input image for now in order to save space
	typedef itk::ImageRegionIteratorWithIndex< InputImageType > IteratorType2;
	IteratorType2 iterator2(rescaler->GetOutput(),rescaler->GetOutput()->GetRequestedRegion());
	
	for(int i=0; i<r*c*z; i++)
	{					
		imgIn[i] = iterator2.Get();
		++iterator2;		
	}

	return 1;
}
int main(int argc, char** argv) {

    if (argc < 5) {
        std::cerr << "From the 3 images representing fiber orientation estimate angles and calculate angle homogeneity in the neighborhoods." << std::endl;
        std::cerr << "Usage: CalculateEntropyFiberAngles coordx_image coordy_image coordz_image out_image neigborhood_radius" << std::endl;
        return EXIT_FAILURE;
    }

    //parsing parameters
    int c = 1;
    const char* imagex_filename = argv[c++];
    const char* imagey_filename = argv[c++];
    const char* imagez_filename = argv[c++];
    const char* output_filename = argv[c++];
    int neighborhood_radius = atoi(argv[c++]);


    const unsigned int Dimension = 3;

    std::cout << "Input x: " << imagex_filename << std::endl;
    std::cout << "Input y: " << imagey_filename << std::endl;
    std::cout << "Input z: " << imagez_filename << std::endl;
    std::cout << "Output: " << output_filename << std::endl;
    std::cout << "Neighborhood radius: " << neighborhood_radius << std::endl;



    //main program
    typedef float InputPixelType;
    typedef float OutputPixelType;
    typedef itk::Image< InputPixelType, Dimension > InputImageType;
    typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
    typedef itk::ImageFileReader< InputImageType > ReaderType;
    typedef itk::ImageFileWriter< OutputImageType > WriterType;
    ReaderType::Pointer readerx = ReaderType::New();
    ReaderType::Pointer readery = ReaderType::New();
    ReaderType::Pointer readerz = ReaderType::New();
    WriterType::Pointer writer = WriterType::New();
    readerx->SetFileName(imagex_filename);
    readery->SetFileName(imagex_filename);
    readerz->SetFileName(imagex_filename);
    writer->SetFileName(output_filename);



    std::cout<<"Reading X"<<std::endl;
    readerx->Update();
    std::cout<<"Reading Y"<<std::endl;
    readery->Update();
    std::cout<<"Reading Z"<<std::endl;
    readerz->Update();

    
    const InputImageType * inputx = readerx->GetOutput();
    const InputImageType * inputy = readery->GetOutput();
    const InputImageType * inputz = readerz->GetOutput();


    //create the output image
    OutputImageType::Pointer image = OutputImageType::New();
    image->SetRegions(inputx->GetLargestPossibleRegion());
    image->SetSpacing(inputx->GetSpacing());
    image->SetOrigin(inputx->GetOrigin());
    image->Allocate();
    image->FillBuffer(0);

    
    InputImageType::SizeType radius;
    radius[0] = neighborhood_radius;
    radius[1] = neighborhood_radius;
    radius[2] = neighborhood_radius;
    
    itk::ConstNeighborhoodIterator<InputImageType> 
            iteratorx(radius, inputx, image->GetRequestedRegion());
    itk::ConstNeighborhoodIterator<InputImageType> 
            iteratory(radius, inputy, image->GetRequestedRegion());
    itk::ConstNeighborhoodIterator<InputImageType> 
            iteratorz(radius, inputz, image->GetRequestedRegion());

    itk::ImageRegionIterator<OutputImageType>  it( image, image->GetRequestedRegion() );
    
    iteratorx.GoToBegin();
    iteratory.GoToBegin();
    iteratorz.GoToBegin();
    it.GoToBegin();
  
    const unsigned int nneighbors = (neighborhood_radius*2+1)*(neighborhood_radius*2+1)*(neighborhood_radius*2+1);
    Eigen::MatrixXf neighbors( nneighbors-1, 3 ); //to store the vectors
    Eigen::Vector3f central_vector;
    
    int c_id = (int) (nneighbors / 2); // get offset of center pixel
    
    
    //check image size for the progress indicator
    OutputImageType::RegionType region = image->GetLargestPossibleRegion();
    OutputImageType::SizeType size = region.GetSize();
    const unsigned long int npixels = size[0]*size[1]*size[2];
    
    unsigned long int k = 0;
    while ( ! iteratorx.IsAtEnd() )
    {
        if(k%10000 == 0)
        {
            std::cout<<"Processed "<<k<<"/"<<npixels<<"\r"<<std::flush;
        }
            
        k++;
            
        unsigned int j = 0;
        for (unsigned int i = 0; i < nneighbors; ++i)
        {    
            if(i!=c_id) //exclude the center
            {
                neighbors(j, 0) = iteratorx.GetPixel(i);  
                neighbors(j, 1) = iteratory.GetPixel(i);  
                neighbors(j, 2) = iteratorz.GetPixel(i);  
                j++;
            }
            else
            {
                central_vector(0) = iteratorx.GetPixel(i);  
                central_vector(1) = iteratory.GetPixel(i);  
                central_vector(2) = iteratorz.GetPixel(i);                  
            }
        }
        
        // calculate the angles 
        Eigen::VectorXf dp = neighbors*central_vector;
        
        const float variance = ((dp.array()-dp.mean()).pow(2)).mean();
        it.Set(variance);        
        
        ++iteratorx;
        ++iteratory;
        ++iteratorz;
        ++it;
    }    
    std::cout<<std::endl;
    
    //  The output of the resampling filter is connected to a writer and the
    //  execution of the pipeline is triggered by a writer update.
    try {
        writer->SetInput(image);
        writer->Update();
    } catch (itk::ExceptionObject & excep) {
        std::cerr << "Exception caught !" << std::endl;
        std::cerr << excep << std::endl;
    }

    

    
    return EXIT_SUCCESS;
}