19 #include <vtkPolyLine.h>
20 #include <vtkCellArray.h>
21 #include <vtkCellData.h>
26 #include <boost/progress.hpp>
30 template<
class OutputImageType >
32 : m_InvertImage(false)
34 , m_UpsamplingFactor(1)
36 , m_BinaryOutput(false)
37 , m_UseImageGeometry(false)
38 , m_OutputAbsoluteValues(false)
39 , m_UseTrilinearInterpolation(false)
40 , m_DoFiberResampling(true)
45 template<
class OutputImageType >
50 template<
class OutputImageType >
53 itk::Point<float, 3> itkPoint;
54 itkPoint[0] = point[0];
55 itkPoint[1] = point[1];
56 itkPoint[2] = point[2];
60 template<
class OutputImageType >
68 itk::Vector<double,3> newSpacing;
70 itk::Matrix<double, 3, 3> newDirection;
71 ImageRegion<3> upsampledRegion;
72 if (m_UseImageGeometry && !m_InputImage.IsNull())
74 MITK_INFO <<
"TractDensityImageFilter: using image geometry";
75 newSpacing = m_InputImage->GetSpacing()/m_UpsamplingFactor;
76 upsampledRegion = m_InputImage->GetLargestPossibleRegion();
77 newOrigin = m_InputImage->GetOrigin();
78 typename OutputImageType::RegionType::SizeType size = upsampledRegion.GetSize();
79 size[0] *= m_UpsamplingFactor;
80 size[1] *= m_UpsamplingFactor;
81 size[2] *= m_UpsamplingFactor;
82 upsampledRegion.SetSize(size);
83 newDirection = m_InputImage->GetDirection();
87 MITK_INFO <<
"TractDensityImageFilter: using fiber bundle geometry";
88 newSpacing = geometry->GetSpacing()/m_UpsamplingFactor;
89 newOrigin = geometry->GetOrigin();
94 newOrigin[0] += bounds.GetElement(0) + 0.5 * newSpacing[0];
95 newOrigin[1] += bounds.GetElement(2) + 0.5 * newSpacing[1];
96 newOrigin[2] += bounds.GetElement(4) + 0.5 * newSpacing[2];
98 for (
int i=0; i<3; i++)
99 for (
int j=0; j<3; j++)
100 newDirection[j][i] = geometry->GetMatrixColumn(i)[j];
101 upsampledRegion.SetSize(0, ceil( geometry->GetExtent(0)*m_UpsamplingFactor ) );
102 upsampledRegion.SetSize(1, ceil( geometry->GetExtent(1)*m_UpsamplingFactor ) );
103 upsampledRegion.SetSize(2, ceil( geometry->GetExtent(2)*m_UpsamplingFactor ) );
105 typename OutputImageType::RegionType::SizeType upsampledSize = upsampledRegion.GetSize();
108 outImage->SetSpacing( newSpacing );
109 outImage->SetOrigin( newOrigin );
110 outImage->SetDirection( newDirection );
111 outImage->SetLargestPossibleRegion( upsampledRegion );
112 outImage->SetBufferedRegion( upsampledRegion );
113 outImage->SetRequestedRegion( upsampledRegion );
114 outImage->Allocate();
115 outImage->FillBuffer(0.0);
117 int w = upsampledSize[0];
118 int h = upsampledSize[1];
119 int d = upsampledSize[2];
125 float minSpacing = 1;
126 if(newSpacing[0]<newSpacing[1] && newSpacing[0]<newSpacing[2])
127 minSpacing = newSpacing[0];
128 else if (newSpacing[1] < newSpacing[2])
129 minSpacing = newSpacing[1];
131 minSpacing = newSpacing[2];
133 MITK_INFO <<
"TractDensityImageFilter: resampling fibers to ensure sufficient voxel coverage";
134 if (m_DoFiberResampling)
136 m_FiberBundle = m_FiberBundle->GetDeepCopy();
137 m_FiberBundle->ResampleSpline(minSpacing/10);
140 MITK_INFO <<
"TractDensityImageFilter: starting image generation";
142 vtkSmartPointer<vtkPolyData> fiberPolyData = m_FiberBundle->GetFiberPolyData();
143 vtkSmartPointer<vtkCellArray> vLines = fiberPolyData->GetLines();
144 vLines->InitTraversal();
145 int numFibers = m_FiberBundle->GetNumFibers();
146 boost::progress_display disp(numFibers);
147 for(
int i=0; i<numFibers; i++ )
150 vtkIdType numPoints(0);
151 vtkIdType* points(NULL);
152 vLines->GetNextCell ( numPoints, points );
153 float weight = m_FiberBundle->GetFiberWeight(i);
156 for(
int j=0; j<numPoints; j++)
158 itk::Point<float, 3> vertex = GetItkPoint(fiberPolyData->GetPoint(points[j]));
160 itk::ContinuousIndex<float, 3> contIndex;
161 outImage->TransformPhysicalPointToIndex(vertex, index);
162 outImage->TransformPhysicalPointToContinuousIndex(vertex, contIndex);
164 if (!m_UseTrilinearInterpolation && outImage->GetLargestPossibleRegion().IsInside(index))
167 outImage->SetPixel(index, 1);
169 outImage->SetPixel(index, outImage->GetPixel(index)+0.01*weight);
173 float frac_x = contIndex[0] - index[0];
174 float frac_y = contIndex[1] - index[1];
175 float frac_z = contIndex[2] - index[2];
198 if (index[0] < 0 || index[0] >= w-1)
200 if (index[1] < 0 || index[1] >= h-1)
202 if (index[2] < 0 || index[2] >= d-1)
207 outImageBufferPointer[( index[0] + w*(index[1] + h*index[2] ))] = 1;
208 outImageBufferPointer[( index[0] + w*(index[1]+1+ h*index[2] ))] = 1;
209 outImageBufferPointer[( index[0] + w*(index[1] + h*index[2]+h))] = 1;
210 outImageBufferPointer[( index[0] + w*(index[1]+1+ h*index[2]+h))] = 1;
211 outImageBufferPointer[( index[0]+1 + w*(index[1] + h*index[2] ))] = 1;
212 outImageBufferPointer[( index[0]+1 + w*(index[1] + h*index[2]+h))] = 1;
213 outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2] ))] = 1;
214 outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]+h))] = 1;
218 outImageBufferPointer[( index[0] + w*(index[1] + h*index[2] ))] += ( frac_x)*( frac_y)*( frac_z);
219 outImageBufferPointer[( index[0] + w*(index[1]+1+ h*index[2] ))] += ( frac_x)*(1-frac_y)*( frac_z);
220 outImageBufferPointer[( index[0] + w*(index[1] + h*index[2]+h))] += ( frac_x)*( frac_y)*(1-frac_z);
221 outImageBufferPointer[( index[0] + w*(index[1]+1+ h*index[2]+h))] += ( frac_x)*(1-frac_y)*(1-frac_z);
222 outImageBufferPointer[( index[0]+1 + w*(index[1] + h*index[2] ))] += (1-frac_x)*( frac_y)*( frac_z);
223 outImageBufferPointer[( index[0]+1 + w*(index[1] + h*index[2]+h))] += (1-frac_x)*( frac_y)*(1-frac_z);
224 outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2] ))] += (1-frac_x)*(1-frac_y)*( frac_z);
225 outImageBufferPointer[( index[0]+1 + w*(index[1]+1+ h*index[2]+h))] += (1-frac_x)*(1-frac_y)*(1-frac_z);
230 if (!m_OutputAbsoluteValues && !m_BinaryOutput)
232 MITK_INFO <<
"TractDensityImageFilter: max-normalizing output image";
234 for (
int i=0; i<w*h*d; i++)
235 if (max < outImageBufferPointer[i])
236 max = outImageBufferPointer[i];
238 for (
int i=0; i<w*h*d; i++)
240 outImageBufferPointer[i] /=
max;
245 MITK_INFO <<
"TractDensityImageFilter: inverting image";
246 for (
int i=0; i<w*h*d; i++)
247 outImageBufferPointer[i] = 1-outImageBufferPointer[i];
249 MITK_INFO <<
"TractDensityImageFilter: finished processing";
OutputImageType::PixelType OutPixelType
itk::SmartPointer< Self > Pointer
BoundingBoxType::BoundsArrayType BoundsArrayType
virtual ~TractDensityImageFilter()
TractDensityImageFilter()
itk::Point< float, 3 > GetItkPoint(double point[3])