Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
itkMrtrixPeakImageConverter.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 #ifndef __itkMrtrixPeakImageConverter_cpp
17 #define __itkMrtrixPeakImageConverter_cpp
18 
19 #include <time.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 
24 #include <itkImageRegionConstIterator.h>
25 #include <itkImageRegionConstIteratorWithIndex.h>
26 #include <itkImageRegionIterator.h>
27 #include <itkContinuousIndex.h>
28 
29 #include <vtkSmartPointer.h>
30 #include <vtkPolyData.h>
31 #include <vtkCellArray.h>
32 #include <vtkPoints.h>
33 #include <vtkPolyLine.h>
34 
35 
36 namespace itk {
37 
38 template< class PixelType >
40  m_NormalizationMethod(NO_NORM)
41 {
42 
43 }
44 
45 template< class PixelType >
48 {
49  // output vector field
50  vtkSmartPointer<vtkCellArray> m_VtkCellArray = vtkSmartPointer<vtkCellArray>::New();
51  vtkSmartPointer<vtkPoints> m_VtkPoints = vtkSmartPointer<vtkPoints>::New();
52 
53  Vector<float, 4> spacing4 = m_InputImage->GetSpacing();
54  Point<float, 4> origin4 = m_InputImage->GetOrigin();
55  Matrix<double, 4, 4> direction4 = m_InputImage->GetDirection();
56  ImageRegion<4> imageRegion4 = m_InputImage->GetLargestPossibleRegion();
57 
58  Vector<double, 3> spacing3;
59  Point<float, 3> origin3;
60  Matrix<double, 3, 3> direction3;
61  ImageRegion<3> imageRegion3;
62 
63  spacing3[0] = spacing4[0]; spacing3[1] = spacing4[1]; spacing3[2] = spacing4[2];
64  origin3[0] = origin4[0]; origin3[1] = origin4[1]; origin3[2] = origin4[2];
65  for (int r=0; r<3; r++)
66  for (int c=0; c<3; c++)
67  direction3[r][c] = direction4[r][c];
68  imageRegion3.SetSize(0, imageRegion4.GetSize()[0]);
69  imageRegion3.SetSize(1, imageRegion4.GetSize()[1]);
70  imageRegion3.SetSize(2, imageRegion4.GetSize()[2]);
71 
72  double minSpacing = spacing3[0];
73  if (spacing3[1]<minSpacing)
74  minSpacing = spacing3[1];
75  if (spacing3[2]<minSpacing)
76  minSpacing = spacing3[2];
77 
78  m_DirectionImageContainer = DirectionImageContainerType::New();
79 
80  typedef ImageRegionConstIterator< InputImageType > InputIteratorType;
81 
82  int x = m_InputImage->GetLargestPossibleRegion().GetSize(0);
83  int y = m_InputImage->GetLargestPossibleRegion().GetSize(1);
84  int z = m_InputImage->GetLargestPossibleRegion().GetSize(2);
85  int numDirs = m_InputImage->GetLargestPossibleRegion().GetSize(3)/3;
86 
87  m_NumDirectionsImage = ItkUcharImgType::New();
88  m_NumDirectionsImage->SetSpacing( spacing3 );
89  m_NumDirectionsImage->SetOrigin( origin3 );
90  m_NumDirectionsImage->SetDirection( direction3 );
91  m_NumDirectionsImage->SetRegions( imageRegion3 );
92  m_NumDirectionsImage->Allocate();
93  m_NumDirectionsImage->FillBuffer(0);
94 
95  for (int i=0; i<numDirs; i++)
96  {
98  directionImage->SetSpacing( spacing3 );
99  directionImage->SetOrigin( origin3 );
100  directionImage->SetDirection( direction3 );
101  directionImage->SetRegions( imageRegion3 );
102  directionImage->Allocate();
103  Vector< PixelType, 3 > nullVec; nullVec.Fill(0.0);
104  directionImage->FillBuffer(nullVec);
105  m_DirectionImageContainer->InsertElement(m_DirectionImageContainer->Size(), directionImage);
106  }
107 
108  double minangle = 0;
109  for (int i=0; i<numDirs; i++)
110  {
111  for (int a=0; a<x; a++)
112  for (int b=0; b<y; b++)
113  for (int c=0; c<z; c++)
114  {
115  // generate vector field
116  typename InputImageType::IndexType index;
117  index.SetElement(0,a);
118  index.SetElement(1,b);
119  index.SetElement(2,c);
120  vnl_vector<double> dirVec; dirVec.set_size(4);
121  for (int k=0; k<3; k++)
122  {
123  index.SetElement(3,k+i*3);
124  dirVec[k] = m_InputImage->GetPixel(index);
125  }
126  dirVec[3] = 0;
127 
128  if (dirVec.magnitude()<0.0001)
129  continue;
130 
131  vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
132  itk::ContinuousIndex<double, 4> center;
133  center[0] = index[0];
134  center[1] = index[1];
135  center[2] = index[2];
136  center[3] = 0;
137  itk::Point<double, 4> worldCenter;
138  m_InputImage->TransformContinuousIndexToPhysicalPoint( center, worldCenter );
139 
140  switch (m_NormalizationMethod)
141  {
142  case NO_NORM:
143  break;
144  case SINGLE_VEC_NORM:
145  dirVec.normalize();
146  break;
147  }
148  dirVec.normalize();
149  dirVec = m_InputImage->GetDirection()*dirVec;
150 
151  itk::Point<double> worldStart;
152  worldStart[0] = worldCenter[0]-dirVec[0]/2 * minSpacing;
153  worldStart[1] = worldCenter[1]-dirVec[1]/2 * minSpacing;
154  worldStart[2] = worldCenter[2]-dirVec[2]/2 * minSpacing;
155  vtkIdType id = m_VtkPoints->InsertNextPoint(worldStart.GetDataPointer());
156  container->GetPointIds()->InsertNextId(id);
157  itk::Point<double> worldEnd;
158  worldEnd[0] = worldCenter[0]+dirVec[0]/2 * minSpacing;
159  worldEnd[1] = worldCenter[1]+dirVec[1]/2 * minSpacing;
160  worldEnd[2] = worldCenter[2]+dirVec[2]/2 * minSpacing;
161  id = m_VtkPoints->InsertNextPoint(worldEnd.GetDataPointer());
162  container->GetPointIds()->InsertNextId(id);
163  m_VtkCellArray->InsertNextCell(container);
164 
165  // generate direction image
166  typename ItkDirectionImageType::IndexType index2;
167  index2[0] = a; index2[1] = b; index2[2] = c;
168 
169  // workaround *********************************************
170  dirVec = m_InputImage->GetDirection()*dirVec;
171  dirVec.normalize();
172  // workaround *********************************************
173 
174  Vector< PixelType, 3 > pixel;
175  pixel.SetElement(0, dirVec[0]);
176  pixel.SetElement(1, dirVec[1]);
177  pixel.SetElement(2, dirVec[2]);
178 
179  for (int j=0; j<numDirs; j++)
180  {
181  ItkDirectionImageType::Pointer directionImage = m_DirectionImageContainer->ElementAt(j);
182  Vector< PixelType, 3 > tempPix = directionImage->GetPixel(index2);
183 
184  if (tempPix.GetNorm()<0.01)
185  {
186  directionImage->SetPixel(index2, pixel);
187  break;
188  }
189  else
190  {
191  if ( fabs(dot_product(tempPix.GetVnlVector(), pixel.GetVnlVector()))>minangle )
192  {
193  minangle = fabs(dot_product(tempPix.GetVnlVector(), pixel.GetVnlVector()));
194  MITK_INFO << "Minimum angle: " << acos(minangle)*180.0/M_PI;
195  }
196  }
197  }
198 
199  m_NumDirectionsImage->SetPixel(index2, m_NumDirectionsImage->GetPixel(index2)+1);
200  }
201  }
202 
203  vtkSmartPointer<vtkPolyData> directionsPolyData = vtkSmartPointer<vtkPolyData>::New();
204  directionsPolyData->SetPoints(m_VtkPoints);
205  directionsPolyData->SetLines(m_VtkCellArray);
206  m_OutputFiberBundle = mitk::FiberBundle::New(directionsPolyData);
207 }
208 
209 }
210 
211 #endif // __itkMrtrixPeakImageConverter_cpp
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.