Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.