All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TiePointsLocator.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/rp/TiePointsLocator.cpp
22  \brief Tie points locator.
23 */
24 
25 #include "TiePointsLocator.h"
26 #include "Macros.h"
29 #include "Functions.h"
30 #include "../geometry/GTFactory.h"
31 #include "../geometry/GTFilter.h"
32 #include "../common/progress/TaskProgress.h"
33 
34 namespace te
35 {
36  namespace rp
37  {
38 
40  {
41  reset();
42  }
43 
45  {
46  reset();
47  operator=( other );
48  }
49 
51  {
52  reset();
53  }
54 
55  void TiePointsLocator::OutputParameters::reset() throw( te::rp::Exception )
56  {
57  m_tiePoints.clear();
58  m_transformationPtr.reset();
59  }
60 
63  {
64  reset();
65 
66  m_tiePoints = params.m_tiePoints;
67  m_transformationPtr.reset( params.m_transformationPtr->clone() );
68 
69  return *this;
70  }
71 
73  {
74  return new OutputParameters( *this );
75  }
76 
77  // -----------------------------------------------------------------------
78 
80  {
81  reset();
82  }
83 
85  {
86  }
87 
89  throw( te::rp::Exception )
90  {
91  if( ! m_isInitialized ) return false;
92 
93  TiePointsLocator::OutputParameters* outParamsPtr = dynamic_cast<
94  TiePointsLocator::OutputParameters* >( &outputParams );
95  TERP_TRUE_OR_THROW( outParamsPtr, "Invalid paramters" );
96 
97  outParamsPtr->m_tiePoints.clear();
98  outParamsPtr->m_tiePointsWeights.clear();
99  outParamsPtr->m_transformationPtr.reset();
100 
101  // creating the choosed strategy
102 
103  std::auto_ptr< TiePointsLocatorStrategy > stratPtr;
105  {
107  {
108  stratPtr.reset( new te::rp::TiePointsLocatorMoravecStrategy() );
109  break;
110  }
112  {
113  stratPtr.reset( new te::rp::TiePointsLocatorSURFStrategy() );
114  break;
115  }
116  default :
117  {
118  TERP_LOG_AND_THROW( "Invalid strategy" );
119  break;
120  }
121  }
122 
123  // Matching
124 
126 
128  {
129  TERP_TRUE_OR_RETURN_FALSE( stratPtr->initialize( m_inputParameters ),
130  "Tie points locator strategy initialization error" );
131 
132  TERP_TRUE_OR_RETURN_FALSE( stratPtr->getMatchedInterestPoints(
134  matchedInterestPoints ),
135  "Tie points interest points location error" );
136  }
137  else
138  {
139  // First pass : trying to find mathed points over
140  // the sub-sampled raster
141 
142  TiePointsLocator::InputParameters subSampledinputParameters =
144  subSampledinputParameters.m_geomTransfMaxError = 0;
145  subSampledinputParameters.m_maxTiePoints = (unsigned int)
146  (
147  ((double)subSampledinputParameters.m_maxTiePoints)
148  *
149  std::sqrt( subSampledinputParameters.m_subSampleOptimizationRescaleFactor )
150  );
152  {
154  {
155  subSampledinputParameters.m_moravecCorrelationWindowWidth =
156  3
157  +
158  (unsigned int)
159  (
160  ((double)( subSampledinputParameters.m_moravecCorrelationWindowWidth - 3 ))
161  *
162  subSampledinputParameters.m_subSampleOptimizationRescaleFactor
163  );
164 
165  subSampledinputParameters.m_moravecWindowWidth =
166  3
167  +
168  (unsigned int)
169  (
170  ((double)( subSampledinputParameters.m_moravecWindowWidth - 3 ))
171  *
172  subSampledinputParameters.m_subSampleOptimizationRescaleFactor
173  );
174  break;
175  }
177  {
178  subSampledinputParameters.m_surfScalesNumber =
179  3
180  +
181  (unsigned int)
182  (
183  ((double)( subSampledinputParameters.m_surfScalesNumber - 3 ))
184  *
185  subSampledinputParameters.m_subSampleOptimizationRescaleFactor
186  );
187  subSampledinputParameters.m_surfOctavesNumber =
188  1
189  +
190  (unsigned int)
191  (
192  ((double)( subSampledinputParameters.m_surfOctavesNumber - 1 ))
193  *
194  subSampledinputParameters.m_subSampleOptimizationRescaleFactor
195  );
196  break;
197  }
198  default :
199  {
200  TERP_LOG_AND_THROW( "Invalid strategy" );
201  break;
202  }
203  }
204 
205  te::rp::TiePointsLocatorStrategy::MatchedInterestPointsSetT subSampledMatchedInterestPoints;
206  TERP_TRUE_OR_RETURN_FALSE( stratPtr->initialize( subSampledinputParameters ),
207  "Tie points locator strategy initialization error" );
208  if( ! stratPtr->getMatchedInterestPoints( (te::gm::GeometricTransformation*)0,
209  0, subSampledMatchedInterestPoints ) )
210  {
211  subSampledMatchedInterestPoints.clear();
212  }
213 
214  // Generating tie-points
215 
216  te::gm::GTParameters subSampledTransParams;
217  std::vector< double > subSampledTiePointsWeights;
218  convertMatchedInterestPoints2TiePoints( subSampledMatchedInterestPoints,
219  subSampledTransParams.m_tiePoints, subSampledTiePointsWeights );
220 
221  subSampledMatchedInterestPoints.clear();
222 
223  // trying to create the global geometric transformation
224 
225  std::auto_ptr< te::gm::GeometricTransformation > transformationPtr(
227  TERP_TRUE_OR_RETURN_FALSE( transformationPtr.get(), "Invalid geometric transformation" );
228 
229  double transformationCoveredAreaPercentR1 = 0;
230  double transformationCoveredAreaPercentR2 = 0;
231 
233  {
234  std::vector< te::gm::GTParameters::TiePoint > filteredTiePoints;
235  te::gm::GTFilter filter;
236  if( filter.applyRansac(
238  subSampledTransParams,
241  0,
244  subSampledTiePointsWeights,
245  filteredTiePoints,
246  transformationPtr ) )
247  {
248  transformationCoveredAreaPercentR1 =
249  (
250  te::rp::GetTPConvexHullArea( filteredTiePoints, false )
251  /
252  (double)(
254  *
256  )
257  );
258 
259  transformationCoveredAreaPercentR2 =
260  (
261  te::rp::GetTPConvexHullArea( filteredTiePoints, true )
262  /
263  (double)(
265  *
267  )
268  );
269 
270  if(
271  (
272  ((double)filteredTiePoints.size())
273  <
274  (
276  *
277  ((double)transformationPtr->getMinRequiredTiePoints() )
278  )
279  )
280  ||
281  (
282  std::max(
283  transformationCoveredAreaPercentR1
284  ,
285  transformationCoveredAreaPercentR2
286  )
287  <
288  (
290  /
291  100.0
292  )
293  )
294  )
295  {
296  transformationPtr.reset();
297  }
298  }
299  else
300  {
301  transformationPtr.reset();
302  };
303  }
304  else
305  {
306  if( !transformationPtr->initialize( subSampledTransParams ) )
307  {
308  transformationPtr.reset();
309  }
310  }
311 
312  // Second pass - Trying to find tie-points over the original images using the found
313  // global geometric transformation
314 
315  TiePointsLocator::InputParameters noSubSampledInputParameters =
317  noSubSampledInputParameters.m_subSampleOptimizationRescaleFactor = 1.0;
318 
319  TERP_TRUE_OR_RETURN_FALSE( stratPtr->initialize( noSubSampledInputParameters ),
320  "Tie points locator strategy initialization error" );
321 
322  TERP_TRUE_OR_RETURN_FALSE( stratPtr->getMatchedInterestPoints(
323  transformationPtr.get(),
324  m_inputParameters.m_geomTransfMaxError / ( transformationCoveredAreaPercentR2 *
326  matchedInterestPoints ),
327  "Tie points interest points location error" );
328  }
329 
330  // Converting to tie-points
331 
332  std::vector< te::gm::GTParameters::TiePoint > tiePoints;
333  std::vector< double > tiePointsWeights;
334  convertMatchedInterestPoints2TiePoints( matchedInterestPoints, tiePoints,
335  tiePointsWeights );
336 
337  matchedInterestPoints.clear();
338 
339  // Execute outliers remotion, if required
340 
342  {
343  te::gm::GTParameters transfParams;
344  transfParams.m_tiePoints = tiePoints;
345 
346  te::gm::GTFilter filter;
347  if( !filter.applyRansac(
349  transfParams,
352  0,
355  tiePointsWeights,
356  outParamsPtr->m_tiePoints,
357  outParamsPtr->m_transformationPtr ) )
358  {
359  return false;
360  };
361  }
362  else
363  {
364  outParamsPtr->m_tiePoints = tiePoints;
365 
366  outParamsPtr->m_transformationPtr.reset( te::gm::GTFactory::make(
368  TERP_DEBUG_TRUE_OR_THROW( outParamsPtr->m_transformationPtr.get(),
369  "Invalid transformation" );
370 
371  te::gm::GTParameters transfParams;
372  transfParams.m_tiePoints = outParamsPtr->m_tiePoints;
373 
374  if( ! outParamsPtr->m_transformationPtr->initialize( transfParams ) )
375  {
376  outParamsPtr->m_transformationPtr.reset();
377  }
378  }
379 
380  // tie-points weights
381 
382  unsigned int tiePointsIdx = 0;
383 
384  for( unsigned int outTiePointdx = 0 ; outTiePointdx < outParamsPtr->m_tiePoints.size() ;
385  ++outTiePointdx )
386  {
387  for( tiePointsIdx = 0 ; tiePointsIdx < tiePoints.size() ; ++tiePointsIdx )
388  {
389  if( tiePoints[ tiePointsIdx ] == outParamsPtr->m_tiePoints[ outTiePointdx ] )
390  {
391  outParamsPtr->m_tiePointsWeights.push_back( tiePointsWeights[ tiePointsIdx ] );
392  break;
393  }
394  }
395  }
396 
397  TERP_TRUE_OR_THROW( outParamsPtr->m_tiePoints.size() ==
398  outParamsPtr->m_tiePointsWeights.size(), "Internal error" );
399 
400  return true;
401  }
402 
403  void TiePointsLocator::reset() throw( te::rp::Exception )
404  {
406  m_isInitialized = false;
407  }
408 
410  throw( te::rp::Exception )
411  {
412  reset();
413 
414  {
415  TiePointsLocator::InputParameters const* inputParamsPtr = dynamic_cast<
416  TiePointsLocator::InputParameters const* >( &inputParams );
417  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr, "Invalid parameters" );
418 
419  m_inputParameters = *inputParamsPtr;
420  }
421 
422  // Checking m_inRaster1Ptr
423 
425  "Invalid m_inRaster1Ptr" );
428  "Invalid m_inRaster1Ptr" );
429 
430  // Checking m_inMaskRaster1Ptr
431 
433  {
436  "Invalid m_inMaskRaster1Ptr" );
439  "Invalid m_inMaskRaster1Ptr" );
443  "Invalid m_inMaskRaster1Ptr" );
447  "Invalid m_inMaskRaster1Ptr" );
448  }
449 
450  // Checking raster 1 target area
451 
454  "Invalid m_raster1TargetAreaLineStart" );
455 
458  "Invalid m_raster1TargetAreaColStart" );
459 
462  {
465  ( ( unsigned int ) m_inputParameters.m_inRaster1Ptr->getNumberOfColumns() )
467 
470  ( ( unsigned int ) m_inputParameters.m_inRaster1Ptr->getNumberOfRows() )
472  }
473  else
474  {
479  }
480 
482  "Invalid m_raster1TargetAreaWidth" );
484  "Invalid m_raster1TargetAreaHeight" );
485 
486  // Checking raster 1 bands
487  {
488  for( unsigned int bandIdx = 0 ; bandIdx <
489  m_inputParameters.m_inRaster1Bands.size() ; ++bandIdx )
490  {
494  "Invalid m_inRaster1Bands" );
495  }
496  }
497 
498  // Checking raster 2
499 
501  "Invalid m_inRaster2Ptr" );
504  "Invalid m_inRaster2Ptr" );
505 
506  // Checking m_inMaskRaster2Ptr
507 
509  {
512  "Invalid m_inMaskRaster2Ptr" );
515  "Invalid m_inMaskRaster2Ptr" );
519  "Invalid m_inMaskRaster2Ptr" );
523  "Invalid m_inMaskRaster2Ptr" );
524  }
525 
526  // Checking raster target area
527 
530  "Invalid m_raster2TargetAreaLineStart" );
531 
534  "Invalid m_raster2TargetAreaColStart" );
535 
538  {
541  ( ( unsigned int ) m_inputParameters.m_inRaster2Ptr->getNumberOfColumns() )
543 
546  ( ( unsigned int ) m_inputParameters.m_inRaster2Ptr->getNumberOfRows() )
548  }
549  else
550  {
555  }
556 
558  "Invalid m_raster2TargetAreaWidth" );
560  "Invalid m_raster2TargetAreaHeight" );
561 
562  // Checking raster 2 bands
563 
564  {
565  for( unsigned int bandIdx = 0 ; bandIdx <
566  m_inputParameters.m_inRaster2Bands.size() ; ++bandIdx )
567  {
571  "Invalid m_inRaster2Bands" );
572  }
573  }
574 
575  // Checking strategy
576 
578  {
580  {
581  break;
582  }
584  {
585  break;
586  }
587  default :
588  {
589  TERP_LOG_AND_RETURN_FALSE( "Invalid strategy" );
590  break;
591  }
592  };
593 
594  // Checking other parameters
595 
597  "Invalid m_pixelSizeXRelation" )
598 
600  "Invalid m_pixelSizeYRelation" )
601 
603  "Invalid m_geomTransfMaxError" )
604 
607  "Invalid m_geomTransfName" );
608 
611  "Invalid m_geometryFilterAssurance" );
612 
615  "Invalid m_subSampleOptimizationRescaleFactor" );
616 
619  "Invalid m_subSampleOptimizationMinTPAreaCoverage" );
620 
622  "Invalid m_subSampleOptimizationMinTPNumber" );
623 
625  "Invalid m_tiePointsSubSectorsSplitFactor" );
626 
627  m_isInitialized = true;
628 
629  return true;
630  }
631 
633  {
634  return m_isInitialized;
635  }
636 
639  std::vector< te::gm::GTParameters::TiePoint >& tiePoints,
640  std::vector< double >& tiePointsWeights )
641  {
642  tiePoints.clear();
643  tiePointsWeights.clear();
644 
646  te::rp::TiePointsLocatorStrategy::MatchedInterestPointsSetT::const_iterator
647  itB = matchedInterestPoints.begin();
648  const te::rp::TiePointsLocatorStrategy::MatchedInterestPointsSetT::const_iterator
649  itE = matchedInterestPoints.end();
650 
651  while( itB != itE )
652  {
653  auxTP.first.x = itB->m_point1.m_x;
654  auxTP.first.y = itB->m_point1.m_y;
655  auxTP.second.x = itB->m_point2.m_x;
656  auxTP.second.y = itB->m_point2.m_y;
657  tiePoints.push_back( auxTP );
658 
659  tiePointsWeights.push_back( itB->m_feature );
660 
661  ++itB;
662  }
663  }
664 
665  } // end namespace rp
666 } // end namespace te
667 
std::vector< te::gm::GTParameters::TiePoint > m_tiePoints
The generated tie-points (te::gm::GTParameters::TiePoint::first are raster 1 line/column indexes...
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
std::vector< unsigned int > m_inRaster2Bands
Bands to be used from the input raster 2.
AbstractParameters * clone() const
Create a clone copy of this instance.
void reset()
Clear all internal allocated objects and reset the algorithm to its initial state.
unsigned int m_raster2TargetAreaLineStart
The first line of the raster 2 target area to process (default:0 - The entire raster will be consider...
unsigned int m_moravecWindowWidth
The Moravec window width used to locate canditate tie-points (minimum 3, default: 21 )...
unsigned int m_surfScalesNumber
The number of sub-sampling scales to generate, when applicable (default:3, minimum:3).
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
Definition: Raster.cpp:213
double GetTPConvexHullArea(const ContainerT &tiePoints, const bool useTPSecondCoordPair)
Returns the tie points converx hull area.
Definition: Functions.h:633
double m_geomTransfMaxError
The maximum allowed transformation error (pixel units, default:2).
double m_subSampleOptimizationRescaleFactor
Sub-sampled optimization tie-points search rescale factor (Tie-ponts will be searched into a subsabmp...
te::rst::Raster const * m_inRaster2Ptr
Input raster 2.
Raster Processing algorithm output parameters base interface.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
2D Geometric transformation base class.
Tie-Pointsr locator SURF strategy.
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
unsigned int m_moravecCorrelationWindowWidth
The correlation window width used to correlate points between the images (minimum 3...
std::pair< Coord2D, Coord2D > TiePoint
Tie point type definition.
Definition: GTParameters.h:59
2D Geometric transformation tie-points filter (outliers remotion).
Definition: GTFilter.h:52
bool applyRansac(const std::string &transfName, const GTParameters &inputParams, const double maxDirectMapError, const double maxInverseMapError, const RansacIntegerCounterT &maxIterations, const double &assurance, const bool enableMultiThread, const std::vector< double > &tiePointsWeights, std::vector< te::gm::GTParameters::TiePoint > &outTiePoints, std::auto_ptr< GeometricTransformation > &outTransf)
Apply a RANSAC based outliers remotion strategy.
Definition: GTFilter.cpp:199
Raster Processing functions.
unsigned int m_maxTiePoints
The maximum number of tie-points to generate (0:Automatically calculated, default:2500).
#define TERP_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged and a return of context wi...
Definition: Macros.h:183
const Algorithm & operator=(const Algorithm &)
Definition: Algorithm.cpp:43
Tie-Pointsr locator Moravec strategy.
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
Definition: Raster.cpp:89
void convertMatchedInterestPoints2TiePoints(const te::rp::TiePointsLocatorStrategy::MatchedInterestPointsSetT &matchedInterestPoints, std::vector< te::gm::GTParameters::TiePoint > &tiePoints, std::vector< double > &tiePointsWeights)
Convert matched interest points to tie-points.
unsigned int m_raster1TargetAreaHeight
The raster 1 target area height (default:0 - The entire raster will be considered).
TiePointsLocator::InputParameters m_inputParameters
TiePointsLocator input execution parameters.
std::auto_ptr< te::gm::GeometricTransformation > m_transformationPtr
The generated geometric transformation with the base mininum required tie-points set ( depending on t...
double m_pixelSizeXRelation
The pixel resolution relation m_pixelSizeXRelation = raster1_pixel_res_x / raster2_pixel_res_x (defau...
double m_geometryFilterAssurance
Geometry assurance (the error-free selection percent assurance) - Use Lower values for good tie-point...
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
bool m_enableGeometryFilter
Enable/disable the geometry filter/outliers remotion (default:true).
#define TERP_LOG_AND_THROW(message)
Logs a error message and throws.
Definition: Macros.h:138
std::vector< unsigned int > m_inRaster1Bands
Bands to be used from the input raster 1.
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
double m_subSampleOptimizationMinTPAreaCoverage
Sub-sampled optimization - mininumum required tie-points covered area percent of each raster area - v...
static GeometricTransformation * make(const std::string &factoryKey)
It creates an object with the appropriated factory.
TiePointsLocator output parameters.
unsigned int m_tiePointsSubSectorsSplitFactor
The algorithm will try to generate tie-points distributed over image sectors ( Default: 3 - 3x3 sub-s...
Tie-points locator SURF strategy.
te::rst::Raster const * m_inRaster1Ptr
Input raster 1.
unsigned int m_surfOctavesNumber
The number of octaves to generate, when applicable (default: 2, minimum:2).
double m_subSampleOptimizationMinTPNumberFactor
Sub-sampled optimization - mininumum required tie-points number factor - valid range [1...
bool m_isInitialized
Tells if this instance is initialized.
Abstract parameters base interface.
const OutputParameters & operator=(const OutputParameters &params)
#define TERP_LOG_AND_RETURN_FALSE(message)
Logs a warning message will and return false.
Definition: Macros.h:236
unsigned int m_raster1TargetAreaWidth
The raster 1 target area width (default:0 - The entire raster will be considered).
std::vector< double > m_tiePointsWeights
The generated tie-points weights.
double m_pixelSizeYRelation
The pixel resolution relation m_pixelSizeYRelation = raster1_pixel_res_y / raster2_pixel_res_y (defau...
unsigned int m_raster1TargetAreaLineStart
The first line of the raster 1 target area to process (default:0 - The entire raster will be consider...
unsigned int m_raster2TargetAreaColStart
The first column of the raster 2 target area to process (default:0 - The entire raster will be consid...
unsigned int m_raster2TargetAreaHeight
The raster 2 target area height (default:0 - The entire raster will be considered).
static const factory_type * find(const std::string &factoryKey)
bool m_enableMultiThread
Enable/Disable the use of multi-threads (default:true).
TiePointsLocator locator.
te::rst::Raster const * m_inMaskRaster1Ptr
Optional one band input mask raster 1 (tie-points will not be generated inside mask image areas marke...
Raster Processing algorithm input parameters base interface.
te::rst::Raster const * m_inMaskRaster2Ptr
Optional one band input mask raster 2 (tie-points will not be generated inside mask image areas marke...
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
2D Geometric transformation parameters.
Definition: GTParameters.h:50
std::string m_geomTransfName
The name of the geometric transformation used to ensure tie-points consistency (see each te::gm::GTFa...
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:356
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
unsigned int m_raster1TargetAreaColStart
The first column of the raster 2 target area to process (default:0 - The entire raster will be consid...
std::multiset< MatchedInterestPointsT > MatchedInterestPointsSetT
unsigned int m_raster2TargetAreaWidth
The raster 2 target area width (default:0 - The entire raster will be considered).
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:149
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
InteresPointsLocationStrategyType m_interesPointsLocationStrategy
The strategy used to locate interest points (default:MoravecStrategyT).