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; }