Orfeo Toolbox  3.16
itkWarpHarmonicEnergyCalculator.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkWarpHarmonicEnergyCalculator.txx,v $
5  Language: C++
6  Date: $Date: 2008-07-05 18:44:01 $
7  Version: $Revision: 1.2 $
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 __itkWarpHarmonicEnergyCalculator_txx
18 #define __itkWarpHarmonicEnergyCalculator_txx
19 
22 #include "itkImageRegionIterator.h"
24 
25 #include "vnl/vnl_matrix.h"
26 #include "vnl/vnl_math.h"
27 
28 namespace itk
29 {
30 
34 template<class TInputImage>
37 {
38  m_Image = TInputImage::New();
39  m_HarmonicEnergy = 0.0;
40  m_RegionSetByUser = false;
41  unsigned int i;
42  m_UseImageSpacing = true;
43  for (i = 0; i < ImageDimension; i++)
44  {
45  m_NeighborhoodRadius[i] = 1; // radius of neighborhood we will use
46  m_DerivativeWeights[i] = 1.0;
47  }
48 }
49 
50 template <class TInputImage>
51 void
53 ::SetDerivativeWeights(double data[])
54 {
55  m_UseImageSpacing = false;
56 
57  for (unsigned int i = 0; i < ImageDimension; ++i)
58  {
59  if (m_DerivativeWeights[i] != data[i])
60  {
61  this->Modified();
62  m_DerivativeWeights[i] = data[i];
63  }
64  }
65 }
66 
67 template <class TInputImage>
68 void
71 {
72  if (m_UseImageSpacing == f)
73  {
74  return;
75  }
76 
77  // Only reset the weights if they were previously set to the image spacing,
78  // otherwise, the user may have provided their own weightings.
79  if (f == false && m_UseImageSpacing == true)
80  {
81  for (unsigned int i = 0; i < ImageDimension; ++i)
82  {
83  m_DerivativeWeights[i] = 1.0;
84  }
85  }
86 
87  m_UseImageSpacing = f;
88 }
89 
90 
91 /*
92  * Compute
93  */
94 template<class TInputImage>
95 void
97 ::Compute(void)
98 {
99  if( !m_RegionSetByUser )
100  {
101  m_Region = m_Image->GetRequestedRegion();
102  }
103 
104  // Set the weights on the derivatives.
105  // Are we using image spacing in the calculations? If so we must update now
106  // in case our input image has changed.
107  if (m_UseImageSpacing == true)
108  {
109 
110  for (unsigned int i = 0; i < ImageDimension; i++)
111  {
112  if (m_Image->GetSpacing()[i] <= 0.0)
113  {
114  itkExceptionMacro(<< "Image spacing in dimension " << i << " is zero.");
115  }
116  m_DerivativeWeights[i] = 1.0 / static_cast<double>(m_Image->GetSpacing()[i]);
117  }
118  }
119 
120  m_HarmonicEnergy = 0.0;
121 
124 
125  // Find the data-set boundary "faces"
127  FaceListType faceList;
129  faceList = bC(m_Image, m_Region, m_NeighborhoodRadius);
130 
132  FaceListType::iterator fit;
133  fit = faceList.begin();
134 
135  // Process each of the data set faces. The iterator is reinitialized on each
136  // face so that it can determine whether or not to check for boundary
137  // conditions.
138  for (fit=faceList.begin(); fit != faceList.end(); ++fit)
139  {
140  bit = ConstNeighborhoodIteratorType(m_NeighborhoodRadius,
141  m_Image,
142  *fit);
143  bit.OverrideBoundaryCondition(&nbc);
144  bit.GoToBegin();
145 
146  while ( ! bit.IsAtEnd() )
147  {
148  m_HarmonicEnergy += this->EvaluateAtNeighborhood(bit);
149  ++bit;
150  }
151  }
152 
153  m_HarmonicEnergy /= m_Region.GetNumberOfPixels();
154 }
155 
156 
157 template <class TInputImage>
158 double
161 {
162  // Simple method using field derivatives
163 
164  unsigned int i, j;
165  vnl_matrix_fixed<double,ImageDimension,VectorDimension> J;
166 
167  PixelType next, prev;
168 
169  double weight;
170 
171  for (i = 0; i < ImageDimension; ++i)
172  {
173  next = it.GetNext(i);
174  prev = it.GetPrevious(i);
175 
176  weight = 0.5*m_DerivativeWeights[i];
177 
178  for (j = 0; j < VectorDimension; ++j)
179  {
180  J[i][j]=weight*(static_cast<double>(next[j])-static_cast<double>(prev[j]));
181  }
182 
183  // add one on the diagonal to consider the warping and not only the deformation field
184  //J[i][i] += 1.0;
185  }
186 
187  const double norm = J.fro_norm();
188  return norm*norm;
189 }
190 
191 
192 template<class TInputImage>
193 void
195 ::SetRegion( const RegionType & region )
196 {
197  m_Region = region;
198  m_RegionSetByUser = true;
199 }
200 
201 
202 template<class TInputImage>
203 void
205 ::PrintSelf( std::ostream& os, Indent indent ) const
206 {
207  Superclass::PrintSelf(os,indent);
208 
209  os << indent << "HarmonicEnergy: "<<m_HarmonicEnergy<< std::endl;
210  os << indent << "Image: " << std::endl;
211  m_Image->Print(os, indent.GetNextIndent());
212  os << indent << "Region: " << std::endl;
213  m_Region.Print(os,indent.GetNextIndent());
214  os << indent << "Region set by User: " << m_RegionSetByUser << std::endl;
215  os << indent << "Use image spacing: " << this->m_UseImageSpacing << std::endl;
216  os << indent << "Derivative Weights: " << this->m_DerivativeWeights << std::endl;
217  os << indent << "Neighborhood Radius: " << this->m_NeighborhoodRadius << std::endl;
218 }
219 
220 } // end namespace itk
221 
222 #endif

Generated at Sun Feb 3 2013 00:14:20 for Orfeo Toolbox with doxygen 1.8.1.1