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 
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 
87  throw( te::rp::Exception )
88  {
89  if( ! m_isInitialized ) return false;
90 
91  TiePointsLocator::OutputParameters* outParamsPtr = dynamic_cast<
92  TiePointsLocator::OutputParameters* >( &outputParams );
93  TERP_TRUE_OR_THROW( outParamsPtr, "Invalid paramters" );
94 
95  outParamsPtr->m_tiePoints.clear();
96  outParamsPtr->m_tiePointsWeights.clear();
97  outParamsPtr->m_transformationPtr.reset();
98 
99  // creating the choosed strategy
100 
101  std::unique_ptr< TiePointsLocatorStrategy > stratPtr(
104  TERP_TRUE_OR_THROW( stratPtr.get() != nullptr, "Invalid strategy" );
105 
106  // Matching
107 
109 
111  {
112  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( stratPtr->initialize( m_inputParameters ),
113  "Tie points locator strategy initialization error: " +
114  stratPtr->getErrorMessage() );
115 
116  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( stratPtr->getMatchedInterestPoints(
117  (te::gm::GeometricTransformation*)nullptr, 0,
118  matchedInterestPoints ),
119  "Tie points interest points location error: " +
120  stratPtr->getErrorMessage() );
121  }
122  else
123  {
124  // First pass : trying to find mathed points over
125  // the sub-sampled raster
126 
127  TiePointsLocator::InputParameters subSampledinputParameters =
129  subSampledinputParameters.m_geomTransfMaxError = 0;
130  subSampledinputParameters.m_maxTiePoints = (unsigned int)
131  (
132  ((double)subSampledinputParameters.m_maxTiePoints)
133  *
134  std::sqrt( subSampledinputParameters.m_subSampleOptimizationRescaleFactor )
135  );
136 
137  std::unique_ptr< TiePointsLocatorStrategyParameters > subSampledSpecStratParametersPtr;
138  stratPtr->getSubSampledSpecStrategyParams(
141  subSampledSpecStratParametersPtr );
142  subSampledinputParameters.setSpecStrategyParams( *subSampledSpecStratParametersPtr );
143 
144  te::rp::TiePointsLocatorStrategy::MatchedInterestPointsSetT subSampledMatchedInterestPoints;
145  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( stratPtr->initialize( subSampledinputParameters ),
146  "Tie points locator strategy initialization error: " + stratPtr->getErrorMessage() );
147  if( ! stratPtr->getMatchedInterestPoints( (te::gm::GeometricTransformation*)nullptr,
148  0, subSampledMatchedInterestPoints ) )
149  {
150  subSampledMatchedInterestPoints.clear();
151  }
152 
153  // Generating tie-points
154 
155  te::gm::GTParameters subSampledTransParams;
156  std::vector< double > subSampledTiePointsWeights;
157  convertMatchedInterestPoints2TiePoints( subSampledMatchedInterestPoints,
158  subSampledTransParams.m_tiePoints, subSampledTiePointsWeights );
159 
160  subSampledMatchedInterestPoints.clear();
161 
162  // trying to create the global geometric transformation
163 
164  std::unique_ptr< te::gm::GeometricTransformation > transformationPtr(
166  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( transformationPtr.get(), "Invalid geometric transformation" );
167 
168  double transformationCoveredAreaPercentR1 = 0;
169  double transformationCoveredAreaPercentR2 = 0;
170 
172  {
173  std::vector< te::gm::GTParameters::TiePoint > filteredTiePoints;
174  te::gm::GTFilter filter;
175  if( filter.applyRansac(
177  subSampledTransParams,
180  0,
183  subSampledTiePointsWeights,
184  filteredTiePoints,
185  transformationPtr ) )
186  {
187  transformationCoveredAreaPercentR1 =
188  (
189  te::rp::GetTPConvexHullArea( filteredTiePoints, false )
190  /
191  (double)(
193  *
195  )
196  );
197 
198  transformationCoveredAreaPercentR2 =
199  (
200  te::rp::GetTPConvexHullArea( filteredTiePoints, true )
201  /
202  (double)(
204  *
206  )
207  );
208 
209  if(
210  (
211  ((double)filteredTiePoints.size())
212  <
213  (
215  *
216  ((double)transformationPtr->getMinRequiredTiePoints() )
217  )
218  )
219  ||
220  (
221  std::max(
222  transformationCoveredAreaPercentR1
223  ,
224  transformationCoveredAreaPercentR2
225  )
226  <
227  (
229  /
230  100.0
231  )
232  )
233  )
234  {
235  transformationPtr.reset();
236  }
237  }
238  else
239  {
240  transformationPtr.reset();
241  };
242  }
243  else
244  {
245  if( !transformationPtr->initialize( subSampledTransParams ) )
246  {
247  transformationPtr.reset();
248  }
249  }
250 
251  // Second pass - Trying to find tie-points over the original images using the found
252  // global geometric transformation
253 
254  TiePointsLocator::InputParameters noSubSampledInputParameters =
256  noSubSampledInputParameters.m_subSampleOptimizationRescaleFactor = 1.0;
257 
258  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( stratPtr->initialize( noSubSampledInputParameters ),
259  "Tie points locator strategy initialization error: " + stratPtr->getErrorMessage() );
260 
261  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( stratPtr->getMatchedInterestPoints(
262  transformationPtr.get(),
263  m_inputParameters.m_geomTransfMaxError / ( transformationCoveredAreaPercentR2 *
265  matchedInterestPoints ),
266  "Tie points interest points location error: " + stratPtr->getErrorMessage() );
267  }
268 
269  // Converting to tie-points
270 
271  std::vector< te::gm::GTParameters::TiePoint > tiePoints;
272  std::vector< double > tiePointsWeights;
273  convertMatchedInterestPoints2TiePoints( matchedInterestPoints, tiePoints,
274  tiePointsWeights );
275 
276  matchedInterestPoints.clear();
277 
278  // Execute outliers remotion, if required
279 
281  {
282  te::gm::GTParameters transfParams;
283  transfParams.m_tiePoints = tiePoints;
284 
285  te::gm::GTFilter filter;
286  if( !filter.applyRansac(
288  transfParams,
291  0,
294  tiePointsWeights,
295  outParamsPtr->m_tiePoints,
296  outParamsPtr->m_transformationPtr ) )
297  {
298  return false;
299  };
300  }
301  else
302  {
303  outParamsPtr->m_tiePoints = tiePoints;
304 
305  outParamsPtr->m_transformationPtr.reset( te::gm::GTFactory::make(
307  TERP_DEBUG_TRUE_OR_THROW( outParamsPtr->m_transformationPtr.get(),
308  "Invalid transformation" );
309 
310  te::gm::GTParameters transfParams;
311  transfParams.m_tiePoints = outParamsPtr->m_tiePoints;
312 
313  if( ! outParamsPtr->m_transformationPtr->initialize( transfParams ) )
314  {
315  outParamsPtr->m_transformationPtr.reset();
316  }
317  }
318 
319  // tie-points weights
320 
321  unsigned int tiePointsIdx = 0;
322 
323  for( unsigned int outTiePointdx = 0 ; outTiePointdx < outParamsPtr->m_tiePoints.size() ;
324  ++outTiePointdx )
325  {
326  for( tiePointsIdx = 0 ; tiePointsIdx < tiePoints.size() ; ++tiePointsIdx )
327  {
328  if( tiePoints[ tiePointsIdx ] == outParamsPtr->m_tiePoints[ outTiePointdx ] )
329  {
330  outParamsPtr->m_tiePointsWeights.push_back( tiePointsWeights[ tiePointsIdx ] );
331  break;
332  }
333  }
334  }
335 
336  TERP_TRUE_OR_THROW( outParamsPtr->m_tiePoints.size() ==
337  outParamsPtr->m_tiePointsWeights.size(), "Internal error" );
338 
339  return true;
340  }
341 
342  void TiePointsLocator::reset() throw( te::rp::Exception )
343  {
345 
347  m_isInitialized = false;
348  }
349 
351  throw( te::rp::Exception )
352  {
353  reset();
354 
355  {
356  TiePointsLocator::InputParameters const* inputParamsPtr = dynamic_cast<
357  TiePointsLocator::InputParameters const* >( &inputParams );
358  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( inputParamsPtr, "Invalid parameters" );
359 
360  m_inputParameters = *inputParamsPtr;
361  }
362 
363  // Checking m_inRaster1Ptr
364 
366  "Invalid m_inRaster1Ptr" );
369  "Invalid m_inRaster1Ptr" );
370 
371  // Checking m_inMaskRaster1Ptr
372 
374  {
377  "Invalid m_inMaskRaster1Ptr" );
380  "Invalid m_inMaskRaster1Ptr" );
384  "Invalid m_inMaskRaster1Ptr" );
388  "Invalid m_inMaskRaster1Ptr" );
389  }
390 
391  // Checking raster 1 target area
392 
395  "Invalid m_raster1TargetAreaLineStart" );
396 
399  "Invalid m_raster1TargetAreaColStart" );
400 
403  {
406  ( ( unsigned int ) m_inputParameters.m_inRaster1Ptr->getNumberOfColumns() )
408 
411  ( ( unsigned int ) m_inputParameters.m_inRaster1Ptr->getNumberOfRows() )
413  }
414  else
415  {
420  }
421 
423  "Invalid m_raster1TargetAreaWidth" );
425  "Invalid m_raster1TargetAreaHeight" );
426 
427  // Checking raster 1 bands
428  {
429  for( unsigned int bandIdx = 0 ; bandIdx <
430  m_inputParameters.m_inRaster1Bands.size() ; ++bandIdx )
431  {
435  "Invalid m_inRaster1Bands" );
436  }
437  }
438 
439  // Checking raster 2
440 
442  "Invalid m_inRaster2Ptr" );
445  "Invalid m_inRaster2Ptr" );
446 
447  // Checking m_inMaskRaster2Ptr
448 
450  {
453  "Invalid m_inMaskRaster2Ptr" );
456  "Invalid m_inMaskRaster2Ptr" );
460  "Invalid m_inMaskRaster2Ptr" );
464  "Invalid m_inMaskRaster2Ptr" );
465  }
466 
467  // Checking raster target area
468 
471  "Invalid m_raster2TargetAreaLineStart" );
472 
475  "Invalid m_raster2TargetAreaColStart" );
476 
479  {
482  ( ( unsigned int ) m_inputParameters.m_inRaster2Ptr->getNumberOfColumns() )
484 
487  ( ( unsigned int ) m_inputParameters.m_inRaster2Ptr->getNumberOfRows() )
489  }
490  else
491  {
496  }
497 
499  "Invalid m_raster2TargetAreaWidth" );
501  "Invalid m_raster2TargetAreaHeight" );
502 
503  // Checking raster 2 bands
504 
505  {
506  for( unsigned int bandIdx = 0 ; bandIdx <
507  m_inputParameters.m_inRaster2Bands.size() ; ++bandIdx )
508  {
512  "Invalid m_inRaster2Bands" );
513  }
514  }
515 
516  // Checking strategy
517 
520  "Invalid strategy" );
521 
522  // Checking other parameters
523 
525  "Invalid m_pixelSizeXRelation" )
526 
528  "Invalid m_pixelSizeYRelation" )
529 
531  "Invalid m_geomTransfMaxError" )
532 
535  "Invalid m_geomTransfName" );
536 
539  "Invalid m_geometryFilterAssurance" );
540 
543  "Invalid m_subSampleOptimizationRescaleFactor" );
544 
547  "Invalid m_subSampleOptimizationMinTPAreaCoverage" );
548 
550  "Invalid m_subSampleOptimizationMinTPNumber" );
551 
553  "Invalid m_tiePointsSubSectorsSplitFactor" );
554 
555  m_isInitialized = true;
556 
557  return true;
558  }
559 
561  {
562  return m_isInitialized;
563  }
564 
567  std::vector< te::gm::GTParameters::TiePoint >& tiePoints,
568  std::vector< double >& tiePointsWeights )
569  {
570  tiePoints.clear();
571  tiePointsWeights.clear();
572 
574  te::rp::TiePointsLocatorStrategy::MatchedInterestPointsSetT::const_iterator
575  itB = matchedInterestPoints.begin();
576  const te::rp::TiePointsLocatorStrategy::MatchedInterestPointsSetT::const_iterator
577  itE = matchedInterestPoints.end();
578 
579  while( itB != itE )
580  {
581  auxTP.first.x = itB->m_point1.m_x;
582  auxTP.first.y = itB->m_point1.m_y;
583  auxTP.second.x = itB->m_point2.m_x;
584  auxTP.second.y = itB->m_point2.m_y;
585  tiePoints.push_back( auxTP );
586 
587  tiePointsWeights.push_back( itB->m_feature );
588 
589  ++itB;
590  }
591  }
592 
593  } // end namespace rp
594 } // end namespace te
595 
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...
Base exception class for plugin module.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
double GetTPConvexHullArea(const ContainerT &tiePoints, const bool useTPSecondCoordPair)
Returns the tie points converx hull area.
TiePointsLocatorStrategyParameters const * getSpecStrategyParams() const
Returns a pointer to the internal specific tie-points locator strategy parameters.
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.
static dictionary_type & getDictionary()
It returns a reference to the internal dictionary of concrete factories.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
std::string m_interesPointsLocationStrategyName
The strategy used to locate interest points (default:Moravec).
Raster tie points locator strategy factory base class.
2D Geometric transformation base class.
Tie-Pointsr locator SURF strategy.
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
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
void setSpecStrategyParams(const TiePointsLocatorStrategyParameters &specStratParams)
Set specific tie-points locator strategy parameters.
unsigned int m_maxTiePoints
The maximum number of tie-points to generate (0:Automatically calculated, default:2500).
std::unique_ptr< te::gm::GeometricTransformation > m_transformationPtr
The generated geometric transformation with the base mininum required tie-points set ( depending on t...
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
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.
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.
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
bool m_enableGeometryFilter
Enable/disable the geometry filter/outliers remotion (default:true).
std::vector< unsigned int > m_inRaster1Bands
Bands to be used from the input raster 1.
URI C++ Library.
Definition: Attributes.h:37
double m_subSampleOptimizationMinTPAreaCoverage
Sub-sampled optimization - mininumum required tie-points covered area percent of each raster area - v...
static te::rp::TiePointsLocatorStrategy * 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...
te::rst::Raster const * m_inRaster1Ptr
Input raster 1.
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)
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...
Raster Processing functions.
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::unique_ptr< GeometricTransformation > &outTransf)
Apply a RANSAC based outliers remotion strategy.
Definition: GTFilter.cpp:194
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:400
virtual void reset() _NOEXCEPT_OP(false)
Clear all internal allocated objects and reset the algorithm to its initial state.
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
#define TERP_INSTANCE_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged, the current instance erro...
Definition: Macros.h:200
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:150
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.