PageRenderTime 65ms CodeModel.GetById 41ms RepoModel.GetById 0ms app.codeStats 0ms

/Modules/DiffusionImaging/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h

https://github.com/cim-unito/MITK
C Header | 300 lines | 139 code | 59 blank | 102 comment | 1 complexity | b9f390e34286245960398eae3996cc46 MD5 | raw file
  1. /*=========================================================================
  2. Program: Medical Imaging & Interaction Toolkit
  3. Language: C++
  4. Date: $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $
  5. Version: $Revision: 18127 $
  6. Copyright (c) German Cancer Research Center, Division of Medical and
  7. Biological Informatics. All rights reserved.
  8. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #ifndef __itkAnalyticalDiffusionQballReconstructionImageFilter_h_
  14. #define __itkAnalyticalDiffusionQballReconstructionImageFilter_h_
  15. #include "itkImageToImageFilter.h"
  16. #include "vnl/vnl_vector_fixed.h"
  17. #include "vnl/vnl_matrix.h"
  18. #include "vnl/algo/vnl_svd.h"
  19. #include "itkVectorContainer.h"
  20. #include "itkVectorImage.h"
  21. namespace itk{
  22. /** \class AnalyticalDiffusionQballReconstructionImageFilter
  23. * \brief This class takes as input one or more reference image (acquired in the
  24. * absence of diffusion sensitizing gradients) and 'n' diffusion
  25. * weighted images and their gradient directions and computes an image of
  26. * orientation distribution function coefficients in a spherical harmonic basis.
  27. *
  28. * \par Inputs and Usage
  29. * \par
  30. * When you have the 'n' gradient and one or more reference images in a single
  31. * multi-component image (VectorImage), you can specify the images as
  32. * \code
  33. * filter->SetGradientImage( directionsContainer, vectorImage );
  34. * \endcode
  35. * Note that this method is used to specify both the reference and gradient images.
  36. * This is convenient when the DWI images are read in using the
  37. * <a href="http://wiki.na-mic.org/Wiki/index.php/NAMIC_Wiki:DTI:Nrrd_format">NRRD</a>
  38. * format. Like the Nrrd format, the reference images are those components of the
  39. * vectorImage whose gradient direction is (0,0,0). If more than one reference image
  40. * is present, they are averaged prior to the reconstruction.
  41. *
  42. * \par Outputs
  43. * The output image is an image of vectors that must be understood as ODFs:
  44. * \code
  45. * Image< Vector< TPixelType, OdfNrDirections >, 3 >
  46. * \endcode
  47. *
  48. * \par Parameters
  49. * \li Threshold - Threshold on the reference image data. The output ODF will
  50. * be a null pdf for pixels in the reference image that have a value less
  51. * than this.
  52. * \li BValue - See the documentation of SetBValue().
  53. * \li At least 6 gradient images must be specified for the filter to be able
  54. * to run. If the input gradient directions g_i are majorly sampled on one half
  55. * of the sqhere, then each input image I_i will be duplicated and assign -g_i
  56. * in order to guarantee stability of the algorithm.
  57. * \li OdfDirections - directions of resulting orientation distribution function
  58. * \li EquatorNrSamplingPoints - number of sampling points on equator when
  59. * performing Funk Radeon Transform (FRT)
  60. * \li BasisFunctionCenters - the centers of the basis functions are used for
  61. * the sRBF (spherical radial basis functions interpolation). If not set, they
  62. * will be defaulted to equal m_EquatorNrSamplingPoints
  63. *
  64. * \par Template parameters
  65. * The class is templated over
  66. * \li the pixel type of the reference and gradient images
  67. * (expected to be scalar data types)
  68. * \li the internal representation of the ODF pixels (double, float etc).
  69. * \li the number of OdfDirections
  70. * \li the number of basis function centers for the sRBF
  71. *
  72. * \par References:
  73. * \li<a href="http://www3.interscience.wiley.com/cgi-bin/fulltext/109800293/PDFSTART">[1]</a>
  74. * <em>Tuch DS,
  75. * "Q-ball imaging", Magn Reson Med. 2004 Dec;52(6):1358-72.</em>
  76. *
  77. */
  78. template< class TReferenceImagePixelType,
  79. class TGradientImagePixelType,
  80. class TOdfPixelType,
  81. int NOrderL,
  82. int NrOdfDirections>
  83. class AnalyticalDiffusionQballReconstructionImageFilter :
  84. public ImageToImageFilter< Image< TReferenceImagePixelType, 3 >,
  85. Image< Vector< TOdfPixelType, NrOdfDirections >, 3 > >
  86. {
  87. public:
  88. enum Normalization {
  89. QBAR_STANDARD,
  90. QBAR_B_ZERO_B_VALUE,
  91. QBAR_B_ZERO,
  92. QBAR_NONE,
  93. QBAR_ADC_ONLY,
  94. QBAR_RAW_SIGNAL,
  95. QBAR_SOLID_ANGLE,
  96. QBAR_NONNEG_SOLID_ANGLE
  97. };
  98. typedef AnalyticalDiffusionQballReconstructionImageFilter Self;
  99. typedef SmartPointer<Self> Pointer;
  100. typedef SmartPointer<const Self> ConstPointer;
  101. typedef ImageToImageFilter< Image< TReferenceImagePixelType, 3>,
  102. Image< Vector< TOdfPixelType, NrOdfDirections >, 3 > >
  103. Superclass;
  104. /** Method for creation through the object factory. */
  105. itkNewMacro(Self);
  106. /** Runtime information support. */
  107. itkTypeMacro(AnalyticalDiffusionQballReconstructionImageFilter,
  108. ImageToImageFilter);
  109. typedef TReferenceImagePixelType ReferencePixelType;
  110. typedef TGradientImagePixelType GradientPixelType;
  111. typedef Vector< TOdfPixelType, NrOdfDirections >
  112. OdfPixelType;
  113. /** Reference image data, This image is aquired in the absence
  114. * of a diffusion sensitizing field gradient */
  115. typedef typename Superclass::InputImageType ReferenceImageType;
  116. typedef Image< OdfPixelType, 3 > OdfImageType;
  117. typedef OdfImageType OutputImageType;
  118. typedef TOdfPixelType BZeroPixelType;
  119. typedef Image< BZeroPixelType, 3 > BZeroImageType;
  120. typedef typename Superclass::OutputImageRegionType
  121. OutputImageRegionType;
  122. /** Typedef defining one (of the many) gradient images. */
  123. typedef Image< GradientPixelType, 3 > GradientImageType;
  124. /** An alternative typedef defining one (of the many) gradient images.
  125. * It will be assumed that the vectorImage has the same dimension as the
  126. * Reference image and a vector length parameter of \c n (number of
  127. * gradient directions)*/
  128. typedef VectorImage< GradientPixelType, 3 > GradientImagesType;
  129. /** Holds the ODF reconstruction matrix */
  130. typedef vnl_matrix< TOdfPixelType >*
  131. OdfReconstructionMatrixType;
  132. typedef vnl_matrix< double > CoefficientMatrixType;
  133. /** Holds each magnetic field gradient used to acquire one DWImage */
  134. typedef vnl_vector_fixed< double, 3 > GradientDirectionType;
  135. /** Container to hold gradient directions of the 'n' DW measurements */
  136. typedef VectorContainer< unsigned int,
  137. GradientDirectionType > GradientDirectionContainerType;
  138. /** set method to add gradient directions and its corresponding
  139. * image. The image here is a VectorImage. The user is expected to pass the
  140. * gradient directions in a container. The ith element of the container
  141. * corresponds to the gradient direction of the ith component image the
  142. * VectorImage. For the baseline image, a vector of all zeros
  143. * should be set.*/
  144. void SetGradientImage( GradientDirectionContainerType *,
  145. const GradientImagesType *image);
  146. /** Get reference image */
  147. virtual ReferenceImageType * GetReferenceImage()
  148. { return ( static_cast< ReferenceImageType *>(this->ProcessObject::GetInput(0)) ); }
  149. /** Return the gradient direction. idx is 0 based */
  150. virtual GradientDirectionType GetGradientDirection( unsigned int idx) const
  151. {
  152. if( idx >= m_NumberOfGradientDirections )
  153. {
  154. itkExceptionMacro( << "Gradient direction " << idx << "does not exist" );
  155. }
  156. return m_GradientDirectionContainer->ElementAt( idx+1 );
  157. }
  158. static void tofile2(vnl_matrix<double> *A, std::string fname);
  159. static double factorial(int number);
  160. static void Cart2Sph(double x, double y, double z, double* cart);
  161. static double legendre0(int l);
  162. static double spherical_harmonic(int m,int l,double theta,double phi, bool complexPart);
  163. static double Yj(int m, int k, double theta, double phi);
  164. OdfPixelType Normalize(OdfPixelType odf, typename NumericTraits<ReferencePixelType>::AccumulateType b0 );
  165. vnl_vector<TOdfPixelType> PreNormalize( vnl_vector<TOdfPixelType> vec, typename NumericTraits<ReferencePixelType>::AccumulateType b0 );
  166. /** Threshold on the reference image data. The output ODF will be a null
  167. * pdf for pixels in the reference image that have a value less than this
  168. * threshold. */
  169. itkSetMacro( Threshold, ReferencePixelType );
  170. itkGetMacro( Threshold, ReferencePixelType );
  171. itkSetMacro( NormalizationMethod, Normalization);
  172. itkGetMacro( NormalizationMethod, Normalization );
  173. typedef Image<float, 3> BlaImage;
  174. itkGetMacro( BZeroImage, typename BZeroImageType::Pointer);
  175. itkGetMacro( ODFSumImage, typename BlaImage::Pointer);
  176. itkSetMacro( BValue, TOdfPixelType);
  177. #ifdef GetBValue
  178. #undef GetBValue
  179. #endif
  180. itkGetConstReferenceMacro( BValue, TOdfPixelType);
  181. itkSetMacro( Lambda, double );
  182. itkGetMacro( Lambda, double );
  183. #ifdef ITK_USE_CONCEPT_CHECKING
  184. /** Begin concept checking */
  185. itkConceptMacro(ReferenceEqualityComparableCheck,
  186. (Concept::EqualityComparable<ReferencePixelType>));
  187. itkConceptMacro(TensorEqualityComparableCheck,
  188. (Concept::EqualityComparable<OdfPixelType>));
  189. itkConceptMacro(GradientConvertibleToDoubleCheck,
  190. (Concept::Convertible<GradientPixelType, double>));
  191. itkConceptMacro(DoubleConvertibleToTensorCheck,
  192. (Concept::Convertible<double, OdfPixelType>));
  193. itkConceptMacro(GradientReferenceAdditiveOperatorsCheck,
  194. (Concept::AdditiveOperators<GradientPixelType, GradientPixelType,
  195. ReferencePixelType>));
  196. itkConceptMacro(ReferenceOStreamWritableCheck,
  197. (Concept::OStreamWritable<ReferencePixelType>));
  198. itkConceptMacro(TensorOStreamWritableCheck,
  199. (Concept::OStreamWritable<OdfPixelType>));
  200. /** End concept checking */
  201. #endif
  202. protected:
  203. AnalyticalDiffusionQballReconstructionImageFilter();
  204. ~AnalyticalDiffusionQballReconstructionImageFilter() {};
  205. void PrintSelf(std::ostream& os, Indent indent) const;
  206. void ComputeReconstructionMatrix();
  207. void BeforeThreadedGenerateData();
  208. void ThreadedGenerateData( const
  209. OutputImageRegionType &outputRegionForThread, int);
  210. private:
  211. OdfReconstructionMatrixType m_ReconstructionMatrix;
  212. OdfReconstructionMatrixType m_CoeffReconstructionMatrix;
  213. OdfReconstructionMatrixType m_SphericalHarmonicBasisMatrix;
  214. /** container to hold gradient directions */
  215. GradientDirectionContainerType::Pointer m_GradientDirectionContainer;
  216. /** Number of gradient measurements */
  217. unsigned int m_NumberOfGradientDirections;
  218. /** Number of baseline images */
  219. unsigned int m_NumberOfBaselineImages;
  220. /** Threshold on the reference image data */
  221. ReferencePixelType m_Threshold;
  222. /** LeBihan's b-value for normalizing tensors */
  223. TOdfPixelType m_BValue;
  224. typename BZeroImageType::Pointer m_BZeroImage;
  225. double m_Lambda;
  226. bool m_DirectionsDuplicated;
  227. Normalization m_NormalizationMethod;
  228. int m_NumberCoefficients;
  229. vnl_matrix<double>* m_B_t;
  230. vnl_vector<double>* m_LP;
  231. BlaImage::Pointer m_ODFSumImage;
  232. };
  233. }
  234. #ifndef ITK_MANUAL_INSTANTIATION
  235. #include "itkAnalyticalDiffusionQballReconstructionImageFilter.cpp"
  236. #endif
  237. #endif //__itkAnalyticalDiffusionQballReconstructionImageFilter_h_