Orfeo Toolbox  3.16
itkHistogramImageToImageMetric.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkHistogramImageToImageMetric.txx,v $
5  Language: C++
6  Date: $Date: 2009-05-05 17:47:30 $
7  Version: $Revision: 1.30 $
8 
9  Copyright (c) Insight Software Consortium. All rights reserved.
10  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11 
12  This software is distributed WITHOUT ANY WARRANTY; without even
13  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  PURPOSE. See the above copyright notices for more information.
15 
16 =========================================================================*/
17 #ifndef __itkHistogramImageToImageMetric_txx
18 #define __itkHistogramImageToImageMetric_txx
19 
20 #include "itkArray.h"
22 #include "itkNumericTraits.h"
25 
26 namespace itk
27 {
28 template <class TFixedImage, class TMovingImage>
31 {
32  itkDebugMacro("Constructor");
33 
34  m_HistogramSize.Fill(256);
35  m_UsePaddingValue = false;
36  m_DerivativeStepLength = 0.1;
37  m_DerivativeStepLengthScales.Fill(1);
38  m_UpperBoundIncreaseFactor = 0.001;
40  m_Histogram = HistogramType::New();
41 #ifdef ITK_USE_REVIEW_STATISTICS
42  m_Histogram->SetMeasurementVectorSize(2);
43 #endif
44  m_LowerBoundSetByUser = false;
45  m_UpperBoundSetByUser = false;
46 }
47 
48 
49 template <class TFixedImage, class TMovingImage>
52 {
53  m_UpperBound = bounds;
54  m_UpperBoundSetByUser = true;
55  this->Modified();
56 }
57 
58 
59 template <class TFixedImage, class TMovingImage>
62 {
63  m_LowerBound = bounds;
64  m_LowerBoundSetByUser = true;
65  this->Modified();
66 }
67 
68 template <class TFixedImage, class TMovingImage>
71 {
72  Superclass::Initialize();
73 
74  if (!this->m_FixedImage)
75  {
76  itkExceptionMacro(<<"Fixed image has not been set.");
77  }
78  else if (!this->m_MovingImage)
79  {
80  itkExceptionMacro(<<"Moving image has not been set.");
81  }
82 
83  if( !m_LowerBoundSetByUser || !m_UpperBoundSetByUser )
84  {
85  // Calculate min and max image values in fixed image.
86  FixedImageConstPointerType pFixedImage = this->m_FixedImage;
88  pFixedImage->
89  GetBufferedRegion());
90  fiIt.GoToBegin();
91  FixedImagePixelType minFixed = fiIt.Value();
92  FixedImagePixelType maxFixed = fiIt.Value();
93  ++fiIt;
94  while ( !fiIt.IsAtEnd() )
95  {
96  FixedImagePixelType value = fiIt.Value();
97 
98  if (value < minFixed)
99  {
100  minFixed = value;
101  }
102  else if (value > maxFixed)
103  {
104  maxFixed = value;
105  }
106 
107  ++fiIt;
108  }
109 
110  // Calculate min and max image values in moving image.
111  MovingImageConstPointerType pMovingImage = this->m_MovingImage;
113  pMovingImage->
114  GetBufferedRegion());
115  miIt.GoToBegin();
116  MovingImagePixelType minMoving = miIt.Value();
117  MovingImagePixelType maxMoving = miIt.Value();
118  ++miIt;
119  while ( !miIt.IsAtEnd() )
120  {
121  MovingImagePixelType value = miIt.Value();
122 
123  if (value < minMoving)
124  {
125  minMoving = value;
126  }
127  else if (value > maxMoving)
128  {
129  maxMoving = value;
130  }
131  ++miIt;
132  }
133 
134 
135  // Initialize the upper and lower bounds of the histogram.
136  if( !m_LowerBoundSetByUser )
137  {
138 #ifdef ITK_USE_REVIEW_STATISTICS
139  m_LowerBound.SetSize(2);
140 #endif
141  m_LowerBound[0] = minFixed;
142  m_LowerBound[1] = minMoving;
143  }
144 
145  if( !m_UpperBoundSetByUser )
146  {
147 #ifdef ITK_USE_REVIEW_STATISTICS
148  m_UpperBound.SetSize(2);
149 #endif
150  m_UpperBound[0] =
151  maxFixed + (maxFixed - minFixed ) * m_UpperBoundIncreaseFactor;
152  m_UpperBound[1] =
153  maxMoving + (maxMoving - minMoving ) * m_UpperBoundIncreaseFactor;
154  }
155 
156  }
157 
158 }
159 
160 template <class TFixedImage, class TMovingImage>
161 void
164 {
165  if(m_DerivativeStepLengthScales.GetSize()
166  != transform->GetNumberOfParameters())
167  {
168  m_DerivativeStepLengthScales.SetSize(transform->GetNumberOfParameters());
169  m_DerivativeStepLengthScales.Fill(1.0);
170  }
171  Superclass::SetTransform(transform);
172 }
173 
174 template <class TFixedImage, class TMovingImage>
177 ::GetValue(const TransformParametersType& parameters) const
178 {
179  itkDebugMacro("GetValue( " << parameters << " ) ");
180 
181  this->ComputeHistogram(parameters, *m_Histogram);
182 
183  return this->EvaluateMeasure(*m_Histogram);
184 }
185 
186 template <class TFixedImage, class TMovingImage>
187 void
190  DerivativeType& derivative) const
191 {
192  itkDebugMacro("GetDerivative( " << parameters << " ) ");
193 
194  const unsigned int ParametersDimension = this->GetNumberOfParameters();
195 
196  // Make sure the scales have been set
197  if (m_DerivativeStepLengthScales.size() != ParametersDimension)
198  {
199  itkExceptionMacro(<< "The size of DerivativesStepLengthScales is "
200  << m_DerivativeStepLengthScales.size()
201  << ", but the Number of Parameters is "
202  << ParametersDimension
203  << ".");
204  }
205 
206  // Calculate gradient.
207  derivative = DerivativeType(ParametersDimension);
208  derivative.Fill(NumericTraits<ITK_TYPENAME
210 
211  typename HistogramType::Pointer pHistogram = HistogramType::New();
212 #ifdef ITK_USE_REVIEW_STATISTICS
213  pHistogram->SetMeasurementVectorSize(2);
214 #endif
215  this->ComputeHistogram(parameters, *pHistogram);
216 
217  for (unsigned int i = 0; i < ParametersDimension; i++)
218  {
219  typename HistogramType::Pointer pHistogram2 = HistogramType::New();
220 #ifdef ITK_USE_REVIEW_STATISTICS
221  pHistogram2->SetMeasurementVectorSize(2);
222 #endif
223  this->CopyHistogram(*pHistogram2, *pHistogram);
224 
225  TransformParametersType newParameters = parameters;
226  newParameters[i] -=
227  m_DerivativeStepLength/m_DerivativeStepLengthScales[i];
228  this->ComputeHistogram(newParameters, *pHistogram2);
229 
230  MeasureType e0 = EvaluateMeasure(*pHistogram2);
231 
232  pHistogram2 = HistogramType::New();
233 #ifdef ITK_USE_REVIEW_STATISTICS
234  pHistogram2->SetMeasurementVectorSize(2);
235 #endif
236  this->CopyHistogram(*pHistogram2, *pHistogram);
237 
238  newParameters = parameters;
239  newParameters[i] +=
240  m_DerivativeStepLength/m_DerivativeStepLengthScales[i];
241  this->ComputeHistogram(newParameters, *pHistogram2);
242 
243  MeasureType e1 = EvaluateMeasure(*pHistogram2);
244 
245  derivative[i] =
246  (e1 - e0)/(2*m_DerivativeStepLength/m_DerivativeStepLengthScales[i]);
247  }
248 }
249 
250 template <class TFixedImage, class TMovingImage>
251 void
254  MeasureType& value,
255  DerivativeType& derivative) const
256 {
257  value = GetValue(parameters);
258  this->GetDerivative(parameters, derivative);
259 }
260 
261 template <class TFixedImage, class TMovingImage>
262 void
265  HistogramType& histogram) const
266 {
267  FixedImageConstPointerType fixedImage = this->m_FixedImage;
268 
269  if(!fixedImage)
270  {
271  itkExceptionMacro(<< "Fixed image has not been assigned");
272  }
273 
275  FixedIteratorType;
276 
277  typename FixedImageType::IndexType index;
278  typename FixedImageType::RegionType fixedRegion;
279 
280  fixedRegion = this->GetFixedImageRegion();
281  FixedIteratorType ti( fixedImage, fixedRegion );
282 
283  this->m_NumberOfPixelsCounted = 0;
284  this->SetTransformParameters( parameters );
285 
286  histogram.Initialize( m_HistogramSize, m_LowerBound, m_UpperBound );
287 
288  ti.GoToBegin();
289  while ( !ti.IsAtEnd() )
290  {
291  index = ti.GetIndex();
292 
293  if (fixedRegion.IsInside(index) &&
294  (!m_UsePaddingValue ||
295  (m_UsePaddingValue && ti.Get() > m_PaddingValue)))
296  {
297  InputPointType inputPoint;
298  fixedImage->TransformIndexToPhysicalPoint(index, inputPoint);
299 
300  if( this->m_FixedImageMask &&
301  !this->m_FixedImageMask->IsInside( inputPoint ) )
302  {
303  ++ti;
304  continue;
305  }
306 
307  OutputPointType transformedPoint =
308  this->m_Transform->TransformPoint(inputPoint);
309 
310  if( this->m_MovingImageMask &&
311  !this->m_MovingImageMask->IsInside( transformedPoint ) )
312  {
313  ++ti;
314  continue;
315  }
316 
317  if ( this->m_Interpolator->IsInsideBuffer(transformedPoint) )
318  {
319  const RealType movingValue =
320  this->m_Interpolator->Evaluate(transformedPoint);
321  const RealType fixedValue = ti.Get();
322  this->m_NumberOfPixelsCounted++;
323 
324  typename HistogramType::MeasurementVectorType sample;
325 #ifdef ITK_USE_REVIEW_STATISTICS
326  sample.SetSize(2);
327 #endif
328  sample[0] = fixedValue;
329  sample[1] = movingValue;
330  histogram.IncreaseFrequency(sample, 1);
331  }
332  }
333 
334  ++ti;
335  }
336 
337  itkDebugMacro("NumberOfPixelsCounted = " << this->m_NumberOfPixelsCounted );
338  if (this->m_NumberOfPixelsCounted == 0)
339  {
340  itkExceptionMacro(
341  << "All the points mapped to outside of the moving image");
342  }
343 }
344 
345 template <class TFixedImage, class TMovingImage>
346 void
349 {
350  // Initialize the target.
351  typename HistogramType::MeasurementVectorType min, max;
352 
353 #ifdef ITK_USE_REVIEW_STATISTICS
354  min.SetSize(2);
355  max.SetSize(2);
356 #endif
357 
358  typename HistogramType::SizeType size = source.GetSize();
359 
360  for (unsigned int i = 0; i < min.Size(); i++)
361  {
362  min[i] = source.GetBinMin(i, 0);
363  }
364 
365  for (unsigned int i = 0; i < max.Size(); i++)
366  {
367  max[i] = source.GetBinMax(i, size[i] - 1);
368  }
369 
370  target.Initialize(size, min, max);
371 
372  // Copy the values.
373  typename HistogramType::Iterator sourceIt = source.Begin();
374  typename HistogramType::Iterator sourceEnd = source.End();
375  typename HistogramType::Iterator targetIt = target.Begin();
376  typename HistogramType::Iterator targetEnd = target.End();
377 
378  while (sourceIt != sourceEnd && targetIt != targetEnd)
379  {
380 #ifdef ITK_USE_REVIEW_STATISTICS
381  typename HistogramType::AbsoluteFrequencyType
382 #else
384 #endif
385  freq = sourceIt.GetFrequency();
386 
387  if (freq > 0)
388  {
389  targetIt.SetFrequency(freq);
390  }
391 
392  ++sourceIt;
393  ++targetIt;
394  }
395 }
396 
397 template <class TFixedImage, class TMovingImage>
398 void
400 ::PrintSelf(std::ostream& os, Indent indent) const
401 {
402  Superclass::PrintSelf(os,indent);
403  os << indent << "Padding value: "
404  << static_cast<typename NumericTraits<FixedImagePixelType>::PrintType>(
405  m_PaddingValue)
406  << std::endl;
407  os << indent << "Use padding value?: " << m_UsePaddingValue << std::endl;
408  os << indent << "Derivative step length: " << m_DerivativeStepLength
409  << std::endl;
410  os << indent << "Derivative step length scales: ";
411  os << m_DerivativeStepLengthScales << std::endl;
412  os << indent << "Histogram size: ";
413  os << m_HistogramSize << std::endl;
414  os << indent << "Histogram upper bound increase factor: ";
415  os << m_UpperBoundIncreaseFactor << std::endl;
416  os << indent << "Histogram computed by GetValue(): ";
417  os << m_Histogram.GetPointer() << std::endl;
418 }
419 
420 } // end namespace itk
421 
422 #endif // itkHistogramImageToImageMetric_txx

Generated at Sat May 18 2013 23:42:34 for Orfeo Toolbox with doxygen 1.8.3.1