22 #include "itkTensorFractionalAnisotropyImageFilter.h" 23 #include "itkDiscreteGaussianImageFilter.h" 24 #include "itkImageFileReader.h" 25 #include "itkImageFileWriter.h" 26 #include "itkMetaDataDictionary.h" 27 #include "itkImageSeriesReader.h" 28 #include "itkDisplacementFieldJacobianDeterminantFilter.h" 29 #include "itkImageRegionIteratorWithIndex.h" 30 #include "itkNiftiImageIO.h" 31 #include "itkNrrdImageIO.h" 32 #include "itkImageMaskSpatialObject.h" 33 #include "itkBinaryThresholdImageFilter.h" 34 #include "itkNumericTraits.h" 35 #include "itkCommand.h" 48 template<
typename TOutputImageType,
typename TTensorImageType >
49 inline void allocateImage(
typename TOutputImageType::Pointer scIm,
const typename TTensorImageType::Pointer tenIm)
51 scIm->SetOrigin(tenIm->GetOrigin());
52 scIm->SetSpacing(tenIm->GetSpacing());
53 scIm->SetDirection(tenIm->GetDirection());
54 scIm->SetLargestPossibleRegion(tenIm->GetLargestPossibleRegion());
55 scIm->SetRequestedRegion(tenIm->GetRequestedRegion());
56 scIm->SetBufferedRegion(tenIm->GetBufferedRegion());
63 template <
typename TVectorImageType,
typename TScalarImageType,
typename TMaskImageType,
typename TOutputTensorCompType>
64 std::vector< typename TScalarImageType::Pointer > dtiRecon(
typename TVectorImageType::Pointer inputImage,
const typename TMaskImageType::Pointer maskImage,
const std::vector< std::vector< float > >& gradValues,
const float &bValue, std::string outputBasename,
bool verbose,
bool inputIsVectorImage)
66 const unsigned int Dimensions = 3;
69 typedef itk::VectorImage< typename TScalarImageType::PixelType, Dimensions > GradientImageType;
71 GradientImageType::Pointer gradIm = inputImage;
73 std::cout <<
"Converting DWI to vector image\n";
76 typename TScalarImageType::PixelType, TOutputTensorCompType > TensorReconstructionImageFilterType;
79 TensorReconstructionImageFilterType::GradientDirectionType vect3d;
80 TensorReconstructionImageFilterType::GradientDirectionContainerType::Pointer DiffusionVectors = TensorReconstructionImageFilterType::GradientDirectionContainerType::New();
82 for (
size_t i = 0; i < gradValues.size(); i++)
84 vec3d = gradValues[i];
88 DiffusionVectors->InsertElement(i, vect3d);
92 TensorReconstructionImageFilterType::Pointer tensorReconstructionFilter = TensorReconstructionImageFilterType::New();
94 typedef itk::ImageMaskSpatialObject< Dimensions > MaskType;
95 MaskType::Pointer spatialObjectMask = MaskType::New();
96 typedef itk::BinaryThresholdImageFilter<TMaskImageType, MaskType::ImageType> ThresholderType;
97 ThresholderType::Pointer thresholder = ThresholderType::New();
98 thresholder->SetOutsideValue(itk::NumericTraits< MaskType::ImageType::PixelType>::Zero);
99 thresholder->SetInsideValue(itk::NumericTraits< MaskType::ImageType::PixelType>::One);
100 thresholder->SetLowerThreshold(itk::NumericTraits<unsigned short>::One);
101 thresholder->InPlaceOn();
103 thresholder->SetInput(maskImage);
104 thresholder->Update();
105 spatialObjectMask->SetImage(thresholder->GetOutput());
109 tensorReconstructionFilter->SetGradientImage(DiffusionVectors, gradIm);
110 tensorReconstructionFilter->SetNumberOfThreads(1);
111 tensorReconstructionFilter->SetBValue(static_cast<TensorReconstructionImageFilterType::TTensorPixelType>(bValue));
114 tensorReconstructionFilter->Update();
125 std::string default_ext =
".nii.gz";
126 static int writeFA = 1;
127 static int writeTR = 1;
128 static int writeEign = 0;
129 static int writeGeo = 0;
130 static int writeGordR = 0;
131 static int writeGordK = 0;
132 static int writeRadAx = 1;
133 static int writeSkew = 0;
134 static int writeKurt = 0;
136 typedef itk::DiffusionTensor3D< typename TScalarImageType::PixelType > TensorPixelType;
137 typedef itk::Image< TensorPixelType, Dimensions > TensorImageType;
139 std::vector< TScalarImageType::Pointer > vectorOfDTIScalars;
141 typedef itk::ImageRegionConstIteratorWithIndex < TensorImageType > ConstIterType;
145 typename TensorImageType::Pointer tensorIm = TensorImageType::New();
146 tensorIm = tensorReconstructionFilter->GetOutput();
149 typename TScalarImageType::Pointer faIm = ScalarImageType::New();
152 typename TScalarImageType::Pointer trIm = ScalarImageType::New();
155 typename TScalarImageType::Pointer l1Im = ScalarImageType::New();
156 typename TScalarImageType::Pointer l2Im = ScalarImageType::New();
157 typename TScalarImageType::Pointer l3Im = ScalarImageType::New();
158 typename TVectorImageType::Pointer v1Im = VectorImageType::New();
159 typename TVectorImageType::Pointer v2Im = VectorImageType::New();
160 typename TVectorImageType::Pointer v3Im = VectorImageType::New();
163 typename TScalarImageType::Pointer skIm = ScalarImageType::New();
164 typename TScalarImageType::Pointer kuIm = ScalarImageType::New();
167 typename TScalarImageType::Pointer clIm = ScalarImageType::New();
168 typename TScalarImageType::Pointer cpIm = ScalarImageType::New();
169 typename TScalarImageType::Pointer csIm = ScalarImageType::New();
172 typename TScalarImageType::Pointer rdIm = ScalarImageType::New();
173 typename TScalarImageType::Pointer adIm = ScalarImageType::New();
176 typename TScalarImageType::Pointer r1Im = ScalarImageType::New();
177 typename TScalarImageType::Pointer r2Im = ScalarImageType::New();
178 typename TScalarImageType::Pointer r3Im = ScalarImageType::New();
181 typename TScalarImageType::Pointer k1Im = ScalarImageType::New();
182 typename TScalarImageType::Pointer k2Im = ScalarImageType::New();
183 typename TScalarImageType::Pointer k3Im = ScalarImageType::New();
187 allocateImage<TScalarImageType, TensorImageType>(faIm, tensorIm);
190 allocateImage<TScalarImageType, TensorImageType>(trIm, tensorIm);
194 allocateImage<TScalarImageType, TensorImageType>(l1Im, tensorIm);
195 allocateImage<TScalarImageType, TensorImageType>(l2Im, tensorIm);
196 allocateImage<TScalarImageType, TensorImageType>(l3Im, tensorIm);
197 v1Im->SetVectorLength(3);
198 v2Im->SetVectorLength(3);
199 v3Im->SetVectorLength(3);
200 allocateImage<TVectorImageType, TensorImageType>(v1Im, tensorIm);
201 allocateImage<TVectorImageType, TensorImageType>(v2Im, tensorIm);
202 allocateImage<TVectorImageType, TensorImageType>(v3Im, tensorIm);
208 allocateImage<TScalarImageType, TensorImageType>(skIm, tensorIm);
213 allocateImage<TScalarImageType, TensorImageType>(kuIm, tensorIm);
218 allocateImage<TScalarImageType, TensorImageType>(clIm, tensorIm);
219 allocateImage<TScalarImageType, TensorImageType>(cpIm, tensorIm);
220 allocateImage<TScalarImageType, TensorImageType>(csIm, tensorIm);
224 allocateImage<TScalarImageType, TensorImageType>(rdIm, tensorIm);
225 allocateImage<TScalarImageType, TensorImageType>(adIm, tensorIm);
229 allocateImage<TScalarImageType, TensorImageType>(r1Im, tensorIm);
230 allocateImage<TScalarImageType, TensorImageType>(r2Im, tensorIm);
231 allocateImage<TScalarImageType, TensorImageType>(r3Im, tensorIm);
235 allocateImage<TScalarImageType, TensorImageType>(k1Im, tensorIm);
236 allocateImage<TScalarImageType, TensorImageType>(k2Im, tensorIm);
237 allocateImage<TScalarImageType, TensorImageType>(k3Im, tensorIm);
240 ConstIterType iter(tensorIm, tensorIm->GetLargestPossibleRegion());
241 for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter)
243 TensorPixelType tmp = iter.Get();
244 typename TensorPixelType::EigenValuesArrayType lambda;
245 typename TensorPixelType::EigenVectorsMatrixType vMat;
246 tmp.ComputeEigenAnalysis(lambda, vMat);
248 typename ScalarImageType::IndexType index = iter.GetIndex();
251 trIm->SetPixel(index, lambda[0] + lambda[1] + lambda[2]);
255 faIm->SetPixel(index, tmp.GetFractionalAnisotropy());
260 l1Im->SetPixel(index, lambda[2]);
261 l2Im->SetPixel(index, lambda[1]);
262 l3Im->SetPixel(index, lambda[0]);
264 typename TVectorImageType::PixelType vec1(Dimensions);
265 typename TVectorImageType::PixelType vec2(Dimensions);
266 typename TVectorImageType::PixelType vec3(Dimensions);
268 vec1[0] = vMat[2][0];
269 vec1[1] = vMat[2][1];
270 vec1[2] = vMat[2][2];
272 vec2[0] = vMat[1][0];
273 vec2[1] = vMat[1][1];
274 vec2[2] = vMat[1][2];
276 vec3[0] = vMat[0][0];
277 vec3[1] = vMat[0][1];
278 vec3[2] = vMat[0][2];
280 v1Im->SetPixel(index, vec1);
281 v2Im->SetPixel(index, vec2);
282 v3Im->SetPixel(index, vec3);
288 typename TScalarImageType::PixelType m1, m3, l1, l2, l3;
292 m1 = (l1 + l2 + l3) / 3.0;
296 m3 = (vcl_pow(l1 - m1, 3) + vcl_pow(l2 - m1, 3) + vcl_pow(l3 - m1, 3)) / (vcl_pow(l1, 3) + vcl_pow(l2, 3) + vcl_pow(l3, 3));
299 skIm->SetPixel(index, vcl_pow(m3, static_cast<ScalarPixelType>(1.0 / 3.0)));
303 skIm->SetPixel(index, -1 * vcl_pow((-1 * m3), static_cast<ScalarPixelType>(1.0 / 3.0)));
308 skIm->SetPixel(index, static_cast<ScalarPixelType>(0));
314 typename TScalarImageType::PixelType m1, m4, l1, l2, l3;
318 m1 = (l1 + l2 + l3) / 3.0;
321 m4 = (vcl_pow(l1 - m1, 4) + vcl_pow(l2 - m1, 4) + vcl_pow(l3 - m1, 4)) / (vcl_pow(l1, 4) + vcl_pow(l2, 4) + vcl_pow(l3, 4));
322 kuIm->SetPixel(index, vcl_pow(m4, static_cast<ScalarPixelType>(1.0 / 4.0)));
326 kuIm->SetPixel(index, static_cast<ScalarPixelType>(0));
334 clIm->SetPixel(index, (lambda[2] - lambda[1]) / lambda[2]);
335 cpIm->SetPixel(index, (lambda[1] - lambda[0]) / lambda[2]);
336 csIm->SetPixel(index, lambda[0] / lambda[2]);
340 clIm->SetPixel(index, 0);
341 cpIm->SetPixel(index, 0);
342 csIm->SetPixel(index, 0);
348 rdIm->SetPixel(index, (lambda[1] + lambda[0]) / 2);
349 adIm->SetPixel(index, lambda[2]);
355 typename TScalarImageType::PixelType m1, m2, m3, r1, r2, r3;
356 m1 = (lambda[0] + lambda[1] + lambda[2]) / 3.0;
357 m2 = (vcl_pow(lambda[0] - m1, 2) + vcl_pow(lambda[1] - m1, 2)
358 + vcl_pow(lambda[2] - m1, 2)) / 3.0;
359 m3 = (vcl_pow(lambda[0] - m1, 3) + vcl_pow(lambda[1] - m1, 3)
360 + vcl_pow(lambda[2] - m1, 3)) / 3.0;
362 r1 = sqrt(3 * (vcl_pow(m1, 2) + m2));
363 r2 = sqrt(3 * m2 / 2 / (vcl_pow(m1, 2) + m2));
365 r3 = (lambda[0] * lambda[1] * lambda[2]) / vcl_pow(static_cast<double>(sqrt(3 * m2)), 3);
367 r1Im->SetPixel(index, r1);
368 r2Im->SetPixel(index, r2);
369 r3Im->SetPixel(index, r3);
375 typename TScalarImageType::PixelType m1, m2, m3, k1, k2, k3;
377 m1 = (lambda[0] + lambda[1] + lambda[2]) / 3.0;
378 m2 = (vcl_pow(lambda[0] - m1, 2) + vcl_pow(lambda[1] - m1, 2)
379 + vcl_pow(lambda[2] - m1, 2)) / 3.0;
380 m3 = (vcl_pow(lambda[0] - m1, 3) + vcl_pow(lambda[1] - m1, 3)
381 + vcl_pow(lambda[2] - m1, 3)) / 3.0;
386 k3 = (lambda[0] * lambda[1] * lambda[2]) / vcl_pow(static_cast<double>(sqrt(3 * m2)), 3);
389 k1Im->SetPixel(index, k1);
390 k2Im->SetPixel(index, k2);
391 k3Im->SetPixel(index, k3);
395 std::cout <<
"Done Computing Scalars\n";
397 typedef itk::ImageFileWriter< TScalarImageType > ScalarWriterType;
398 typedef itk::ImageFileWriter< TVectorImageType > VectorWriterType;
401 vectorOfDTIScalars.push_back(faIm);
404 vectorOfDTIScalars.push_back(trIm);
408 vectorOfDTIScalars.push_back(rdIm);
409 vectorOfDTIScalars.push_back(adIm);
412 catch (itk::ExceptionObject & excp)
415 return vectorOfDTIScalars;
Declaration of the Logging class.
Declaration of DiffusionTensor3DReconstructionImageFilter.
Declaration of the CommonHolder class.
This class takes as input one or more reference image (acquired in the absence of diffusion sensitizi...
Definition: itkDiffusionTensor3DReconstructionImageFilter.h:133