4 #include <itkImageRegionConstIteratorWithIndex.h> 5 #include <itkSymmetricEigenAnalysis.h> 10 template <
class T1,
class T2,
unsigned int Dimension>
12 itk::VariableLengthVector <T2> &patchMean, vnl_matrix <T2> &patchCov)
14 unsigned int ndim = inputImage->GetNumberOfComponentsPerPixel();
15 if (patchMean.GetSize() != ndim)
16 patchMean.SetSize(ndim);
19 patchCov.set_size(ndim,ndim);
22 typedef itk::VectorImage <T1, Dimension> VectorImageType;
23 typedef itk::ImageRegionConstIteratorWithIndex< VectorImageType > InIteratorType;
25 InIteratorType imageIt(inputImage,patchRegion);
27 unsigned int numPixels = 0;
28 while (!imageIt.IsAtEnd())
30 patchMean += imageIt.Get();
35 patchMean /= numPixels;
38 itk::VariableLengthVector <T2> patchDiff(ndim);
41 while (!imageIt.IsAtEnd())
43 for (
unsigned int i = 0;i < ndim;++i)
44 patchDiff[i] = patchMean[i] - imageIt.Get()[i];
46 for (
unsigned int i = 0;i < ndim;++i)
47 for (
unsigned int j = i;j < ndim;++j)
49 double sqDiff = patchDiff[i] * patchDiff[j];
50 patchCov(i,j) += sqDiff;
56 patchCov /= (numPixels - 1.0);
57 for (
unsigned int i = 0;i < ndim;++i)
58 for (
unsigned int j = i+1;j < ndim;++j)
59 patchCov(j,i) = patchCov(i,j);
64 template <
class T1,
class T2,
unsigned int Dimension>
66 itk::Image<unsigned char, Dimension> *maskImage,
const itk::ImageRegion<Dimension> &averagingRegion,
67 int localNeighborhood)
71 typedef itk::VectorImage <T1, Dimension> VectorImageType;
72 typedef itk::ImageRegionConstIteratorWithIndex< VectorImageType > InIteratorType;
73 typedef itk::ImageRegionConstIterator < itk::Image<unsigned char, Dimension> > MaskRegionIteratorType;
75 typedef itk::ImageRegion<Dimension> ImageRegionType;
76 typedef typename VectorImageType::IndexType ImageIndexType;
77 typedef itk::VariableLengthVector <T2> VectorType;
79 ImageRegionType largestRegion = inputImage->GetLargestPossibleRegion();
81 MaskRegionIteratorType maskIterator (maskImage, averagingRegion);
82 InIteratorType dataIterator (inputImage, averagingRegion);
84 unsigned int ndim = inputImage->GetNumberOfComponentsPerPixel();
85 resVariance.set_size(ndim,ndim);
88 VectorType averageLocalSignal(ndim), diffSignal(ndim);
89 VectorType baseSignal(ndim);
90 ImageIndexType baseIndex;
92 unsigned int numEstimations = 0;
94 while (!maskIterator.IsAtEnd())
96 if (maskIterator.Get() == 0)
103 baseSignal = dataIterator.Get();
104 baseIndex = dataIterator.GetIndex();
105 averageLocalSignal = - baseSignal;
107 ImageRegionType diffRegion;
108 for (
unsigned int i = 0;i < Dimension;++i)
110 diffRegion.SetIndex(i,std::max(0,(
int)baseIndex[i] - localNeighborhood));
111 diffRegion.SetSize(i,std::min((
unsigned int)(largestRegion.GetSize()[i] - 1),(
unsigned int)(baseIndex[i] + localNeighborhood)) - diffRegion.GetIndex(i) + 1);
114 unsigned int numLocalPixels = diffRegion.GetSize()[0];
115 for (
unsigned int i = 1;i < Dimension;++i)
116 numLocalPixels *= diffRegion.GetSize()[i];
118 InIteratorType localIterator(inputImage,diffRegion);
120 while (!localIterator.IsAtEnd())
122 averageLocalSignal += localIterator.Get();
126 averageLocalSignal /= numLocalPixels;
127 diffSignal = sqrt(numLocalPixels / (numLocalPixels + 1.0)) * (baseSignal - averageLocalSignal);
129 for (
unsigned int i = 0;i < ndim;++i)
130 for (
unsigned int j = i;j < ndim;++j)
132 double tmpVal = diffSignal[i] * diffSignal[j];
133 resVariance(i,j) += tmpVal;
135 resVariance(j,i) += tmpVal;
144 resVariance /= numEstimations;
150 unsigned int ndim = logRefPatchCov.rows();
152 vnl_matrix <double> eVec(ndim,ndim);
153 vnl_diag_matrix <double> eVals(ndim);
154 itk::SymmetricEigenAnalysis <vnl_matrix <T>, vnl_diag_matrix <double>, vnl_matrix <double> > EigenAnalysis(ndim);
156 EigenAnalysis.ComputeEigenValuesAndVectors(movingPatchCov, eVals, eVec);
158 for (
unsigned int i = 0;i < ndim;++i)
159 eVals[i] = log(eVals[i]);
161 vnl_matrix <double> logMoving = eVec.transpose() * eVals * eVec;
164 for (
unsigned int i = 0;i < ndim;++i)
165 for (
unsigned int j = i;j < ndim;++j)
168 varsDist += (logRefPatchCov(i,j) - logMoving(i,j)) * (logRefPatchCov(i,j) - logMoving(i,j));
170 varsDist += 2.0 * (logRefPatchCov(i,j) - logMoving(i,j)) * (logRefPatchCov(i,j) - logMoving(i,j));
173 varsDist = std::sqrt(varsDist);
179 double VectorMeansTest(itk::VariableLengthVector <T> &refPatchMean, itk::VariableLengthVector <T> &movingPatchMean,
180 const unsigned int &refPatchNumElts,
const unsigned int &movingPatchNumElts,
181 vnl_matrix <T> &refPatchCov, vnl_matrix <T> &movingPatchCov)
184 unsigned int ndim = refPatchMean.GetNumberOfElements();
186 itk::VariableLengthVector <T> meansDiff;
188 vnl_matrix <double> S_pooled(ndim,ndim), S_pooled_inv(ndim,ndim);
190 S_pooled = refPatchCov * refPatchNumElts + movingPatchCov * movingPatchNumElts;
191 S_pooled /= (refPatchNumElts + movingPatchNumElts - 2.0);
193 vnl_matrix_inverse <double> spoolInverter(S_pooled);
194 S_pooled_inv = spoolInverter.inverse();
196 meansDiff = refPatchMean - movingPatchMean;
197 double distMeans = 0;
199 for (
unsigned int j = 0;j < ndim;++j)
200 for (
unsigned int k = j;k < ndim;++k)
203 distMeans += 2.0 * S_pooled_inv(j,k) * meansDiff[j] * meansDiff[k];
205 distMeans += S_pooled_inv(j,k) * meansDiff[j] * meansDiff[k];
208 distMeans = std::sqrt(distMeans);
unsigned int computePatchMeanAndCovariance(const itk::VectorImage< T1, Dimension > *inputImage, const itk::ImageRegion< Dimension > &patchRegion, itk::VariableLengthVector< T2 > &patchMean, vnl_matrix< T2 > &patchCov)
Computes the average and covariance matrix from a patch of a vector image.
double VectorCovarianceTest(vnl_matrix< T > &logRefPatchCov, vnl_matrix< T > &movingPatchCov)
Test if covariance matrices are different (returns distance)
double VectorMeansTest(itk::VariableLengthVector< T > &refPatchMean, itk::VariableLengthVector< T > &movingPatchMean, const unsigned int &refPatchNumElts, const unsigned int &movingPatchNumElts, vnl_matrix< T > &refPatchCov, vnl_matrix< T > &movingPatchCov)
Test if vector means are different (returns distance)
void computeAverageLocalCovariance(vnl_matrix< T2 > &resVariance, itk::VectorImage< T1, Dimension > *inputImage, itk::Image< unsigned char, Dimension > *maskImage, const itk::ImageRegion< Dimension > &averagingRegion, int localNeighborhood)
Noise estimation for a patch of a vector image.