32 #ifndef _itk_RadialMultishellToSingleshellImageFilter_cpp_
33 #define _itk_RadialMultishellToSingleshellImageFilter_cpp_
36 #define _USE_MATH_DEFINES
46 template <
class TInputScalarType,
class TOutputScalarType>
50 this->SetNumberOfRequiredInputs( 1 );
54 template <
class TInputScalarType,
class TOutputScalarType>
59 if(m_BValueMap.size() == 0)
61 itkWarningMacro(<<
"No BValueMap given: create one using GradientDirectionContainer");
63 GradientDirectionContainerType::ConstIterator gdcit;
64 for( gdcit = m_OriginalGradientDirections->Begin(); gdcit != m_OriginalGradientDirections->End(); ++gdcit)
66 double bValueKey = int(((m_OriginalBValue * gdcit.Value().two_norm() * gdcit.Value().two_norm())+7.5)/10)*10;
67 m_BValueMap[bValueKey].push_back(gdcit.Index());
72 if(m_BValueMap.find(0.0) == m_BValueMap.end())
74 MITK_INFO <<
"No ReferenceSignal (BZeroImages) found!";
75 itkExceptionMacro(<<
"No ReferenceSignal (BZeroImages) found!");
81 m_NumberTargetDirections = m_TargetDirectionsIndicies.size();
84 m_ShellInterpolationMatrixVector.reserve(m_BValueMap.size()-1);
87 BValueMap::const_iterator it = m_BValueMap.begin();
90 unsigned int shellIndex = 0;
91 for(;it != m_BValueMap.end();++it)
95 unsigned int SHMaxOrder = 12;
96 while( ((SHMaxOrder+1)*(SHMaxOrder+2)/2) > currentShell.size() && ((SHMaxOrder+1)*(SHMaxOrder+2)/2) >= 4 )
100 vnl_matrix<double> sphericalCoordinates;
107 vnl_matrix_inverse<double> invShellSHBasis(ShellSHBasis);
108 vnl_matrix<double> shellInterpolationMatrix = TargetSHBasis * invShellSHBasis.pinverse();
110 m_ShellInterpolationMatrixVector.push_back(shellInterpolationMatrix);
117 outImage->SetSpacing( this->GetInput()->GetSpacing() );
118 outImage->SetOrigin( this->GetInput()->GetOrigin() );
119 outImage->SetDirection( this->GetInput()->GetDirection() );
120 outImage->SetLargestPossibleRegion( this->GetInput()->GetLargestPossibleRegion());
121 outImage->SetBufferedRegion( this->GetInput()->GetLargestPossibleRegion() );
122 outImage->SetRequestedRegion( this->GetInput()->GetLargestPossibleRegion() );
123 outImage->SetVectorLength( 1+m_NumberTargetDirections );
124 outImage->Allocate();
127 m_ErrorImage->SetSpacing( this->GetInput()->GetSpacing() );
128 m_ErrorImage->SetOrigin( this->GetInput()->GetOrigin() );
129 m_ErrorImage->SetDirection( this->GetInput()->GetDirection() );
130 m_ErrorImage->SetLargestPossibleRegion( this->GetInput()->GetLargestPossibleRegion());
131 m_ErrorImage->SetBufferedRegion( this->GetInput()->GetLargestPossibleRegion() );
132 m_ErrorImage->SetRequestedRegion( this->GetInput()->GetLargestPossibleRegion() );
133 m_ErrorImage->Allocate();
135 MITK_INFO <<
"Input:" << std::endl << std::endl
136 <<
" GradientDirections: " << m_OriginalGradientDirections->Size() << std::endl
137 <<
" Shells: " << (m_BValueMap.size() - 1) << std::endl
138 <<
" ReferenceImages: " << m_BValueMap[0.0].size() << std::endl;
140 MITK_INFO <<
"Output:" << std::endl << std::endl
141 <<
" OutImageVectorLength: " << outImage->GetVectorLength() << std::endl
142 <<
" TargetDirections: " << m_NumberTargetDirections << std::endl
147 template <
class TInputScalarType,
class TOutputScalarType>
155 ImageRegionIterator< InputImageType > iit(inputImage, outputRegionForThread);
161 ImageRegionIterator< OutputImageType > oit(outputImage, outputRegionForThread);
165 ImageRegionIterator< ErrorImageType > eit(m_ErrorImage, outputRegionForThread);
170 double AverageS0 = 0.0;
172 unsigned int numberOfShells = m_BValueMap.size()-1;
175 vnl_matrix<double> SignalMatrix(m_NumberTargetDirections, numberOfShells);
178 vnl_vector<double> SignalVector(m_NumberTargetDirections);
181 BValueMap::const_iterator shellIterator;
182 vnl_matrix<double> NewSignalMatrix (m_NumberTargetDirections, 2);
183 vnl_vector<double> InterpVector;
184 unsigned int shellIndex = 0;
186 while(!iit.IsAtEnd())
190 for(
unsigned int i = 0 ; i < IndicesS0.size(); i++){
191 AverageS0 += b[IndicesS0[i]];
193 AverageS0 /= (double)IndicesS0.size();
195 out.SetElement(0,AverageS0);
197 shellIterator = m_BValueMap.begin();
202 while(shellIterator != m_BValueMap.end())
205 InterpVector.set_size(currentShell.size());
208 for(
unsigned int i = 0 ; i < currentShell.size(); i++)
209 InterpVector.put(i,b[currentShell[i]]);
212 SignalVector = m_ShellInterpolationMatrixVector.at(shellIndex) * InterpVector;
215 SignalMatrix.set_column(shellIndex, SignalVector);
222 (*m_Functor)(NewSignalMatrix, SignalMatrix, AverageS0);
223 SignalVector = NewSignalMatrix.get_column(0);
225 for(
unsigned int i = 1 ; i < out.Size(); i ++)
226 out.SetElement(i,SignalVector.get(i-1));
228 eit.Set(NewSignalMatrix.get_column(1).mean());
OutputImageType::PixelType OutputPixelType
itk::SmartPointer< Self > Pointer
Superclass::OutputImageRegionType OutputImageRegionType
itk::VectorImage< InputScalarType, 3 > InputImageType
static vnl_matrix< double > ComputeSphericalHarmonicsBasis(const vnl_matrix< double > &QBallReference, const unsigned int &LOrder)
itk::VectorImage< OutputScalarType, 3 > OutputImageType
std::vector< unsigned int > IndicesVector
void ThreadedGenerateData(const OutputImageRegionType &, ThreadIdType)
static mitk::gradients::GradientDirectionContainerType::Pointer CreateNormalizedUniqueGradientDirectionContainer(const BValueMap &bValueMap, const GradientDirectionContainerType *origninalGradentcontainer)
InputImageType::PixelType InputPixelType
RadialMultishellToSingleshellImageFilter()
static std::vector< unsigned int > GetAllUniqueDirections(const BValueMap &bValueMap, GradientDirectionContainerType *refGradientsContainer)
void BeforeThreadedGenerateData()
static vnl_matrix< double > ComputeSphericalFromCartesian(const IndiciesVector &refShell, const GradientDirectionContainerType *refGradientsContainer)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.