4 #include <vnl/vnl_matrix_fixed.h> 6 #include <itkImageRegionConstIteratorWithIndex.h> 8 #include <boost/math/special_functions/factorials.hpp> 13 template <
class TFixedImagePixelType,
class TMovingImagePixelType,
unsigned int ImageDimension >
17 m_FixedImagePoints.clear();
18 m_FixedImageCompartmentWeights.clear();
19 m_FixedImageLogTensors.clear();
20 m_NumberOfFixedCompartments = 1;
29 m_leCalculator = LECalculatorType::New();
32 template <
class TFixedImagePixelType,
class TMovingImagePixelType,
unsigned int ImageDimension >
39 for (
unsigned int i = 0;i < val->GetNumberOfCompartments();++i)
41 if (!val->GetCompartment(i)->GetTensorCompatible())
46 val = movingImage->GetDescriptionModel();
47 for (
unsigned int i = 0;i < val->GetNumberOfCompartments();++i)
49 if (!val->GetCompartment(i)->GetTensorCompatible())
56 template <
class TFixedImagePixelType,
class TMovingImagePixelType,
unsigned int ImageDimension >
64 itkExceptionMacro(
"Fixed image has not been assigned");
66 bool tensorCompatibilityCondition = this->CheckTensorCompatibility();
67 if (!tensorCompatibilityCondition)
68 itkExceptionMacro(
"Only tensor compatible models handled")
70 if (this->m_NumberOfPixelsCounted == 0)
73 this->SetTransformParameters( parameters );
81 MCModelPointer currentMovingValue = movingImage->GetDescriptionModel()->Clone();
83 std::vector < std::vector <double> > movingImageCompartmentWeights(this->m_NumberOfPixelsCounted);
84 std::vector < std::vector <PixelType> > movingImageLogTensors(this->m_NumberOfPixelsCounted);
85 std::vector <double> tmpWeights;
86 vnl_matrix <double> workLogMatrix(3,3);
89 for (
unsigned int i = 0;i < this->m_NumberOfPixelsCounted;++i)
91 transformedPoint = this->m_Transform->TransformPoint( m_FixedImagePoints[i] );
92 this->m_Interpolator->GetInputImage()->TransformPhysicalPointToContinuousIndex(transformedPoint,transformedIndex);
94 if( this->m_Interpolator->IsInsideBuffer( transformedIndex ) )
96 movingValue = this->m_Interpolator->EvaluateAtContinuousIndex( transformedIndex );
98 if (!isZero(movingValue))
100 currentMovingValue->SetModelVector(movingValue);
101 if (this->GetModelRotation() != Superclass::NONE)
102 currentMovingValue->Reorient(this->m_OrientationMatrix, (this->GetModelRotation() ==
Superclass::PPD));
104 tmpWeights = currentMovingValue->GetCompartmentWeights();
105 unsigned int internalCounter = 0;
106 for (
unsigned int j = 0;j < currentMovingValue->GetNumberOfCompartments();++j)
108 if (tmpWeights[internalCounter] <= 0)
109 tmpWeights.erase(tmpWeights.begin() + internalCounter);
113 m_leCalculator->GetTensorLogarithm(currentMovingValue->GetCompartment(j)->GetDiffusionTensor().GetVnlMatrix().as_matrix(),workLogMatrix);
115 movingImageLogTensors[i].push_back(workValue);
119 movingImageCompartmentWeights[i] = tmpWeights;
123 movingImageLogTensors[i].resize(1);
124 anima::GetVectorRepresentation(m_ZeroDiffusionModel->GetCompartment(0)->GetDiffusionTensor().GetVnlMatrix().as_matrix(),movingImageLogTensors[i][0],6,
true);
125 movingImageCompartmentWeights[i].resize(1);
126 movingImageCompartmentWeights[i][0] = 1.0;
131 movingImageLogTensors[i].resize(1);
132 anima::GetVectorRepresentation(m_ZeroDiffusionModel->GetCompartment(0)->GetDiffusionTensor().GetVnlMatrix().as_matrix(),movingImageLogTensors[i][0],6,
true);
133 movingImageCompartmentWeights[i].resize(1);
134 movingImageCompartmentWeights[i][0] = 1.0;
138 double mRS = this->ComputeMapping(m_FixedImageCompartmentWeights,m_FixedImageLogTensors,movingImageCompartmentWeights,movingImageLogTensors);
139 double mRR = this->ComputeMapping(m_FixedImageCompartmentWeights,m_FixedImageLogTensors,m_FixedImageCompartmentWeights,m_FixedImageLogTensors);
140 double mSS = this->ComputeMapping(movingImageCompartmentWeights,movingImageLogTensors,movingImageCompartmentWeights,movingImageLogTensors);
143 double numMaxCompartments = std::max(movingImage->GetDescriptionModel()->GetNumberOfCompartments(),m_NumberOfFixedCompartments);
144 double epsilon = std::sqrt(numMaxCompartments / (3.0 * this->m_NumberOfPixelsCounted)) / numMaxCompartments;
146 for (
unsigned int i = 0;i < this->m_NumberOfPixelsCounted;++i)
148 for (
unsigned int k = 0;k < m_FixedImageCompartmentWeights[i].size();++k)
151 for (
unsigned int l = 0;l < 3;++l)
153 unsigned int index = l * (l + 1) / 2 - 1;
154 dotProd += m_FixedImageLogTensors[i][k][index];
157 mRT += m_FixedImageCompartmentWeights[i][k] * dotProd;
160 for (
unsigned int k = 0;k < movingImageCompartmentWeights[i].size();++k)
163 for (
unsigned int l = 0;l < 3;++l)
165 unsigned int index = l * (l + 1) / 2 - 1;
166 dotProd += movingImageLogTensors[i][k][index];
169 mST += movingImageCompartmentWeights[i][k] * dotProd;
177 double measure = (mRS - mRT * mST) * (mRS - mRT * mST);
178 double denom = (mRR - mRT * mRT) * (mSS - mST * mST);
188 template <
class TFixedImagePixelType,
class TMovingImagePixelType,
unsigned int ImageDimension >
191 ::ComputeMapping(
const std::vector < std::vector <double> > &refImageCompartmentWeights,
const std::vector < std::vector <PixelType> > &refImageLogTensors,
192 const std::vector < std::vector <double> > &movingImageCompartmentWeights,
const std::vector < std::vector <PixelType> > &movingImageLogTensors)
const 194 std::vector <unsigned int> currentPermutation;
195 double mappingDistanceValue = 0;
196 for (
unsigned int i = 0;i < this->m_NumberOfPixelsCounted;++i)
198 double bestValue = 0.0;
199 unsigned int fixedNumCompartments = refImageCompartmentWeights[i].size();
200 unsigned int movingNumCompartments = movingImageCompartmentWeights[i].size();
202 unsigned int minCompartmentsNumber = fixedNumCompartments;
203 int rest = movingNumCompartments - minCompartmentsNumber;
204 bool fixedMin =
true;
208 minCompartmentsNumber = movingNumCompartments;
212 unsigned int maxCompartmentsNumber = minCompartmentsNumber + rest;
214 currentPermutation.resize(maxCompartmentsNumber);
215 for (
unsigned int j = 0;j < maxCompartmentsNumber;++j)
216 currentPermutation[j] = j;
221 double distValue = 0;
223 for (
unsigned int j = 0;j < maxCompartmentsNumber;++j)
225 unsigned int firstIndex;
226 unsigned int secondIndex;
230 firstIndex = currentPermutation[j];
236 secondIndex = currentPermutation[j];
239 if ((firstIndex >= refImageCompartmentWeights[i].size())||(secondIndex >= movingImageCompartmentWeights[i].size()))
243 for (
unsigned int k = 0;k < refImageLogTensors[i][firstIndex].GetSize();++k)
244 dist += refImageLogTensors[i][firstIndex][k] * movingImageLogTensors[i][secondIndex][k];
246 distValue += refImageCompartmentWeights[i][firstIndex] * movingImageCompartmentWeights[i][secondIndex] * dist;
249 if (std::abs(distValue) > std::abs(bestValue))
250 bestValue = distValue;
252 }
while(std::next_permutation(currentPermutation.begin(),currentPermutation.end()));
254 mappingDistanceValue += bestValue;
257 return mappingDistanceValue;
260 template <
class TFixedImagePixelType,
class TMovingImagePixelType,
unsigned int ImageDimension >
265 unsigned int ndim = vector.GetSize();
267 for (
unsigned int i = 0;i < ndim;++i)
276 template <
class TFixedImagePixelType,
class TMovingImagePixelType,
unsigned int ImageDimension >
281 if(!this->m_FixedImage)
282 itkExceptionMacro( <<
"Fixed image has not been assigned" );
286 this->m_NumberOfPixelsCounted = this->GetFixedImageRegion().GetNumberOfPixels();
287 typedef itk::ImageRegionConstIteratorWithIndex<FixedImageType> FixedIteratorType;
288 FixedIteratorType ti(fixedImage, this->GetFixedImageRegion());
289 typename FixedImageType::IndexType index;
291 m_FixedImagePoints.resize(this->m_NumberOfPixelsCounted);
292 m_FixedImageCompartmentWeights.resize(this->m_NumberOfPixelsCounted);
293 m_FixedImageLogTensors.resize(this->m_NumberOfPixelsCounted);
296 MCModelPointer fixedMCM = fixedImage->GetDescriptionModel()->Clone();
297 m_NumberOfFixedCompartments = fixedMCM->GetNumberOfCompartments();
299 unsigned int pos = 0;
301 std::vector <double> tmpWeights;
302 vnl_matrix <double> workLogMatrix(3,3);
306 index = ti.GetIndex();
307 fixedImage->TransformIndexToPhysicalPoint(index, inputPoint);
309 m_FixedImagePoints[pos] = inputPoint;
310 fixedValue = ti.Get();
312 if (!isZero(fixedValue))
314 fixedMCM->SetModelVector(fixedValue);
315 tmpWeights = fixedMCM->GetCompartmentWeights();
316 unsigned int internalCounter = 0;
317 for (
unsigned int i = 0;i < fixedMCM->GetNumberOfCompartments();++i)
319 if (tmpWeights[internalCounter] <= 0)
320 tmpWeights.erase(tmpWeights.begin() + internalCounter);
324 m_leCalculator->GetTensorLogarithm(fixedMCM->GetCompartment(i)->GetDiffusionTensor().GetVnlMatrix().as_matrix(),workLogMatrix);
326 m_FixedImageLogTensors[pos].push_back(workValue);
330 m_FixedImageCompartmentWeights[pos] = tmpWeights;
334 m_FixedImageLogTensors[pos].resize(1);
335 anima::GetVectorRepresentation(m_ZeroDiffusionModel->GetCompartment(0)->GetDiffusionTensor().GetVnlMatrix().as_matrix(),m_FixedImageLogTensors[pos][0],6,
true);
336 m_FixedImageCompartmentWeights[pos].resize(1);
337 m_FixedImageCompartmentWeights[pos][0] = 1.0;
MCMPointer GetNewMultiCompartmentModel()
void SetNumberOfCompartments(unsigned int num)
itk::ContinuousIndex< double, ImageDimension > ContinuousIndexType
TFixedImage::PixelType PixelType
void SetModelWithStationaryWaterComponent(bool arg)
void GetVectorRepresentation(const vnl_matrix< T1 > &tensor, itk::VariableLengthVector< T2 > &vector, unsigned int vecDim=0, bool scale=false)
Superclass::TransformParametersType TransformParametersType
MCModelType::Pointer MCModelPointer
MTPairingCorrelationImageToImageMetric()
Superclass::MovingImageType MovingImageType
bool isZero(PixelType &vector) const
Superclass::MeasureType MeasureType
Superclass::FixedImageConstPointer FixedImageConstPointer
Superclass::OutputPointType OutputPointType
void PreComputeFixedValues()
MeasureType GetValue(const TransformParametersType ¶meters) const ITK_OVERRIDE
Superclass::InputPointType InputPointType
double ComputeMapping(const std::vector< std::vector< double > > &refImageCompartmentWeights, const std::vector< std::vector< PixelType > > &refImageLogTensors, const std::vector< std::vector< double > > &movingImageCompartmentWeights, const std::vector< std::vector< PixelType > > &movingImageLogTensors) const
Superclass::FixedImageType FixedImageType
Really this class is some simplified factory that creates the MCM that it knows.
void SetModelWithFreeWaterComponent(bool arg)
bool CheckTensorCompatibility() const