TiePointsLocatorMoravecStrategy.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/TiePointsLocatorMoravecStrategy.cpp
22  \brief Tie-Pointsr locator Moravec strategy.
23 */
24 
26 #include "Macros.h"
27 #include "../common/progress/TaskProgress.h"
28 #include "../common/MathUtils.h"
29 
30 #include <memory>
31 
32 namespace
33 {
35  TiePointsLocatorMoravecStrategyFactoryInstance;
36 }
37 
38 namespace te
39 {
40  namespace rp
41  {
43  {
44  reset();
45  }
46 
49  {
50  reset();
51  operator=( other );
52  }
53 
55  {
56  reset();
57  }
58 
60  throw( te::rp::Exception )
61  {
66  }
67 
71  {
72  reset();
73 
78 
79  return *this;
80  }
81 
84  {
85  return new Parameters( *this );
86  }
87 
88  /* ------------------------------------------------------------------------*/
89 
91  {
92  reset();
93  }
94 
96  {
97  reset();
98  }
99 
101  const double subSampleOptimizationRescaleFactor,
102  const TiePointsLocatorStrategyParameters& inputSpecParams,
103  std::unique_ptr< TiePointsLocatorStrategyParameters >& subSampledSpecParamsPtr ) const
104  {
105  Parameters const* inputSpecParamsPtr = dynamic_cast< Parameters const* >( &inputSpecParams );
106  TERP_TRUE_OR_THROW( inputSpecParamsPtr, "Invalid specific parameters" );
107 
108  subSampledSpecParamsPtr.reset( (te::rp::TiePointsLocatorStrategyParameters*)inputSpecParams.clone() );
109 
110  Parameters* subSampledSpecParamsNakedPtr = dynamic_cast< Parameters* >( subSampledSpecParamsPtr.get() );
111  TERP_TRUE_OR_THROW( subSampledSpecParamsNakedPtr, "Invalid specific parameters" );
112 
113  subSampledSpecParamsNakedPtr->m_moravecCorrelationWindowWidth =
114  3
115  +
116  (unsigned int)
117  (
118  ((double)( inputSpecParamsPtr->m_moravecCorrelationWindowWidth - 3 ))
119  *
120  subSampleOptimizationRescaleFactor
121  );
122  subSampledSpecParamsNakedPtr->m_moravecCorrelationWindowWidth +=
123  ( ( subSampledSpecParamsNakedPtr->m_moravecCorrelationWindowWidth % 2 ) ?
124  0 : 1 );
125 
126  subSampledSpecParamsNakedPtr->m_moravecWindowWidth =
127  3
128  +
129  (unsigned int)
130  (
131  ((double)( inputSpecParamsPtr->m_moravecWindowWidth - 3 ))
132  *
133  subSampleOptimizationRescaleFactor
134  );
135  subSampledSpecParamsNakedPtr->m_moravecWindowWidth +=
136  ( ( subSampledSpecParamsNakedPtr->m_moravecWindowWidth % 2 ) ?
137  0 : 1 );
138  }
139 
141  std::unique_ptr< TiePointsLocatorStrategyParameters >& defaultSpecParamsPtr ) const
142  {
143  defaultSpecParamsPtr.reset( new Parameters() );
144  }
145 
147  const te::rp::TiePointsLocatorInputParameters& inputParameters )
148  {
149  m_inputParameters = inputParameters;
150 
152  == 1, "Invalid number of raster 1 bands" );
154  == 1, "Invalid number of raster 2 bands" );
155 
156  // other stuff
157 
158  Parameters const* specParsPtr = dynamic_cast< Parameters const* >(
159  inputParameters.getSpecStrategyParams() );
160  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( specParsPtr, "Invalid specific parameters" );
161 
162  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( ( specParsPtr->m_moravecCorrelationWindowWidth % 2 ) != 0,
163  "Invalid m_moravecCorrelationWindowWidth (should be an odd number)" );
164  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( specParsPtr->m_moravecCorrelationWindowWidth > 2,
165  "Invalid m_moravecCorrelationWindowWidth" );
166 
167  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( ( specParsPtr->m_moravecWindowWidth % 2 ) != 0,
168  "Invalid m_moravecWindowWidth (should be an odd number)" );
169  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( specParsPtr->m_moravecWindowWidth > 2,
170  "Invalid m_moravecWindowWidth" );
171 
172  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( ( specParsPtr->m_moravecMinAbsCorrelation >= 0 ) &&
173  ( specParsPtr->m_moravecMinAbsCorrelation <= 1.0 ),
174  "Invalid m_moravecMinAbsCorrelation" );
175 
176  m_isInitialized = true;
177 
178  // Defining the number of tie points
179 
181  {
183  }
184 
185  return true;
186  }
187 
189  {
191 
192  m_isInitialized = false;
194  }
195 
197  te::gm::GeometricTransformation const * const raster1ToRaster2TransfPtr,
198  const double raster1ToRaster2TransfDMapError,
199  MatchedInterestPointsSetT& matchedInterestPoints )
200  {
201  matchedInterestPoints.clear();
202 
203  if( !m_isInitialized )
204  {
205  return false;
206  }
207 
208  /* Calculating the rescale factors
209  factor = rescaled_orignal_image / original_image */
210 
211  double raster1XRescFact = 1.0;
212  double raster1YRescFact = 1.0;
213  double raster2XRescFact = 1.0;
214  double raster2YRescFact = 1.0;
215 
217  {
218  /* The image 1 has poor resolution - bigger pixel resolution values -
219  and image 2 needs to be rescaled down */
220 
221  raster2XRescFact = 1.0 / m_inputParameters.m_pixelSizeXRelation;
222  }
223  else if( m_inputParameters.m_pixelSizeXRelation < 1.0 )
224  {
225  /* The image 2 has poor resolution - bigger pixel resolution values
226  and image 1 needs to be rescaled down */
227 
228  raster1XRescFact = m_inputParameters.m_pixelSizeXRelation;
229  }
230 
232  {
233  /* The image 1 has poor resolution - bigger pixel resolution values -
234  and image 2 needs to be rescaled down */
235 
236  raster2YRescFact = 1.0 / m_inputParameters.m_pixelSizeYRelation;
237  }
238  else if( m_inputParameters.m_pixelSizeYRelation < 1.0 )
239  {
240  /* The image 2 has poor resolution - bigger pixel resolution values
241  and image 1 needs to be rescaled down */
242 
243  raster1YRescFact = m_inputParameters.m_pixelSizeYRelation;
244  }
245 
250 
251  // Defining the maximum number of interest points
252 
253  unsigned int maxInterestPoints1 = m_inputParameters.m_maxTiePoints;
254  unsigned int maxInterestPoints2 = m_inputParameters.m_maxTiePoints;
255 
256  {
257  const double width1 = ((double)m_inputParameters.m_raster1TargetAreaWidth)
258  * raster1XRescFact;
259  const double height1 = ((double)m_inputParameters.m_raster1TargetAreaHeight)
260  * raster1YRescFact;
261 
262  const double width2 = ((double)m_inputParameters.m_raster2TargetAreaWidth)
263  * raster2XRescFact;
264  const double height2 = ((double)m_inputParameters.m_raster2TargetAreaHeight)
265  * raster2YRescFact;
266 
267  const double area1 = width1 * height1;
268  const double area2 = width2 * height2;
269 
270  if( area1 > area2 )
271  {
272  maxInterestPoints1 = (unsigned int)( ((double)maxInterestPoints1)*( area1 / area2 ) );
273  }
274  else
275  {
276  maxInterestPoints2 = (unsigned int)( ((double)maxInterestPoints2)*( area2 / area1 ) );
277  }
278  }
279 
280  // progress
281 
282  std::unique_ptr< te::common::TaskProgress > progressPtr;
284  {
285  progressPtr.reset( new te::common::TaskProgress );
286  progressPtr->setTotalSteps( 11 );
287  progressPtr->setMessage( "Locating tie points" );
288  progressPtr->pulse();
289  if( ! progressPtr->isActive() ) return false;
290  }
291 
292  // Generating raster 1 features
293 
294  FloatsMatrix raster1Features;
295  InterestPointsSetT raster1InterestPoints;
296  {
297  // loading raster data
298  std::vector< boost::shared_ptr< FloatsMatrix > > raster1Data;
299  UCharsMatrix maskRaster1Data;
300  double achievedRescaleFactorX = 0;
301  double achievedRescaleFactorY = 0;
302 
303  if( !loadRasterData(
307  0,
312  raster1XRescFact,
313  raster1YRescFact,
315  20,
316  raster1Data,
317  maskRaster1Data,
318  achievedRescaleFactorX,
319  achievedRescaleFactorY ) )
320  {
321  return false;
322  }
323 
324  raster1XRescFact = achievedRescaleFactorX;
325  raster1YRescFact = achievedRescaleFactorY;
326 
327 // createTifFromMatrix( *(raster1Data[ 0 ]), InterestPointsSetT(), "raster1Loaded");
328 
330  {
331  progressPtr->pulse();
332  if( ! progressPtr->isActive() ) return false;
333  }
334 
335  // applying the noise filter
336 
337  if( ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecNoiseFilterIterations )
338  {
339  boost::shared_ptr< FloatsMatrix > tempMatrix(
340  new FloatsMatrix );
342  "Cannot allocate image matrix" );
343 
344  if( !applyMeanFilter( *(raster1Data[ 0 ]),
345  *tempMatrix,
346  ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecNoiseFilterIterations ) )
347  {
348  return false;
349  }
350 
351  raster1Data[ 0 ]->reset();
352  raster1Data[ 0 ] = tempMatrix;
353 
354 // createTifFromMatrix( *(raster1Data[ 0 ]), InterestPointsSetT(), "raster1Filtered");
355  }
356 
358  {
359  progressPtr->pulse();
360  if( ! progressPtr->isActive() ) return false;
361  }
362 
363  // locating interest points
364 
366  maxInterestPoints1,
367  *(raster1Data[ 0 ]),
368  maskRaster1Data.getLinesNumber() ? (&maskRaster1Data) : nullptr,
369  raster1InterestPoints ) )
370  {
371  return false;
372  }
373 
374 /* double x, y;
375  TERP_TRUE_OR_THROW( checkForDuplicatedInterestPoints( raster1InterestPoints, x, y ),
376  "Duplicated point " + boost::lexical_cast< std::string >( x ) + "," +
377  boost::lexical_cast< std::string >( y ) );
378 
379  createTifFromMatrix( *(raster1Data[ 0 ]), raster1InterestPoints, "raster1InterestPoints"); */
380 
382  {
383  progressPtr->pulse();
384  if( ! progressPtr->isActive() ) return false;
385  }
386 
387  // Generting features (one feature per line)
388 
389  raster1Features.reset( FloatsMatrix::RAMMemPol );
390  InterestPointsSetT auxInterestPoints;
391 
393  raster1InterestPoints,
394  ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecCorrelationWindowWidth,
395  *(raster1Data[ 0 ]),
396  raster1Features,
397  auxInterestPoints ),
398  "Error generating raster 1 features" );
399 
400 // features2Tiff( raster1Features, raster1InterestPoints, "raster1features" );
401 
402  // Bring interest points to full raster indexed coords reference
403 
404  raster1InterestPoints.clear();
405 
406  {
407  InterestPointsSetT::iterator itB = auxInterestPoints.begin();
408  const InterestPointsSetT::iterator itE = auxInterestPoints.end();
409  InterestPointT auxIP;
410 
411  while( itB != itE )
412  {
413  auxIP = *itB;
414  auxIP.m_x = static_cast<unsigned int>((auxIP.m_x / raster1XRescFact) +
416  auxIP.m_y = static_cast<unsigned int>((auxIP.m_y / raster1YRescFact) +
418 
419  raster1InterestPoints.insert( auxIP );
420 
421  ++itB;
422  }
423  }
424 
426  {
427  progressPtr->pulse();
428  if( ! progressPtr->isActive() ) return false;
429  }
430  }
431 
432  // Generating raster 2 features
433 
434  FloatsMatrix raster2Features;
435  InterestPointsSetT raster2InterestPoints;
436  {
437  // Loading image data
438 
439  std::vector< boost::shared_ptr< FloatsMatrix > > raster2Data;
440  UCharsMatrix maskRaster2Data;
441  double achievedRescaleFactorX = 0;
442  double achievedRescaleFactorY = 0;
443 
444  if( !loadRasterData(
448  0,
453  raster2XRescFact,
454  raster2YRescFact,
456  20,
457  raster2Data,
458  maskRaster2Data,
459  achievedRescaleFactorX,
460  achievedRescaleFactorY ) )
461  {
462  return false;
463  }
464 
465  raster2XRescFact = achievedRescaleFactorX;
466  raster2YRescFact = achievedRescaleFactorY;
467 
469  {
470  progressPtr->pulse();
471  if( ! progressPtr->isActive() ) return false;
472  }
473 
474  // applying the noise filter
475 
476  if( ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecNoiseFilterIterations )
477  {
478  boost::shared_ptr< FloatsMatrix > tempMatrix(
479  new FloatsMatrix );
480 
481  tempMatrix.reset( new FloatsMatrix );
482  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( tempMatrix->reset( 0, 0,
484  "Cannot allocate image matrix" );
485 
486  if( !applyMeanFilter( *(raster2Data[ 0 ]),
487  *tempMatrix, ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecNoiseFilterIterations ) )
488  {
489  return false;
490  }
491 
492  raster2Data[ 0 ] = tempMatrix;
493 
494 // createTifFromMatrix( *(raster2Data[ 0 ]), InterestPointsSetT(), "raster2Filtered");
495  }
496 
498  {
499  progressPtr->pulse();
500  if( ! progressPtr->isActive() ) return false;
501  }
502 
503  // locating interest points
504 
506  maxInterestPoints2,
507  *(raster2Data[ 0 ]),
508  maskRaster2Data.getLinesNumber() ? (&maskRaster2Data) : nullptr,
509  raster2InterestPoints ) )
510  {
511  return false;
512  }
513 
514 /* double x, y;
515  TERP_TRUE_OR_THROW( checkForDuplicatedInterestPoints( raster2InterestPoints, x, y ),
516  "Duplicated point " + boost::lexical_cast< std::string >( x ) + "," +
517  boost::lexical_cast< std::string >( y ) );
518 
519  createTifFromMatrix( *(raster2Data[ 0 ]), raster2InterestPoints, "raster2InterestPoints");*/
520 
522  {
523  progressPtr->pulse();
524  if( ! progressPtr->isActive() ) return false;
525  }
526 
527  // Generting features (one feature per line)
528 
529  raster2Features.reset( FloatsMatrix::RAMMemPol );
530  InterestPointsSetT auxInterestPoints;
531 
533  raster2InterestPoints,
534  ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecCorrelationWindowWidth,
535  *(raster2Data[ 0 ]),
536  raster2Features,
537  auxInterestPoints ),
538  "Error generating raster 2 features" );
539 
540 
541 // features2Tiff( raster2Features, raster2InterestPoints, "raster2features" );
542 
543  // Bring interest points to full raster indexed coords reference
544 
545  raster2InterestPoints.clear();
546 
547  {
548  InterestPointsSetT::iterator itB = auxInterestPoints.begin();
549  const InterestPointsSetT::iterator itE = auxInterestPoints.end();
550  InterestPointT auxIP;
551 
552  while( itB != itE )
553  {
554  auxIP = *itB;
555  auxIP.m_x = static_cast<unsigned int>((auxIP.m_x / raster2XRescFact) +
557  auxIP.m_y = static_cast<unsigned int>((auxIP.m_y / raster2YRescFact) +
559 
560  raster2InterestPoints.insert( auxIP );
561 
562  ++itB;
563  }
564  }
565 
567  {
568  progressPtr->pulse();
569  if( ! progressPtr->isActive() ) return false;
570  }
571  }
572 
573  // Matching features
574 
575  MatchedInterestPointsSetT internalMatchedInterestPoints;
576 
578  raster1Features,
579  raster2Features,
580  raster1InterestPoints,
581  raster2InterestPoints,
582  raster1ToRaster2TransfPtr,
583  raster1ToRaster2TransfDMapError,
584  internalMatchedInterestPoints ),
585  "Error matching features" );
586 
588  {
589  progressPtr->pulse();
590  if( ! progressPtr->isActive() ) return false;
591  }
592 
593  // Clean anused data
594 
595  raster1Features.reset();
596  raster2Features.reset();
597  raster1InterestPoints.clear();
598  raster2InterestPoints.clear();
599 
600  // Generating the output matched interest points
601 
602  {
603  MatchedInterestPointsT auxMatchedPoints;
604  MatchedInterestPointsSetT::const_iterator itB = internalMatchedInterestPoints.begin();
605  const MatchedInterestPointsSetT::const_iterator itE = internalMatchedInterestPoints.end();
606 
607  float minFeatureValue1 = FLT_MAX;
608  float maxFeatureValue1 = (-1.0) * FLT_MAX;
609  float minFeatureValue2 = FLT_MAX;
610  float maxFeatureValue2 = (-1.0) * FLT_MAX;
611  float minCorrelationValue = FLT_MAX;
612  float maxCorrelationValue = (-1.0) * FLT_MAX;
613 
614  itB = internalMatchedInterestPoints.begin();
615  while( itB != itE )
616  {
617  if( minFeatureValue1 > itB->m_point1.m_feature1 )
618  minFeatureValue1 = itB->m_point1.m_feature1;
619  if( maxFeatureValue1 < itB->m_point1.m_feature1 )
620  maxFeatureValue1 = itB->m_point1.m_feature1;
621 
622  if( minFeatureValue2 > itB->m_point2.m_feature1 )
623  minFeatureValue2 = itB->m_point2.m_feature1;
624  if( maxFeatureValue2 < itB->m_point2.m_feature1 )
625  maxFeatureValue2 = itB->m_point2.m_feature1;
626 
627  if( minCorrelationValue > itB->m_feature )
628  minCorrelationValue = itB->m_feature;
629  if( maxCorrelationValue < itB->m_feature )
630  maxCorrelationValue = itB->m_feature;
631 
632  ++itB;
633  }
634 
635  float featureValue1Range = maxFeatureValue1 - minFeatureValue1;
636  float featureValue2Range = maxFeatureValue2 - minFeatureValue2;
637  float correlationValueRange = maxCorrelationValue - minCorrelationValue;
638 
639  if( ( featureValue1Range == 0.0 ) || ( featureValue2Range == 0.0 ) ||
640  ( correlationValueRange == 0.0 ) )
641  {
642  itB = internalMatchedInterestPoints.begin();
643 
644  while( itB != itE )
645  {
646  auxMatchedPoints = *itB;
647  auxMatchedPoints.m_feature = 1.0;
648  matchedInterestPoints.insert( auxMatchedPoints );
649 
650  ++itB;
651  }
652  }
653  else
654  {
655  itB = internalMatchedInterestPoints.begin();
656 
657  while( itB != itE )
658  {
659  auxMatchedPoints = *itB;
660  auxMatchedPoints.m_feature =
661  (
662  (
663  ( auxMatchedPoints.m_feature - minCorrelationValue )
664  /
665  correlationValueRange
666  )
667  +
668  (
669  ( auxMatchedPoints.m_point1.m_feature1 - minFeatureValue1 )
670  /
671  featureValue1Range
672  )
673  +
674  (
675  ( auxMatchedPoints.m_point2.m_feature1 - minFeatureValue2 )
676  /
677  featureValue2Range
678  )
679  )
680  /
681  static_cast<float>(3.0);
682 
683  matchedInterestPoints.insert( auxMatchedPoints );
684 
685  ++itB;
686  }
687  }
688  }
689 
691  {
692  progressPtr->pulse();
693  if( ! progressPtr->isActive() ) return false;
694  }
695 
696  return true;
697  }
698 
700  {
701  TERP_TRUE_OR_THROW( m_isInitialized, "Not initialized instance" );
702 
703  unsigned int returnValue = 0;
704 
705  const unsigned int maxRastersArea = (unsigned int)
706  std::max(
707  (
709  *
711  *
713  *
715  )
716  ,
717  (
719  *
721  *
723  *
725  )
726  );
727 
728  returnValue = maxRastersArea /
729  ( ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecCorrelationWindowWidth *
730  ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecCorrelationWindowWidth );
731 
732  // This is because the features and matching matrix are being allocated in RAM
733 
734  const double totalPhysMem = (double)te::common::GetTotalPhysicalMemory();
735  const double usedVMem = (double)te::common::GetUsedVirtualMemory();
736  const double totalVMem = (double)te::common::GetTotalVirtualMemory();
737  const double freeVMem = 0.75 * std::min( totalPhysMem, ( totalVMem - usedVMem ) );
738 
739  const double featureElementsNumber = (double)(
740  ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecCorrelationWindowWidth *
741  ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecCorrelationWindowWidth );
742 
743  double maxFeaturesMemory =
744  std::max(
745  0.0
746  ,
747  (
748  (-2.0) * featureElementsNumber
749  +
750  std::sqrt(
751  ( 4.0 * featureElementsNumber * featureElementsNumber )
752  +
753  ( 4.0 * freeVMem / ((double)sizeof( float ) ) )
754  )
755  )
756  );
757  maxFeaturesMemory =
758  std::max(
759  maxFeaturesMemory
760  ,
761  (
762  (-2.0) * featureElementsNumber
763  -
764  std::sqrt(
765  ( 4.0 * featureElementsNumber * featureElementsNumber )
766  +
767  ( 4.0 * freeVMem / ((double)sizeof( float ) ) )
768  )
769  )
770  );
771 
772  returnValue = std::min( returnValue, (unsigned int)maxFeaturesMemory );
773 
774  return returnValue;
775  }
776 
778  FloatsMatrix& outputData, const unsigned int iterationsNumber )
779  {
780  if( iterationsNumber == 0 )
781  {
782  outputData = inputData;
783  }
784  else
785  {
786  if( inputData.getColumnsNumber() < 3 )
787  {
788  return false;
789  }
790  if( inputData.getLinesNumber() < 3 )
791  {
792  return false;
793  }
794 
795  TERP_TRUE_OR_RETURN_FALSE( outputData.reset( inputData.getLinesNumber(),
796  inputData.getColumnsNumber() ), "Cannot allocate image matrix" );
797 
798  const unsigned int nLines = inputData.getLinesNumber();
799  const unsigned int nCols = inputData.getColumnsNumber();
800  const unsigned int lastLineIndex = nLines - 1;
801  const unsigned int lastColIndex = nCols - 1;
802  unsigned int currLine = 0;
803  unsigned int currCol = 0;
804 
805  // internal temp matrixes
806 
807  FloatsMatrix tempMatrix;
808 
809  if( iterationsNumber > 1 )
810  {
811  TERP_TRUE_OR_RETURN_FALSE( tempMatrix.reset( nLines, nCols,
813  "Cannot allocate image matrix" );
814  }
815 
816  /* Fill borders with zero */
817 
818  for( currLine = 0 ; currLine < nLines ; ++currLine ) {
819  outputData( currLine, 0 ) = 0.0;
820  outputData( currLine, lastColIndex ) = 0.0;
821  }
822 
823  for( currCol = 0 ; currCol < nCols ; ++currCol ) {
824  outputData( 0, currCol ) = 0.0;
825  outputData( lastLineIndex, currCol ) = 0.0;
826  }
827 
828  /* Smoothing */
829 
830  FloatsMatrix const* inputPtr = nullptr;
831  FloatsMatrix* outputPtr = nullptr;
832  FloatsMatrix const* auxPtr = nullptr;
833  float* outputLinePtr = nullptr;
834  unsigned int prevLine = 0;
835  unsigned int prevCol = 0;
836  unsigned int nextLine = 0;
837  unsigned int nextCol = 0;
838 
839  for( unsigned int iteration = 0 ; iteration < iterationsNumber ;
840  ++iteration )
841  {
842  if( iteration == 0 )
843  {
844  inputPtr = &inputData;
845 
846  if( iterationsNumber > 1 )
847  outputPtr = &tempMatrix;
848  else
849  outputPtr = &outputData;
850  }
851  else if( iteration == iterationsNumber - 1 )
852  {
853  inputPtr = outputPtr;
854  outputPtr = &outputData;
855  }
856  else
857  {
858  auxPtr = inputPtr;
859  inputPtr = outputPtr;
860  outputPtr = (FloatsMatrix*)auxPtr;
861  }
862 
863  const FloatsMatrix& internalInputMatrix = *inputPtr;
864 
865  for( currLine = 1 ; currLine < lastLineIndex ; ++currLine )
866  {
867  prevLine = currLine - 1;
868  nextLine = currLine + 1;
869 
870  outputLinePtr = outputPtr->operator[]( currLine );
871 
872  for( currCol = 1 ; currCol < lastColIndex ; ++currCol )
873  {
874  prevCol = currCol - 1;
875  nextCol = currCol + 1;
876 
877  outputLinePtr[ currCol ] =
878  (
879  internalInputMatrix( prevLine, prevCol )
880  + internalInputMatrix( prevLine, currCol )
881  + internalInputMatrix( prevLine, nextCol )
882  + internalInputMatrix( currLine, prevCol )
883  + internalInputMatrix( currLine, nextCol )
884  + internalInputMatrix( nextLine, prevCol )
885  + internalInputMatrix( nextLine, currCol )
886  + internalInputMatrix( nextLine, nextCol )
887  ) / 8.0f;
888  }
889  }
890  }
891  }
892 
893  return true;
894  }
895 
897  const unsigned int maxInterestPoints,
898  const FloatsMatrix& rasterData,
899  UCharsMatrix const* maskRasterDataPtr,
900  InterestPointsSetT& interestPoints ) const
901  {
902  interestPoints.clear();
903 
904  const unsigned int minRasterWidthAndHeight =
905  ( 4 * ( ( ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecWindowWidth ) / 2 ) ) + 1;
906  // There is not enough data to look for interest points!
907  if( rasterData.getColumnsNumber() < minRasterWidthAndHeight ) return true;
908  if( rasterData.getLinesNumber() < minRasterWidthAndHeight ) return true;
909 
910  bool returnValue = true;
911  boost::mutex rastaDataAccessMutex;
912  boost::mutex interestPointsAccessMutex;
913  unsigned int nextRasterLinesBlockToProcess = 0;
914  std::vector< InterestPointsSetT > interestPointsSubSectors(
917 
918  MoravecLocatorThreadParams threadParams;
919  threadParams.m_returnValuePtr = &returnValue;
920  threadParams.m_rastaDataAccessMutexPtr = &rastaDataAccessMutex;
921  threadParams.m_interestPointsAccessMutexPtr = &interestPointsAccessMutex;
923  &nextRasterLinesBlockToProcess;
924  threadParams.m_interestPointsSubSectorsPtr = &interestPointsSubSectors;
925  threadParams.m_maxInterestPointsBySubSector = maxInterestPoints /
929  threadParams.m_rasterDataPtr = &rasterData;
930  threadParams.m_maskRasterDataPtr = maskRasterDataPtr;
931  threadParams.m_moravecWindowWidth = ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecWindowWidth;
932 
934  {
936 
937  boost::thread_group threads;
938 
939  for( unsigned int threadIdx = 0 ; threadIdx < threadParams.m_processingBlocksNumber ;
940  ++threadIdx )
941  {
942  threads.add_thread( new boost::thread(
944  &threadParams ) );
945  }
946 
947  threads.join_all();
948  }
949  else
950  {
951  threadParams.m_processingBlocksNumber = 1;
953  }
954 
955  // transfering sector maximas to output
956 
957  const unsigned int interestPointsSubSectorsSize = static_cast<unsigned int>(interestPointsSubSectors.size());
958 
959  for( unsigned int interestPointsSubSectorsIdx = 0 ; interestPointsSubSectorsIdx <
960  interestPointsSubSectorsSize ; ++interestPointsSubSectorsIdx )
961  {
962  interestPoints.insert(
963  interestPointsSubSectors[ interestPointsSubSectorsIdx ].begin(),
964  interestPointsSubSectors[ interestPointsSubSectorsIdx ].end() );
965  }
966 
967  return returnValue;
968  }
969 
971  {
972  assert( paramsPtr );
973  assert( paramsPtr->m_returnValuePtr );
974  assert( paramsPtr->m_moravecWindowWidth > 2 );
975  assert( paramsPtr->m_rasterDataPtr );
976  assert( paramsPtr->m_interestPointsSubSectorsPtr );
977  assert( paramsPtr->m_rastaDataAccessMutexPtr );
978  assert( paramsPtr->m_interestPointsAccessMutexPtr );
979  assert( paramsPtr->m_processingBlocksNumber > 0 );
980  assert( paramsPtr->m_nextRasterLinesBlockToProcessValuePtr );
981 
982  // globals
983 
984  paramsPtr->m_rastaDataAccessMutexPtr->lock();
985 
986  const unsigned int moravecWindowWidth = paramsPtr->m_moravecWindowWidth;
987  const unsigned int moravecWindowRadius = moravecWindowWidth / 2;
988  const unsigned int tiePointsSubSectorsSplitFactor = paramsPtr->m_tiePointsSubSectorsSplitFactor;
989  const unsigned int rowsBySubSector = (unsigned int)std::ceil(
990  ((double)paramsPtr->m_rasterDataPtr->getLinesNumber())
991  /
992  ((double)tiePointsSubSectorsSplitFactor) );
993  const unsigned int colsBySubSector = (unsigned int)std::ceil(
994  ((double)paramsPtr->m_rasterDataPtr->getColumnsNumber())
995  /
996  ((double)tiePointsSubSectorsSplitFactor) );
997  const unsigned int maxInterestPointsBySubSector = paramsPtr->m_maxInterestPointsBySubSector;
998  const unsigned int rasterLines = paramsPtr->m_rasterDataPtr->getLinesNumber();
999  const unsigned int lastBufferLineIdx = moravecWindowWidth - 1;
1000  const unsigned int bufferCols = paramsPtr->m_rasterDataPtr->getColumnsNumber();
1001  const unsigned int rasterBufferLineSizeBytes = sizeof(
1002  FloatsMatrix::ElementTypeT ) * bufferCols;
1003  const unsigned int maskRasterBufferLineSizeBytes = sizeof(
1005  bufferCols;
1006  const unsigned int processingBlocksNumber = paramsPtr->m_processingBlocksNumber;
1007  const unsigned int maxLinesPerProcessingBlock = (unsigned int)
1008  std::ceil(
1009  ((double)rasterLines)
1010  /
1011  ((double)processingBlocksNumber)
1012  );
1013 
1014  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1015 
1016  // Allocating the internal raster data buffer
1017  // and the mask raster buffer
1018 
1019  FloatsMatrix rasterBufferDataHandler;
1020  if( ! rasterBufferDataHandler.reset( moravecWindowWidth, bufferCols,
1022  {
1023  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1024  *(paramsPtr->m_returnValuePtr) = false;
1025  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1026  return;
1027  }
1028 
1029  boost::scoped_array< float* > rasterBufferHandler( new float*[ moravecWindowWidth ] );
1030  for( unsigned int rasterBufferDataHandlerLine = 0 ; rasterBufferDataHandlerLine <
1031  moravecWindowWidth ; ++rasterBufferDataHandlerLine )
1032  {
1033  rasterBufferHandler[ rasterBufferDataHandlerLine ] = rasterBufferDataHandler[
1034  rasterBufferDataHandlerLine ];
1035  }
1036 
1037  float** rasterBufferPtr = rasterBufferHandler.get();
1038 
1039  // Allocating the mask raster buffer
1040 
1041  UCharsMatrix maskRasterBufferDataHandler;
1042 
1043  boost::scoped_array< unsigned char* > maskRasterBufferHandler( new unsigned char*[ moravecWindowWidth ] );
1044 
1045  unsigned char** maskRasterBufferPtr = nullptr;
1046 
1047  if( paramsPtr->m_maskRasterDataPtr )
1048  {
1049  if( ! maskRasterBufferDataHandler.reset( moravecWindowWidth, bufferCols,
1051  {
1052  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1053  *(paramsPtr->m_returnValuePtr) = false;
1054  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1055  return;
1056  }
1057 
1058  for( unsigned int maskRasterBufferDataHandlerLine = 0 ; maskRasterBufferDataHandlerLine <
1059  moravecWindowWidth ; ++maskRasterBufferDataHandlerLine )
1060  {
1061  maskRasterBufferHandler[ maskRasterBufferDataHandlerLine ] = maskRasterBufferDataHandler[
1062  maskRasterBufferDataHandlerLine ];
1063  }
1064 
1065  maskRasterBufferPtr = maskRasterBufferHandler.get();
1066  }
1067 
1068  // Allocating the internal maximas values data buffer
1069 
1070  FloatsMatrix maximasBufferDataHandler;
1071  if( ! maximasBufferDataHandler.reset( moravecWindowWidth, bufferCols,
1073  {
1074  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1075  *(paramsPtr->m_returnValuePtr) = false;
1076  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1077  return;
1078  }
1079 
1080  boost::scoped_array< float* > maximasBufferHandler( new float*[ moravecWindowWidth ] );
1081  float** maximasBufferPtr = maximasBufferHandler.get();
1082  unsigned int bufferCol = 0;
1083  for( unsigned int maximasBufferDataHandlerLine = 0 ; maximasBufferDataHandlerLine <
1084  moravecWindowWidth ; ++maximasBufferDataHandlerLine )
1085  {
1086  maximasBufferHandler[ maximasBufferDataHandlerLine ] = maximasBufferDataHandler[
1087  maximasBufferDataHandlerLine ];
1088  for( bufferCol = 0 ; bufferCol < bufferCols ; ++bufferCol )
1089  {
1090  maximasBufferPtr[ maximasBufferDataHandlerLine ][ bufferCol ] = 0;
1091  }
1092  }
1093 
1094  // Processing each input data block
1095 
1096  std::vector< InterestPointsSetT > interestPointsSubSectors(
1098  paramsPtr->m_tiePointsSubSectorsSplitFactor );
1099 
1100  for( unsigned int rasterLinesBlockIdx = 0; rasterLinesBlockIdx <
1101  processingBlocksNumber ; ++rasterLinesBlockIdx )
1102  {
1103  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1104 
1105  if( rasterLinesBlockIdx == ( *(paramsPtr->m_nextRasterLinesBlockToProcessValuePtr ) ) )
1106  {
1107  ++( *(paramsPtr->m_nextRasterLinesBlockToProcessValuePtr ) );
1108 
1109  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1110 
1111  // Processing each raster line from the current block
1112 
1113  const unsigned int rasterLinesStart =
1114  (unsigned int)
1115  std::max(
1116  0
1117  ,
1118  (
1119  (int)(rasterLinesBlockIdx * maxLinesPerProcessingBlock )
1120  -
1121  (int)( 2 * moravecWindowRadius )
1122  )
1123  );
1124  const unsigned int rasterLinesEndBound =
1125  std::min(
1126  rasterLines
1127  ,
1128  (
1129  (
1130  ( rasterLinesBlockIdx + 1 )
1131  *
1132  maxLinesPerProcessingBlock
1133  )
1134  +
1135  ( 2 * moravecWindowRadius )
1136  )
1137  );
1138  const unsigned int varianceCalcStartRasterLineStart = rasterLinesStart +
1139  moravecWindowRadius;
1140  const unsigned int maximasLocationStartRasterLineStart = rasterLinesStart +
1141  4 * moravecWindowRadius;
1142  unsigned int windowStartBufCol = 0;
1143  const unsigned int windowEndBufColsBound = bufferCols -
1144  moravecWindowWidth;
1145  unsigned int windowStartBufOffset = 0;
1146  unsigned int windowStartBufXOffset = 0;
1147  unsigned int windowStartBufYOffset = 0;
1148  float horVar = 0;
1149  float verVar = 0;
1150  float diagVar = 0;
1151  float adiagVar = 0;
1152  float diffValue = 0;
1153  bool isLocalMaxima = false;
1154  InterestPointT auxInterestPoint;
1155  float neighborMaximaDif = 0;
1156  unsigned int interestPointsSubSectorsIdx = 0;
1157 
1158  for( unsigned int rasterLine = rasterLinesStart; rasterLine < rasterLinesEndBound ;
1159  ++rasterLine )
1160  {
1161  // read a new raster line into the last raster buffer line
1162 
1163  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1164 
1165  roolUpBuffer( rasterBufferPtr, moravecWindowWidth );
1166  memcpy( rasterBufferPtr[ lastBufferLineIdx ],
1167  paramsPtr->m_rasterDataPtr->operator[]( rasterLine ),
1168  rasterBufferLineSizeBytes );
1169 
1170  // read a new mask raster line into the last mask raster buffer line
1171  if( paramsPtr->m_maskRasterDataPtr )
1172  {
1173  roolUpBuffer( maskRasterBufferPtr, moravecWindowWidth );
1174  memcpy( maskRasterBufferPtr[ lastBufferLineIdx ],
1175  paramsPtr->m_maskRasterDataPtr->operator[]( rasterLine ),
1176  maskRasterBufferLineSizeBytes );
1177  }
1178 
1179  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1180 
1181  // calc the diretional variance for last line from the
1182  // diretional variances buffer
1183  if( rasterLine >= varianceCalcStartRasterLineStart )
1184  {
1185  roolUpBuffer( maximasBufferPtr, moravecWindowWidth );
1186 
1187  for( windowStartBufCol = 0 ; windowStartBufCol < windowEndBufColsBound ;
1188  ++windowStartBufCol )
1189  {
1190  const float& windowCenterPixelValue = rasterBufferPtr[
1191  moravecWindowRadius ][ windowStartBufCol +
1192  moravecWindowRadius ];
1193  horVar = 0;
1194  verVar = 0;
1195  diagVar = 0;
1196  adiagVar = 0;
1197 
1198  for( windowStartBufOffset = 0 ; windowStartBufOffset <
1199  moravecWindowWidth ; ++windowStartBufOffset )
1200  {
1201  diffValue = windowCenterPixelValue - rasterBufferPtr[
1202  moravecWindowRadius ][ windowStartBufCol +
1203  windowStartBufOffset ];
1204  horVar += ( diffValue * diffValue );
1205 
1206  diffValue = windowCenterPixelValue - rasterBufferPtr[
1207  windowStartBufOffset ][ windowStartBufCol +
1208  moravecWindowRadius ];
1209  verVar += ( diffValue * diffValue );
1210 
1211  diffValue = windowCenterPixelValue - rasterBufferPtr[
1212  windowStartBufOffset ][ windowStartBufCol +
1213  windowStartBufOffset ];
1214  diagVar += ( diffValue * diffValue );
1215 
1216  diffValue = windowCenterPixelValue - rasterBufferPtr[
1217  moravecWindowWidth - 1 - windowStartBufOffset ][ windowStartBufCol +
1218  windowStartBufOffset ];
1219  adiagVar += ( diffValue * diffValue );
1220  }
1221 
1222  maximasBufferPtr[ lastBufferLineIdx ][ windowStartBufCol +
1223  moravecWindowRadius ] = std::min( horVar, std::min(
1224  verVar, std::min( diagVar, adiagVar ) ) );
1225  }
1226  }
1227 
1228  // find the local maxima points for the diretional variances buffer
1229  // center line.
1230  if( rasterLine >= maximasLocationStartRasterLineStart )
1231  {
1232  for( windowStartBufCol = 0 ; windowStartBufCol < windowEndBufColsBound ;
1233  ++windowStartBufCol )
1234  {
1235  isLocalMaxima = true;
1236  const float& windowCenterPixelValue = maximasBufferPtr[
1237  moravecWindowRadius ][ windowStartBufCol +
1238  moravecWindowRadius ];
1239  auxInterestPoint.m_feature1 = 0.0;
1240 
1241  for( windowStartBufYOffset = 0 ; windowStartBufYOffset <
1242  moravecWindowWidth ; ++windowStartBufYOffset )
1243  {
1244  for( windowStartBufXOffset = 0 ; windowStartBufXOffset <
1245  moravecWindowWidth ; ++windowStartBufXOffset )
1246  {
1247  neighborMaximaDif = windowCenterPixelValue - maximasBufferPtr[
1248  windowStartBufYOffset ][ windowStartBufCol +
1249  windowStartBufXOffset ];
1250 
1251  if( neighborMaximaDif < 0.0 )
1252  {
1253  isLocalMaxima = false;
1254  windowStartBufYOffset = moravecWindowWidth;
1255  break;
1256  }
1257 
1258  auxInterestPoint.m_feature1 += std::abs( neighborMaximaDif );
1259  }
1260  }
1261 
1262  if( isLocalMaxima )
1263  {
1264  auxInterestPoint.m_x = windowStartBufCol +
1265  moravecWindowRadius;
1266  auxInterestPoint.m_y = rasterLine - ( 2 * moravecWindowRadius );
1267  assert( auxInterestPoint.m_x <
1268  paramsPtr->m_rasterDataPtr->getColumnsNumber() );
1269  assert( auxInterestPoint.m_y <
1270  paramsPtr->m_rasterDataPtr->getLinesNumber() );
1271 
1272  if(
1273  ( maskRasterBufferPtr == nullptr )
1274  ||
1275  ( maskRasterBufferPtr[ 0 ][ auxInterestPoint.m_x ] )
1276  )
1277  {
1278  interestPointsSubSectorsIdx = ( ( auxInterestPoint.m_y /
1279  rowsBySubSector ) * tiePointsSubSectorsSplitFactor ) +
1280  ( auxInterestPoint.m_x / colsBySubSector );
1281  assert( interestPointsSubSectorsIdx < interestPointsSubSectors.size() );
1282 
1283  interestPointsSubSectors[ interestPointsSubSectorsIdx ].insert(
1284  auxInterestPoint );
1285 
1286  if( interestPointsSubSectors[ interestPointsSubSectorsIdx ].size() >
1287  maxInterestPointsBySubSector )
1288  {
1289  interestPointsSubSectors[ interestPointsSubSectorsIdx ].erase(
1290  interestPointsSubSectors[ interestPointsSubSectorsIdx ].begin() );
1291  }
1292  }
1293  }
1294  }
1295  }
1296  }
1297  }
1298  else
1299  {
1300  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1301  }
1302  }
1303 
1304  // Copying the best found maximas to the external sector maximas container
1305 
1306  paramsPtr->m_interestPointsAccessMutexPtr->lock();
1307 
1308  assert( interestPointsSubSectors.size() == paramsPtr->m_interestPointsSubSectorsPtr->size() );
1309 
1310  for( unsigned int interestPointsSubSectorsIdx = 0 ; interestPointsSubSectorsIdx <
1311  interestPointsSubSectors.size() ; ++interestPointsSubSectorsIdx )
1312  {
1313  paramsPtr->m_interestPointsSubSectorsPtr->operator[](
1314  interestPointsSubSectorsIdx ).insert(
1315  interestPointsSubSectors[ interestPointsSubSectorsIdx ].begin(),
1316  interestPointsSubSectors[ interestPointsSubSectorsIdx ].end() );
1317 
1318  while( paramsPtr->m_interestPointsSubSectorsPtr->operator[](
1319  interestPointsSubSectorsIdx ).size() >
1320  maxInterestPointsBySubSector )
1321  {
1322  paramsPtr->m_interestPointsSubSectorsPtr->operator[](
1323  interestPointsSubSectorsIdx ).erase(
1324  paramsPtr->m_interestPointsSubSectorsPtr->operator[](
1325  interestPointsSubSectorsIdx ).begin() );
1326  }
1327  }
1328 
1329  paramsPtr->m_interestPointsAccessMutexPtr->unlock();
1330 
1331  }
1332 
1334  const InterestPointsSetT& interestPoints,
1335  const unsigned int correlationWindowWidth,
1336  const FloatsMatrix& rasterData,
1337  FloatsMatrix& features,
1338  InterestPointsSetT& validInteresPoints )
1339  {
1340  validInteresPoints.clear();
1341 
1342  /* The radius of a feature window rotated by 90 degrees.
1343  * over the input image */
1344 
1345  const unsigned int rotated90CorralationWindowRadius = (unsigned int)
1346  (
1347  std::ceil(
1348  sqrt(
1349  2
1350  *
1351  (
1352  ( (double)correlationWindowWidth )
1353  *
1354  ( (double)correlationWindowWidth )
1355  )
1356  ) / 2.0
1357  )
1358  );
1359 
1360  // Locating the the valid interest points
1361 
1362  {
1363  /* The radius of a feature window rotated by 90 degrees.
1364  * over the input image */
1365 
1366  const unsigned int rasterDataCols = rasterData.getColumnsNumber();
1367  const unsigned int rasterDataLines = rasterData.getLinesNumber();
1368  const unsigned int firstValidInterestPointX =
1369  rotated90CorralationWindowRadius + 1;
1370  const unsigned int lastValidInterestPointX = rasterDataCols
1371  - rotated90CorralationWindowRadius - 2;
1372  const unsigned int firstValidInterestPointY =
1373  rotated90CorralationWindowRadius + 1;
1374  const unsigned int lastValidInterestPointY = rasterDataLines
1375  - rotated90CorralationWindowRadius - 2;
1376 
1377  {
1378  InterestPointsSetT::const_iterator iPointsIt = interestPoints.begin();
1379  const InterestPointsSetT::const_iterator iPointsItEnd = interestPoints.end();
1380 
1381  while( iPointsIt != iPointsItEnd )
1382  {
1383  if( ( iPointsIt->m_x >= firstValidInterestPointX ) &&
1384  ( iPointsIt->m_x <= lastValidInterestPointX ) &&
1385  ( iPointsIt->m_y >= firstValidInterestPointY ) &&
1386  ( iPointsIt->m_y <= lastValidInterestPointY ) )
1387  {
1388  validInteresPoints.insert( *iPointsIt );
1389  }
1390 
1391  ++iPointsIt;
1392  }
1393  }
1394  }
1395 
1396  // Allocating the features matrix
1397 
1398  const unsigned int featureElemsNmb = correlationWindowWidth *
1399  correlationWindowWidth;
1400  const unsigned int featureSizeBytes = sizeof( float ) *
1401  featureElemsNmb;
1402 
1403  TERP_TRUE_OR_RETURN_FALSE( features.reset(
1404  static_cast<unsigned int>(validInteresPoints.size()), featureElemsNmb),
1405  "Cannot allocate features matrix" );
1406 
1407  // Allocating the auxiliary features buffer
1408 
1409  boost::scoped_array< float > auxFeatureBufferHandler(
1410  new float[ featureElemsNmb ] );
1411  float* auxFeatureBufferPtr = auxFeatureBufferHandler.get();
1412 
1413  // Creating features
1414 
1415  unsigned int curr_window_x_start = 0; //related to the current window over the hole image
1416  unsigned int curr_window_y_start = 0; //related to the current window over the hole image
1417  unsigned int curr_window_x_center = 0; //related to the current window over the hole image
1418  unsigned int curr_window_y_center = 0; //related to the current window over the hole image
1419  unsigned int curr_window_x_end = 0; // this coord is also counted in
1420  unsigned int curr_window_y_end = 0; // this coord is also counted in
1421  const unsigned int wind_radius = correlationWindowWidth / 2; //output window radius
1422  const float wind_radius_double = (float)wind_radius;
1423  unsigned int curr_x = 0;
1424  unsigned int curr_y = 0;
1425  float curr_x_minus_radius = 0;
1426  float curr_y_minus_radius = 0;
1427  unsigned int curr_offset = 0;
1428  float int_x_dir = 0;
1429  float int_y_dir = 0;
1430  float int_norm = 0;
1431  float rotated_curr_x = 0;/* rotaded coord - window ref */
1432  float rotated_curr_y = 0;/* rotaded coord - window ref */
1433  float rot_cos = 0;
1434  float rot_sin = 0;
1435  unsigned int rotated_curr_x_img = 0; //coords rotated but in the hole image reference
1436  unsigned int rotated_curr_y_img = 0; //coords rotated but in the hole image reference
1437  float featureElementsNormalizeFactor = 0.0;
1438  unsigned int featureElementIdx = 0;
1439  float* featurePtr = nullptr;
1440  float featureElementValue = 0.0;
1441  float featureElementMaxValue = 0.0;
1442  float featureElementMinValue = 0.0;
1443 
1444  InterestPointsSetT::const_iterator viPointsIt = validInteresPoints.begin();
1445  const InterestPointsSetT::const_iterator viPointsItEnd = validInteresPoints.end();
1446  unsigned int validInteresPointsIndex = 0 ;
1447 
1448  while( viPointsIt != viPointsItEnd )
1449  {
1450  /* Calculating the current window position */
1451 
1452  curr_window_x_center = viPointsIt->m_x;
1453  assert( curr_window_x_center >= rotated90CorralationWindowRadius );
1454  assert( curr_window_x_center < ( rasterData.getColumnsNumber() - 1 -
1455  rotated90CorralationWindowRadius ) );
1456  curr_window_y_center = viPointsIt->m_y;
1457  assert( curr_window_y_center >= rotated90CorralationWindowRadius );
1458  assert( curr_window_y_center < ( rasterData.getLinesNumber() - 1 -
1459  rotated90CorralationWindowRadius ) );
1460 
1461  curr_window_x_start = curr_window_x_center - wind_radius;
1462  curr_window_y_start = curr_window_y_center - wind_radius;
1463  curr_window_x_end = curr_window_x_start + correlationWindowWidth - 1;
1464  curr_window_y_end = curr_window_y_start + correlationWindowWidth - 1;
1465 
1466  /* Estimating the intensity vector X direction */
1467 
1468  int_x_dir = 0;
1469 
1470  for( curr_y = curr_window_y_start ; curr_y <= curr_window_y_end ;
1471  ++curr_y )
1472  {
1473  for( curr_offset = 0 ; curr_offset < wind_radius ;
1474  ++curr_offset )
1475  {
1476  int_x_dir += rasterData( curr_y, curr_window_x_end - curr_offset ) -
1477  rasterData( curr_y, curr_window_x_start + curr_offset );
1478  }
1479  }
1480 
1481  /* Estimating the intensity vector y direction */
1482 
1483  int_y_dir = 0;
1484 
1485  for( curr_x = curr_window_x_start ; curr_x <= curr_window_x_end ;
1486  ++curr_x )
1487  {
1488  for( curr_offset = 0 ; curr_offset < wind_radius ; ++curr_offset )
1489  {
1490  int_y_dir += rasterData( curr_window_y_start + curr_offset, curr_x ) -
1491  rasterData( curr_window_y_end - curr_offset, curr_x );
1492  }
1493  }
1494 
1495  /* Calculating the rotation parameters -
1496  */
1497  int_norm = std::sqrt( ( int_x_dir * int_x_dir ) +
1498  ( int_y_dir * int_y_dir ) );
1499 
1500  if( int_norm != 0.0 ) {
1501  rot_cos = int_x_dir / int_norm;
1502  rot_sin = int_y_dir / int_norm;
1503  } else {
1504  /* No rotation */
1505  rot_cos = 1.0;
1506  rot_sin = 0.0;
1507  }
1508 
1509  assert( ( rot_cos >= -1.0 ) && ( rot_cos <= 1.0 ) );
1510  assert( ( rot_sin >= -1.0 ) && ( rot_sin <= 1.0 ) );
1511 
1512  /* Generating the rotated window data and inserting it into
1513  the img_features_matrix by setting the intensity vector
1514  to the direction (1,0)
1515 
1516  counterclockwise rotation
1517  | u | |cos -sin| |X|
1518  | v | == |sin cos| x |Y|
1519 
1520  clockwise rotation
1521  | u | |cos sin| |X|
1522  | v | == |-sin cos| x |Y|
1523  */
1524 
1525  memset( auxFeatureBufferPtr, 0, featureSizeBytes );
1526  featureElementIdx = 0;
1527  featureElementMaxValue = -1.0 * FLT_MAX;
1528  featureElementMinValue = FLT_MAX;
1529 
1530  for( curr_y = 0 ; curr_y < correlationWindowWidth ; ++curr_y )
1531  {
1532  for( curr_x = 0 ; curr_x < correlationWindowWidth ; ++curr_x )
1533  {
1534  /* briging the window to the coord system center */
1535 
1536  curr_x_minus_radius = ((float)curr_x) -
1537  wind_radius_double;
1538  curr_y_minus_radius = ((float)curr_y) -
1539  wind_radius_double;
1540 
1541  /* rotating the centered window */
1542 
1543  rotated_curr_x =
1544  ( rot_cos * curr_x_minus_radius ) +
1545  ( rot_sin * curr_y_minus_radius );
1546 
1547  rotated_curr_y =
1548  ( rot_cos * curr_y_minus_radius )
1549  - ( rot_sin * curr_x_minus_radius );
1550 
1551  /* bringing the window back to its original
1552  location with the correct new scale */
1553 
1554  rotated_curr_x += wind_radius_double;
1555  rotated_curr_y += wind_radius_double;
1556 
1557  /* copy the new rotated window to the output vector */
1558 
1559  rotated_curr_x_img = curr_window_x_start +
1560  (unsigned int)te::common::Round< float, unsigned int >( rotated_curr_x );
1561  rotated_curr_y_img = curr_window_y_start +
1562  (unsigned int)te::common::Round< float, unsigned int >( rotated_curr_y );
1563 
1564  featureElementValue = rasterData( rotated_curr_y_img,
1565  rotated_curr_x_img );
1566 
1567  auxFeatureBufferPtr[ featureElementIdx++ ] = featureElementValue;
1568 
1569  if( featureElementMaxValue < featureElementValue )
1570  featureElementMaxValue = featureElementValue;
1571 
1572  if( featureElementMinValue > featureElementValue )
1573  featureElementMinValue = featureElementValue;
1574 
1575  }
1576  }
1577 
1578  // feature normaliztion
1579 
1580  if( featureElementMaxValue == featureElementMinValue )
1581  featureElementsNormalizeFactor = 0.0;
1582  else
1583  featureElementsNormalizeFactor = 1.0f / ( featureElementMaxValue -
1584  featureElementMinValue );
1585 
1586  featurePtr = features[ validInteresPointsIndex ];
1587 
1588  for( featureElementIdx = 0 ; featureElementIdx < featureElemsNmb ;
1589  ++featureElementIdx )
1590  {
1591  featurePtr[ featureElementIdx ] = (
1592  ( auxFeatureBufferPtr[ featureElementIdx ] - featureElementMinValue )
1593  * featureElementsNormalizeFactor );
1594  assert( featurePtr[ featureElementIdx ] >= 0.0 );
1595  assert( featurePtr[ featureElementIdx ] <= 1.0 );
1596  }
1597 
1598  ++validInteresPointsIndex;
1599  ++viPointsIt;
1600  }
1601 
1602  return true;
1603  }
1604 
1606  const FloatsMatrix& featuresSet1,
1607  const FloatsMatrix& featuresSet2,
1608  const InterestPointsSetT& interestPointsSet1,
1609  const InterestPointsSetT& interestPointsSet2,
1610  te::gm::GeometricTransformation const * const raster1ToRaster2TransfPtr,
1611  const double raster1ToRaster2TransfDMapError,
1612  MatchedInterestPointsSetT& matchedPoints )
1613  {
1614  matchedPoints.clear();
1615 
1616  const unsigned int interestPointsSet1Size = static_cast<unsigned int>(interestPointsSet1.size());
1617  if( interestPointsSet1Size == 0 ) return true;
1618 
1619  const unsigned int interestPointsSet2Size = static_cast<unsigned int>(interestPointsSet2.size());
1620  if( interestPointsSet2Size == 0 ) return true;
1621 
1622  assert( featuresSet1.getColumnsNumber() == featuresSet2.getColumnsNumber() );
1623  assert( featuresSet1.getLinesNumber() == interestPointsSet1Size );
1624  assert( featuresSet2.getLinesNumber() == interestPointsSet2Size );
1625 
1626  // Creating internal objects
1627 
1628  InterestPointsSetT::const_iterator it1 = interestPointsSet1.begin();
1629  boost::scoped_array< InterestPointT > internalInterestPointsSet1(
1630  new InterestPointT[ interestPointsSet1Size ] );
1631  for( unsigned int idx1 = 0 ; idx1 < interestPointsSet1Size ; ++idx1 )
1632  {
1633  internalInterestPointsSet1[ idx1 ] = *it1;
1634 
1635  ++it1;
1636  }
1637 
1638  InterestPointsSetT::const_iterator it2 = interestPointsSet2.begin();
1639  boost::scoped_array< InterestPointT > internalInterestPointsSet2(
1640  new InterestPointT[ interestPointsSet2Size ] );
1641  for( unsigned int idx2 = 0 ; idx2 < interestPointsSet2Size ; ++idx2 )
1642  {
1643  internalInterestPointsSet2[ idx2 ] = *it2;
1644 
1645  ++it2;
1646  }
1647 
1648  // Creating the correlation matrix
1649 
1650  FloatsMatrix corrMatrix;
1651  TERP_INSTANCE_TRUE_OR_RETURN_FALSE( corrMatrix.reset( interestPointsSet1Size,
1652  interestPointsSet2Size, FloatsMatrix::RAMMemPol ),
1653  "Error crearting the correlation matrix" );
1654 
1655  unsigned int col = 0;
1656  unsigned int line = 0;
1657  float* linePtr = nullptr;
1658 
1659  for( line = 0 ; line < interestPointsSet1Size ; ++line )
1660  {
1661  linePtr = corrMatrix[ line ];
1662 
1663  for( col = 0 ; col < interestPointsSet2Size ; ++col )
1664  {
1665  linePtr[ col ] = 0;
1666  }
1667  }
1668 
1669  boost::mutex syncMutex;
1670  unsigned int nextFeatureIdx1ToProcess = 0;
1671 
1673  params.m_featuresSet1Ptr = &featuresSet1;
1674  params.m_featuresSet2Ptr = &featuresSet2;
1675  params.m_interestPointsSet1Ptr = internalInterestPointsSet1.get();
1676  params.m_interestPointsSet2Ptr = internalInterestPointsSet2.get();
1677  params.m_nextFeatureIdx1ToProcessPtr = &nextFeatureIdx1ToProcess;
1678  params.m_corrMatrixPtr = &corrMatrix;
1679  params.m_syncMutexPtr = &syncMutex;
1680  params.m_raster1ToRaster2TransfPtr = raster1ToRaster2TransfPtr;
1681  params.m_searchOptTreeSearchRadius = raster1ToRaster2TransfDMapError;
1682 
1684  {
1686  FloatsMatrix::RAMMemPol, "Invalid memory policy" )
1688  FloatsMatrix::RAMMemPol, "Invalid memory policy" )
1689 
1690  const unsigned int procsNumber = te::common::GetPhysProcNumber();
1691 
1692  boost::thread_group threads;
1693 
1694  for( unsigned int threadIdx = 0 ; threadIdx < procsNumber ;
1695  ++threadIdx )
1696  {
1697  threads.add_thread( new boost::thread(
1699  }
1700 
1701  threads.join_all();
1702 
1703  }
1704  else
1705  {
1707  }
1708 
1709  // finding the correlation matrix maximas for each line and column
1710 
1711  std::vector< float > eachLineMaxABSValues( interestPointsSet1Size,
1712  0.0 );
1713  std::vector< unsigned int > eachLineMaxABSIndexes( interestPointsSet1Size,
1714  interestPointsSet2Size );
1715  std::vector< float > eachColMaxABSValues( interestPointsSet2Size,
1716  0.0 );
1717  std::vector< unsigned int > eachColMaxABSIndexes( interestPointsSet2Size,
1718  interestPointsSet1Size );
1719  float absValue = 0;
1720  const double moravecMinAbsCorrelation =
1721  ((Parameters*)(m_inputParameters.getSpecStrategyParams()))->m_moravecMinAbsCorrelation;
1722 
1723  for( line = 0 ; line < interestPointsSet1Size ; ++line )
1724  {
1725  linePtr = corrMatrix[ line ];
1726 
1727  for( col = 0 ; col < interestPointsSet2Size ; ++col )
1728  {
1729  absValue = std::abs( linePtr[ col ] );
1730 
1731  if( absValue >= moravecMinAbsCorrelation )
1732  {
1733  if( absValue > eachLineMaxABSValues[ line ] )
1734  {
1735  eachLineMaxABSValues[ line ] = absValue;
1736  eachLineMaxABSIndexes[ line ] = col;
1737  }
1738 
1739  if( absValue > eachColMaxABSValues[ col ] )
1740  {
1741  eachColMaxABSValues[ col ] = absValue;
1742  eachColMaxABSIndexes[ col ] = line;
1743  }
1744  }
1745  }
1746  }
1747 
1748  // Finding tiepoints
1749 
1750  MatchedInterestPointsT auxMatchedPoints;
1751 
1752  for( line = 0 ; line < interestPointsSet1Size ; ++line )
1753  {
1754  col = eachLineMaxABSIndexes[ line ];
1755 
1756  if( ( col < interestPointsSet2Size ) &&
1757  ( eachColMaxABSIndexes[ col ] == line ) )
1758  {
1759  auxMatchedPoints.m_point1 = internalInterestPointsSet1[ line ];
1760  auxMatchedPoints.m_point2 = internalInterestPointsSet2[ col ];
1761  auxMatchedPoints.m_feature = std::abs( corrMatrix( line, col ) );
1762 
1763  matchedPoints.insert( auxMatchedPoints );
1764  }
1765  }
1766 
1767  return true;
1768  }
1769 
1772  {
1773  assert( paramsPtr->m_featuresSet1Ptr->getMemPolicy() ==
1775  assert( paramsPtr->m_featuresSet2Ptr->getMemPolicy() ==
1777  assert( paramsPtr->m_corrMatrixPtr->getMemPolicy() ==
1779 
1780  // globals
1781 
1782  const double interestPointsSet2RTreeSearchRadius = paramsPtr->m_searchOptTreeSearchRadius;
1783  const unsigned int featureElementsNmb = paramsPtr->m_featuresSet1Ptr->getColumnsNumber();
1784  unsigned int feat2Idx = 0;
1785  float const* feat1Ptr = nullptr;
1786  float const* feat2Ptr = nullptr;
1787  float* corrMatrixLinePtr = nullptr;
1788  unsigned int featCol = 0;
1789  float sumAA = 0;
1790  float sumBB = 0;
1791  float cc_norm = 0;
1792  float ccorrelation = 0;
1793  te::gm::Envelope auxEnvelope;
1794 
1795  // local transformation copy
1796 
1797  std::unique_ptr< te::gm::GeometricTransformation > raster1ToRaster2TransfPtr;
1798  if( paramsPtr->m_raster1ToRaster2TransfPtr )
1799  {
1800  paramsPtr->m_syncMutexPtr->lock();
1801  raster1ToRaster2TransfPtr.reset( paramsPtr->m_raster1ToRaster2TransfPtr->clone() );
1802  paramsPtr->m_syncMutexPtr->unlock();
1803  }
1804 
1805  // Indexing tree building
1806 
1807  const unsigned int featuresSet1Size =
1808  paramsPtr->m_featuresSet1Ptr->getLinesNumber();
1809  const unsigned int featuresSet2Size =
1810  paramsPtr->m_featuresSet2Ptr->getLinesNumber();
1811 
1812  te::sam::rtree::Index< unsigned int > interestPointsSet2RTree;
1813 
1814  std::vector< unsigned int > selectedFeaturesSet2Indexes;
1815  unsigned int selectedFeaturesSet2IndexesSize = 0;
1816 
1817  if( paramsPtr->m_raster1ToRaster2TransfPtr )
1818  {
1819  for( unsigned int feat2Idx = 0 ; feat2Idx < featuresSet2Size ; ++feat2Idx )
1820  {
1821  interestPointsSet2RTree.insert(
1823  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_x,
1824  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_y,
1825  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_x,
1826  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_y ),
1827  feat2Idx );
1828  }
1829  }
1830  else
1831  {
1832  selectedFeaturesSet2Indexes.resize( featuresSet2Size );
1833  selectedFeaturesSet2IndexesSize = featuresSet2Size;
1834  for( unsigned int feat2Idx = 0 ; feat2Idx < featuresSet2Size ; ++feat2Idx )
1835  {
1836  selectedFeaturesSet2Indexes[ feat2Idx ] = feat2Idx;
1837  }
1838  }
1839 
1840  // Analysing each feature
1841 
1842  for( unsigned int feat1Idx = 0 ; feat1Idx < featuresSet1Size ; ++feat1Idx )
1843  {
1844  paramsPtr->m_syncMutexPtr->lock();
1845 
1846  if( feat1Idx == (*paramsPtr->m_nextFeatureIdx1ToProcessPtr) )
1847  {
1848  ++(*paramsPtr->m_nextFeatureIdx1ToProcessPtr);
1849 
1850  paramsPtr->m_syncMutexPtr->unlock();
1851 
1852  if( paramsPtr->m_raster1ToRaster2TransfPtr )
1853  {
1854  raster1ToRaster2TransfPtr->directMap(
1855  paramsPtr->m_interestPointsSet1Ptr[ feat1Idx ].m_x,
1856  paramsPtr->m_interestPointsSet1Ptr[ feat1Idx ].m_y,
1857  auxEnvelope.m_llx,
1858  auxEnvelope.m_lly );
1859 
1860  auxEnvelope.m_urx = auxEnvelope.m_llx;
1861  auxEnvelope.m_ury = auxEnvelope.m_lly;
1862 
1863  auxEnvelope.m_llx -= interestPointsSet2RTreeSearchRadius;
1864  auxEnvelope.m_lly -= interestPointsSet2RTreeSearchRadius;
1865  auxEnvelope.m_urx += interestPointsSet2RTreeSearchRadius;
1866  auxEnvelope.m_ury += interestPointsSet2RTreeSearchRadius;
1867 
1868  selectedFeaturesSet2Indexes.clear();
1869  interestPointsSet2RTree.search( auxEnvelope,
1870  selectedFeaturesSet2Indexes );
1871 
1872  selectedFeaturesSet2IndexesSize = static_cast<unsigned int>(selectedFeaturesSet2Indexes.size());
1873  }
1874 
1875  corrMatrixLinePtr = paramsPtr->m_corrMatrixPtr->operator[]( feat1Idx );
1876 
1877  feat1Ptr = paramsPtr->m_featuresSet1Ptr->operator[]( feat1Idx );
1878 
1879  for( unsigned int selectedFSIIdx = 0 ; selectedFSIIdx <
1880  selectedFeaturesSet2IndexesSize ; ++selectedFSIIdx )
1881  {
1882  feat2Idx = selectedFeaturesSet2Indexes[ selectedFSIIdx ];
1883 
1884  feat2Ptr = paramsPtr->m_featuresSet2Ptr->operator[]( feat2Idx );
1885 
1886  sumAA = 0.0;
1887  sumBB = 0.0;
1888  for( featCol = 0 ; featCol < featureElementsNmb ; ++featCol )
1889  {
1890  sumAA += feat1Ptr[ featCol ] * feat1Ptr[ featCol ];
1891  sumBB += feat2Ptr[ featCol ] * feat2Ptr[ featCol ];
1892  }
1893 
1894  cc_norm = std::sqrt( sumAA * sumBB );
1895 
1896  if( cc_norm == 0.0 )
1897  {
1898  corrMatrixLinePtr[ feat2Idx ] = 0;
1899  }
1900  else
1901  {
1902  ccorrelation = 0.0;
1903  for( featCol = 0 ; featCol < featureElementsNmb ; ++featCol )
1904  {
1905  ccorrelation += ( feat1Ptr[ featCol ] * feat2Ptr[ featCol ] ) /
1906  cc_norm;
1907  }
1908 
1909  corrMatrixLinePtr[ feat2Idx ] = ccorrelation;
1910  }
1911  }
1912  }
1913  else
1914  {
1915  paramsPtr->m_syncMutexPtr->unlock();
1916  }
1917  }
1918  }
1919 
1920  /* ----------------------------------------------------------------------- */
1921 
1923  : te::rp::TiePointsLocatorStrategyFactory( "Moravec" )
1924  {
1925  }
1926 
1929 
1931  {
1933  }
1934 
1935  } // end namespace rp
1936 } // end namespace te
1937 
te::rp::TiePointsLocatorInputParameters m_inputParameters
Input parameters.
std::vector< InterestPointsSetT > * m_interestPointsSubSectorsPtr
A pointer to a valid interest points container (one element by subsector)..
TECOMMONEXPORT unsigned long long int GetTotalVirtualMemory()
Returns the amount of total virtual memory (bytes) that can be claimed by the current process (physic...
std::vector< unsigned int > m_inRaster2Bands
Bands to be used from the input raster 2.
void reset()
Clear all internal allocated resources and go back to the initial not-initialized state...
bool m_enableProgress
Enable/Disable the progress interface (default:false).
unsigned int m_raster2TargetAreaLineStart
The first line of the raster 2 target area to process (default:0 - The entire raster will be consider...
A class that represents an R-tree.
Base exception class for plugin module.
TiePointsLocatorStrategyParameters const * getSpecStrategyParams() const
Returns a pointer to the internal specific tie-points locator strategy parameters.
static bool applyMeanFilter(const FloatsMatrix &inputData, FloatsMatrix &outputData, const unsigned int iterationsNumber)
Mean Filter.
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.
bool initialize(const te::rp::TiePointsLocatorInputParameters &inputParameters)
Initialize the strategy.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
double m_urx
Upper right corner x-coordinate.
unsigned int m_moravecWindowWidth
The Moravec window width used to locate canditate tie-points (minimum 3, default: 21...
2D Geometric transformation base class.
te::rp::TiePointsLocatorStrategy * build()
Concrete factories (derived from this one) must implement this method in order to create objects...
Moravec tie-points locator strategy factory.
void getSubSampledSpecStrategyParams(const double subSampleOptimizationRescaleFactor, const TiePointsLocatorStrategyParameters &inputSpecParams, std::unique_ptr< TiePointsLocatorStrategyParameters > &subSampledSpecParamsPtr) const
Returns a sub-sampled version of the given locator strategy specific input parameters.
te::gm::GeometricTransformation const * m_raster1ToRaster2TransfPtr
A pointer to a transformation direct mapping raster 1 indexed coords into raster 2 indexed coords...
unsigned int m_maxTiePoints
The maximum number of tie-points to generate (0:Automatically calculated, default:2500).
MemoryPolicy getMemPolicy() const
Returns the current memory policy.
Definition: Matrix.h:837
#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:185
unsigned int line
Tie-Pointsr locator Moravec strategy.
unsigned int unsigned int nCols
static bool generateCorrelationFeatures(const InterestPointsSetT &interestPoints, const unsigned int correlationWindowWidth, const FloatsMatrix &rasterData, FloatsMatrix &features, InterestPointsSetT &validInteresPoints)
Generate correlation features ( normalized - unit vector ) matrix for the given interes points...
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
TECOMMONEXPORT unsigned int GetPhysProcNumber()
Returns the number of physical processors.
unsigned int m_raster1TargetAreaHeight
The raster 1 target area height (default:0 - The entire raster will be considered).
double m_llx
Lower left corner x-coordinate.
unsigned int m_processingBlocksNumber
The raster data will be splitted into this number of blocks for processing.
AbstractParameters * clone() const
Create a clone copy of this instance.
An Envelope defines a 2D rectangular region.
double m_pixelSizeXRelation
The pixel resolution relation m_pixelSizeXRelation = raster1_pixel_res_x / raster2_pixel_res_x (defau...
static void locateMoravecInterestPointsThreadEntry(MoravecLocatorThreadParams *paramsPtr)
Movavec locator thread entry.
unsigned int getColumnsNumber() const
The number of current matrix columns.
Definition: Matrix.h:798
std::vector< unsigned int > m_inRaster1Bands
Bands to be used from the input raster 1.
mydialect insert("+", new te::da::BinaryOpEncoder("+"))
virtual void reset()
Clear all internal allocated resources and go back to the initial not-initialized state...
URI C++ Library.
Definition: Attributes.h:37
TiePointsLocator Moravec strategy parameters.
std::multiset< InterestPointT > InterestPointsSetT
bool m_isInitialized
true if this instance is initialized.
unsigned int m_moravecCorrelationWindowWidth
The correlation window width used to correlate points between the images (minimum 3...
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
unsigned int m_maxInterestPointsBySubSector
The maximum number of interest points by sub-sector.
The parameters passed to the matchCorrelationEuclideanThreadEntry method.
unsigned int m_tiePointsSubSectorsSplitFactor
The algorithm will try to generate tie-points distributed over image sectors ( Default: 3 - 3x3 sub-s...
virtual GeometricTransformation * clone() const =0
Creat a clone copy of this instance.
static bool loadRasterData(te::rst::Raster const *rasterPtr, const std::vector< unsigned int > &rasterBands, te::rst::Raster const *maskRasterPtr, const unsigned int maskRasterBand, const unsigned int rasterTargetAreaLineStart, const unsigned int rasterTargetAreaColStart, const unsigned int rasterTargetAreaWidth, const unsigned int rasterTargetAreaHeight, const double desiredRescaleFactorX, const double desiredRescaleFactorY, const te::rst::Interpolator::Method rasterInterpMethod, const unsigned char maxMemPercentUsage, std::vector< boost::shared_ptr< FloatsMatrix > > &loadedRasterData, UCharsMatrix &loadedMaskRasterData, double &achievedRescaleFactorX, double &achievedRescaleFactorY)
Load rasters data (normalized between 0 and 1).
void reset()
Reset (clear) the active instance data.
Definition: Matrix.h:502
Tie-points locator strategy.
te::rst::Raster const * m_inRaster1Ptr
Input raster 1.
double m_lly
Lower left corner y-coordinate.
bool getMatchedInterestPoints(te::gm::GeometricTransformation const *const raster1ToRaster2TransfPtr, const double raster1ToRaster2TransfDMapError, MatchedInterestPointsSetT &matchedInterestPoints)
Try to find matched interest points.
unsigned int getAutoMaxTiePointsNumber() const
Returns a automatically calculated optimum maximum amount tie-points following the current parameters...
TECOMMONEXPORT unsigned long long int GetTotalPhysicalMemory()
Returns the amount of total physical memory (bytes).
Abstract parameters base interface.
bool locateMoravecInterestPoints(const unsigned int maxInterestPoints, const FloatsMatrix &rasterData, UCharsMatrix const *maskRasterDataPtr, InterestPointsSetT &interestPoints) const
Moravec interest points locator.
static void roolUpBuffer(BufferElementT **bufferPtr, const unsigned int &bufferLinesNumber)
RoolUp a buffer of lines.
unsigned int m_moravecNoiseFilterIterations
The number of noise filter iterations, when applicable (used to remove image noise, zero will disable the noise Filter, default:1).
void getDefaultSpecStrategyParams(std::unique_ptr< TiePointsLocatorStrategyParameters > &defaultSpecParamsPtr) const
Returns a sub-sampled version of the given locator strategy specific input parameters.
unsigned int m_raster1TargetAreaWidth
The raster 1 target area width (default:0 - The entire raster will be considered).
double m_pixelSizeYRelation
The pixel resolution relation m_pixelSizeYRelation = raster1_pixel_res_y / raster2_pixel_res_y (defau...
The parameters passed to the moravecLocatorThreadEntry method.
unsigned int m_raster1TargetAreaLineStart
The first line of the raster 1 target area to process (default:0 - The entire raster will be consider...
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
double m_ury
Upper right corner y-coordinate.
unsigned int m_tiePointsSubSectorsSplitFactor
The number of sectors along each direction.
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).
bool m_enableMultiThread
Enable/Disable the use of multi-threads (default:true).
A generic template matrix.
Definition: Matrix.h:55
TemplateElementType ElementTypeT
Public matrix element type definition.
Definition: Matrix.h:61
boost::mutex * m_interestPointsAccessMutexPtr
A pointer to a valid mutex to control the output interest points container access.
te::rst::Raster const * m_inMaskRaster1Ptr
Optional one band input mask raster 1 (tie-points will not be generated inside mask image areas marke...
static void executeMatchingByCorrelationThreadEntry(ExecuteMatchingByCorrelationThreadEntryParams *paramsPtr)
Correlation/Euclidean match thread entry.
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...
UCharsMatrix const * m_maskRasterDataPtr
The loaded mask raster data pointer (or zero if no mask is avaliable).
bool executeMatchingByCorrelation(const FloatsMatrix &featuresSet1, const FloatsMatrix &featuresSet2, const InterestPointsSetT &interestPointsSet1, const InterestPointsSetT &interestPointsSet2, te::gm::GeometricTransformation const *const raster1ToRaster2TransfPtr, const double raster1ToRaster2TransfDMapError, MatchedInterestPointsSetT &matchedPoints)
Match each feature using correlation.
Raster tie-points locator strategy factory base class.
TECOMMONEXPORT unsigned long long int GetUsedVirtualMemory()
Returns the amount of used virtual memory (bytes) for the current process (physical + swapped)...
unsigned int * m_nextRasterLinesBlockToProcessValuePtr
A pointer to a valid counter to control the blocks processing sequence.
#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 nLines
unsigned int m_raster1TargetAreaColStart
The first column of the raster 2 target area to process (default:0 - The entire raster will be consid...
unsigned int getLinesNumber() const
The number of current matrix lines.
Definition: Matrix.h:791
std::multiset< MatchedInterestPointsT > MatchedInterestPointsSetT
unsigned int m_raster2TargetAreaWidth
The raster 2 target area width (default:0 - The entire raster will be considered).
unsigned int col
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:150
double m_moravecMinAbsCorrelation
The minimum acceptable absolute correlation value when matching features (when applicable), default:0.25, valid range: [0,1].
virtual AbstractParameters * clone() const =0
Create a clone copy of this instance.
te::rst::Interpolator::Method m_interpMethod
The raster interpolator method (default:NearestNeighbor).
float m_feature1
Interest point feature 1 value.
boost::mutex * m_rastaDataAccessMutexPtr
A pointer to a valid mutex to controle raster data access.