Extract principal eigenvectors from diffusion tensor image

Hello all,
I am a beginner in VTK.

I have a brainDTI image in .nrrd format. I want to extract the principal eigenvalues from the that image and create a separate vector image.

First of all, I tried reading the .nrrd image using different vtk classes like vtkStructuredPointsReader , vtkXMLPolyDataReader and vtkPolyDataReader even vtkNrrdImageReader or so. But none of them works.

I tried to create the vector image using slicer3D tool’s DTIProcess extension and generated a .vtk file.

#include <vtkSmartPointer.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkNrrdReader.h>
#include <vtkPolyData.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkStructuredPointsReader.h>
#include <vtkArrowSource.h>
#include <vtkGlyph3D.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataReader.h>
#include <vtkProperty.h>
#include <vtkImageDataGeometryFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkQuadricDecimation.h>

// all the includes                                                                                                                      
int main(int argc, char *argv[])
{
  //read file:                                                                                                                           
  //vtkSmartPointer <vtkNrrdReader>reader = vtkSmartPointer<vtkNrrdReader>::New();                                                       
  // vtkSmartPointer<vtkXMLPolyDataReader>reader = vtkSmartPointer<vtkXMLPolyDataReader>::New();                                         
  //vtkSmartPointer<vtkPolyDataReader> reader = vtkSmartPointer<vtkPolyDataReader>::New();                                               
  vtkSmartPointer<vtkStructuredPointsReader> reader = vtkSmartPointer<vtkStructuredPointsReader>::New();
  reader->SetFileName("../PEoutput.vtk");
  reader->Update();
  std::cout<<"Here@@@@@ "<<std::endl;
  std::cout<<reader->GetOutput()->GetPoints()->GetNumberOfPoints()<<std::endl;

  vtkSmartPointer<vtkImageDataGeometryFilter>geometryFilter = vtkSmartPointer<vtkImageDataGeometryFilter>::New();
  geometryFilter->SetInputConnection(reader->GetOutputPort());
  geometryFilter->Update();

  vtkSmartPointer<vtkQuadricDecimation> decimationFilter = vtkSmartPointer<vtkQuadricDecimation>::New();
  decimationFilter->SetInputData(geometryFilter->GetOutput());
  decimationFilter->SetTargetReduction(0.1);
  decimationFilter->Update();

  std::cout << decimationFilter->GetOutput()->GetNumberOfPoints() << std::endl ;
  // vtkMapper for object geometry mapping to rendering basics                                                                           
  vtkSmartPointer <vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  //mapper->SetInputConnection(reader->GetOutputPort());                                                                                 
  mapper->SetInputConnection(geometryFilter->GetOutputPort());

  vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor ( 1, 0, 0 ) ;


  // Compute & Visualize Normal Vectors                                                                                                  
  vtkSmartPointer < vtkPolyDataNormals > normalsFilter = vtkSmartPointer < vtkPolyDataNormals > ::New() ;
  normalsFilter->SetInputData (decimationFilter->GetOutput());//decimationFilter                                                         
  normalsFilter->ComputePointNormalsOn() ;
  normalsFilter->Update();

  vtkSmartPointer<vtkArrowSource>oneArrow = vtkSmartPointer<vtkArrowSource>::New();
  oneArrow->Update();

  vtkSmartPointer<vtkGlyph3D>lotsOfArrows = vtkSmartPointer<vtkGlyph3D>::New();
  lotsOfArrows->SetSourceData(oneArrow->GetOutput());
  lotsOfArrows->SetInputData(geometryFilter->GetOutput()); //reader                                                                      
  lotsOfArrows->OrientOn(); //                                                                                                           
  lotsOfArrows->SetVectorModeToUseNormal();
  lotsOfArrows->SetScaleFactor(5);
  lotsOfArrows->Update();

 vtkSmartPointer < vtkPolyDataMapper > arrowMapper = vtkSmartPointer < vtkPolyDataMapper > ::New();
  arrowMapper->SetInputData ( lotsOfArrows->GetOutput()) ;

  //One actor for all of the arrows:                                                                                                     
  vtkSmartPointer < vtkActor > arrowActor = vtkSmartPointer < vtkActor >::New() ;
  arrowActor->SetMapper ( arrowMapper ) ;
  arrowActor->GetProperty()->SetColor ( 0, 0, 1 );

  // vtkRenderer for collecting the items in the scene                                                                                   
  vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New() ;
  vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New() ;
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow(renderWindow);
  renderer->AddActor(arrowActor);

  // step 5: add the arrow actor to the scene                                                                                            
  //renderer->AddActor ( actor ); //arrowActor                                                                                           

  renderer->SetBackground( 1, 1, 1);

  // vtkRenderWindow for the window                                                                                                      

  //renderWindow->AddRenderer ( renderer ) ;                                                                                             
  renderWindow->Render();
  //renderWindow->SetSize ( 300, 300 ) ;                                                                                                 

  // vtkRenderWindowInteractor for user interactions                                                                                     
  //vtkSmartPointer < vtkRenderWindowInteractor > interactor = vtkSmartPointer < vtkRenderWindowInteractor >::New() ;                    
  // interactor->SetRenderWindow ( renderWindow ) ;                                                                                      
  interactor->Start() ;
  return 0;
}

As a beginner I would appreciate any help…
Thanks in advance.

You might take a look at the python library DIPY and its sibling project FURY. DIPY focuses on dMRI analysis. Then the results can be visualized using FURY, which wraps VTK.

I have looked at the python packages you shared, but I was looking for C++ options to implement.

All the SlicerDMRI vtk classes are available for reuse:

Hey thanks,
Looks like this will be very helpful what I am trying to do.