# Extract principal eigenvectors from diffusion tensor image

**URL:** https://discourse.vtk.org/t/extract-principal-eigenvectors-from-diffusion-tensor-image/2129
**Category:** Support
**Created:** [November 22, 2019, 5:52pm UTC](https://discourse.vtk.org/t/extract-principal-eigenvectors-from-diffusion-tensor-image/2129 "2019-11-22T17:52:01Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![banikr](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/b/b9bd4f/32.png) [@banikr](https://discourse.vtk.org/u/banikr)
#### Post date: [November 22, 2019, 5:52pm UTC](https://discourse.vtk.org/t/extract-principal-eigenvectors-from-diffusion-tensor-image/2129/1 "2019-11-22T17:52:01Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![dmreagan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dmreagan/32/7489_2.png) [@dmreagan](https://discourse.vtk.org/u/dmreagan)
#### Post date: [November 25, 2019, 5:44pm UTC](https://discourse.vtk.org/t/extract-principal-eigenvectors-from-diffusion-tensor-image/2129/2 "2019-11-25T17:44:29Z")

</div>

You might take a look at the python library [DIPY](https://dipy.org/) and its sibling project [FURY](http://fury.gl/). DIPY focuses on dMRI analysis. Then the results can be visualized using FURY, which wraps VTK.

---

<div class="post-metadata">

### Author: ![banikr](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/b/b9bd4f/32.png) [@banikr](https://discourse.vtk.org/u/banikr)
#### Post date: [November 25, 2019, 6:48pm UTC](https://discourse.vtk.org/t/extract-principal-eigenvectors-from-diffusion-tensor-image/2129/3 "2019-11-25T18:48:18Z")

</div>

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

---

<div class="post-metadata">

### Author: ![pieper](https://discourse.vtk.org/user_avatar/discourse.vtk.org/pieper/32/17_2.png) [@pieper](https://discourse.vtk.org/u/pieper)
#### Post date: [November 25, 2019, 11:21pm UTC](https://discourse.vtk.org/t/extract-principal-eigenvectors-from-diffusion-tensor-image/2129/4 "2019-11-25T23:21:20Z")

</div>

All the SlicerDMRI vtk classes are available for reuse:

> **[SlicerDMRI/SlicerDMRI](https://github.com/SlicerDMRI/SlicerDMRI/tree/master/Libs/vtkDMRI)**
>
> Diffusion MRI analysis and visualization in 3D Slicer open source medical imaging platform. - SlicerDMRI/SlicerDMRI

---

<div class="post-metadata">

### Author: ![banikr](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/b/b9bd4f/32.png) [@banikr](https://discourse.vtk.org/u/banikr)
#### Post date: [November 25, 2019, 11:42pm UTC](https://discourse.vtk.org/t/extract-principal-eigenvectors-from-diffusion-tensor-image/2129/5 "2019-11-25T23:42:09Z")

</div>

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