otbFineRegistrationImageFilter.h 9.7 KB
Newer Older
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
/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$


  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt 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 __otbFineRegistrationImageFilter_h
#define __otbFineRegistrationImageFilter_h

#include "itkImageToImageFilter.h"
#include "itkInterpolateImageFunction.h"
#include "itkContinuousIndex.h"

#include "itkTranslationTransform.h"
26
#include "itkImageToImageMetric.h"
27 28 29 30 31

namespace otb
{

/** \class FineRegistrationImageFilter
32
 * \brief Computes a displacement field between two images using a given metric.
33
 *
34 35 36
 * This filter tries to find at each location of the fixed image the corresponding best matching
 * patch of radius set by SetRadius() method in the moving image within a search windows whose radius
 * is defined by SetSearchRadius() method.
37
 *
38
 * To do so, it optimizes a metric set using the SetMetric() method, which accepts any itk metric
39
 * deriving from the itk::ImageToImageMetric. The MinimizeOn()/MinimizeOff() flag allows searching for
40
 * minimum or maximum depending on the metric (default is On).
41
 *
42 43
 * Once a coarse (pixel wise) offset has been found, this match is further refined using golden section search search
 * until convergence accuracy (given by the SetConvergenceAccuracy()) is reached, or when the max number of iteration () is reached.
44
 *
45
 * The filter proposes two outputs: GetOutput() return the image of the metric optimum at each location, and
46
 * the GetOutputDisplacementField() method returns the corresponding offset.
47
 *
48 49
 * If the UseSpacingOn() flag is used, the output displacement field takes the input image spacing into account.
 * otherwise, the displacement field is expressed in pixels (default ins On).
50
 *
51 52 53
 * This filter accepts fixed and moving images with different sizes and spacing. Metric and search windows radius
 * are expressed in terms of number of pixels in the fixed image.
 *
54
 * An initial offset can be used to reduce computation time in case of input and moving images with a significant
55
 * offset. This offset is taken into account in the output displacement field.
56
 *
57
 * It is possible to generate an output metric map and displacement field at a coarser resolution by setting
58 59
 * grid step to value higher than 1 (grid step is expressed in terms of number of fixed image pixels).
 * Default value is 1.
60
 *
61
 * The FineRegistrationImageFilter allows using the full range of itk::ImageToImageMetric provided by itk.
62
 *
63 64
 * \example DisparityMap/FineRegistrationImageFilterExample.cxx
 *
65
 * \sa      FastCorrelationImageFilter, DisparityMapEstimationMethod
66
 * \ingroup IntensityImageFilters, Streamed
67
 *
68
 * \ingroup OTBDisparityMap
69
 */
70
template <class TInputImage, class T0utputCorrelation, class TOutputDisplacementField>
OTB Bot's avatar
OTB Bot committed
71
class ITK_EXPORT FineRegistrationImageFilter : public itk::ImageToImageFilter<TInputImage, T0utputCorrelation>
72 73 74
{
public:
  /** Standard class typedefs. */
Julien Michel's avatar
Julien Michel committed
75
  typedef FineRegistrationImageFilter                             Self;
OTB Bot's avatar
OTB Bot committed
76
  typedef itk::ImageToImageFilter<TInputImage, T0utputCorrelation> Superclass;
77 78 79 80 81 82 83 84 85 86 87
  typedef itk::SmartPointer<Self>                                 Pointer;
  typedef itk::SmartPointer<const Self>                           ConstPointer;

  /** Method for creation through the object factory. */
  itkNewMacro(Self);

  /** Run-time type information (and related methods). */
  itkTypeMacro(FineRegistrationImageFilter, ImageToImageFilter);

  /** Some convenient typedefs. */
  typedef typename T0utputCorrelation::RegionType                 OutputImageRegionType;
88
  typedef typename TOutputDisplacementField::PixelType             DisplacementValueType;
89 90 91 92 93
  typedef typename TInputImage::Pointer                           InputImagePointerType;
  typedef typename TInputImage::RegionType                        InputImageRegionType;
  typedef typename TInputImage::SizeType                          SizeType;
  typedef typename TInputImage::IndexType                         IndexType;
  typedef typename TInputImage::SpacingType                       SpacingType;
94 95
  typedef typename TInputImage::PointType                         PointType;
  typedef typename TInputImage::OffsetType                        OffsetType;
96
  typedef itk::InterpolateImageFunction<TInputImage, double>      InterpolatorType;
97
  typedef typename InterpolatorType::Pointer                      InterpolatorPointerType;
98 99
  typedef itk::ContinuousIndex<double, 2>                         ContinuousIndexType;
  typedef itk::ImageToImageMetric<TInputImage, TInputImage>       MetricType;
100
  typedef typename MetricType::Pointer                            MetricPointerType;
OTB Bot's avatar
OTB Bot committed
101
  typedef itk::TranslationTransform<double, 2>                     TranslationType;
102
  typedef typename TranslationType::Pointer                       TranslationPointerType;
OTB Bot's avatar
OTB Bot committed
103
  typedef typename itk::Transform<double, 2, 2>                     TransformType;
104
  typedef typename TransformType::Pointer                         TransformPointerType;
105 106

  /** Set/Get the Metric used to compare images */
OTB Bot's avatar
OTB Bot committed
107 108
  itkSetObjectMacro(Metric, MetricType);
  itkGetObjectMacro(Metric, MetricType);
109

110
  /** Set/Get the interpolator used to interpolate moving image at non-grid positions */
OTB Bot's avatar
OTB Bot committed
111 112
  itkSetObjectMacro(Interpolator, InterpolatorType);
  itkGetObjectMacro(Interpolator, InterpolatorType);
113 114 115 116 117 118 119 120 121 122 123

  /** Connect one of the operands for pixel-wise addition */
  void SetFixedInput( const TInputImage * image);

  /** Connect one of the operands for pixel-wise addition */
  void SetMovingInput( const TInputImage * image);

  /** Get the inputs */
  const TInputImage * GetFixedInput();
  const TInputImage * GetMovingInput();

124 125
  /** Get the output displacement field */
  TOutputDisplacementField * GetOutputDisplacementField();
126

127 128 129 130 131
  /** Set the radius of the area on which metric is evaluated */
  itkSetMacro(Radius, SizeType);
  itkGetMacro(Radius, SizeType);

  /** Set the searh radius */
OTB Bot's avatar
OTB Bot committed
132 133
  itkSetMacro(SearchRadius, SizeType);
  itkGetMacro(SearchRadius, SizeType);
134

135 136 137 138
  /** Set/Get convergence accuracy */
  itkSetMacro(ConvergenceAccuracy, double);
  itkGetMacro(ConvergenceAccuracy, double);
  
139 140 141 142
  /** Set/Get subpixel accuracy */
  itkSetMacro(SubPixelAccuracy, double);
  itkGetMacro(SubPixelAccuracy, double);
  
143 144 145
  /** Set/Get max number of iterations */
  itkSetMacro(MaxIter, int);
  itkGetMacro(MaxIter, int);
146 147

  /** True if metric should be minimized. False otherwise */
OTB Bot's avatar
OTB Bot committed
148
  itkSetMacro(Minimize, bool);
149 150
  itkBooleanMacro(Minimize);

151
  /** True if displacement field takes spacing into account. False otherwise */
OTB Bot's avatar
OTB Bot committed
152
  itkSetMacro(UseSpacing, bool);
153 154
  itkBooleanMacro(UseSpacing);

155
  /** Set default offset between the two images */
OTB Bot's avatar
OTB Bot committed
156 157
  itkSetMacro(InitialOffset, SpacingType);
  itkGetConstReferenceMacro(InitialOffset, SpacingType);
158 159

  /** Set the grid step */
OTB Bot's avatar
OTB Bot committed
160 161
  itkSetMacro(GridStep, OffsetType);
  itkGetConstReferenceMacro(GridStep, OffsetType);
162

163 164 165 166 167
  /** Set unsigned int radius */
  void SetRadius(unsigned int radius)
  {
    m_Radius.Fill(radius);
  }
168

169
 /** Set unsigned int radius */
170 171 172 173 174
  void SetSearchRadius(unsigned int radius)
  {
    m_SearchRadius.Fill(radius);
  }

175 176 177 178 179 180
  /** Set unsigned int grid step */
  void SetGridStep(unsigned int step)
  {
    m_GridStep.Fill(step);
  }

Emmanuel Christophe's avatar
Emmanuel Christophe committed
181
  /** Set/Get the transform for the initial offset */
182 183 184
  itkSetObjectMacro(Transform, TransformType);
  itkGetConstObjectMacro(Transform, TransformType);

185 186 187 188 189 190 191 192 193 194 195 196
protected:
  /** Constructor */
  FineRegistrationImageFilter();
  /** Destructor */
  virtual ~FineRegistrationImageFilter() {};

  /** Threaded generate data */
  virtual void GenerateData();

  /** Generate the input requested regions  */
  virtual void GenerateInputRequestedRegion(void);

197 198 199
  /** Generate output information */
  virtual void GenerateOutputInformation(void);

200 201 202
private:
  FineRegistrationImageFilter(const Self&); //purposely not implemented
  void operator=(const Self&); //purposely not implemented
Christophe Palmann's avatar
Christophe Palmann committed
203 204 205 206 207 208 209
  
  inline double callMetric(double val1,double val2,double &oldRes,bool &flag);
  inline void updateOptParams(double potBestVal,double parx,double pary,                             //inputs
                              double &bestVal, typename TranslationType::ParametersType& optParams); //outputs
  inline void updatePoints(double& gn, double& in1, double& in2, double &in3,      //inputs
                           double& out1, double& out2, double& out3, double& out4); //outputs
  inline void updateMinimize(double& a, double& b);
210 211 212 213 214 215 216 217 218 219

  /** The radius for correlation */
  SizeType                      m_Radius;

  /** The search radius */
  SizeType                      m_SearchRadius;

  /** Minimize/maximize metric */
  bool                          m_Minimize;

220
  /** If true, displacement field uses spacing. Otherwise, uses pixel grid */
221 222 223
  bool                          m_UseSpacing;

  /** Search step */
224
  double                        m_ConvergenceAccuracy;
225
  double                        m_SubPixelAccuracy;
226 227 228
  
  /** Max number of iterations */
  int                           m_MaxIter;
229 230 231 232 233 234 235 236

  /** The interpolator */
  InterpolatorPointerType       m_Interpolator;

  /** The metric */
  MetricPointerType             m_Metric;

  /** The translation */
237
  TranslationPointerType        m_Translation;
238

239 240 241 242 243 244
  /** Default offset */
  SpacingType                   m_InitialOffset;

  /** Grid step */
  OffsetType                    m_GridStep;

245 246 247
  /** Transform for initial offset */
  TransformPointerType          m_Transform;

248 249 250 251 252 253 254 255 256
};

} // end namespace otb

#ifndef OTB_MANUAL_INSTANTIATION
#include "otbFineRegistrationImageFilter.txx"
#endif

#endif