OTB  6.1.0
Orfeo Toolbox
otbNCCRegistrationFilter.txx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbNCCRegistrationFilter_txx
22 #define otbNCCRegistrationFilter_txx
24 
25 namespace otb
26 {
27 
28 /*
29  * Default constructor
30  */
31 template <class TFixedImage, class TMovingImage, class TDisplacementField>
34 {
35 
37  drfp = NCCRegistrationFunctionType::New();
38 
39  drfp->SetDisplacementField(this->GetDisplacementField());
40 
41  this->SetDifferenceFunction(static_cast<FiniteDifferenceFunctionType *>(
42  drfp.GetPointer()));
43 
44 }
45 
46 template <class TFixedImage, class TMovingImage, class TDisplacementField>
47 void
49 ::PrintSelf(std::ostream& os, itk::Indent indent) const
50 {
51  Superclass::PrintSelf(os, indent);
52  os << indent << "NCC Radius: " <<
53  this->GetNCCRadius() << std::endl;
54 }
55 
56 /*
57  * Set the function state values before each iteration
58  */
59 template <class TFixedImage, class TMovingImage, class TDisplacementField>
60 void
63 {
64 
65  // call the superclass implementation
66  Superclass::InitializeIteration();
67 
68  // set the gradient selection flag
70  dynamic_cast<NCCRegistrationFunctionType *>
71  (this->GetDifferenceFunction().GetPointer());
72 
73  if (!drfp)
74  {
75  itkExceptionMacro(<<
76  "Could not cast difference function to NCCRegistrationFunction");
77  }
78 
79  /*
80  * Smooth the displacement field
81 
82  if ( this->GetSmoothDisplacementField() )
83  {
84  this->SmoothDisplacementField();
85  }
86  */
87 }
88 
89 /*
90  * Get the metric value from the difference function
91  */
92 template <class TFixedImage, class TMovingImage, class TDisplacementField>
93 double
95 ::GetMetric() const
96 {
97 
99  dynamic_cast<NCCRegistrationFunctionType *>
100  (this->GetDifferenceFunction().GetPointer());
101 
102  if (!drfp)
103  {
104  itkExceptionMacro(<<
105  "Could not cast difference function to NCCRegistrationFunction");
106  }
107 
108  return drfp->GetEnergy();
109 
110 }
111 
112 /*
113  *
114  */
115 template <class TFixedImage, class TMovingImage, class TDisplacementField>
119 {
120 
122  dynamic_cast<NCCRegistrationFunctionType *>
123  (this->GetDifferenceFunction().GetPointer());
124 
125  if (!drfp)
126  {
127  itkExceptionMacro(<<
128  "Could not cast difference function to NCCRegistrationFunction");
129  }
130 
131  return drfp->GetRadius();
132 
133 }
134 
135 /*
136  *
137  */
138 template <class TFixedImage, class TMovingImage, class TDisplacementField>
139 void
142 {
143 
145  dynamic_cast<NCCRegistrationFunctionType *>
146  (this->GetDifferenceFunction().GetPointer());
147 
148  if (!drfp)
149  {
150  itkExceptionMacro(<<
151  "Could not cast difference function to NCCRegistrationFunction");
152  }
153 
154  drfp->SetRadius(radius);
155 
156  this->Modified();
157 }
158 
159 template <class TFixedImage, class TMovingImage, class TDisplacementField>
160 void
163 {
164  // get pointers to the input and output
165  typename Superclass::FixedImagePointer fixedPtr =
166  const_cast<TFixedImage *>(this->GetFixedImage());
167  typename Superclass::MovingImagePointer movingPtr =
168  const_cast<TMovingImage *>(this->GetMovingImage());
169  typename TDisplacementField::Pointer outputPtr = this->GetOutput();
170 
171  if (!fixedPtr || !movingPtr || !outputPtr)
172  {
173  return;
174  }
175 
176  // get a copy of the input requested region (should equal the output
177  // requested region)
178  typename TDisplacementField::RegionType requestedRegion;
179  requestedRegion = outputPtr->GetRequestedRegion();
180 
181  // pad the input requested region by the operator radius
182  requestedRegion.PadByRadius(this->GetNCCRadius());
183 
184  // crop the input requested region at the input's largest possible region
185  if (requestedRegion.Crop(fixedPtr->GetLargestPossibleRegion()))
186  {
187  if (requestedRegion.Crop(movingPtr->GetLargestPossibleRegion()))
188  {
189  fixedPtr->SetRequestedRegion(requestedRegion);
190  movingPtr->SetRequestedRegion(requestedRegion);
191  return;
192  }
193  else
194  {
195  // Couldn't crop the region (requested region is outside the largest
196  // possible region). Throw an exception.
197 
198  // store what we tried to request (prior to trying to crop)
199  movingPtr->SetRequestedRegion(requestedRegion);
200 
201  // build an exception
202  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
203  e.SetLocation(ITK_LOCATION);
204  e.SetDescription(
205  "Requested region is (at least partially) outside the largest possible region of the moving image.");
206  e.SetDataObject(movingPtr);
207  throw e;
208 
209  }
210  }
211  else
212  {
213  // Couldn't crop the region (requested region is outside the largest
214  // possible region). Throw an exception.
215 
216  // store what we tried to request (prior to trying to crop)
217  fixedPtr->SetRequestedRegion(requestedRegion);
218 
219  // build an exception
220  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
221  e.SetLocation(ITK_LOCATION);
222  e.SetDescription("Requested region is (at least partially) outside the largest possible region of the fixed image.");
223  e.SetDataObject(fixedPtr);
224  throw e;
225  }
226 }
227 
228 /*
229  * Get the metric value from the difference function
230  */
231 template <class TFixedImage, class TMovingImage, class TDisplacementField>
232 void
235 {
236  // If we smooth the update buffer before applying it, then the are
237  // approximating a viscuous problem as opposed to an elastic problem
238  /* if ( this->GetSmoothUpdateField() )
239  {
240  this->SmoothUpdateField();
241  }
242  */
243  this->Superclass::ApplyUpdate(dt);
244 
246  dynamic_cast<NCCRegistrationFunctionType *>
247  (this->GetDifferenceFunction().GetPointer());
248 
249  if (!drfp)
250  {
251  itkExceptionMacro(<<
252  "Could not cast difference function to NCCRegistrationFunction");
253  }
254 
255 // this->SetRMSChange( drfp->GetRMSChange() );
256 
257 }
258 
259 } // end namespace otb
260 
261 #endif
void SetDataObject(DataObject *dobj)
virtual void SetDescription(const std::string &s)
virtual void SetNCCRadius(RadiusType radius)
virtual void SetLocation(const std::string &s)
void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE
ObjectType * GetPointer() const
NCCRegistrationFunctionType::RadiusType RadiusType
const RadiusType & GetRadius() const
FiniteDifferenceFunctionType::RadiusType RadiusType
virtual RadiusType GetNCCRadius() const
void SetRadius(const RadiusType &r)
virtual void ApplyUpdate(TimeStepType dt)
FiniteDifferenceFunctionType::TimeStepType TimeStepType
void GenerateInputRequestedRegion() ITK_OVERRIDE