Orfeo Toolbox  3.16
itkDisplacementFieldJacobianDeterminantFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkDisplacementFieldJacobianDeterminantFilter.txx,v $
5  Language: C++
6  Date: $Date: 2008-12-07 17:07:52 $
7  Version: $Revision: 1.5 $
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 __itkDisplacementFieldJacobianDeterminantFilter_txx
18 #define __itkDisplacementFieldJacobianDeterminantFilter_txx
19 
21 
23 #include "itkImageRegionIterator.h"
25 #include "itkProgressReporter.h"
27 
28 #include "vnl/vnl_math.h"
29 
30 namespace itk
31 {
32 
33 template <typename TInputImage, typename TRealType, typename TOutputImage>
36 {
37  m_UseImageSpacing = false;
38  m_RequestedNumberOfThreads = this->GetNumberOfThreads();
39  for (unsigned int i = 0; i < ImageDimension; i++)
40  {
41  m_NeighborhoodRadius[i] = 1; // radius of neighborhood we will use
42  m_DerivativeWeights[i] = static_cast<TRealType>(1.0);
43  m_HalfDerivativeWeights[i] = static_cast<TRealType>(0.5);
44  }
45 }
46 template <typename TInputImage, typename TRealType, typename TOutputImage>
47 void
49 ::SetDerivativeWeights(TRealType data[])
50 {
51  m_UseImageSpacing = false;
52 
53  for (unsigned int i = 0; i < ImageDimension; ++i)
54  {
55  if (m_DerivativeWeights[i] != data[i])
56  {
57  this->Modified();
58  m_DerivativeWeights[i] = data[i];
59  m_HalfDerivativeWeights[i] = 0.5*data[i];
60  }
61  }
62 }
63 
64 template <typename TInputImage, typename TRealType, typename TOutputImage>
65 void
68 {
69  if (m_UseImageSpacing == f)
70  {
71  return;
72  }
73 
74  // Only reset the weights if they were previously set to the image spacing,
75  // otherwise, the user may have provided their own weightings.
76  if (f == false && m_UseImageSpacing == true)
77  {
78  for (unsigned int i = 0; i < ImageDimension; ++i)
79  {
80  m_DerivativeWeights[i] = static_cast<TRealType>(1.0);
81  m_HalfDerivativeWeights[i] = static_cast<TRealType>(0.5);
82  }
83  }
84 
85  m_UseImageSpacing = f;
86  this->Modified();
87 }
88 
89 template <typename TInputImage, typename TRealType, typename TOutputImage>
90 void
93 {
94  // call the superclass' implementation of this method
95  Superclass::GenerateInputRequestedRegion();
96 
97  // get pointers to the input and output
98  InputImagePointer inputPtr =
99  const_cast< InputImageType * >( this->GetInput());
100  OutputImagePointer outputPtr = this->GetOutput();
101 
102  if ( !inputPtr || !outputPtr )
103  {
104  return;
105  }
106 
107  // get a copy of the input requested region (should equal the output
108  // requested region)
109  typename TInputImage::RegionType inputRequestedRegion;
110  inputRequestedRegion = inputPtr->GetRequestedRegion();
111 
112  // pad the input requested region by the operator radius
113  inputRequestedRegion.PadByRadius( m_NeighborhoodRadius );
114 
115  // crop the input requested region at the input's largest possible region
116  if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
117  {
118  inputPtr->SetRequestedRegion( inputRequestedRegion );
119  return;
120  }
121  else
122  {
123  // Couldn't crop the region (requested region is outside the largest
124  // possible region). Throw an exception.
125 
126  // store what we tried to request (prior to trying to crop)
127  inputPtr->SetRequestedRegion( inputRequestedRegion );
128 
129  // build an exception
130  InvalidRequestedRegionError e(__FILE__, __LINE__);
131  e.SetLocation(ITK_LOCATION);
132  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
133  e.SetDataObject(inputPtr);
134  throw e;
135  }
136 }
137 
138 template< typename TInputImage, typename TRealType, typename TOutputImage >
139 void
142 {
143  Superclass::BeforeThreadedGenerateData();
144 
145  // Set the weights on the derivatives.
146  // Are we using image spacing in the calculations? If so we must update now
147  // in case our input image has changed.
148  if (m_UseImageSpacing == true)
149  {
150 
151  for (unsigned int i = 0; i < ImageDimension; i++)
152  {
153  if (static_cast<TRealType>(this->GetInput()->GetSpacing()[i]) == 0.0)
154  {
155  itkExceptionMacro(<< "Image spacing in dimension " << i << " is zero.");
156  }
157  m_DerivativeWeights[i]
158  = static_cast<TRealType>( 1.0 /
159  static_cast<TRealType>(this->GetInput()->GetSpacing()[i]) );
160  m_HalfDerivativeWeights[i]=0.5*m_DerivativeWeights[i];
161  }
162  }
163 
167  if ( typeid( typename InputImageType::PixelType ) != typeid( RealVectorType ) )
168  {
171  caster->SetInput(this->GetInput());
172  caster->Update();
173  m_RealValuedInputImage = caster->GetOutput();
174  }
175  else
176  {
177  m_RealValuedInputImage
178  = dynamic_cast<const ImageBase<ImageDimension> *>(this->GetInput());
179  }
180 
181 }
182 
183 template< typename TInputImage, typename TRealType, typename TOutputImage >
184 void
186 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
187  int threadId)
188 {
189 
193 
194  // Find the data-set boundary "faces"
196  FaceListType faceList;
198  faceList = bC(dynamic_cast<const RealVectorImageType *>(m_RealValuedInputImage.GetPointer()),
199  outputRegionForThread, m_NeighborhoodRadius);
200 
202  FaceListType::iterator fit;
203  fit = faceList.begin();
204 
205  // Support progress methods/callbacks
206  ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
207 
208  // Process each of the data set faces. The iterator is reinitialized on each
209  // face so that it can determine whether or not to check for boundary
210  // conditions.
211  for (fit=faceList.begin(); fit != faceList.end(); ++fit)
212  {
213  bit = ConstNeighborhoodIteratorType(m_NeighborhoodRadius,
214  dynamic_cast<const RealVectorImageType *>(m_RealValuedInputImage.GetPointer()),
215  *fit);
216  it = ImageRegionIterator<TOutputImage>(this->GetOutput(), *fit);
217  bit.OverrideBoundaryCondition(&nbc);
218  bit.GoToBegin();
219 
220  while ( ! bit.IsAtEnd() )
221  {
222  it.Set( static_cast<OutputPixelType>( this->EvaluateAtNeighborhood(bit) ) );
223  ++bit;
224  ++it;
225  progress.CompletedPixel();
226  }
227  }
228 }
229 
230 template <typename TInputImage, typename TRealType, typename TOutputImage>
231 TRealType
234 {
235  vnl_matrix_fixed<TRealType,ImageDimension,VectorDimension> J;
236  for (unsigned int i = 0; i < ImageDimension; ++i)
237  {
238  for (unsigned int j = 0; j < VectorDimension; ++j)
239  {
240  J[i][j] = m_HalfDerivativeWeights[i] * (it.GetNext(i)[j] - it.GetPrevious(i)[j]);
241  }
242  // add one on the diagonal to consider the warping and not only the deformation field
243  J[i][i] += 1.0;
244  }
245  return vnl_det(J);
246 }
247 
248 template <typename TInputImage, typename TRealType, typename TOutputImage>
249 void
251 ::PrintSelf(std::ostream& os, Indent indent) const
252 {
253  unsigned int i;
254  Superclass::PrintSelf(os,indent);
255  os << indent << "m_UseImageSpacing = " << m_UseImageSpacing
256  << std::endl;
257  os << indent << "m_RequestedNumberOfThreads = " << m_RequestedNumberOfThreads
258  << std::endl;
259  os << indent << "m_DerivativeWeights = ";
260  for (i = 0; i < ImageDimension; i++)
261  { os << m_DerivativeWeights[i] << " "; }
262  os << std::endl;
263  os << indent << "m_HalfDerivativeWeights = ";
264  for (i = 0; i < ImageDimension; i++)
265  { os << m_HalfDerivativeWeights[i] << " "; }
266  os << std::endl;
267  os << indent << "m_NeighborhoodRadius = " << m_NeighborhoodRadius
268  << std::endl;
269  os << indent << "m_RealValuedInputImage = " << m_RealValuedInputImage.GetPointer()
270  << std::endl;
271 }
272 
273 } // end namespace itk
274 
275 #endif

Generated at Sat Feb 2 2013 23:35:42 for Orfeo Toolbox with doxygen 1.8.1.1