18 #ifndef __itkODFFromSPFImageFilter_hxx 19 #define __itkODFFromSPFImageFilter_hxx 21 #include <itkProgressReporter.h> 30 template<
class TInputImage,
class TOutputImage >
35 Superclass::GenerateOutputInformation();
36 typename TOutputImage::Pointer outputPtr = this->GetOutput();
37 unsigned int numberOfComponentsPerPixel =
utl::RankToDimSH(this->GetSHRank());
38 outputPtr->SetNumberOfComponentsPerPixel(numberOfComponentsPerPixel);
41 template<
class TInputImage,
class TOutputImage >
46 Superclass::VerifyInputParameters();
48 utlGlobalException(this->m_ODFOrder==-1 && this->m_BMax<=0,
"for Funk-Radon transform, bvalue can not be negative!");
51 template<
class TInputImage,
class TOutputImage >
56 utlException(this->m_SHRank<0 || this->m_RadialRank<0, "need to set this->m_SHRank and this->m_RadialRank
"); 60 qValue = std::sqrt(this->m_BMax/(4*M_PI*M_PI*this->m_Tau)); 63 utlException(this->m_ODFOrder==-1,"for Funk-Radon transform, this->m_BMax can not be negative
"); 66 double C = qValue>0 ? qValue*qValue/this->m_BasisScale : -1; 71 std::cout << "integration in a disk
" << std::endl; 72 std::cout << "C =
" << C << std::endl; 73 std::cout << "qValue =
" << qValue << ", m_BasisScale =
" << this->m_BasisScale << std::endl; 80 std::cout << "integration in the whole plane
" << std::endl; 82 std::cout << "C =
" << C << ", m_BasisScale =
" << this->m_BasisScale << std::endl; 86 if (this->m_BasisType==Superclass::SPF || this->m_BasisType==Superclass::DSPF) 88 typedef SphericalPolarFourierRadialGenerator<double> SPFGenerator; 89 int n_b_sh = (this->m_SHRank+1)*(this->m_SHRank+2)/2; 90 int n_b_ra = this->m_RadialRank+1; 91 int n_b = n_b_sh * n_b_ra; 92 this->m_SPFToFeatureTransform = MatrixPointer (new MatrixType(n_b_sh,n_b) ); 93 this->m_SPFToFeatureTransform->Fill(0.0); 94 if (this->m_BasisType==Superclass::SPF) 96 for ( int n = 0; n <= this->m_RadialRank; n += 1 ) 99 double first_temp = 2.0 / std::pow((double)this->m_BasisScale,(double)1.5) * utl::Factorial(n) / utl::Gamma(n+1.5); 100 first_temp = std::sqrt(first_temp); 101 switch ( this->m_ODFOrder ) 105 // std::cout << "order 0, ODF by Tuch, Funk-Radon Transform
" << std::endl; 106 temp = first_temp * std::exp( -1.0*qValue*qValue / (2*this->m_BasisScale) ) * utl::Lagurre(n, 0.5, qValue*qValue/this->m_BasisScale); 107 for ( int j = 0; j < n_b_sh; j += 1 ) 108 (*this->m_SPFToFeatureTransform)(j,n*n_b_sh+j) = m_P(j) * temp; 113 // std::cout << "order 0, ODF by Tuch, integrate in a disk or a plane
" << std::endl; 114 double second_temp = 0; 118 for ( int i = 0; i <= n; i += 1 ) 119 second_temp += utl::Binomial(n+0.5,n-i) * std::pow((double)-2.0,(double)i) * utl::GammaLower(i+1,0.5*C) / utl::Factorial(i); 124 for ( int i = 0; i <= n; i += 1 ) 126 double tmp = utl::Binomial(i-0.5,i); 127 second_temp += (n-i)%2==0 ? tmp : -tmp; 130 second_temp *= this->m_BasisScale; 131 temp = first_temp*second_temp; 132 //************************************************************** 134 for ( int j = 0; j < n_b_sh; j += 1 ) 135 (*this->m_SPFToFeatureTransform)(j,n*n_b_sh+j) = m_P(j) * temp; 140 // std::cout << "order 2, OPDF (maginal pdf), integrate in a disk or a plane
" << std::endl; 141 // NOTE: -1 is in transformBasis 142 double second_temp = 0; 146 for ( int i = 1; i <= n; i += 1 ) 148 double tmp = utl::Binomial(n+0.5,n-i) * std::pow((double)2.0,(double)i) * utl::GammaLower(i,0.5*C) / utl::Factorial(i); 149 second_temp += (i%2==0 ? tmp : -tmp); 155 for ( int i = 1; i <= n; i += 1 ) 157 double tmp = utl::Binomial(n+0.5,n-i) * std::pow((double)2.0,(double)i) / i; 158 second_temp += (i%2==0 ? tmp : -tmp); 162 temp = first_temp*second_temp; 163 //************************************************************** 165 for ( int j = 0; j < n_b_sh; j += 1 ) 166 (*this->m_SPFToFeatureTransform)(j,n*n_b_sh+j) = -1.0 * m_P(j) * m_L(j) * temp; 170 utlGlobalException(true,"wrong type
"); 178 utlGlobalException(true, "TODO
"); 181 if (this->GetDebug()) 182 utl::PrintUtlMatrix(*this->m_SPFToFeatureTransform, "m_SPFToFeatureTransform
"); 185 template< class TInputImage, class TOutputImage > 186 typename LightObject::Pointer 187 ODFFromSPFImageFilter< TInputImage, TOutputImage > 188 ::InternalClone() const 190 typename LightObject::Pointer loPtr = Superclass::InternalClone(); 192 typename Self::Pointer rval = dynamic_cast<Self *>(loPtr.GetPointer()); 195 itkExceptionMacro(<< "downcast to type
" << this->GetNameOfClass()<< " failed.
"); 199 rval->m_ODFOrder = m_ODFOrder; 200 rval->m_BMax = m_BMax; 204 template< class TInputImage, class TOutputImage > 206 ODFFromSPFImageFilter< TInputImage, TOutputImage > 207 ::BeforeThreadedGenerateData ( ) 209 // utlShowPosition(true); 210 this->SetSPFIEstimator(); 212 int n_b_sh = (this->m_SHRank+1)*(this->m_SHRank+2)/2; 217 for(int l = 0; l <= this->m_SHRank; l+=2) 219 diag = 2*M_PI* utl::LegendrePolynomialAt0(l); 220 for(int m = -l; m <= l; m++) 227 // utl::PrintUtlVector(m_L,"m_L
"); 228 // utl::PrintUtlVector(m_P,"m_P
"); 229 Superclass::BeforeThreadedGenerateData(); 232 template <class TInputImage, class TOutputImage> 234 ODFFromSPFImageFilter<TInputImage,TOutputImage> 235 ::ThreadedGenerateData( const typename TOutputImage::RegionType &outputRegionForThread, ThreadIdType threadId) 237 // utlShowPosition(true); 238 typename TInputImage::ConstPointer inputPtr = this->GetInput(); 239 typename TOutputImage::Pointer outputPtr = this->GetOutput(); 241 // Define the iterators 242 ImageRegionConstIteratorWithIndex<TInputImage> inputIt(inputPtr, outputRegionForThread); 243 ImageRegionIteratorWithIndex<TOutputImage> outputIt(outputPtr, outputRegionForThread); 244 ImageRegionIteratorWithIndex<MaskImageType> maskIt; 245 if (this->IsMaskUsed()) 246 maskIt = ImageRegionIteratorWithIndex<MaskImageType>(this->m_MaskImage, outputRegionForThread); 248 ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); 249 typename TInputImage::PixelType inputPixel; 250 typename TInputImage::IndexType inputIndex; 251 typename TOutputImage::PixelType outputPixel; 253 unsigned int outputDim = outputPtr->GetNumberOfComponentsPerPixel();; 254 outputPixel.SetSize(outputDim); 255 unsigned int inputDim = inputPtr->GetNumberOfComponentsPerPixel(); 256 inputPixel.SetSize(inputDim); 259 outputIt.GoToBegin(); 260 VectorType spfVec, result; 262 Pointer selfClone = this->Clone(); 264 while( !inputIt.IsAtEnd() ) 266 if (!this->IsMaskUsed() || (this->IsMaskUsed() && maskIt.Get()>0)) 268 inputPixel = inputIt.Get(); 269 if (inputPixel.GetSquaredNorm()>1e-8) 271 inputIndex = inputIt.GetIndex(); 272 if (this->GetDebug()) 273 std::cout << "index =
" << inputIndex << std::endl << std::flush; 275 if (!IsImageEmpty(this->m_ScaleImage)) 276 selfClone->SetBasisScale(this->m_ScaleImage->GetPixel(inputIndex)); 277 if (selfClone->m_SPFToFeatureTransform->Size()==0) 278 selfClone->ComputeSPFToFeatureTransform(); 280 spfVec = utl::VariableLengthVectorToUtlVector(inputPixel); 281 switch ( this->m_ODFOrder ) 285 // if (this->GetDebug()) 286 // std::cout << "order 0, ODF by Tuch, Funk-Radon Transform
" << std::endl; 287 utlException(this->m_BMax<=0,"for Funk-Radon transform, bvalue can not be negative
"); 288 result = (*selfClone->m_SPFToFeatureTransform) * spfVec; 289 double normalizefactor = 1.0 / (std::sqrt(4*M_PI)*result[0]); 290 result %= normalizefactor; 295 // if (this->GetDebug()) 296 // std::cout << "order 0, ODF by Tuch, integrate in a disk or a plane
" << std::endl; 297 result = (*selfClone->m_SPFToFeatureTransform) * spfVec; 298 double normalizefactor = 1.0 / (std::sqrt(4*M_PI)*result[0]); 299 result %= normalizefactor; 304 // if (this->GetDebug()) 305 // std::cout << "order 2, OPDF (maginal pdf), integrate in a disk or a plane
" << std::endl; 306 result = (*selfClone->m_SPFToFeatureTransform) * spfVec / (8*M_PI*M_PI); 307 result[0] += 1/std::sqrt(4*M_PI); 311 utlGlobalException(true,"Wrong type
"); 314 if (this->GetDebug()) 315 utl::PrintUtlVector(result, "odf
"); 317 outputPixel = utl::UtlVectorToVariableLengthVector(result); 321 outputPixel.Fill(0.0); 324 outputPixel.Fill(0.0); 326 outputIt.Set(outputPixel); 327 progress.CompletedPixel(); 328 if (this->IsMaskUsed()) 332 progress.CompletedPixel(); // potential exception thrown here 336 template< class TInputImage, class TOutputImage > 338 ODFFromSPFImageFilter< TInputImage, TOutputImage > 339 ::PrintSelf(std::ostream &os, Indent indent) const 341 Superclass::PrintSelf(os, indent); 343 << ", m_ODFOrder =
" << this->m_ODFOrder 344 << ", m_BMax =
" << this->m_BMax void GenerateOutputInformation() ITK_OVERRIDE
void VerifyInputParameters() const ITK_OVERRIDE
helper functions specifically used in dmritool
#define utlException(cond, expout)
#define utlGlobalException(cond, expout)
void ComputeSPFToFeatureTransform() ITK_OVERRIDE
int RankToDimSH(const int shRank)