4 #include <itkImageRegionConstIteratorWithIndex.h> 5 #include <itkSymmetricEigenAnalysis.h> 13 template <
class TFixedImagePixelType,
class TMovingImagePixelType,
unsigned int ImageDimension >
17 m_OrientationPenalty =
true;
18 m_VarianceThreshold = 0.000001;
20 m_FixedImagePoints.clear();
21 m_FixedImageValues.clear();
23 m_leCalculator = LECalculatorType::New();
29 template <
class TFixedImagePixelType,
class TMovingImagePixelType,
unsigned int ImageDimension >
38 itkExceptionMacro(
"Fixed image has not been assigned");
40 if (this->m_NumberOfPixelsCounted <= 1)
43 this->SetTransformParameters( parameters );
45 unsigned int vectorSize = m_FixedMean.GetSize();
47 vnl_matrix <double> Sigma_YY(vectorSize,vectorSize);
50 vnl_matrix <double> Sigma_XY(vectorSize,vectorSize);
59 unsigned int tensorDimension = 3;
60 vnl_matrix <double> tmpMat(tensorDimension, tensorDimension);
61 vnl_matrix <double> currentTensor(tensorDimension, tensorDimension);
62 vnl_matrix <double> ppdOrientationMatrix(tensorDimension, tensorDimension);
63 typedef itk::Matrix <double, 3, 3> EigVecMatrixType;
64 typedef vnl_vector_fixed <double,3> EigValVectorType;
65 itk::SymmetricEigenAnalysis < EigVecMatrixType, EigValVectorType, EigVecMatrixType> eigenComputer(3);
66 EigVecMatrixType eigVecs;
67 EigValVectorType eigVals;
69 std::vector <PixelType> movingValues(this->m_NumberOfPixelsCounted);
70 unsigned int numOutside = 0;
74 for (
unsigned int i = 0;i < this->m_NumberOfPixelsCounted;++i)
76 transformedPoint = this->m_Transform->TransformPoint(m_FixedImagePoints[i]);
77 movingImage->TransformPhysicalPointToContinuousIndex(transformedPoint,transformedIndex);
79 if (this->m_Interpolator->IsInsideBuffer(transformedIndex))
81 movingValues[i] = this->m_Interpolator->EvaluateAtContinuousIndex(transformedIndex);
83 if (this->GetModelRotation() != Superclass::NONE)
88 if (this->GetModelRotation() == Superclass::FINITE_STRAIN)
92 eigenComputer.ComputeEigenValuesAndVectors(tmpMat,eigVals,eigVecs);
100 for (
unsigned int j = 0;j < vectorSize;++j)
101 movingMean[j] += movingValues[i][j];
106 movingValues[i] = zeroVector;
110 if (this->m_NumberOfPixelsCounted / 2.0 < numOutside)
113 movingMean /= this->m_NumberOfPixelsCounted;
115 for (
unsigned int i = 0;i < this->m_NumberOfPixelsCounted;++i)
117 for (
unsigned int j = 0;j < vectorSize;++j)
119 for (
unsigned int k = 0;k < vectorSize;++k)
120 Sigma_XY(j,k) += (m_FixedImageValues[i][j] - m_FixedMean[j]) * (movingValues[i][k] - movingMean[k]);
122 for (
unsigned int k = j;k < vectorSize;++k)
123 Sigma_YY(j,k) += (movingValues[i][j] - movingMean[j]) * (movingValues[i][k] - movingMean[k]);
127 Sigma_YY /= (this->m_NumberOfPixelsCounted - 1.0);
130 for (
unsigned int i = 0;i < vectorSize;++i)
132 for (
unsigned int j = i;j < vectorSize;++j)
134 if (Sigma_YY(i,j) != 0)
148 double movingVariance = 0;
149 for (
unsigned int j = 0;j < vectorSize;++j)
150 for (
unsigned int k = j;k < vectorSize;++k)
153 movingVariance += Sigma_YY(j,k) * Sigma_YY(j,k);
155 movingVariance += 2 * Sigma_YY(j,k) * Sigma_YY(j,k);
158 movingVariance = std::sqrt(movingVariance);
159 if (movingVariance <= m_VarianceThreshold)
162 Sigma_XY /= (this->m_NumberOfPixelsCounted - 1.0);
164 for (
unsigned int j = 0;j < vectorSize;++j)
165 for (
unsigned int k = j + 1;k < vectorSize;++k)
166 Sigma_YY(k,j) = Sigma_YY(j,k);
168 double ovlWeight = 1.0;
169 if (m_OrientationPenalty)
171 vnl_matrix <double> tmpXEVecs(tensorDimension,tensorDimension), tmpYEVecs(tensorDimension,tensorDimension);
172 vnl_diag_matrix <double> tmpEigX(tensorDimension), tmpEigY(tensorDimension);
174 for (
unsigned int i = 0;i < vectorSize;++i)
175 movingMean[i] /= this->m_NumberOfPixelsCounted;
177 itk::SymmetricEigenAnalysis < vnl_matrix <double>, vnl_diag_matrix<double>, vnl_matrix <double> > eigenComputer(tensorDimension);
180 eigenComputer.ComputeEigenValuesAndVectors(tmpMat, tmpEigX, tmpXEVecs);
183 eigenComputer.ComputeEigenValuesAndVectors(tmpMat, tmpEigY, tmpYEVecs);
185 for (
unsigned int a = 0;a < tensorDimension;++a)
187 tmpEigX[a] = std::exp(tmpEigX[a]);
188 tmpEigY[a] = std::exp(tmpEigY[a]);
194 m_leCalculator->GetTensorPower(Sigma_YY,Sigma_YY,-0.5);
196 tmpMat = m_FixedHalfInvCovarianceMatrix * Sigma_XY * Sigma_YY;
200 for (
unsigned int i = 0;i < vectorSize;++i)
201 for (
unsigned int j = 0;j < vectorSize;++j)
202 measure += tmpMat(i,j)*tmpMat(i,j);
204 double tentativeMeasure = ovlWeight * measure / vectorSize;
205 measure = std::min(1.0,std::max(tentativeMeasure,0.0));
210 template <
class TFixedImagePixelType,
class TMovingImagePixelType,
unsigned int ImageDimension >
218 itkExceptionMacro(
"Fixed image has not been assigned");
220 unsigned int vectorSize = fixedImage->GetNumberOfComponentsPerPixel();
221 if (m_FixedMean.GetSize() != vectorSize)
222 m_FixedMean.SetSize(vectorSize);
225 vnl_matrix <double> covarianceMatrix(vectorSize,vectorSize,0);
227 typedef itk::ImageRegionConstIteratorWithIndex<FixedImageType> FixedIteratorType;
229 FixedIteratorType ti( fixedImage, this->GetFixedImageRegion() );
231 this->m_NumberOfPixelsCounted = this->GetFixedImageRegion().GetNumberOfPixels();
233 m_FixedImagePoints.resize(this->m_NumberOfPixelsCounted);
234 m_FixedImageValues.resize(this->m_NumberOfPixelsCounted);
238 unsigned int pos = 0;
239 while (!ti.IsAtEnd())
241 fixedImage->TransformIndexToPhysicalPoint( ti.GetIndex(), inputPoint );
243 m_FixedImagePoints[pos] = inputPoint;
244 m_FixedImageValues[pos] = ti.Get();
246 for (
unsigned int i = 0;i < vectorSize;++i)
247 m_FixedMean[i] += m_FixedImageValues[pos][i];
253 m_FixedMean /= this->m_NumberOfPixelsCounted;
254 for (
unsigned int k = 0;k < this->m_NumberOfPixelsCounted;++k)
256 for (
unsigned int i = 0;i < vectorSize;++i)
258 for (
unsigned int j = i;j < vectorSize;++j)
259 covarianceMatrix(i,j) += (m_FixedImageValues[k][i] - m_FixedMean[i]) * (m_FixedImageValues[k][j] - m_FixedMean[j]);
263 covarianceMatrix /= this->m_NumberOfPixelsCounted;
265 for (
unsigned int i = 0;i < vectorSize;++i)
267 for (
unsigned int j = i+1;j < vectorSize;++j)
268 covarianceMatrix(j,i) = covarianceMatrix(i,j);
271 m_leCalculator->GetTensorPower(covarianceMatrix,m_FixedHalfInvCovarianceMatrix,-0.5);
274 template <
class TFixedImagePixelType,
class TMovingImagePixelType,
unsigned int ImageDimension >
279 Superclass::PrintSelf(os, indent);
280 os << indent << m_FixedMean << std::endl;
281 os << indent << m_FixedHalfInvCovarianceMatrix << std::endl;
Superclass::FixedImageConstPointer FixedImageConstPointer
double ovlScore(vnl_diag_matrix< T1 > &eigsX, vnl_matrix< T1 > &eigVecsX, vnl_diag_matrix< T1 > &eigsY, vnl_matrix< T1 > &eigVecsY)
Superclass::OutputPointType OutputPointType
TensorGeneralizedCorrelationImageToImageMetric()
TFixedImage::PixelType PixelType
void GetVectorRepresentation(const vnl_matrix< T1 > &tensor, itk::VariableLengthVector< T2 > &vector, unsigned int vecDim=0, bool scale=false)
MeasureType GetValue(const TransformParametersType ¶meters) const ITK_OVERRIDE
void RotateSymmetricMatrix(T1 &tensor, T2 &rotationMatrix, T3 &rotated_tensor, unsigned int tensorDim)
Rotates a symmetric matrix by performing R^T D R where R is a rotation matrix and D the symmetric mat...
void GetTensorFromVectorRepresentation(const itk::VariableLengthVector< T1 > &vector, vnl_matrix< T2 > &tensor, unsigned int tensDim=0, bool scale=false)
Superclass::TransformParametersType TransformParametersType
void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE
Superclass::MeasureType MeasureType
itk::ContinuousIndex< double, ImageDimension > ContinuousIndexType
Superclass::MovingImageConstPointer MovingImageConstPointer
void ExtractPPDRotationFromJacobianMatrix(vnl_matrix< RealType > &jacobianMatrix, vnl_matrix< RealType > &rotationMatrix, MatrixType &eigenVectors)
Superclass::InputPointType InputPointType
void PreComputeFixedValues()