forked from InsightSoftwareConsortium/ITK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
itkMutualInformationImageToImageMetric.h
246 lines (204 loc) · 10.2 KB
/
itkMutualInformationImageToImageMetric.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: itkMutualInformationImageToImageMetric.h
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef __itkMutualInformationImageToImageMetric_h
#define __itkMutualInformationImageToImageMetric_h
#include "itkImageToImageMetric.h"
#include "itkCovariantVector.h"
#include "itkPoint.h"
#include "itkIndex.h"
#include "itkKernelFunction.h"
#include "itkCentralDifferenceImageFunction.h"
namespace itk
{
/** \class MutualInformationImageToImageMetric
* \brief Computes the mutual information between two images to be registered
*
* MutualInformationImageToImageMetric computes the mutual information
* between a fixed and moving image to be registered.
*
* This class is templated over the FixedImage type and the MovingImage type.
*
* The fixed and moving images are set via methods SetFixedImage() and
* SetMovingImage(). This metric makes use of user specified Transform and
* Interpolator. The Transform is used to map points from the fixed image to
* the moving image domain. The Interpolator is used to evaluate the image
* intensity at user specified geometric points in the moving image.
* The Transform and Interpolator are set via methods SetTransform() and
* SetInterpolator().
*
* \warning This metric assumes that the moving image has already been
* connected to the interpolator outside of this class.
*
* The method GetValue() computes of the mutual information
* while method GetValueAndDerivative() computes
* both the mutual information and its derivatives with respect to the
* transform parameters.
*
* The calculations are based on the method of Viola and Wells
* where the probability density distributions are estimated using
* Parzen windows.
*
* By default a Gaussian kernel is used in the density estimation.
* Other option include Cauchy and spline-based. A user can specify
* the kernel passing in a pointer a KernelFunction using the
* SetKernelFunction() method.
*
* Mutual information is estimated using two sample sets: one to calculate
* the singular and joint pdf's and one to calculate the entropy
* integral. By default 50 samples points are used in each set.
* Other values can be set via the SetNumberOfSpatialSamples() method.
*
* Quality of the density estimate depends on the choice of the
* kernel's standard deviation. Optimal choice will depend on the images.
* It is can be shown that around the optimal variance, the mutual
* information estimate is relatively insensitive to small changes
* of the standard deviation. In our experiments, we have found that a
* standard deviation of 0.4 works well for images normalized to have a mean
* of zero and standard deviation of 1.0.
* The variance can be set via methods SetFixedImageStandardDeviation()
* and SetMovingImageStandardDeviation().
*
* Implementaton of this class is based on:
* Viola, P. and Wells III, W. (1997).
* "Alignment by Maximization of Mutual Information"
* International Journal of Computer Vision, 24(2):137-154
*
* \sa KernelFunction
* \sa GaussianKernelFunction
*
* \ingroup RegistrationMetrics
*/
template <class TFixedImage,class TMovingImage >
class ITK_EXPORT MutualInformationImageToImageMetric :
public ImageToImageMetric< TFixedImage, TMovingImage >
{
public:
/** Standard class typedefs. */
typedef MutualInformationImageToImageMetric Self;
typedef ImageToImageMetric< TFixedImage, TMovingImage > Superclass;
typedef SmartPointer<Self> Pointer;
typedef SmartPointer<const Self> ConstPointer;
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(MutualInformationImageToImageMetric, ImageToImageMetric);
/** Types inherited from Superclass. */
typedef typename Superclass::TransformType TransformType;
typedef typename Superclass::TransformPointer TransformPointer;
typedef typename Superclass::TransformJacobianType TransformJacobianType;
typedef typename Superclass::InterpolatorType InterpolatorType;
typedef typename Superclass::MeasureType MeasureType;
typedef typename Superclass::DerivativeType DerivativeType;
typedef typename Superclass::ParametersType ParametersType;
typedef typename Superclass::FixedImageType FixedImageType;
typedef typename Superclass::MovingImageType MovingImageType;
typedef typename Superclass::FixedImageConstPointer FixedImageConstPointer;
typedef typename Superclass::MovingImageConstPointer MovingImageCosntPointer;
/** Index and Point typedef support. */
typedef typename FixedImageType::IndexType FixedImageIndexType;
typedef typename FixedImageIndexType::IndexValueType FixedImageIndexValueType;
typedef typename MovingImageType::IndexType MovingImageIndexType;
typedef typename TransformType::InputPointType FixedImagePointType;
typedef typename TransformType::OutputPointType MovingImagePointType;
/** Enum of the moving image dimension. */
itkStaticConstMacro(MovingImageDimension, unsigned int,
MovingImageType::ImageDimension);
/** Get the derivatives of the match measure. */
void GetDerivative(
const ParametersType& parameters,
DerivativeType & Derivative ) const;
/** Get the value. */
MeasureType GetValue( const ParametersType& parameters ) const;
/** Get the value and derivatives for single valued optimizers. */
void GetValueAndDerivative( const ParametersType& parameters,
MeasureType& Value, DerivativeType& Derivative ) const;
/** Set the number of spatial samples. This is the number of image
* samples used to calculate the joint probability distribution.
* The number of spatial samples is clamped to be a minimum of 1.
* Default value is 50. */
void SetNumberOfSpatialSamples( unsigned int num );
/** Get the number of spatial samples. */
itkGetConstReferenceMacro( NumberOfSpatialSamples, unsigned int );
/** Set/Get the moving image intensitiy standard deviation. This defines
* the kernel bandwidth used in the joint probability distribution
* calculation. Default value is 0.4 which works well for image intensities
* normalized to a mean of 0 and standard deviation of 1.0.
* Value is clamped to be always greater than zero. */
itkSetClampMacro( MovingImageStandardDeviation, double,
NumericTraits<double>::NonpositiveMin(), NumericTraits<double>::max() );
itkGetConstReferenceMacro( MovingImageStandardDeviation, double );
/** Set/Get the fixed image intensitiy standard deviation. This defines
* the kernel bandwidth used in the joint probability distribution
* calculation. Default value is 0.4 which works well for image intensities
* normalized to a mean of 0 and standard deviation of 1.0.
* Value is clamped to be always greater than zero. */
itkSetClampMacro( FixedImageStandardDeviation, double,
NumericTraits<double>::NonpositiveMin(), NumericTraits<double>::max() );
itkGetMacro( FixedImageStandardDeviation, double );
/** Set/Get the kernel function. This is used to calculate the joint
* probability distribution. Default is the GaussianKernelFunction. */
itkSetObjectMacro( KernelFunction, KernelFunction );
itkGetObjectMacro( KernelFunction, KernelFunction );
void ReinitializeSeed();
void ReinitializeSeed(int);
protected:
MutualInformationImageToImageMetric();
virtual ~MutualInformationImageToImageMetric() {};
void PrintSelf(std::ostream& os, Indent indent) const;
private:
MutualInformationImageToImageMetric(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
/** A spatial sample consists of the fixed domain point, the fixed image value
* at that point, and the corresponding moving image value. */
class SpatialSample
{
public:
SpatialSample():FixedImageValue(0.0),MovingImageValue(0.0)
{ FixedImagePointValue.Fill( 0.0 ); }
~SpatialSample(){};
FixedImagePointType FixedImagePointValue;
double FixedImageValue;
double MovingImageValue;
};
/** SpatialSampleContainer typedef support. */
typedef std::vector<SpatialSample> SpatialSampleContainer;
/** Container to store sample set A - used to approximate the probability
* density function (pdf). */
mutable SpatialSampleContainer m_SampleA;
/** Container to store sample set B - used to approximate the mutual
* information value. */
mutable SpatialSampleContainer m_SampleB;
unsigned int m_NumberOfSpatialSamples;
double m_MovingImageStandardDeviation;
double m_FixedImageStandardDeviation;
typename KernelFunction::Pointer m_KernelFunction;
double m_MinProbability;
/** Uniformly select samples from the fixed image buffer. */
void SampleFixedImageDomain( SpatialSampleContainer& samples ) const;
/**
* Calculate the intensity derivatives at a point
*/
void CalculateDerivatives( const FixedImagePointType& , DerivativeType& ) const;
typedef typename Superclass::CoordinateRepresentationType
CoordinateRepresentationType;
typedef CentralDifferenceImageFunction< MovingImageType,
CoordinateRepresentationType > DerivativeFunctionType;
typename DerivativeFunctionType::Pointer m_DerivativeCalculator;
bool m_ReseedIterator;
int m_RandomSeed;
};
} // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkMutualInformationImageToImageMetric.txx"
#endif
#endif