All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TiePointsLocator.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2001-2009 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"
27 #include "../geometry/GTFactory.h"
28 #include "../common/PlatformUtils.h"
29 #include "../common/StringUtils.h"
30 #include "../raster/Band.h"
31 #include "../raster/Grid.h"
32 #include "../raster/BandProperty.h"
33 #include "../raster/RasterFactory.h"
34 #include "../datatype/Enums.h"
35 #include "../geometry/GTFilter.h"
36 
37 #include <boost/scoped_array.hpp>
38 #include <boost/shared_array.hpp>
39 #include <boost/lexical_cast.hpp>
40 
41 #include <algorithm>
42 
43 #include <climits>
44 #include <cfloat>
45 #include <cstdio>
46 #include <cmath>
47 #include <boost/concept_check.hpp>
48 
49 #include <cstring>
50 
51 namespace te
52 {
53  namespace rp
54  {
55  // -----------------------------------------------------------------------
56 
58  {
59  reset();
60  }
61 
63  {
64  reset();
65  operator=( other );
66  }
67 
69  {
70  reset();
71  }
72 
73  void TiePointsLocator::InputParameters::reset() throw( te::rp::Exception )
74  {
75  m_interesPointsLocationStrategy = InputParameters::SurfStrategyT;
76  m_inRaster1Ptr = 0;
77  m_inMaskRaster1Ptr = 0;
78  m_inRaster1Bands.clear();
79  m_raster1TargetAreaLineStart = 0;
80  m_raster1TargetAreaColStart = 0;
81  m_raster1TargetAreaWidth = 0;
82  m_raster1TargetAreaHeight = 0;
83  m_inRaster2Ptr = 0;
84  m_inMaskRaster2Ptr = 0;
85  m_inRaster2Bands.clear();
86  m_raster2TargetAreaLineStart = 0;
87  m_raster2TargetAreaColStart = 0;
88  m_raster2TargetAreaWidth = 0;
89  m_raster2TargetAreaHeight = 0;
90  m_enableMultiThread = true;
91  m_enableProgress = false;
92  m_maxTiePoints = 0;
93  m_pixelSizeXRelation = 1;
94  m_pixelSizeYRelation = 1;
95  m_geomTransfName = "Affine";
96  m_geomTransfMaxError = 2;
97  m_moravecCorrelationWindowWidth = 11;
98  m_moravecWindowWidth = 5;
99  m_maxR1ToR2Offset = 0;
100  m_enableGeometryFilter = true;
101  m_geometryFilterAssurance = 0.1;
102  m_moravecGaussianFilterIterations = 1;
103  m_surfScalesNumber = 4;
104  m_surfOctavesNumber = 2;
105  m_rastersRescaleFactor = 1.0;
106  m_surfMaxNormEuclideanDist = 0.5;
107  m_moravecMinAbsCorrelation = 0.5;
109  }
110 
112  const TiePointsLocator::InputParameters& params )
113  {
114  reset();
115 
116  m_interesPointsLocationStrategy = params.m_interesPointsLocationStrategy;
117  m_inRaster1Ptr = params.m_inRaster1Ptr;
118  m_inMaskRaster1Ptr = params.m_inMaskRaster1Ptr;
119  m_inRaster1Bands = params.m_inRaster1Bands;
120  m_raster1TargetAreaLineStart = params.m_raster1TargetAreaLineStart;
121  m_raster1TargetAreaColStart = params.m_raster1TargetAreaColStart;
122  m_raster1TargetAreaWidth = params.m_raster1TargetAreaWidth;
123  m_raster1TargetAreaHeight = params.m_raster1TargetAreaHeight;
124  m_inRaster2Ptr = params.m_inRaster2Ptr;
125  m_inMaskRaster2Ptr = params.m_inMaskRaster2Ptr;
126  m_inRaster2Bands = params.m_inRaster2Bands;
127  m_raster2TargetAreaLineStart = params.m_raster2TargetAreaLineStart;
128  m_raster2TargetAreaColStart = params.m_raster2TargetAreaColStart;
129  m_raster2TargetAreaWidth = params.m_raster2TargetAreaWidth;
130  m_raster2TargetAreaHeight = params.m_raster2TargetAreaHeight;
131  m_enableMultiThread = params.m_enableMultiThread;
132  m_enableProgress = params.m_enableProgress;
133  m_maxTiePoints = params.m_maxTiePoints;
134  m_pixelSizeXRelation = params.m_pixelSizeXRelation;
135  m_pixelSizeYRelation = params.m_pixelSizeYRelation;
136  m_geomTransfName = params.m_geomTransfName;
137  m_geomTransfMaxError = params.m_geomTransfMaxError;
138  m_moravecCorrelationWindowWidth = params.m_moravecCorrelationWindowWidth;
139  m_moravecWindowWidth = params.m_moravecWindowWidth;
140  m_maxR1ToR2Offset = params.m_maxR1ToR2Offset;
141  m_enableGeometryFilter = params.m_enableGeometryFilter;
142  m_geometryFilterAssurance = params.m_geometryFilterAssurance;
143  m_moravecGaussianFilterIterations = params.m_moravecGaussianFilterIterations;
144  m_surfScalesNumber = params.m_surfScalesNumber;
145  m_surfOctavesNumber = params.m_surfOctavesNumber;
146  m_rastersRescaleFactor = params.m_rastersRescaleFactor;
147  m_surfMaxNormEuclideanDist = params.m_surfMaxNormEuclideanDist;
148  m_moravecMinAbsCorrelation = params.m_moravecMinAbsCorrelation;
149  m_interpMethod = params.m_interpMethod;
150 
151  return *this;
152  }
153 
155  {
156  return new InputParameters( *this );
157  }
158 
159  // -----------------------------------------------------------------------
160 
162  {
163  reset();
164  }
165 
167  {
168  reset();
169  operator=( other );
170  }
171 
173  {
174  reset();
175  }
176 
177  void TiePointsLocator::OutputParameters::reset() throw( te::rp::Exception )
178  {
179  m_tiePoints.clear();
180  m_transformationPtr.reset();
181  }
182 
184  const TiePointsLocator::OutputParameters& params )
185  {
186  reset();
187 
188  m_tiePoints = params.m_tiePoints;
189  m_transformationPtr.reset( params.m_transformationPtr->clone() );
190 
191  return *this;
192  }
193 
195  {
196  return new OutputParameters( *this );
197  }
198 
199  // -----------------------------------------------------------------------
200 
202  {
203  reset();
204  }
205 
207  {
208  }
209 
211  throw( te::rp::Exception )
212  {
213  if( ! m_isInitialized ) return false;
214 
215  TiePointsLocator::OutputParameters* outParamsPtr = dynamic_cast<
216  TiePointsLocator::OutputParameters* >( &outputParams );
217  TERP_TRUE_OR_THROW( outParamsPtr, "Invalid paramters" );
218 
219  /* Calculating the rescale factors
220  factor = rescaled_orignal_image / original_image */
221 
222  double raster1XRescFact = 1.0;
223  double raster1YRescFact = 1.0;
224  double raster2XRescFact = 1.0;
225  double raster2YRescFact = 1.0;
226 
228  {
229  /* The image 1 has poor resolution - bigger pixel resolution values -
230  and image 2 needs to be rescaled down */
231 
232  raster2XRescFact = 1.0 / m_inputParameters.m_pixelSizeXRelation;
233  }
234  else if( m_inputParameters.m_pixelSizeXRelation < 1.0 )
235  {
236  /* The image 2 has poor resolution - bigger pixel resolution values
237  and image 1 needs to be rescaled down */
238 
239  raster1XRescFact = m_inputParameters.m_pixelSizeXRelation;
240  }
241 
243  {
244  /* The image 1 has poor resolution - bigger pixel resolution values -
245  and image 2 needs to be rescaled down */
246 
247  raster2YRescFact = 1.0 / m_inputParameters.m_pixelSizeYRelation;
248  }
249  else if( m_inputParameters.m_pixelSizeYRelation < 1.0 )
250  {
251  /* The image 2 has poor resolution - bigger pixel resolution values
252  and image 1 needs to be rescaled down */
253 
254  raster1YRescFact = m_inputParameters.m_pixelSizeYRelation;
255  }
256 
257  // Applying the global rescale factor
258 
259  raster1XRescFact *= m_inputParameters.m_rastersRescaleFactor;
260  raster1YRescFact *= m_inputParameters.m_rastersRescaleFactor;
261  raster2XRescFact *= m_inputParameters.m_rastersRescaleFactor;
262  raster2YRescFact *= m_inputParameters.m_rastersRescaleFactor;
263 
264  // progress
265 
266  std::auto_ptr< te::common::TaskProgress > progressPtr;
268  {
269  progressPtr.reset( new te::common::TaskProgress );
270  progressPtr->setTotalSteps( 1 );
271  progressPtr->setMessage( "Locating tie points" );
272  progressPtr->pulse();
273  if( ! progressPtr->isActive() ) return false;
274  }
275 
276  // executing the choosed strategy
277 
278  std::vector< double > tiePointsWeights;
279 
281  {
283  {
285  raster1XRescFact,
286  raster1YRescFact,
287  raster2XRescFact,
288  raster2YRescFact,
289  progressPtr.get(),
290  outParamsPtr,
291  tiePointsWeights ),
292  "Moravec execution error" );
293  break;
294  }
296  {
298  raster1XRescFact,
299  raster1YRescFact,
300  raster2XRescFact,
301  raster2YRescFact,
302  progressPtr.get(),
303  outParamsPtr,
304  tiePointsWeights ),
305  "SURF execution error" );
306  break;
307  }
308  default :
309  {
310  TERP_LOG_AND_THROW( "Invalid strategy" );
311  break;
312  }
313  }
314 
315  // Execute outliers remotion, if required
316 
318  {
319  te::gm::GTParameters transfParams;
320  transfParams.m_tiePoints = outParamsPtr->m_tiePoints;
321 
322  te::gm::GTFilter filter;
325  transfParams,
328  0,
331  tiePointsWeights,
332  outParamsPtr->m_tiePoints,
333  outParamsPtr->m_transformationPtr ), "Outliers remotion error" );
334  }
335  else
336  {
338  TERP_DEBUG_TRUE_OR_THROW( outParamsPtr->m_transformationPtr.get(), "Invalid transformation" );
339 
340  te::gm::GTParameters transfParams;
341 
342  if( ! outParamsPtr->m_transformationPtr->initialize( transfParams ) )
343  {
344  outParamsPtr->m_transformationPtr.reset();
345  }
346  }
347 
349  {
350  progressPtr->pulse();
351  if( ! progressPtr->isActive() ) return false;
352  }
353 
354  return true;
355  }
356 
358  const double raster1XRescFact,
359  const double raster1YRescFact,
360  const double raster2XRescFact,
361  const double raster2YRescFact,
362  te::common::TaskProgress* progressPtr,
364  std::vector< double >& tiePointsWeights )
365  throw( te::rp::Exception )
366  {
367  outParamsPtr->m_tiePoints.clear();
368  tiePointsWeights.clear();
369 
370  // Calculating the number of tie points to be found
371 
372  unsigned int raster1MaxInterestPoints = m_inputParameters.m_maxTiePoints;
373  unsigned int raster2MaxInterestPoints = m_inputParameters.m_maxTiePoints;
374  {
375  double rescRaster1Area =
376  ( (double)( m_inputParameters.m_raster1TargetAreaWidth ) * raster1XRescFact ) *
377  ( (double)( m_inputParameters.m_raster1TargetAreaHeight ) * raster1YRescFact );
378  double rescRaster2Area =
379  ( (double)( m_inputParameters.m_raster2TargetAreaWidth ) * raster2XRescFact ) *
380  ( (double)( m_inputParameters.m_raster2TargetAreaHeight ) * raster2YRescFact );;
381 
382  if( rescRaster1Area > rescRaster2Area )
383  {
384  raster1MaxInterestPoints = (unsigned int)(
385  rescRaster1Area /
386  ( rescRaster2Area / ( (double)m_inputParameters.m_maxTiePoints ) ) );
387  }
388  else if( rescRaster1Area < rescRaster2Area )
389  {
390  raster2MaxInterestPoints = (unsigned int)(
391  rescRaster2Area /
392  ( rescRaster1Area / ( (double)m_inputParameters.m_maxTiePoints ) ) );
393  }
394  }
395 
396  // Updating the progress interface steps number
397 
398  if( progressPtr )
399  progressPtr->setTotalSteps( progressPtr->getTotalSteps() + 10 );
400 
401  // Generating raster 1 features
402 
403  FloatsMatrix raster1Features;
404  InterestPointsSetT raster1InterestPoints;
405  {
406  // loading raster data
407  std::vector< boost::shared_ptr< FloatsMatrix > > raster1Data;
408  UCharsMatrix maskRaster1Data;
409 
414  0,
419  raster1XRescFact,
420  raster1YRescFact,
422  20,
423  raster1Data,
424  maskRaster1Data ),
425  "Error loading raster data" );
426 
427  if( progressPtr )
428  {
429  progressPtr->pulse();
430  if( ! progressPtr->isActive() ) return false;
431  }
432 
433  // applying the noise filter
434 
436  {
437  boost::shared_ptr< FloatsMatrix > tempMatrix(
438  new FloatsMatrix );
439  TERP_TRUE_OR_RETURN_FALSE( tempMatrix->reset(
440  0, 0,
442  raster1Data[ 0 ]->getMaxTmpFileSize(),
443  raster1Data[ 0 ]->getMaxMemPercentUsage() ),
444  "Cannot allocate image matrix" );
445 
447  *(raster1Data[ 0 ]),
449  "Gaussian filter error" );
450 
451  raster1Data[ 0 ]->reset();
452  raster1Data[ 0 ] = tempMatrix;
453 
454 // createTifFromMatrix( *(raster1Data[ 0 ]), InterestPointsSetT(), "raster1Filtered");
455  }
456 
457  if( progressPtr )
458  {
459  progressPtr->pulse();
460  if( ! progressPtr->isActive() ) return false;
461  }
462 
463  // locating interest points
464 
466  *(raster1Data[ 0 ]),
467  maskRaster1Data.getLinesNumber() ? (&maskRaster1Data) : 0,
469  raster1MaxInterestPoints,
471  raster1InterestPoints ),
472  "Error locating raster 1 interest points" );
473 
474  if( progressPtr )
475  {
476  progressPtr->pulse();
477  if( ! progressPtr->isActive() ) return false;
478  }
479 
480  // Generting features (one feature per line)
481 
482  raster1Features.reset( FloatsMatrix::RAMMemPol );
483  InterestPointsSetT auxInterestPoints;
484 
486  raster1InterestPoints,
488  *(raster1Data[ 0 ]),
489  raster1Features,
490  auxInterestPoints ),
491  "Error generating raster 1 features" );
492 
493  raster1InterestPoints = auxInterestPoints;
494 
495 // features2Tiff( raster1Features, raster1InterestPoints, "raster1features" );
496 
497  if( progressPtr )
498  {
499  progressPtr->pulse();
500  if( ! progressPtr->isActive() ) return false;
501  }
502  }
503 
504  // Generating raster 2 features
505 
506  FloatsMatrix raster2Features;
507  InterestPointsSetT raster2InterestPoints;
508  {
509  // Loading image data
510 
511  std::vector< boost::shared_ptr< FloatsMatrix > > raster2Data;
512  UCharsMatrix maskRaster2Data;
513 
518  0,
523  raster2XRescFact,
524  raster2YRescFact,
526  20,
527  raster2Data,
528  maskRaster2Data ),
529  "Error loading raster data" );
530 
531  if( progressPtr )
532  {
533  progressPtr->pulse();
534  if( ! progressPtr->isActive() ) return false;
535  }
536 
537  // applying the noise filter
538 
540  {
541  boost::shared_ptr< FloatsMatrix > tempMatrix(
542  new FloatsMatrix );
543 
544  tempMatrix.reset( new FloatsMatrix );
545  TERP_TRUE_OR_RETURN_FALSE( tempMatrix->reset(
546  0, 0,
548  raster2Data[ 0 ]->getMaxTmpFileSize(),
549  raster2Data[ 0 ]->getMaxMemPercentUsage() ),
550  "Cannot allocate image matrix" );
551 
553  *(raster2Data[ 0 ]),
555  "Gaussian filter error" );
556 
557  raster2Data[ 0 ] = tempMatrix;
558 
559 // createTifFromMatrix( *(raster2Data[ 0 ]), InterestPointsSetT(), "raster2Filtered");
560  }
561 
562  if( progressPtr )
563  {
564  progressPtr->pulse();
565  if( ! progressPtr->isActive() ) return false;
566  }
567 
568  // locating interest points
569 
571  *(raster2Data[ 0 ]),
572  maskRaster2Data.getLinesNumber() ? (&maskRaster2Data) : 0,
574  raster2MaxInterestPoints,
576  raster2InterestPoints ),
577  "Error locating raster 2 interest points" );
578 
579  if( progressPtr )
580  {
581  progressPtr->pulse();
582  if( ! progressPtr->isActive() ) return false;
583  }
584 
585  // Generting features (one feature per line)
586 
587  raster2Features.reset( FloatsMatrix::RAMMemPol );
588  InterestPointsSetT auxInterestPoints;
589 
591  raster2InterestPoints,
593  *(raster2Data[ 0 ]),
594  raster2Features,
595  auxInterestPoints ),
596  "Error generating raster 2 features" );
597 
598  raster2InterestPoints = auxInterestPoints;
599 
600 // features2Tiff( raster2Features, raster2InterestPoints, "raster2features" );
601 
602  if( progressPtr )
603  {
604  progressPtr->pulse();
605  if( ! progressPtr->isActive() ) return false;
606  }
607  }
608 
609  // Matching features
610 
611  MatchedInterestPointsSetT matchedPoints;
612 
614  raster1Features,
615  raster2Features,
616  raster1InterestPoints,
617  raster2InterestPoints,
621  matchedPoints ),
622  "Error matching features" );
623 
624  if( progressPtr )
625  {
626  progressPtr->pulse();
627  if( ! progressPtr->isActive() ) return false;
628  }
629 
630  // Clean anused data
631 
632  raster1Features.clear();
633  raster2Features.clear();
634  raster1InterestPoints.clear();
635  raster2InterestPoints.clear();
636 
637  // Generating the output tie-points
638 
639  {
641  MatchedInterestPointsSetT::const_iterator itB = matchedPoints.begin();
642  const MatchedInterestPointsSetT::const_iterator itE = matchedPoints.end();
643 
644  float minFeatureValue1 = FLT_MAX;
645  float maxFeatureValue1 = (-1.0) * FLT_MAX;
646  float minFeatureValue2 = FLT_MAX;
647  float maxFeatureValue2 = (-1.0) * FLT_MAX;
648  float tiePointWeight = 0;
649 
650  itB = matchedPoints.begin();
651  while( itB != itE )
652  {
653  if( minFeatureValue1 > itB->m_point1.m_feature1 )
654  minFeatureValue1 = itB->m_point1.m_feature1;
655  if( maxFeatureValue1 < itB->m_point1.m_feature1 )
656  maxFeatureValue1 = itB->m_point1.m_feature1;
657 
658  if( minFeatureValue2 > itB->m_point2.m_feature1 )
659  minFeatureValue2 = itB->m_point2.m_feature1;
660  if( maxFeatureValue2 < itB->m_point2.m_feature1 )
661  maxFeatureValue2 = itB->m_point2.m_feature1;
662 
663  ++itB;
664  }
665 
666  float featureValue1Range = maxFeatureValue1 - minFeatureValue1;
667  float featureValue2Range = maxFeatureValue2 - minFeatureValue2;
668 
669  if( ( featureValue1Range == 0.0 ) || ( featureValue2Range == 0.0 ) )
670  {
671  tiePointsWeights.resize( matchedPoints.size(), 1.0 );
672  }
673  else
674  {
675  itB = matchedPoints.begin();
676  while( itB != itE )
677  {
678  auxTP.first.x = ( itB->m_point1.m_x / raster1XRescFact ) +
680  auxTP.first.y = ( itB->m_point1.m_y / raster1YRescFact ) +
682  auxTP.second.x = ( itB->m_point2.m_x / raster2XRescFact ) +
684  auxTP.second.y = ( itB->m_point2.m_y / raster2YRescFact ) +
686 
687  tiePointWeight =
688  (
689  ( 2.0f * itB->m_feature )
690  +
691  std::min(
692  (
693  ( itB->m_point1.m_feature1 - minFeatureValue1 )
694  /
695  featureValue1Range
696  )
697  ,
698  (
699  ( itB->m_point1.m_feature2 - minFeatureValue2 )
700  /
701  featureValue2Range
702  )
703  )
704  );
705 
706  tiePointsWeights.push_back( (double)tiePointWeight );
707 
708  outParamsPtr->m_tiePoints.push_back( auxTP );
709 
710  ++itB;
711  }
712  }
713  }
714 
715  if( progressPtr )
716  {
717  progressPtr->pulse();
718  if( ! progressPtr->isActive() ) return false;
719  }
720 
721  return true;
722  }
723 
725  const double raster1XRescFact,
726  const double raster1YRescFact,
727  const double raster2XRescFact,
728  const double raster2YRescFact,
729  te::common::TaskProgress* progressPtr,
731  std::vector< double >& tiePointsWeights )
732  throw( te::rp::Exception )
733  {
734  outParamsPtr->m_tiePoints.clear();
735  tiePointsWeights.clear();
736 
737  if( progressPtr )
738  progressPtr->setTotalSteps( progressPtr->getTotalSteps() + 8 );
739 
740  // Locating interest points and features from raster 1
741 
742  InterestPointsSetT raster1InterestPoints;
743  FloatsMatrix raster1Features;
744  {
745  // Loading image data
746 
747  std::vector< boost::shared_ptr< FloatsMatrix > > rasterData;
748  UCharsMatrix maskRasterData;
749 
754  0,
759  raster1XRescFact,
760  raster1YRescFact,
762  20,
763  rasterData,
764  maskRasterData ),
765  "Error loading raster data" );
766 
767 // printMatrix( *(rasterData[ 0 ]) );
768 // createTifFromMatrix( *(rasterData[ 0 ]), InterestPointsSetT(), "loadedRaster1");
769 
770  if( progressPtr )
771  {
772  progressPtr->pulse();
773  if( ! progressPtr->isActive() ) return false;
774  }
775 
776  // Creating the integral image
777 
778  FloatsMatrix integralRaster;
779 
780  TERP_TRUE_OR_RETURN_FALSE( createIntegralImage( *(rasterData[ 0 ]),
781  integralRaster ), "Integral image creation error" );
782 
783  rasterData.clear();
784 
785  if( progressPtr )
786  {
787  progressPtr->pulse();
788  if( ! progressPtr->isActive() ) return false;
789  }
790 
791 // printMatrix( integralRaster );
792 // createTifFromMatrix( integralRaster, InterestPointsSetT(), "integralRaster1" );
793 
794  // locating interest points
795 
797  integralRaster,
798  maskRasterData.getLinesNumber() ? (&maskRasterData) : 0,
799  raster1InterestPoints ),
800  "Error locating raster 1 interest points" );
801 
802 // createTifFromMatrix( *(rasterData[ 0 ]), candidateInterestPoints, "surfInterestPoints1");
803 
804  if( progressPtr )
805  {
806  progressPtr->pulse();
807  if( ! progressPtr->isActive() ) return false;
808  }
809 
810 
811  InterestPointsSetT validInterestPoints;
812 
813  TERP_TRUE_OR_RETURN_FALSE( generateSurfFeatures( raster1InterestPoints,
814  integralRaster, validInterestPoints, raster1Features ),
815  "Error generating raster features" );
816 
817  raster1InterestPoints = validInterestPoints;
818 
819  if( progressPtr )
820  {
821  progressPtr->pulse();
822  if( ! progressPtr->isActive() ) return false;
823  }
824 
825  }
826 
827  // Locating interest points and features from raster 2
828 
829  InterestPointsSetT raster2InterestPoints;
830  FloatsMatrix raster2Features;
831  {
832  // Loading image data
833 
834  std::vector< boost::shared_ptr< FloatsMatrix > > rasterData;
835  UCharsMatrix maskRasterData;
836 
841  0,
846  raster2XRescFact,
847  raster2YRescFact,
849  20,
850  rasterData,
851  maskRasterData ),
852  "Error loading raster data" );
853 
854 // printMatrix( *(rasterData[ 0 ]) );
855 // createTifFromMatrix( *(rasterData[ 0 ]), InterestPointsSetT(), "loadedRaster2");
856 
857  if( progressPtr )
858  {
859  progressPtr->pulse();
860  if( ! progressPtr->isActive() ) return false;
861  }
862 
863  // Creating the integral image
864 
865  FloatsMatrix integralRaster;
866 
867  TERP_TRUE_OR_RETURN_FALSE( createIntegralImage( *(rasterData[ 0 ]),
868  integralRaster ), "Integral image creation error" );
869 
870  if( progressPtr )
871  {
872  progressPtr->pulse();
873  if( ! progressPtr->isActive() ) return false;
874  }
875 
876  rasterData.clear();
877 
878 // printMatrix( integralRaster );
879 // createTifFromMatrix( integralRaster, InterestPointsSetT(), "integralRaster2" );
880 
881  // locating interest points
882 
884  integralRaster,
885  maskRasterData.getLinesNumber() ? (&maskRasterData) : 0,
886  raster2InterestPoints ),
887  "Error locating raster interest points" );
888 
889 // createTifFromMatrix( *(rasterData[ 0 ]), candidateInterestPoints, "surfInterestPoints2");
890 
891  if( progressPtr )
892  {
893  progressPtr->pulse();
894  if( ! progressPtr->isActive() ) return false;
895  }
896 
897  InterestPointsSetT validInterestPoints;
898 
899  TERP_TRUE_OR_RETURN_FALSE( generateSurfFeatures( raster2InterestPoints,
900  integralRaster, validInterestPoints, raster2Features ),
901  "Error generating raster features" );
902 
903  raster2InterestPoints = validInterestPoints;
904 
905  if( progressPtr )
906  {
907  progressPtr->pulse();
908  if( ! progressPtr->isActive() ) return false;
909  }
910  }
911 
912 // printMatrix( raster1Features );
913 // printMatrix( raster2Features );
914 
915  // Matching features
916 
917  MatchedInterestPointsSetT matchedPoints;
918 
920  raster1Features,
921  raster2Features,
922  raster1InterestPoints,
923  raster2InterestPoints,
925  m_inputParameters.m_surfMaxNormEuclideanDist * 2.0, /* since surf feature vectors are unitary verctors */
927  matchedPoints ),
928  "Error matching features" );
929 
930  if( progressPtr )
931  {
932  progressPtr->pulse();
933  if( ! progressPtr->isActive() ) return false;
934  }
935 
936  // Removing the repeated matched points (those present in more than one scale)
937  // keeping the higher MatchedInterestPointsT::m_feature value
938 
939  {
940  MatchedInterestPointsSetT::iterator it1 = matchedPoints.begin();
941  MatchedInterestPointsSetT::iterator it2;
942  MatchedInterestPointsSetT::iterator eraseIt;
943 
944  while( it1 != matchedPoints.end() )
945  {
946  it2 = it1;
947  ++it2;
948  eraseIt = matchedPoints.end();
949 
950  while( it2 != matchedPoints.end() )
951  {
952  if(
953  ( it1->m_point1.m_x == it2->m_point1.m_x )
954  &&
955  ( it1->m_point1.m_y == it2->m_point1.m_y )
956  &&
957  ( it1->m_point2.m_x == it2->m_point2.m_x )
958  &&
959  ( it1->m_point2.m_y == it2->m_point2.m_y )
960  )
961  {
962  if( it1->m_feature < it2->m_feature )
963  {
964  eraseIt = it1;
965  }
966  else if( it1->m_feature > it2->m_feature )
967  {
968  eraseIt = it2;
969  }
970 
971  break;
972  }
973  else
974  {
975  ++it2;
976  }
977  }
978 
979  if( eraseIt == it1 )
980  {
981  ++it1;
982  matchedPoints.erase( eraseIt );
983  }
984  else if( eraseIt != matchedPoints.end() )
985  {
986  matchedPoints.erase( eraseIt );
987  ++it1;
988  }
989  else
990  {
991  ++it1;
992  }
993  }
994  }
995 
996  // Removing the worse mathed points to fitting the required amount of matched points
997 
998  while( matchedPoints.size() > m_inputParameters.m_maxTiePoints )
999  {
1000  matchedPoints.erase( matchedPoints.begin() );
1001  }
1002 
1003  // Generating the output tie-points
1004 
1005  {
1007  MatchedInterestPointsSetT::const_iterator itB = matchedPoints.begin();
1008  const MatchedInterestPointsSetT::const_iterator itE = matchedPoints.end();
1009  float minFeature1P1 = FLT_MAX;
1010  float maxFeature1P1 = (-1.0) * FLT_MAX;
1011  float minFeature1P2 = FLT_MAX;
1012  float maxFeature1P2 = (-1.0) * FLT_MAX;
1013 
1014  while( itB != itE )
1015  {
1016  if( minFeature1P1 > itB->m_point1.m_feature1 )
1017  minFeature1P1 = itB->m_point1.m_feature1;
1018  if( maxFeature1P1 < itB->m_point1.m_feature1 )
1019  maxFeature1P1 = itB->m_point1.m_feature1;
1020 
1021  if( minFeature1P2 > itB->m_point2.m_feature1 )
1022  minFeature1P2 = itB->m_point2.m_feature1;
1023  if( maxFeature1P2 < itB->m_point2.m_feature1 )
1024  maxFeature1P2 = itB->m_point2.m_feature1;
1025 
1026  ++itB;
1027  }
1028 
1029  float feature1P1Range = maxFeature1P1 - minFeature1P1;
1030  float feature1P2Range = maxFeature1P2 - minFeature1P2;
1031 
1032  if( ( feature1P1Range == 0.0 ) || ( feature1P2Range == 0.0 ) )
1033  {
1034  tiePointsWeights.resize( matchedPoints.size(), 1.0 );
1035  }
1036  else
1037  {
1038  itB = matchedPoints.begin();
1039 
1040  while( itB != itE )
1041  {
1042  auxTP.first.x = ( itB->m_point1.m_x / raster1XRescFact ) +
1044  auxTP.first.y = ( itB->m_point1.m_y / raster1YRescFact ) +
1046  auxTP.second.x = ( itB->m_point2.m_x / raster2XRescFact ) +
1048  auxTP.second.y = ( itB->m_point2.m_y / raster2YRescFact ) +
1050 
1051  tiePointsWeights.push_back( (double)
1052  (
1053  ( 2.0 * itB->m_feature )
1054  +
1055  std::min(
1056  (
1057  ( itB->m_point1.m_feature1 - minFeature1P1 + feature1P1Range )
1058  /
1059  ( 2.0 * feature1P1Range )
1060  )
1061  ,
1062  (
1063  ( itB->m_point2.m_feature1 - minFeature1P2 + feature1P2Range )
1064  /
1065  ( 2.0 * feature1P2Range )
1066  )
1067  )
1068  )
1069  );
1070 
1071  outParamsPtr->m_tiePoints.push_back( auxTP );
1072 
1073  ++itB;
1074  }
1075  }
1076  }
1077 
1078  return true;
1079  }
1080 
1081 
1082  void TiePointsLocator::reset() throw( te::rp::Exception )
1083  {
1085  m_isInitialized = false;
1086  }
1087 
1089  throw( te::rp::Exception )
1090  {
1091  reset();
1092 
1093  {
1094  TiePointsLocator::InputParameters const* inputParamsPtr = dynamic_cast<
1095  TiePointsLocator::InputParameters const* >( &inputParams );
1096  TERP_TRUE_OR_RETURN_FALSE( inputParamsPtr, "Invalid parameters" );
1097 
1098  m_inputParameters = *inputParamsPtr;
1099  }
1100 
1101  // Checking m_inRaster1Ptr
1102 
1104  "Invalid m_inRaster1Ptr" );
1107  "Invalid m_inRaster1Ptr" );
1108 
1109  // Checking m_inMaskRaster1Ptr
1110 
1112  {
1115  "Invalid m_inMaskRaster1Ptr" );
1118  "Invalid m_inMaskRaster1Ptr" );
1122  "Invalid m_inMaskRaster1Ptr" );
1126  "Invalid m_inMaskRaster1Ptr" );
1127  }
1128 
1129  // Checking raster 1 target area
1130 
1133  "Invalid m_raster1TargetAreaLineStart" );
1134 
1137  "Invalid m_raster1TargetAreaColStart" );
1138 
1141  {
1144  ( ( unsigned int ) m_inputParameters.m_inRaster1Ptr->getNumberOfColumns() )
1146 
1149  ( ( unsigned int ) m_inputParameters.m_inRaster1Ptr->getNumberOfRows() )
1151  }
1152  else
1153  {
1158  }
1159 
1161  "Invalid m_raster1TargetAreaWidth" );
1163  "Invalid m_raster1TargetAreaHeight" );
1164 
1165  // Checking raster 1 bands
1166  {
1167  for( unsigned int bandIdx = 0 ; bandIdx <
1168  m_inputParameters.m_inRaster1Bands.size() ; ++bandIdx )
1169  {
1171  m_inputParameters.m_inRaster1Bands[ bandIdx ] <
1173  "Invalid m_inRaster1Bands" );
1174  }
1175  }
1176 
1177  // Checking raster 2
1178 
1180  "Invalid m_inRaster2Ptr" );
1183  "Invalid m_inRaster2Ptr" );
1184 
1185  // Checking m_inMaskRaster2Ptr
1186 
1188  {
1191  "Invalid m_inMaskRaster2Ptr" );
1194  "Invalid m_inMaskRaster2Ptr" );
1198  "Invalid m_inMaskRaster2Ptr" );
1202  "Invalid m_inMaskRaster2Ptr" );
1203  }
1204 
1205  // Checking raster target area
1206 
1209  "Invalid m_raster2TargetAreaLineStart" );
1210 
1213  "Invalid m_raster2TargetAreaColStart" );
1214 
1217  {
1220  ( ( unsigned int ) m_inputParameters.m_inRaster2Ptr->getNumberOfColumns() )
1222 
1225  ( ( unsigned int ) m_inputParameters.m_inRaster2Ptr->getNumberOfRows() )
1227  }
1228  else
1229  {
1234  }
1235 
1237  "Invalid m_raster2TargetAreaWidth" );
1239  "Invalid m_raster2TargetAreaHeight" );
1240 
1241  // Checking raster 2 bands
1242 
1243  {
1244  for( unsigned int bandIdx = 0 ; bandIdx <
1245  m_inputParameters.m_inRaster2Bands.size() ; ++bandIdx )
1246  {
1248  m_inputParameters.m_inRaster2Bands[ bandIdx ] <
1250  "Invalid m_inRaster2Bands" );
1251  }
1252  }
1253 
1254  // Checking strategy specific parameters
1255 
1257  {
1259  {
1261  == 1, "Invalid number of raster 1 bands" );
1263  == 1, "Invalid number of raster 2 bands" );
1264 
1265  // Defining the number of tie points
1266 
1268  {
1269  const unsigned int maxRastersArea =
1270  std::max(
1273  ,
1276  );
1277  const unsigned maxWindowSize = std::max(
1280  m_inputParameters.m_maxTiePoints = maxRastersArea /
1281  ( 4 * maxWindowSize * maxWindowSize );
1282 
1283  // This is because the features and matching matrix bare eing allocated in RAM
1284  const double totalPhysMem = (double)te::common::GetTotalPhysicalMemory();
1285  const double usedVMem = (double)te::common::GetUsedVirtualMemory();
1286  const double totalVMem = (double)te::common::GetTotalVirtualMemory();
1287  const double freeVMem = 0.4 * std::min( totalPhysMem, ( totalVMem - usedVMem ) );
1288  const double featSize = (double)( m_inputParameters.m_moravecCorrelationWindowWidth *
1291  std::min(
1293  (unsigned int)(
1294  std::sqrt(
1295  ( featSize * featSize )
1296  +
1297  ( freeVMem / (double)( sizeof( float ) ) )
1298  )
1299  -
1300  featSize
1301  )
1302  );
1303  }
1304 
1305  break;
1306  }
1308  {
1310  == 1, "Invalid number of raster 1 bands" );
1312  == 1, "Invalid number of raster 2 bands" );
1313 
1314  // Defining the number of tie points
1315 
1317  {
1318  const unsigned int maxRastersArea =
1319  std::max(
1322  ,
1325  );
1326  const unsigned int maxWindowSize = getSurfFilterSize(
1329  m_inputParameters.m_maxTiePoints = maxRastersArea /
1330  ( 4 * maxWindowSize * maxWindowSize );
1331 
1332  // This is because the features and matching matrix bare eing allocated in RAM
1333  const double totalPhysMem = (double)te::common::GetTotalPhysicalMemory();
1334  const double usedVMem = (double)te::common::GetUsedVirtualMemory();
1335  const double totalVMem = (double)te::common::GetTotalVirtualMemory();
1336  const double freeVMem = 0.4 * std::min( totalPhysMem, ( totalVMem - usedVMem ) );
1338  std::min(
1340  (unsigned int)(
1341  std::sqrt(
1342  ( 65 * 65 )
1343  +
1344  ( freeVMem / (double)( sizeof( float ) ) )
1345  )
1346  -
1347  65
1348  )
1349  );
1350  }
1351 
1352  break;
1353  }
1354  default :
1355  {
1356  TERP_LOG_AND_RETURN_FALSE( "Invalid strategy" );
1357  break;
1358  }
1359  };
1360 
1361  // Checking other parameters
1362 
1364  "Invalid m_maxTiePoints" )
1365 
1367  "Invalid m_pixelSizeXRelation" )
1368 
1370  "Invalid m_pixelSizeYRelation" )
1371 
1373  "Invalid m_geomTransfMaxError" )
1374 
1378  "Invalid m_moravecCorrelationWindowWidth" );
1379 
1383  "Invalid m_moravecWindowWidth" );
1384 
1387  "Invalid m_geomTransfName" );
1388 
1390  "Invalid m_surfScalesNumber" );
1391 
1393  "Invalid m_surfOctavesNumber" );
1394 
1396  "Invalid m_rastersRescaleFactor" );
1397 
1400  "Invalid m_surfMaxNormEuclideanDist" );
1401 
1404  "Invalid m_moravecMinAbsCorrelation" );
1405 
1408  "Invalid m_geometryFilterAssurance" );
1409 
1410  m_isInitialized = true;
1411 
1412  return true;
1413  }
1414 
1416  {
1417  return m_isInitialized;
1418  }
1419 
1421  te::rst::Raster const* rasterPtr,
1422  const std::vector< unsigned int >& rasterBands,
1423  te::rst::Raster const* maskRasterPtr,
1424  const unsigned int maskRasterBand,
1425  const unsigned int rasterTargetAreaLineStart,
1426  const unsigned int rasterTargetAreaColStart,
1427  const unsigned int rasterTargetAreaWidth,
1428  const unsigned int rasterTargetAreaHeight,
1429  const double rescaleFactorX,
1430  const double rescaleFactorY,
1431  const te::rst::Interpolator::Method rasterInterpMethod,
1432  const unsigned char maxMemPercentUsage,
1433  std::vector< boost::shared_ptr< FloatsMatrix > >& loadedRasterData,
1434  UCharsMatrix& loadedMaskRasterData )
1435  {
1436  // Allocating the output matrixes
1437 
1438  const unsigned int rescaledNLines = (unsigned int)(
1439  ((double)rasterTargetAreaHeight) * rescaleFactorY );
1440  const unsigned int rescaledNCols = (unsigned int)(
1441  ((double)rasterTargetAreaWidth) * rescaleFactorX );
1442 
1443  {
1444  unsigned char maxMemPercentUsagePerMatrix = MAX( 1u, maxMemPercentUsage /
1445  (
1446  ( maskRasterPtr ? 1 : 0 )
1447  +
1448  ((unsigned int)rasterBands.size()) )
1449  );
1450 
1451  loadedRasterData.resize( rasterBands.size() );
1452 
1453  for( unsigned int rasterBandsIdx = 0 ; rasterBandsIdx < rasterBands.size() ;
1454  ++rasterBandsIdx )
1455  {
1456  loadedRasterData[ rasterBandsIdx ].reset( new FloatsMatrix );
1457  TERP_TRUE_OR_RETURN_FALSE( loadedRasterData[ rasterBandsIdx ]->reset(
1458  rescaledNLines, rescaledNCols, FloatsMatrix::AutoMemPol,
1459  maxMemPercentUsagePerMatrix ),
1460  "Cannot allocate image 1 matrix" );
1461  maxMemPercentUsagePerMatrix *= 2;
1462  }
1463 
1464  if( maskRasterPtr )
1465  {
1466  TERP_TRUE_OR_RETURN_FALSE( loadedMaskRasterData.reset(
1467  rescaledNLines, rescaledNCols,
1468  UCharsMatrix::AutoMemPol, maxMemPercentUsagePerMatrix ),
1469  "Cannot allocate image 1 mask matrix" );
1470  }
1471  }
1472 
1473  // loading mask data
1474 
1475  if( maskRasterPtr )
1476  {
1477  te::rst::Band const* inMaskRasterBand = maskRasterPtr->getBand( maskRasterBand );
1478  assert( inMaskRasterBand );
1479 
1480  unsigned char* outMaskLinePtr = 0;
1481  unsigned int outLine = 0;
1482  unsigned int outCol = 0;
1483  unsigned int inLine = 0;
1484  unsigned int inCol = 0;
1485  double value = 0;
1486 
1487  for( outLine = 0 ; outLine < rescaledNLines ; ++outLine )
1488  {
1489  inLine = (unsigned int)( ( ( (double)outLine ) /
1490  rescaleFactorY ) + ( (double)rasterTargetAreaLineStart ) );
1491 
1492  outMaskLinePtr = loadedMaskRasterData[ outLine ];
1493 
1494  for( outCol = 0 ; outCol < rescaledNCols ; ++outCol )
1495  {
1496  inCol = (unsigned int)( ( ( (double)outCol ) /
1497  rescaleFactorX ) + ( (double)rasterTargetAreaColStart ) );
1498 
1499  inMaskRasterBand->getValue( inCol, inLine, value );
1500 
1501  if( value == 0 )
1502  outMaskLinePtr[ outCol ] = 0;
1503  else
1504  outMaskLinePtr[ outCol ] = 255;
1505  }
1506  }
1507  }
1508 
1509  // loading raster data
1510  {
1511  const double rasterTargetAreaLineStartDouble = (double)
1512  rasterTargetAreaLineStart;
1513  const double rasterTargetAreaColStartDouble = (double)
1514  rasterTargetAreaColStart;
1515  te::rst::Interpolator interpInstance( rasterPtr, rasterInterpMethod );
1516  float* floatLinePtr = 0;
1517  double* doubleLinePtr = 0;
1518  unsigned int outLine = 0;
1519  unsigned int outCol = 0;
1520  double inLine = 0;
1521  double inCol = 0;
1522  std::complex< double > interpolatedValue;
1523  unsigned int bandIdx = 0;
1524  double bandMin = 0;
1525  double bandMax = 0;
1526  double gain = 0;
1527 
1528  DoublesMatrix auxBandData;
1529  TERP_TRUE_OR_RETURN_FALSE( auxBandData.reset(
1530  rescaledNLines, rescaledNCols, DoublesMatrix::AutoMemPol, 40 ),
1531  "Cannot allocate auxiliar matrix" );
1532 
1533  for( unsigned int rasterBandsIdx = 0 ; rasterBandsIdx < rasterBands.size() ;
1534  ++rasterBandsIdx )
1535  {
1536  bandIdx= rasterBands[ rasterBandsIdx ];
1537  bandMin = DBL_MAX;
1538  bandMax = -1.0 * DBL_MAX;
1539 
1540  for( outLine = 0 ; outLine < rescaledNLines ; ++outLine )
1541  {
1542  inLine = ( ( (double)outLine ) / rescaleFactorY ) +
1543  rasterTargetAreaLineStartDouble;
1544 
1545  doubleLinePtr = auxBandData[ outLine ];
1546 
1547  for( outCol = 0 ; outCol < rescaledNCols ; ++outCol )
1548  {
1549  inCol = ( ( (double)outCol ) / rescaleFactorX ) +
1550  rasterTargetAreaColStartDouble;
1551 
1552  interpInstance.getValue( inCol, inLine, interpolatedValue,
1553  bandIdx );
1554 
1555  doubleLinePtr[ outCol ] = interpolatedValue.real();
1556 
1557  if( interpolatedValue.real() > bandMax ) bandMax = interpolatedValue.real();
1558  if( interpolatedValue.real() < bandMin ) bandMin = interpolatedValue.real();
1559  }
1560  }
1561 
1562  if( bandMin == bandMax )
1563  gain = 0.0;
1564  else
1565  gain = ( 1.0 / ( bandMax - bandMin ) );
1566 
1567  for( outLine = 0 ; outLine < rescaledNLines ; ++outLine )
1568  {
1569  doubleLinePtr = auxBandData[ outLine ];
1570  floatLinePtr = loadedRasterData[ rasterBandsIdx ]->operator[]( outLine );
1571 
1572  for( outCol = 0 ; outCol < rescaledNCols ; ++outCol )
1573  {
1574  floatLinePtr[ outCol ] = (float)( ( doubleLinePtr[ outCol ] - bandMin ) * gain );
1575  }
1576  }
1577  }
1578  }
1579 
1580  return true;
1581  }
1582 
1584  const FloatsMatrix& rasterData,
1585  UCharsMatrix const* maskRasterDataPtr,
1586  const unsigned int moravecWindowWidth,
1587  const unsigned int maxInterestPoints,
1588  const unsigned int enableMultiThread,
1589  InterestPointsSetT& interestPoints )
1590  {
1591  interestPoints.clear();
1592 
1593  const unsigned int minRasterWidthAndHeight = 2 * ( ( 2 *
1594  moravecWindowWidth ) - 1 );
1595  // There is not enough data to look for interest points!
1596  if( rasterData.getColumnsNumber() < minRasterWidthAndHeight ) return true;
1597  if( rasterData.getLinesNumber() < minRasterWidthAndHeight ) return true;
1598 
1599  bool returnValue = true;
1600  boost::mutex rastaDataAccessMutex;
1601  boost::mutex interestPointsAccessMutex;
1602  unsigned int nextRasterLinesBlockToProcess = 0;
1603 
1604  MoravecLocatorThreadParams threadParams;
1605  threadParams.m_returnValuePtr = &returnValue;
1606  threadParams.m_rastaDataAccessMutexPtr = &rastaDataAccessMutex;
1607  threadParams.m_interestPointsAccessMutexPtr = &interestPointsAccessMutex;
1609  &nextRasterLinesBlockToProcess;
1610  threadParams.m_interestPointsPtr = &interestPoints;
1611  threadParams.m_rasterDataPtr = &rasterData;
1612  threadParams.m_maskRasterDataPtr = maskRasterDataPtr;
1613  threadParams.m_moravecWindowWidth = moravecWindowWidth;
1614 
1615  if( enableMultiThread )
1616  {
1617  const unsigned int procsNumber = te::common::GetPhysProcNumber();
1618 
1619  threadParams.m_maxRasterLinesBlockMaxSize = std::max(
1620  minRasterWidthAndHeight, rasterData.getLinesNumber() / procsNumber );
1621 
1622  const unsigned int rasterLinesBlocksNumber =
1623  ( rasterData.getLinesNumber() / threadParams.m_maxRasterLinesBlockMaxSize ) +
1624  ( ( rasterData.getLinesNumber() % threadParams.m_maxRasterLinesBlockMaxSize ) ? 1 : 0 );
1625 
1627  maxInterestPoints / rasterLinesBlocksNumber;
1628 
1629  boost::thread_group threads;
1630 
1631  for( unsigned int threadIdx = 0 ; threadIdx < procsNumber ;
1632  ++threadIdx )
1633  {
1634  threads.add_thread( new boost::thread(
1636  &threadParams ) );
1637  }
1638 
1639  threads.join_all();
1640  }
1641  else
1642  {
1643  threadParams.m_maxRasterLinesBlockMaxSize = rasterData.getLinesNumber();
1644  threadParams.m_maxInterestPointsPerRasterLinesBlock = maxInterestPoints;
1645 
1646  locateMoravecInterestPointsThreadEntry( &threadParams );
1647  }
1648 
1649  return returnValue;
1650  }
1651 
1653  {
1654  assert( paramsPtr );
1655  assert( paramsPtr->m_returnValuePtr );
1656  assert( paramsPtr->m_moravecWindowWidth > 2 );
1657  assert( paramsPtr->m_rasterDataPtr );
1658  assert( paramsPtr->m_interestPointsPtr );
1659  assert( paramsPtr->m_rastaDataAccessMutexPtr );
1660  assert( paramsPtr->m_interestPointsAccessMutexPtr );
1661  assert( paramsPtr->m_maxRasterLinesBlockMaxSize > 2 );
1662  assert( paramsPtr->m_nextRasterLinesBlockToProcessValuePtr );
1663 
1664  const unsigned int moravecWindowWidth = paramsPtr->m_moravecWindowWidth;
1665  const unsigned int moravecWindowRadius = moravecWindowWidth / 2;
1666 
1667  // Allocating the internal raster data buffer
1668  // and the mask raster buffer
1669 
1670  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1671 
1672  const unsigned int rasterLines = paramsPtr->m_rasterDataPtr->getLinesNumber();
1673  const unsigned int bufferLines = moravecWindowWidth;
1674  const unsigned int lastBufferLineIdx = bufferLines - 1;
1675  const unsigned int bufferCols = paramsPtr->m_rasterDataPtr->getColumnsNumber();
1676  const unsigned int rasterBufferLineSizeBytes = sizeof(
1677  FloatsMatrix::ElementTypeT ) * bufferCols;
1678  const unsigned int maskRasterBufferLineSizeBytes = sizeof(
1680  bufferCols;
1681 
1682  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1683 
1684  FloatsMatrix rasterBufferDataHandler;
1685  if( ! rasterBufferDataHandler.reset( bufferLines, bufferCols,
1687  {
1688  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1689  paramsPtr->m_returnValuePtr = false;
1690  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1691  return;
1692  }
1693 
1694  boost::scoped_array< float* > rasterBufferHandler( new float*[ bufferLines ] );
1695  for( unsigned int rasterBufferDataHandlerLine = 0 ; rasterBufferDataHandlerLine <
1696  bufferLines ; ++rasterBufferDataHandlerLine )
1697  {
1698  rasterBufferHandler[ rasterBufferDataHandlerLine ] = rasterBufferDataHandler[
1699  rasterBufferDataHandlerLine ];
1700  }
1701 
1702  float** rasterBufferPtr = rasterBufferHandler.get();
1703 
1704  // Allocating the mask raster buffer
1705 
1706  UCharsMatrix maskRasterBufferDataHandler;
1707 
1708  boost::scoped_array< unsigned char* > maskRasterBufferHandler( new unsigned char*[ bufferLines ] );
1709 
1710  unsigned char** maskRasterBufferPtr = 0;
1711 
1712  if( paramsPtr->m_maskRasterDataPtr )
1713  {
1714  if( ! maskRasterBufferDataHandler.reset( bufferLines, bufferCols,
1716  {
1717  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1718  paramsPtr->m_returnValuePtr = false;
1719  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1720  return;
1721  }
1722 
1723  for( unsigned int maskRasterBufferDataHandlerLine = 0 ; maskRasterBufferDataHandlerLine <
1724  bufferLines ; ++maskRasterBufferDataHandlerLine )
1725  {
1726  maskRasterBufferHandler[ maskRasterBufferDataHandlerLine ] = maskRasterBufferDataHandler[
1727  maskRasterBufferDataHandlerLine ];
1728  }
1729 
1730  maskRasterBufferPtr = maskRasterBufferHandler.get();
1731  }
1732 
1733  // Allocating the internal maximas values data buffer
1734 
1735  FloatsMatrix maximasBufferDataHandler;
1736  if( ! maximasBufferDataHandler.reset( bufferLines, bufferCols,
1738  {
1739  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1740  paramsPtr->m_returnValuePtr = false;
1741  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1742  return;
1743  }
1744 
1745  boost::scoped_array< float* > maximasBufferHandler( new float*[ bufferLines ] );
1746  float** maximasBufferPtr = maximasBufferHandler.get();
1747  unsigned int bufferCol = 0;
1748  for( unsigned int maximasBufferDataHandlerLine = 0 ; maximasBufferDataHandlerLine <
1749  bufferLines ; ++maximasBufferDataHandlerLine )
1750  {
1751  maximasBufferHandler[ maximasBufferDataHandlerLine ] = maximasBufferDataHandler[
1752  maximasBufferDataHandlerLine ];
1753  for( bufferCol = 0 ; bufferCol < bufferCols ; ++bufferCol )
1754  {
1755  maximasBufferPtr[ maximasBufferDataHandlerLine ][ bufferCol ] = 0;
1756  }
1757  }
1758 
1759  // Pick the next block to process
1760 
1761  const unsigned int rasterLinesBlocksNumber =
1762  ( rasterLines / paramsPtr->m_maxRasterLinesBlockMaxSize ) +
1763  ( ( rasterLines % paramsPtr->m_maxRasterLinesBlockMaxSize ) ? 1 : 0 );
1764 
1765  for( unsigned int rasterLinesBlockIdx = 0; rasterLinesBlockIdx <
1766  rasterLinesBlocksNumber ; ++rasterLinesBlockIdx )
1767  {
1768  InterestPointsSetT blockMaximas; // the maxima points found inside the current raster block
1769 
1770  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1771 
1772  if( rasterLinesBlockIdx == ( *(paramsPtr->m_nextRasterLinesBlockToProcessValuePtr ) ) )
1773  {
1774  ++( *(paramsPtr->m_nextRasterLinesBlockToProcessValuePtr ) );
1775 
1776  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1777 
1778  // Processing each raster line from the current block
1779 
1780  const unsigned int rasterLinesStart = (unsigned int)std::max( 0,
1781  (int)(rasterLinesBlockIdx * paramsPtr->m_maxRasterLinesBlockMaxSize ) -
1782  (int)( 2 * moravecWindowRadius ) );
1783  const unsigned int rasterLinesEndBound = std::min( 1 +
1784  (rasterLinesBlockIdx * paramsPtr->m_maxRasterLinesBlockMaxSize ) +
1785  paramsPtr->m_maxRasterLinesBlockMaxSize +
1786  ( 2 * moravecWindowRadius ), rasterLines );
1787  const unsigned int varianceCalcStartRasterLineStart = rasterLinesStart +
1788  moravecWindowWidth - 1;
1789  const unsigned int maximasLocationStartRasterLineStart =
1790  varianceCalcStartRasterLineStart + moravecWindowWidth - 1;
1791  unsigned int windowStartBufCol = 0;
1792  const unsigned int windowEndBufColsBound = bufferCols -
1793  moravecWindowWidth;
1794  unsigned int windowStartBufOffset = 0;
1795  unsigned int windowStartBufXOffset = 0;
1796  unsigned int windowStartBufYOffset = 0;
1797  float horVar = 0;
1798  float verVar = 0;
1799  float diagVar = 0;
1800  float adiagVar = 0;
1801  float diffValue = 0;
1802  bool isLocalMaxima = false;
1803  InterestPointT auxInterestPoint;
1804  float neighborMaximaDif = 0;
1805 
1806  for( unsigned int rasterLine = rasterLinesStart; rasterLine < rasterLinesEndBound ;
1807  ++rasterLine )
1808  {
1809  // read a new raster line into the last raster buffer line
1810  paramsPtr->m_rastaDataAccessMutexPtr->lock();
1811 
1812  roolUpBuffer( rasterBufferPtr, bufferLines );
1813  memcpy( rasterBufferPtr[ lastBufferLineIdx ],
1814  paramsPtr->m_rasterDataPtr->operator[]( rasterLine ),
1815  rasterBufferLineSizeBytes );
1816 
1817  // read a new mask raster line into the last mask raster buffer line
1818  if( paramsPtr->m_maskRasterDataPtr )
1819  {
1820  roolUpBuffer( maskRasterBufferPtr, bufferLines );
1821  memcpy( maskRasterBufferPtr[ lastBufferLineIdx ],
1822  paramsPtr->m_maskRasterDataPtr->operator[]( rasterLine ),
1823  maskRasterBufferLineSizeBytes );
1824  }
1825 
1826  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1827 
1828  // calc the diretional variance for last line from the
1829  // diretional variances buffer
1830  if( rasterLine >= varianceCalcStartRasterLineStart )
1831  {
1832  roolUpBuffer( maximasBufferPtr, bufferLines );
1833 
1834  for( windowStartBufCol = 0 ; windowStartBufCol < windowEndBufColsBound ;
1835  ++windowStartBufCol )
1836  {
1837  const float& windowCenterPixelValue = rasterBufferPtr[
1838  moravecWindowRadius ][ windowStartBufCol +
1839  moravecWindowRadius ];
1840  horVar = 0;
1841  verVar = 0;
1842  diagVar = 0;
1843  adiagVar = 0;
1844 
1845  for( windowStartBufOffset = 0 ; windowStartBufOffset <
1846  moravecWindowWidth ; ++windowStartBufOffset )
1847  {
1848  diffValue = windowCenterPixelValue - rasterBufferPtr[
1849  moravecWindowRadius ][ windowStartBufCol +
1850  windowStartBufOffset ];
1851  horVar += ( diffValue * diffValue );
1852 
1853  diffValue = windowCenterPixelValue - rasterBufferPtr[
1854  windowStartBufOffset ][ windowStartBufCol +
1855  moravecWindowRadius ];
1856  verVar += ( diffValue * diffValue );
1857 
1858  diffValue = windowCenterPixelValue - rasterBufferPtr[
1859  windowStartBufOffset ][ windowStartBufCol +
1860  windowStartBufOffset ];
1861  diagVar += ( diffValue * diffValue );
1862 
1863  diffValue = windowCenterPixelValue - rasterBufferPtr[
1864  moravecWindowWidth - 1 - windowStartBufOffset ][ windowStartBufCol +
1865  windowStartBufOffset ];
1866  adiagVar += ( diffValue * diffValue );
1867  }
1868 
1869  maximasBufferPtr[ lastBufferLineIdx ][ windowStartBufCol +
1870  moravecWindowRadius ] = std::min( horVar, std::min(
1871  verVar, std::min( diagVar, adiagVar ) ) );
1872  }
1873  }
1874 
1875  // find the local maxima points for the diretional variances buffer
1876  // center line.
1877  if( rasterLine >= maximasLocationStartRasterLineStart )
1878  {
1879  for( windowStartBufCol = 0 ; windowStartBufCol < windowEndBufColsBound ;
1880  ++windowStartBufCol )
1881  {
1882  isLocalMaxima = true;
1883  const float& windowCenterPixelValue = maximasBufferPtr[
1884  moravecWindowRadius ][ windowStartBufCol +
1885  moravecWindowRadius ];
1886  auxInterestPoint.m_feature1 = 0.0;
1887 
1888  for( windowStartBufYOffset = 0 ; windowStartBufYOffset <
1889  moravecWindowWidth ; ++windowStartBufYOffset )
1890  {
1891  for( windowStartBufXOffset = 0 ; windowStartBufXOffset <
1892  moravecWindowWidth ; ++windowStartBufXOffset )
1893  {
1894  neighborMaximaDif = windowCenterPixelValue - maximasBufferPtr[
1895  windowStartBufYOffset ][ windowStartBufCol +
1896  windowStartBufXOffset ];
1897 
1898  if( neighborMaximaDif < 0.0 )
1899  {
1900  isLocalMaxima = false;
1901  windowStartBufYOffset = moravecWindowWidth;
1902  break;
1903  }
1904 
1905  auxInterestPoint.m_feature1 += std::abs( neighborMaximaDif );
1906  }
1907  }
1908 
1909  if( isLocalMaxima )
1910  {
1911  auxInterestPoint.m_x = windowStartBufCol +
1912  moravecWindowRadius;
1913  auxInterestPoint.m_y = rasterLine - moravecWindowWidth + 1;
1914  assert( auxInterestPoint.m_x <
1915  paramsPtr->m_rasterDataPtr->getColumnsNumber() );
1916  assert( auxInterestPoint.m_y <
1917  paramsPtr->m_rasterDataPtr->getLinesNumber() );
1918 
1919  if( maskRasterBufferPtr )
1920  {
1921  if( maskRasterBufferPtr[ 0 ][ auxInterestPoint.m_x ] )
1922  {
1923  blockMaximas.insert( auxInterestPoint);
1924 
1925  if( blockMaximas.size() >
1927  {
1928  blockMaximas.erase( blockMaximas.begin() );
1929  }
1930  }
1931  }
1932  else
1933  {
1934  blockMaximas.insert( auxInterestPoint );
1935 
1936  if( blockMaximas.size() >
1938  {
1939  blockMaximas.erase( blockMaximas.begin() );
1940  }
1941  }
1942  }
1943  }
1944  }
1945  }
1946 
1947  // Copying the best found block maximas to the external maximas container
1948 
1949  paramsPtr->m_interestPointsAccessMutexPtr->lock();
1950 
1951  unsigned int pointsToAdd = std::min(
1953  (unsigned int)blockMaximas.size() );
1954  InterestPointsSetT::const_reverse_iterator blockMaximasIt =
1955  blockMaximas.rbegin();
1956 
1957  while( pointsToAdd )
1958  {
1959 // std::cout << std::endl << blockMaximasIt->m_featureValue
1960 // << std::endl;
1961 
1962  paramsPtr->m_interestPointsPtr->insert( *blockMaximasIt );
1963 
1964  ++blockMaximasIt;
1965  --pointsToAdd;
1966  }
1967 
1968  paramsPtr->m_interestPointsAccessMutexPtr->unlock();
1969  }
1970  else
1971  {
1972  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
1973  }
1974  }
1975  }
1976 
1978  const FloatsMatrix& integralRasterData,
1979  UCharsMatrix const* maskRasterDataPtr,
1980  InterestPointsSetT& interestPoints ) const
1981  {
1982  interestPoints.clear();
1983 
1984  // finding interest points
1985 
1986  bool returnValue = true;
1987  boost::mutex rastaDataAccessMutex;
1988  boost::mutex interestPointsAccessMutex;
1989  unsigned int nextRasterLinesBlockToProcess = 0;
1990 
1991  SurfLocatorThreadParams threadParams;
1992  threadParams.m_returnValuePtr = &returnValue;
1993  threadParams.m_rastaDataAccessMutexPtr = &rastaDataAccessMutex;
1994  threadParams.m_interestPointsAccessMutexPtr = &interestPointsAccessMutex;
1996  &nextRasterLinesBlockToProcess;
1997  threadParams.m_interestPointsPtr = &interestPoints;
1998  threadParams.m_integralRasterDataPtr = &integralRasterData;
1999  threadParams.m_maskRasterDataPtr = maskRasterDataPtr;
2002 
2004  {
2005  const unsigned int procsNumber = te::common::GetPhysProcNumber();
2006  const unsigned int maxGausFilterWidth = getSurfFilterSize(
2008 
2009  threadParams.m_maxRasterLinesBlockMaxSize = std::max(
2010  4 * maxGausFilterWidth, integralRasterData.getLinesNumber() / procsNumber );
2011  threadParams.m_maxRasterLinesBlockMaxSize = std::min(
2012  threadParams.m_maxRasterLinesBlockMaxSize,
2013  integralRasterData.getLinesNumber() );
2014 
2015  const unsigned int rasterLinesBlocksNumber =
2016  ( integralRasterData.getLinesNumber() / threadParams.m_maxRasterLinesBlockMaxSize ) +
2017  ( ( integralRasterData.getLinesNumber() % threadParams.m_maxRasterLinesBlockMaxSize ) ? 1 : 0 );
2018 
2020  m_inputParameters.m_maxTiePoints / rasterLinesBlocksNumber;
2021 
2022  boost::thread_group threads;
2023 
2024  for( unsigned int threadIdx = 0 ; threadIdx < procsNumber ;
2025  ++threadIdx )
2026  {
2027  threads.add_thread( new boost::thread(
2029  &threadParams ) );
2030  }
2031 
2032  threads.join_all();
2033  }
2034  else
2035  {
2036  threadParams.m_maxRasterLinesBlockMaxSize = integralRasterData.getLinesNumber();
2038 
2039  locateSurfInterestPointsThreadEntry( &threadParams );
2040  }
2041 
2042  return returnValue;
2043  }
2044 
2045 
2046 
2048  {
2049  assert( paramsPtr );
2050  assert( paramsPtr->m_returnValuePtr );
2051  assert( paramsPtr->m_integralRasterDataPtr );
2052  assert( paramsPtr->m_interestPointsPtr );
2053  assert( paramsPtr->m_rastaDataAccessMutexPtr );
2054  assert( paramsPtr->m_interestPointsAccessMutexPtr );
2055  assert( paramsPtr->m_maxRasterLinesBlockMaxSize > 2 );
2056  assert( paramsPtr->m_nextRasterLinesBlockToProcessValuePtr );
2057  assert( paramsPtr->m_scalesNumber > 2 );
2058  assert( paramsPtr->m_octavesNumber > 0 );
2059 
2060  // Globals
2061 
2062  const unsigned int maxGausFilterWidth = getSurfFilterSize(
2063  paramsPtr->m_octavesNumber - 1, paramsPtr->m_scalesNumber - 1 );
2064  const unsigned int maxGausFilterRadius = maxGausFilterWidth / 2;
2065  const unsigned int prevResponseBufferLineIdx = maxGausFilterRadius - 1;
2066  const unsigned int nextResponseBufferLineIdx = maxGausFilterRadius + 1;
2067  const unsigned int buffersLines = maxGausFilterWidth;
2068  const unsigned int lastBuffersLineIdx = buffersLines - 1;
2069 
2070  paramsPtr->m_rastaDataAccessMutexPtr->lock();
2071  const unsigned int rasterLines = paramsPtr->m_integralRasterDataPtr->getLinesNumber();
2072  const unsigned int buffersCols = paramsPtr->m_integralRasterDataPtr->getColumnsNumber();
2073  const unsigned int rasterBufferLineSizeBytes = sizeof( float ) *
2074  buffersCols;
2075  const unsigned int maskRasterBufferLineSizeBytes = sizeof( UCharsMatrix::ElementTypeT ) *
2076  buffersCols;
2077  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
2078 
2079  const unsigned maxGausFilterCenterBufferColBound = buffersCols -
2080  maxGausFilterRadius;
2081 
2082  unsigned int scaleIdx = 0 ;
2083  unsigned int octaveIdx = 0 ;
2084 
2085  // Allocating the internal raster data buffer
2086  // and the mask raster buffer
2087 
2088  FloatsMatrix rasterBufferDataHandler;
2089  boost::scoped_array< float* > rasterBufferHandler( new float*[ buffersLines ] );
2090  {
2091  if( ! rasterBufferDataHandler.reset( buffersLines, buffersCols,
2093  {
2094  paramsPtr->m_rastaDataAccessMutexPtr->lock();
2095  paramsPtr->m_returnValuePtr = false;
2096  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
2097  return;
2098  }
2099 
2100  for( unsigned int rasterBufferDataHandlerLine = 0 ; rasterBufferDataHandlerLine <
2101  buffersLines ; ++rasterBufferDataHandlerLine )
2102  {
2103  rasterBufferHandler[ rasterBufferDataHandlerLine ] = rasterBufferDataHandler[
2104  rasterBufferDataHandlerLine ];
2105  }
2106  }
2107  float** rasterBufferPtr = rasterBufferHandler.get();
2108 
2109  // Allocating the mask raster buffer
2110 
2111  UCharsMatrix maskRasterBufferDataHandler;
2112 
2113  boost::scoped_array< unsigned char* > maskRasterBufferHandler( new unsigned char*[ buffersLines ] );
2114 
2115  unsigned char** maskRasterBufferPtr = 0;
2116 
2117  if( paramsPtr->m_maskRasterDataPtr )
2118  {
2119  if( ! maskRasterBufferDataHandler.reset( buffersLines, buffersCols,
2121  {
2122  paramsPtr->m_rastaDataAccessMutexPtr->lock();
2123  paramsPtr->m_returnValuePtr = false;
2124  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
2125  return;
2126  }
2127 
2128  for( unsigned int maskRasterBufferDataHandlerLine = 0 ; maskRasterBufferDataHandlerLine <
2129  buffersLines ; ++maskRasterBufferDataHandlerLine )
2130  {
2131  maskRasterBufferHandler[ maskRasterBufferDataHandlerLine ] = maskRasterBufferDataHandler[
2132  maskRasterBufferDataHandlerLine ];
2133  }
2134 
2135  maskRasterBufferPtr = maskRasterBufferHandler.get();
2136  }
2137 
2138  // Allocating the internal octaves buffers
2139 
2140  FloatsMatrix octavesBufferDataHandler;
2141  std::vector< std::vector< boost::shared_array< float* > > >
2142  octavesBufferHandlers;
2143  {
2144  const unsigned int octavesBufferDataHandlerLines =
2145  buffersLines * paramsPtr->m_octavesNumber * paramsPtr->m_scalesNumber;
2146  if( ! octavesBufferDataHandler.reset( octavesBufferDataHandlerLines ,
2147  buffersCols,
2149  {
2150  paramsPtr->m_rastaDataAccessMutexPtr->lock();
2151  paramsPtr->m_returnValuePtr = false;
2152  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
2153  return;
2154  }
2155  unsigned int octavesBufferDataHandlerLine = 0;
2156  unsigned int octavesBufferDataHandlerCol = 0;
2157  float* octavesBufferDataHandlerLinePtr = 0;
2158  for( octavesBufferDataHandlerLine = 0; octavesBufferDataHandlerLine <
2159  octavesBufferDataHandlerLines ; ++octavesBufferDataHandlerLine )
2160  {
2161  octavesBufferDataHandlerLinePtr = octavesBufferDataHandler[
2162  octavesBufferDataHandlerLine ];
2163 
2164  for( octavesBufferDataHandlerCol = 0; octavesBufferDataHandlerCol <
2165  buffersCols ; ++octavesBufferDataHandlerCol )
2166  {
2167  octavesBufferDataHandlerLinePtr[ octavesBufferDataHandlerCol ] = 0.0;
2168  }
2169  }
2170 
2171  octavesBufferDataHandlerLine = 0;
2172  for( octaveIdx = 0 ; octaveIdx < paramsPtr->m_octavesNumber ; ++octaveIdx )
2173  {
2174  octavesBufferHandlers.push_back( std::vector< boost::shared_array< float* > >() );
2175  std::vector< boost::shared_array< float* > >&
2176  currOctaveBuffersHandler = octavesBufferHandlers.back();
2177 
2178  for( scaleIdx = 0 ; scaleIdx < paramsPtr->m_scalesNumber ; ++scaleIdx )
2179  {
2180  currOctaveBuffersHandler.push_back( boost::shared_array< float* >(
2181  new float*[ buffersLines ] ) );
2182  boost::shared_array< float* >& currOctavesBuffer =
2183  currOctaveBuffersHandler.back();
2184  for( unsigned int bufferLine = 0 ; bufferLine < buffersLines ;
2185  ++bufferLine )
2186  {
2187  assert( octavesBufferDataHandlerLine <
2188  octavesBufferDataHandler.getLinesNumber() );
2189 
2190  currOctavesBuffer[ bufferLine ] = octavesBufferDataHandler[
2191  octavesBufferDataHandlerLine ];
2192 
2193  ++octavesBufferDataHandlerLine;
2194  }
2195  }
2196  }
2197  }
2198 
2199  // Allocating the laplacian sign buffers
2200 
2201  UCharsMatrix laplacianSignBufferDataHandler;
2202  std::vector< std::vector< boost::shared_array< unsigned char* > > >
2203  laplacianSignBufferHandlers;
2204  {
2205  const unsigned int laplacianSignBufferDataHandlerLines =
2206  buffersLines * paramsPtr->m_octavesNumber * paramsPtr->m_scalesNumber;
2207  if( ! laplacianSignBufferDataHandler.reset( laplacianSignBufferDataHandlerLines ,
2208  buffersCols,
2210  {
2211  paramsPtr->m_rastaDataAccessMutexPtr->lock();
2212  paramsPtr->m_returnValuePtr = false;
2213  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
2214  return;
2215  }
2216  unsigned int laplacianSignBufferDataHandlerLine = 0;
2217  unsigned int laplacianSignBufferDataHandlerCol = 0;
2218  unsigned char* laplacianSignBufferDataHandlerLinePtr = 0;
2219  for( laplacianSignBufferDataHandlerLine = 0; laplacianSignBufferDataHandlerLine <
2220  laplacianSignBufferDataHandlerLines ; ++laplacianSignBufferDataHandlerLine )
2221  {
2222  laplacianSignBufferDataHandlerLinePtr = laplacianSignBufferDataHandler[
2223  laplacianSignBufferDataHandlerLine ];
2224 
2225  for( laplacianSignBufferDataHandlerCol = 0; laplacianSignBufferDataHandlerCol <
2226  buffersCols ; ++laplacianSignBufferDataHandlerCol )
2227  {
2228  laplacianSignBufferDataHandlerLinePtr[ laplacianSignBufferDataHandlerCol ] =
2229  255;
2230  }
2231  }
2232 
2233  laplacianSignBufferDataHandlerLine = 0;
2234  for( octaveIdx = 0 ; octaveIdx < paramsPtr->m_octavesNumber ; ++octaveIdx )
2235  {
2236  laplacianSignBufferHandlers.push_back( std::vector< boost::shared_array< unsigned char* > >() );
2237  std::vector< boost::shared_array< unsigned char* > >&
2238  currlaplacianSignBuffersHandler = laplacianSignBufferHandlers.back();
2239 
2240  for( scaleIdx = 0 ; scaleIdx < paramsPtr->m_scalesNumber ; ++scaleIdx )
2241  {
2242  currlaplacianSignBuffersHandler.push_back( boost::shared_array< unsigned char* >(
2243  new unsigned char*[ buffersLines ] ) );
2244  boost::shared_array< unsigned char* >& currlaplacianSignBuffer =
2245  currlaplacianSignBuffersHandler.back();
2246  for( unsigned int bufferLine = 0 ; bufferLine < buffersLines ;
2247  ++bufferLine )
2248  {
2249  assert( laplacianSignBufferDataHandlerLine <
2250  laplacianSignBufferDataHandler.getLinesNumber() );
2251 
2252  currlaplacianSignBuffer[ bufferLine ] = laplacianSignBufferDataHandler[
2253  laplacianSignBufferDataHandlerLine ];
2254 
2255  ++laplacianSignBufferDataHandlerLine;
2256  }
2257  }
2258  }
2259  }
2260 
2261  // Pick the next block to process
2262 
2263  const unsigned int rasterLinesBlocksNumber =
2264  ( rasterLines / paramsPtr->m_maxRasterLinesBlockMaxSize ) +
2265  ( ( rasterLines % paramsPtr->m_maxRasterLinesBlockMaxSize ) ? 1 : 0 );
2266 
2267  for( unsigned int rasterLinesBlockIdx = 0; rasterLinesBlockIdx <
2268  rasterLinesBlocksNumber ; ++rasterLinesBlockIdx )
2269  {
2270  // the maxima points found inside the current raster block
2271  // for each combination of octaves and scales
2272  std::vector< InterestPointsSetT > blockMaximas( paramsPtr->m_scalesNumber *
2273  paramsPtr->m_octavesNumber, InterestPointsSetT() );
2274 
2275  paramsPtr->m_rastaDataAccessMutexPtr->lock();
2276 
2277  if( rasterLinesBlockIdx == ( *(paramsPtr->m_nextRasterLinesBlockToProcessValuePtr ) ) )
2278  {
2279  ++( *(paramsPtr->m_nextRasterLinesBlockToProcessValuePtr ) );
2280 
2281  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
2282 
2283  // globals
2284 
2285  const unsigned int rasterLinesStart = (unsigned int)std::max( 0,
2286  (int)(rasterLinesBlockIdx * paramsPtr->m_maxRasterLinesBlockMaxSize ) -
2287  (int)( 2 * maxGausFilterRadius ) );
2288  const unsigned int rasterLinesEndBound = std::min( 1 +
2289  (rasterLinesBlockIdx * paramsPtr->m_maxRasterLinesBlockMaxSize ) +
2290  paramsPtr->m_maxRasterLinesBlockMaxSize +
2291  ( 2 * maxGausFilterRadius ), rasterLines );
2292  const unsigned int firstRasterLineToGenerateResponse =
2293  rasterLinesStart + maxGausFilterWidth - 1;
2294  const unsigned int firstRasterLineToLookForMaximas =
2295  firstRasterLineToGenerateResponse + maxGausFilterRadius + 1;
2296 // unsigned int baseFilterSize = 0;
2297 // unsigned int filterStepSize = 0;
2298  unsigned int filterWidth = 0;
2299  unsigned int filterLobeWidth = 0;
2300  unsigned int filterLobeRadius = 0;
2301  unsigned int filterCenterBufCol = 0 ;
2302 // unsigned int filterCenterBufColBound = 0 ;
2303  float dXX = 0;
2304  float dYY = 0;
2305  float dXY = 0;
2306  InterestPointT auxInterestPoint;
2307  float** currScaleBufferPtr = 0;
2308  unsigned char** currLaplacianSignBufferPtr = 0;
2309  unsigned int lastScaleIdx = 0;
2310  unsigned int nextScaleIdx = 0;
2311  unsigned int prevResponseBufferColIdx = 0;
2312  unsigned int nextResponseBufferColIdx = 0;
2313 
2314  float neighborMaximaDif_0_1 = 0.0;
2315  float neighborMaximaDif_0_2 = 0.0;
2316  float neighborMaximaDif_0_3 = 0.0;
2317  float neighborMaximaDif_0_4 = 0.0;
2318  float neighborMaximaDif_0_5 = 0.0;
2319  float neighborMaximaDif_0_6 = 0.0;
2320  float neighborMaximaDif_0_7 = 0.0;
2321  float neighborMaximaDif_0_8 = 0.0;
2322  float neighborMaximaDif_1_1 = 0.0;
2323  float neighborMaximaDif_1_2 = 0.0;
2324  float neighborMaximaDif_1_3 = 0.0;
2325  float neighborMaximaDif_1_4 = 0.0;
2326  float neighborMaximaDif_1_5 = 0.0;
2327  float neighborMaximaDif_1_6 = 0.0;
2328  float neighborMaximaDif_1_7 = 0.0;
2329  float neighborMaximaDif_1_8 = 0.0;
2330  float neighborMaximaDif_1_9 = 0.0;
2331  float neighborMaximaDif_2_1 = 0.0;
2332  float neighborMaximaDif_2_2 = 0.0;
2333  float neighborMaximaDif_2_3 = 0.0;
2334  float neighborMaximaDif_2_4 = 0.0;
2335  float neighborMaximaDif_2_5 = 0.0;
2336  float neighborMaximaDif_2_6 = 0.0;
2337  float neighborMaximaDif_2_7 = 0.0;
2338  float neighborMaximaDif_2_8 = 0.0;
2339  float neighborMaximaDif_2_9 = 0.0;
2340 
2341  // Processing each raster line from the current block
2342 
2343  for( unsigned int rasterLine = rasterLinesStart; rasterLine < rasterLinesEndBound ;
2344  ++rasterLine )
2345  {
2346  // read a new raster line into the last raster buffer line
2347  paramsPtr->m_rastaDataAccessMutexPtr->lock();
2348  //std::cout << std::endl << "rasterLine"; std::cout << rasterLine << std::endl;
2349  //printBuffer( rasterBufferPtr, buffersLines, buffersCols );
2350  roolUpBuffer( rasterBufferPtr, buffersLines );
2351 // printBuffer( rasterBufferPtr, buffersLines, buffersCols );
2352  memcpy( rasterBufferPtr[ lastBuffersLineIdx ],
2353  paramsPtr->m_integralRasterDataPtr->operator[]( rasterLine ),
2354  rasterBufferLineSizeBytes );
2355 // printBuffer( rasterBufferPtr, buffersLines, buffersCols );
2356  // read a new mask raster line into the last mask raster buffer line
2357  if( paramsPtr->m_maskRasterDataPtr )
2358  {
2359  roolUpBuffer( maskRasterBufferPtr, buffersLines );
2360  memcpy( maskRasterBufferPtr[ lastBuffersLineIdx ],
2361  paramsPtr->m_maskRasterDataPtr->operator[]( rasterLine ),
2362  maskRasterBufferLineSizeBytes );
2363  }
2364  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
2365 
2366  // generating the response maps for each octave/scale
2367 
2368  if( rasterLine >= firstRasterLineToGenerateResponse )
2369  {
2370  for( octaveIdx = 0 ; octaveIdx < paramsPtr->m_octavesNumber ; ++octaveIdx )
2371  {
2372  for( scaleIdx = 0 ; scaleIdx < paramsPtr->m_scalesNumber ;
2373  ++scaleIdx )
2374  {
2375  assert( octavesBufferHandlers.size() > octaveIdx );
2376  assert( octavesBufferHandlers[ octaveIdx].size() > scaleIdx );
2377  currScaleBufferPtr = octavesBufferHandlers[ octaveIdx][ scaleIdx ].get();
2378  assert( currScaleBufferPtr );
2379 
2380  assert( laplacianSignBufferHandlers.size() > octaveIdx );
2381  assert( laplacianSignBufferHandlers[ octaveIdx].size() > scaleIdx );
2382  currLaplacianSignBufferPtr = laplacianSignBufferHandlers[ octaveIdx][ scaleIdx ].get();
2383  assert( currLaplacianSignBufferPtr );
2384 
2385  // Roll up buffers
2386 
2387  roolUpBuffer( currScaleBufferPtr, buffersLines );
2388  roolUpBuffer( currLaplacianSignBufferPtr, buffersLines );
2389 
2390  // applying the filter kernels for the current scale
2391 
2392  filterWidth = getSurfFilterSize( octaveIdx, scaleIdx );
2393  assert( filterWidth <= maxGausFilterWidth );
2394 
2395  filterLobeWidth = filterWidth / 3;
2396  filterLobeRadius = filterLobeWidth / 2;
2397 
2398  for( filterCenterBufCol = maxGausFilterRadius ;
2399  filterCenterBufCol < maxGausFilterCenterBufferColBound ;
2400  ++filterCenterBufCol )
2401  {
2402  dYY = getSurfDyyDerivative( rasterBufferPtr, filterCenterBufCol,
2403  maxGausFilterRadius, filterLobeWidth, filterLobeRadius);
2404  dYY /= (float)( filterWidth * filterWidth );
2405 
2406  dXX = getSurfDxxDerivative( rasterBufferPtr, filterCenterBufCol,
2407  maxGausFilterRadius, filterLobeWidth, filterLobeRadius);
2408  dXX /= (float)( filterWidth * filterWidth );
2409 
2410  dXY = getSurfDxyDerivative( rasterBufferPtr, filterCenterBufCol,
2411  maxGausFilterRadius, filterLobeWidth );
2412  dXY /= (float)( filterWidth * filterWidth );
2413 
2414  currScaleBufferPtr[ lastBuffersLineIdx ][ filterCenterBufCol ] =
2415  ( dXX * dYY ) - ( 0.81f * dXY * dXY );
2416  currLaplacianSignBufferPtr[ lastBuffersLineIdx ][ filterCenterBufCol ] =
2417  ( ( dXX + dYY ) >= 0.0 ) ? 1 : 0;
2418  }
2419  }
2420  }
2421  }
2422 
2423  // Finding local maximas over all scales using 3 x 3 x 3 window
2424  // at the lowest scale
2425 
2426  if( rasterLine >= firstRasterLineToLookForMaximas )
2427  {
2428 // printBuffer( octavesBufferHandlers[ 0 ][ 0 ].get(), buffersLines, buffersCols );
2429 // printBuffer( octavesBufferHandlers[ 0 ][ 1 ].get(), buffersLines, buffersCols );
2430 // printBuffer( octavesBufferHandlers[ 0 ][ 2 ].get(), buffersLines, buffersCols );
2431 // return;
2432 
2433  for( unsigned int windCenterCol = maxGausFilterRadius ;
2434  windCenterCol < maxGausFilterCenterBufferColBound ; ++windCenterCol )
2435  {
2436  prevResponseBufferColIdx = windCenterCol - 1;
2437  nextResponseBufferColIdx = windCenterCol + 1;
2438  auxInterestPoint.m_feature1 = (-1.0) * FLT_MAX;
2439 
2440  for( octaveIdx = 0 ; octaveIdx < paramsPtr->m_octavesNumber ; ++octaveIdx )
2441  {
2442  std::vector< boost::shared_array< float* > >&
2443  currOctaveBuffersHandler = octavesBufferHandlers[ octaveIdx ];
2444 
2445  for( scaleIdx = 1 ; scaleIdx < ( paramsPtr->m_scalesNumber - 1 );
2446  ++scaleIdx )
2447  {
2448  const float& windowCenterPixelValue = currOctaveBuffersHandler[
2449  scaleIdx ][ maxGausFilterRadius ][ windCenterCol ];
2450  lastScaleIdx = scaleIdx - 1;
2451  nextScaleIdx = scaleIdx + 1;
2452 
2453  neighborMaximaDif_0_1 = windowCenterPixelValue - currOctaveBuffersHandler[
2454  scaleIdx ][ prevResponseBufferLineIdx ][ prevResponseBufferColIdx ];
2455  neighborMaximaDif_0_2 = windowCenterPixelValue - currOctaveBuffersHandler[
2456  scaleIdx ][ prevResponseBufferLineIdx ][ windCenterCol ];
2457  neighborMaximaDif_0_3 = windowCenterPixelValue - currOctaveBuffersHandler[
2458  scaleIdx ][ prevResponseBufferLineIdx ][ nextResponseBufferColIdx ];
2459  neighborMaximaDif_0_4 = windowCenterPixelValue - currOctaveBuffersHandler[
2460  scaleIdx ][ maxGausFilterRadius ][ prevResponseBufferColIdx ];
2461  neighborMaximaDif_0_5 = windowCenterPixelValue - currOctaveBuffersHandler[
2462  scaleIdx ][ maxGausFilterRadius ][ nextResponseBufferColIdx ];
2463  neighborMaximaDif_0_6 = windowCenterPixelValue - currOctaveBuffersHandler[
2464  scaleIdx ][ nextResponseBufferLineIdx ][ prevResponseBufferColIdx];
2465  neighborMaximaDif_0_7 = windowCenterPixelValue - currOctaveBuffersHandler[
2466  scaleIdx ][ nextResponseBufferLineIdx ][ windCenterCol ];
2467  neighborMaximaDif_0_8 = windowCenterPixelValue - currOctaveBuffersHandler[
2468  scaleIdx ][ nextResponseBufferLineIdx ][ nextResponseBufferColIdx ];
2469 
2470  if(
2471  ( windowCenterPixelValue > 0.0 )
2472  // verifying the current scale (center not included)
2473  && ( neighborMaximaDif_0_1 > 0.0 )
2474  && ( neighborMaximaDif_0_2 > 0.0 )
2475  && ( neighborMaximaDif_0_3 > 0.0 )
2476  && ( neighborMaximaDif_0_4 > 0.0 )
2477  && ( neighborMaximaDif_0_5 > 0.0 )
2478  && ( neighborMaximaDif_0_6 > 0.0 )
2479  && ( neighborMaximaDif_0_7 > 0.0 )
2480  && ( neighborMaximaDif_0_8 > 0.0 )
2481  )
2482  {
2483  neighborMaximaDif_1_1 = windowCenterPixelValue - currOctaveBuffersHandler[
2484  lastScaleIdx ][ prevResponseBufferLineIdx ][ prevResponseBufferColIdx ];
2485  neighborMaximaDif_1_2 = windowCenterPixelValue - currOctaveBuffersHandler[
2486  lastScaleIdx ][ prevResponseBufferLineIdx ][ windCenterCol ];
2487  neighborMaximaDif_1_3 = windowCenterPixelValue - currOctaveBuffersHandler[
2488  lastScaleIdx ][ prevResponseBufferLineIdx ][ nextResponseBufferColIdx ];
2489  neighborMaximaDif_1_4 = windowCenterPixelValue - currOctaveBuffersHandler[
2490  lastScaleIdx ][ maxGausFilterRadius ][ prevResponseBufferColIdx ];
2491  neighborMaximaDif_1_5 = windowCenterPixelValue - currOctaveBuffersHandler[
2492  lastScaleIdx ][ maxGausFilterRadius ][ windCenterCol ];
2493  neighborMaximaDif_1_6 = windowCenterPixelValue - currOctaveBuffersHandler[
2494  lastScaleIdx ][ maxGausFilterRadius ][ nextResponseBufferColIdx ];
2495  neighborMaximaDif_1_7 = windowCenterPixelValue - currOctaveBuffersHandler[
2496  lastScaleIdx ][ nextResponseBufferLineIdx ][ prevResponseBufferColIdx];
2497  neighborMaximaDif_1_8 = windowCenterPixelValue - currOctaveBuffersHandler[
2498  lastScaleIdx ][ nextResponseBufferLineIdx ][ windCenterCol ];
2499  neighborMaximaDif_1_9 = windowCenterPixelValue - currOctaveBuffersHandler[
2500  lastScaleIdx ][ nextResponseBufferLineIdx ][ nextResponseBufferColIdx ];
2501 
2502  if(
2503  // verifying the top scale
2504  ( neighborMaximaDif_1_1 > 0.0 )
2505  && ( neighborMaximaDif_1_2 > 0.0 )
2506  && ( neighborMaximaDif_1_3 > 0.0 )
2507  && ( neighborMaximaDif_1_4 > 0.0 )
2508  && ( neighborMaximaDif_1_5 > 0.0 )
2509  && ( neighborMaximaDif_1_6 > 0.0 )
2510  && ( neighborMaximaDif_1_7 > 0.0 )
2511  && ( neighborMaximaDif_1_8 > 0.0 )
2512  && ( neighborMaximaDif_1_9 > 0.0 )
2513  )
2514  {
2515  neighborMaximaDif_2_1 = windowCenterPixelValue - currOctaveBuffersHandler[
2516  nextScaleIdx ][ prevResponseBufferLineIdx ][ prevResponseBufferColIdx ];
2517  neighborMaximaDif_2_2 = windowCenterPixelValue - currOctaveBuffersHandler[
2518  nextScaleIdx ][ prevResponseBufferLineIdx ][ windCenterCol ];
2519  neighborMaximaDif_2_3 = windowCenterPixelValue - currOctaveBuffersHandler[
2520  nextScaleIdx ][ prevResponseBufferLineIdx ][ nextResponseBufferColIdx ];
2521  neighborMaximaDif_2_4 = windowCenterPixelValue - currOctaveBuffersHandler[
2522  nextScaleIdx ][ maxGausFilterRadius ][ prevResponseBufferColIdx ];
2523  neighborMaximaDif_2_5 = windowCenterPixelValue - currOctaveBuffersHandler[
2524  nextScaleIdx ][ maxGausFilterRadius ][ windCenterCol ];
2525  neighborMaximaDif_2_6 = windowCenterPixelValue - currOctaveBuffersHandler[
2526  nextScaleIdx ][ maxGausFilterRadius ][ nextResponseBufferColIdx ];
2527  neighborMaximaDif_2_7 = windowCenterPixelValue - currOctaveBuffersHandler[
2528  nextScaleIdx ][ nextResponseBufferLineIdx ][ prevResponseBufferColIdx];
2529  neighborMaximaDif_2_8 = windowCenterPixelValue - currOctaveBuffersHandler[
2530  nextScaleIdx ][ nextResponseBufferLineIdx ][ windCenterCol ];
2531  neighborMaximaDif_2_9 = windowCenterPixelValue - currOctaveBuffersHandler[
2532  nextScaleIdx ][ nextResponseBufferLineIdx ][ nextResponseBufferColIdx ];
2533 
2534  if(
2535  // verifying the next scale
2536  ( neighborMaximaDif_2_1 > 0.0 )
2537  && ( neighborMaximaDif_2_2 > 0.0 )
2538  && ( neighborMaximaDif_2_3 > 0.0 )
2539  && ( neighborMaximaDif_2_4 > 0.0 )
2540  && ( neighborMaximaDif_2_5 > 0.0 )
2541  && ( neighborMaximaDif_2_6 > 0.0 )
2542  && ( neighborMaximaDif_2_7 > 0.0 )
2543  && ( neighborMaximaDif_2_8 > 0.0 )
2544  && ( neighborMaximaDif_2_9 > 0.0 )
2545  && (
2546  maskRasterBufferPtr
2547  ?
2548  ( maskRasterBufferPtr[ 0 ][ windCenterCol ] != 0 )
2549  :
2550  true
2551  )
2552  )
2553  {
2554  auxInterestPoint.m_feature1 =
2555  neighborMaximaDif_0_1
2556  + neighborMaximaDif_0_2
2557  + neighborMaximaDif_0_3
2558  + neighborMaximaDif_0_4
2559  + neighborMaximaDif_0_5
2560  + neighborMaximaDif_0_6
2561  + neighborMaximaDif_0_7
2562  + neighborMaximaDif_0_8
2563  + neighborMaximaDif_1_1
2564  + neighborMaximaDif_1_2
2565  + neighborMaximaDif_1_3
2566  + neighborMaximaDif_1_4
2567  + neighborMaximaDif_1_5
2568  + neighborMaximaDif_1_6
2569  + neighborMaximaDif_1_7
2570  + neighborMaximaDif_1_8
2571  + neighborMaximaDif_1_9
2572  + neighborMaximaDif_2_1
2573  + neighborMaximaDif_2_2
2574  + neighborMaximaDif_2_3
2575  + neighborMaximaDif_2_4
2576  + neighborMaximaDif_2_5
2577  + neighborMaximaDif_2_6
2578  + neighborMaximaDif_2_7
2579  + neighborMaximaDif_2_8
2580  + neighborMaximaDif_2_9;
2581  auxInterestPoint.m_feature2 = (float)getSurfFilterSize(
2582  octaveIdx, scaleIdx );
2583  auxInterestPoint.m_feature3 = (float)
2584  laplacianSignBufferHandlers[ octaveIdx ][ scaleIdx ][
2585  maxGausFilterRadius ][ windCenterCol ] ;
2586 
2587  auxInterestPoint.m_x = windCenterCol;
2588  auxInterestPoint.m_y = rasterLine - ( 2 * maxGausFilterRadius) ;
2589  assert( auxInterestPoint.m_x <
2590  paramsPtr->m_integralRasterDataPtr->getColumnsNumber() );
2591  assert( auxInterestPoint.m_y <
2592  paramsPtr->m_integralRasterDataPtr->getLinesNumber() );
2593 
2594  assert( ( ( octaveIdx * paramsPtr->m_scalesNumber ) +
2595  scaleIdx ) < blockMaximas.size() );
2596  InterestPointsSetT& currScalePointsSet = blockMaximas[
2597  ( octaveIdx * paramsPtr->m_scalesNumber ) + scaleIdx ];
2598 
2599  currScalePointsSet.insert( auxInterestPoint);
2600 
2601  if( currScalePointsSet.size() >
2603  {
2604  currScalePointsSet.erase( currScalePointsSet.begin() );
2605  }
2606  }
2607  }
2608  }
2609  }
2610  }
2611  }
2612  }
2613  }
2614  }
2615  else
2616  {
2617  paramsPtr->m_rastaDataAccessMutexPtr->unlock();
2618  }
2619 
2620  // Copying the best found block maximas to the external maximas container
2621 
2622  paramsPtr->m_interestPointsAccessMutexPtr->lock();
2623 
2624  for( unsigned int blockMaximasIdx = 0 ; blockMaximasIdx <
2625  blockMaximas.size() ; ++blockMaximasIdx )
2626  {
2627  paramsPtr->m_interestPointsPtr->insert(
2628  blockMaximas[ blockMaximasIdx ].begin(),
2629  blockMaximas[ blockMaximasIdx ].end() );
2630  }
2631 
2632  paramsPtr->m_interestPointsAccessMutexPtr->unlock();
2633  }
2634  }
2635 
2637  const DoublesMatrix& rasterData,
2638  const InterestPointsSetT& interestPoints,
2639  const std::string& tifFileName )
2640  {
2641  std::map<std::string, std::string> rInfo;
2642  rInfo["URI"] = tifFileName + ".tif";
2643 
2644  std::vector<te::rst::BandProperty*> bandsProperties;
2645  bandsProperties.push_back(new te::rst::BandProperty( 0, te::dt::UCHAR_TYPE, "" ));
2646  bandsProperties[0]->m_colorInterp = te::rst::RedCInt;
2647  bandsProperties[0]->m_noDataValue = 0;
2648  bandsProperties.push_back(new te::rst::BandProperty( *bandsProperties[0] ));
2649  bandsProperties[1]->m_colorInterp = te::rst::GreenCInt;
2650  bandsProperties.push_back(new te::rst::BandProperty( *bandsProperties[0] ));
2651  bandsProperties[2]->m_colorInterp = te::rst::BlueCInt;
2652 
2653  te::rst::Grid* newgrid = new te::rst::Grid( rasterData.getColumnsNumber(),
2654  rasterData.getLinesNumber(), 0, -1 );
2655 
2656  std::auto_ptr< te::rst::Raster > outputRasterPtr(
2657  te::rst::RasterFactory::make( "GDAL", newgrid, bandsProperties, rInfo, 0, 0));
2658  TERP_TRUE_OR_THROW( outputRasterPtr.get(), "Output raster creation error");
2659 
2660  unsigned int line = 0;
2661  unsigned int col = 0;
2662  const unsigned int nLines = rasterData.getLinesNumber();
2663  const unsigned int nCols = rasterData.getColumnsNumber();
2664  double rasterDataMin = DBL_MAX;
2665  double rasterDataMax = (-1.0) * DBL_MAX;
2666  double value = 0;
2667 
2668  for( line = 0 ; line < nLines ; ++line )
2669  for( col = 0 ; col < nCols ; ++col )
2670  {
2671  value = rasterData[ line ][ col ];
2672 
2673  if( rasterDataMin > value )
2674  rasterDataMin = value;
2675  if( rasterDataMax < value )
2676  rasterDataMax = value;
2677  }
2678 
2679  if( rasterDataMax == rasterDataMin )
2680  {
2681  rasterDataMin = 0.0;
2682  rasterDataMax = 1.0;
2683  }
2684 
2685  for( line = 0 ; line < nLines ; ++line )
2686  for( col = 0 ; col < nCols ; ++col )
2687  {
2688  value = rasterData[ line ][ col ];
2689  value = ( value - rasterDataMin ) / ( rasterDataMax - rasterDataMin );
2690  value *= 255.0;
2691  value = std::max( 0.0, value );
2692  value = std::min( 255.0, value );
2693 
2694  outputRasterPtr->setValue( col, line, value, 0 );
2695  outputRasterPtr->setValue( col, line, value, 1 );
2696  outputRasterPtr->setValue( col, line, value, 2 );
2697  }
2698 
2699  InterestPointsSetT::const_iterator itB = interestPoints.begin();
2700  InterestPointsSetT::const_iterator itE = interestPoints.end();
2701 
2702  while( itB != itE )
2703  {
2704  outputRasterPtr->setValue( itB->m_x, itB->m_y, 0, 0 );
2705  outputRasterPtr->setValue( itB->m_x, itB->m_y, 255, 1 );
2706  outputRasterPtr->setValue( itB->m_x, itB->m_y, 0, 2 );
2707 
2708  ++itB;
2709  }
2710  }
2711 
2713  DoublesMatrix& outputData, const unsigned int iterationsNumber )
2714  {
2715  if( iterationsNumber == 0 ) return false;
2716 
2717  TERP_TRUE_OR_RETURN_FALSE( outputData.reset( inputData.getLinesNumber(),
2718  inputData.getColumnsNumber() ), "Cannot allocate image matrix" );
2719 
2720  const unsigned int nLines = inputData.getLinesNumber();
2721  const unsigned int nCols = inputData.getColumnsNumber();
2722  const unsigned int lastLineIndex = nLines - 1;
2723  const unsigned int lastColIndex = nCols - 1;
2724  unsigned int currLine = 0;
2725  unsigned int currCol = 0;
2726 
2727  // internal temp matrixes
2728 
2729  DoublesMatrix tempMatrix;
2730 
2731  if( iterationsNumber > 1 )
2732  {
2733  TERP_TRUE_OR_RETURN_FALSE( tempMatrix.reset( nLines, nCols,
2735  "Cannot allocate image matrix" );
2736  }
2737 
2738  /* Fill borders with zero */
2739 
2740  for( currLine = 0 ; currLine < nLines ; ++currLine ) {
2741  outputData( currLine, 0 ) = 0.0;
2742  outputData( currLine, lastColIndex ) = 0.0;
2743  }
2744 
2745  for( currCol = 0 ; currCol < nCols ; ++currCol ) {
2746  outputData( 0, currCol ) = 0.0;
2747  outputData( lastLineIndex, currCol ) = 0.0;
2748  }
2749 
2750  /* Smoothing */
2751 
2752  DoublesMatrix const* inputPtr = 0;
2753  DoublesMatrix* outputPtr = 0;
2754  DoublesMatrix const* auxPtr = 0;
2755 
2756  for( unsigned int iteration = 0 ; iteration < iterationsNumber ;
2757  ++iteration )
2758  {
2759  if( iteration == 0 )
2760  {
2761  inputPtr = &inputData;
2762 
2763  if( iterationsNumber > 1 )
2764  outputPtr = &tempMatrix;
2765  else
2766  outputPtr = &outputData;
2767  }
2768  else if( iteration == iterationsNumber - 1 )
2769  {
2770  inputPtr = outputPtr;
2771  outputPtr = &outputData;
2772  }
2773  else
2774  {
2775  auxPtr = inputPtr;
2776  inputPtr = outputPtr;
2777  outputPtr = (DoublesMatrix*)auxPtr;
2778  }
2779 
2780  for( currLine = 1 ; currLine < lastLineIndex ; ++currLine )
2781  {
2782  for( currCol = 1 ; currCol < lastColIndex ; ++currCol )
2783  {
2784  outputPtr->operator()( currLine, currCol ) =
2785  (
2786  inputPtr->operator()( currLine - 1, currCol ) +
2787  ( 4.0 * inputData( currLine, currCol ) ) +
2788  inputPtr->operator()( currLine + 1, currCol ) +
2789  inputPtr->operator()( currLine, currCol - 1 ) +
2790  inputPtr->operator()( currLine, currCol + 1 )
2791  ) / 8.0;
2792  }
2793  }
2794  }
2795 
2796  return true;
2797  }
2798 
2800  FloatsMatrix& outputData, const unsigned int iterationsNumber )
2801  {
2802  if( iterationsNumber == 0 )
2803  {
2804  outputData = inputData;
2805  }
2806  else
2807  {
2808 
2809  TERP_TRUE_OR_RETURN_FALSE( outputData.reset( inputData.getLinesNumber(),
2810  inputData.getColumnsNumber() ), "Cannot allocate image matrix" );
2811 
2812  const unsigned int nLines = inputData.getLinesNumber();
2813  const unsigned int nCols = inputData.getColumnsNumber();
2814  const unsigned int lastLineIndex = nLines - 1;
2815  const unsigned int lastColIndex = nCols - 1;
2816  unsigned int currLine = 0;
2817  unsigned int currCol = 0;
2818 
2819  // internal temp matrixes
2820 
2821  FloatsMatrix tempMatrix;
2822 
2823  if( iterationsNumber > 1 )
2824  {
2825  TERP_TRUE_OR_RETURN_FALSE( tempMatrix.reset( nLines, nCols,
2827  "Cannot allocate image matrix" );
2828  }
2829 
2830  /* Fill borders with zero */
2831 
2832  for( currLine = 0 ; currLine < nLines ; ++currLine ) {
2833  outputData( currLine, 0 ) = 0.0;
2834  outputData( currLine, lastColIndex ) = 0.0;
2835  }
2836 
2837  for( currCol = 0 ; currCol < nCols ; ++currCol ) {
2838  outputData( 0, currCol ) = 0.0;
2839  outputData( lastLineIndex, currCol ) = 0.0;
2840  }
2841 
2842  /* Smoothing */
2843 
2844  FloatsMatrix const* inputPtr = 0;
2845  FloatsMatrix* outputPtr = 0;
2846  FloatsMatrix const* auxPtr = 0;
2847  float* outputLinePtr = 0;
2848  unsigned int prevLine = 0;
2849  unsigned int prevCol = 0;
2850  unsigned int nextLine = 0;
2851  unsigned int nextCol = 0;
2852 
2853  for( unsigned int iteration = 0 ; iteration < iterationsNumber ;
2854  ++iteration )
2855  {
2856  if( iteration == 0 )
2857  {
2858  inputPtr = &inputData;
2859 
2860  if( iterationsNumber > 1 )
2861  outputPtr = &tempMatrix;
2862  else
2863  outputPtr = &outputData;
2864  }
2865  else if( iteration == iterationsNumber - 1 )
2866  {
2867  inputPtr = outputPtr;
2868  outputPtr = &outputData;
2869  }
2870  else
2871  {
2872  auxPtr = inputPtr;
2873  inputPtr = outputPtr;
2874  outputPtr = (FloatsMatrix*)auxPtr;
2875  }
2876 
2877  const FloatsMatrix& internalInputMatrix = *inputPtr;
2878 
2879  for( currLine = 1 ; currLine < lastLineIndex ; ++currLine )
2880  {
2881  prevLine = currLine - 1;
2882  nextLine = currLine + 1;
2883 
2884  outputLinePtr = outputPtr->operator[]( currLine );
2885 
2886  for( currCol = 1 ; currCol < lastColIndex ; ++currCol )
2887  {
2888  prevCol = currCol - 1;
2889  nextCol = currCol + 1;
2890 
2891  outputLinePtr[ currCol ] =
2892  (
2893  internalInputMatrix( prevLine, prevCol )
2894  + internalInputMatrix( prevLine, currCol )
2895  + internalInputMatrix( prevLine, nextCol )
2896  + internalInputMatrix( currLine, prevCol )
2897  + internalInputMatrix( currLine, nextCol )
2898  + internalInputMatrix( nextLine, prevCol )
2899  + internalInputMatrix( nextLine, currCol )
2900  + internalInputMatrix( nextLine, nextCol )
2901  ) / 8.0f;
2902  }
2903  }
2904  }
2905  }
2906 
2907  return true;
2908  }
2909 
2911  FloatsMatrix& outputData )
2912  {
2913  TERP_TRUE_OR_RETURN_FALSE( outputData.reset( inputData.getLinesNumber(),
2914  inputData.getColumnsNumber() ), "Cannot allocate image matrix" );
2915 
2916  const unsigned int nLines = inputData.getLinesNumber();
2917  const unsigned int nCols = inputData.getColumnsNumber();
2918 
2919  unsigned int outCol = 0;
2920  float currSum = 0;
2921 
2922  for( unsigned int outLine = 0 ; outLine < nLines ; ++outLine )
2923  for( outCol = 0; outCol < nCols ; ++outCol )
2924  {
2925  currSum = inputData[ outLine ][ outCol ];
2926 
2927  if( outLine )
2928  currSum += outputData[ outLine - 1 ][ outCol ];
2929  if( outCol )
2930  currSum += outputData[ outLine ][ outCol - 1 ];
2931  if( outLine && outCol )
2932  currSum -= outputData[ outLine - 1 ][ outCol - 1 ];
2933 
2934  outputData[ outLine ][ outCol ] = currSum;
2935  }
2936 
2937  return true;
2938  }
2939 
2941  const InterestPointsSetT& interestPoints,
2942  const unsigned int correlationWindowWidth,
2943  const FloatsMatrix& rasterData,
2944  FloatsMatrix& features,
2945  InterestPointsSetT& validInteresPoints )
2946  {
2947  validInteresPoints.clear();
2948 
2949  /* The radius of a feature window rotated by 90 degrees.
2950  * over the input image */
2951 
2952  const unsigned int rotated90CorralationWindowRadius = (unsigned int)
2953  (
2954  std::ceil(
2955  sqrt(
2956  2
2957  *
2958  (
2959  ( (double)correlationWindowWidth )
2960  *
2961  ( (double)correlationWindowWidth )
2962  )
2963  ) / 2.0
2964  )
2965  );
2966 
2967  // Locating the the valid interest points
2968 
2969  {
2970  /* The radius of a feature window rotated by 90 degrees.
2971  * over the input image */
2972 
2973  const unsigned int rasterDataCols = rasterData.getColumnsNumber();
2974  const unsigned int rasterDataLines = rasterData.getLinesNumber();
2975  const unsigned int firstValidInterestPointX =
2976  rotated90CorralationWindowRadius + 1;
2977  const unsigned int lastValidInterestPointX = rasterDataCols
2978  - rotated90CorralationWindowRadius - 2;
2979  const unsigned int firstValidInterestPointY =
2980  rotated90CorralationWindowRadius + 1;
2981  const unsigned int lastValidInterestPointY = rasterDataLines
2982  - rotated90CorralationWindowRadius - 2;
2983 
2984  {
2985  InterestPointsSetT::const_iterator iPointsIt = interestPoints.begin();
2986  const InterestPointsSetT::const_iterator iPointsItEnd = interestPoints.end();
2987 
2988  while( iPointsIt != iPointsItEnd )
2989  {
2990  if( ( iPointsIt->m_x >= firstValidInterestPointX ) &&
2991  ( iPointsIt->m_x <= lastValidInterestPointX ) &&
2992  ( iPointsIt->m_y >= firstValidInterestPointY ) &&
2993  ( iPointsIt->m_y <= lastValidInterestPointY ) )
2994  {
2995  validInteresPoints.insert( *iPointsIt );
2996  }
2997 
2998  ++iPointsIt;
2999  }
3000  }
3001  }
3002 
3003  // Allocating the features matrix
3004 
3005  const unsigned int featureElemsNmb = correlationWindowWidth *
3006  correlationWindowWidth;
3007  const unsigned int featureSizeBytes = sizeof( float ) *
3008  featureElemsNmb;
3009 
3010  TERP_TRUE_OR_RETURN_FALSE( features.reset(
3011  validInteresPoints.size(), featureElemsNmb ),
3012  "Cannot allocate features matrix" );
3013 
3014  // Allocating the auxiliary features buffer
3015 
3016  boost::scoped_array< float > auxFeatureBufferHandler(
3017  new float[ featureElemsNmb ] );
3018  float* auxFeatureBufferPtr = auxFeatureBufferHandler.get();
3019 
3020  // Creating features
3021 
3022  unsigned int curr_window_x_start = 0; //related to the current window over the hole image
3023  unsigned int curr_window_y_start = 0; //related to the current window over the hole image
3024  unsigned int curr_window_x_center = 0; //related to the current window over the hole image
3025  unsigned int curr_window_y_center = 0; //related to the current window over the hole image
3026  unsigned int curr_window_x_end = 0; // this coord is also counted in
3027  unsigned int curr_window_y_end = 0; // this coord is also counted in
3028  const unsigned int wind_radius = correlationWindowWidth / 2; //output window radius
3029  const float wind_radius_double = (float)wind_radius;
3030  unsigned int curr_x = 0;
3031  unsigned int curr_y = 0;
3032  float curr_x_minus_radius = 0;
3033  float curr_y_minus_radius = 0;
3034  unsigned int curr_offset = 0;
3035  float int_x_dir = 0;
3036  float int_y_dir = 0;
3037  float int_norm = 0;
3038  float rotated_curr_x = 0;/* rotaded coord - window ref */
3039  float rotated_curr_y = 0;/* rotaded coord - window ref */
3040  float rot_cos = 0;
3041  float rot_sin = 0;
3042  unsigned int rotated_curr_x_img = 0; //coords rotated but in the hole image reference
3043  unsigned int rotated_curr_y_img = 0; //coords rotated but in the hole image reference
3044  float featureElementsNormalizeFactor = 0.0;
3045  unsigned int featureElementIdx = 0;
3046  float* featurePtr = 0;
3047  float featureElementValue = 0.0;
3048  float featureElementMaxValue = 0.0;
3049  float featureElementMinValue = 0.0;
3050 
3051  InterestPointsSetT::const_iterator viPointsIt = validInteresPoints.begin();
3052  const InterestPointsSetT::const_iterator viPointsItEnd = validInteresPoints.end();
3053  unsigned int validInteresPointsIndex = 0 ;
3054 
3055  while( viPointsIt != viPointsItEnd )
3056  {
3057  /* Calculating the current window position */
3058 
3059  curr_window_x_center = viPointsIt->m_x;
3060  assert( curr_window_x_center >= rotated90CorralationWindowRadius );
3061  assert( curr_window_x_center < ( rasterData.getColumnsNumber() - 1 -
3062  rotated90CorralationWindowRadius ) );
3063  curr_window_y_center = viPointsIt->m_y;
3064  assert( curr_window_y_center >= rotated90CorralationWindowRadius );
3065  assert( curr_window_y_center < ( rasterData.getLinesNumber() - 1 -
3066  rotated90CorralationWindowRadius ) );
3067 
3068  curr_window_x_start = curr_window_x_center - wind_radius;
3069  curr_window_y_start = curr_window_y_center - wind_radius;
3070  curr_window_x_end = curr_window_x_start + correlationWindowWidth - 1;
3071  curr_window_y_end = curr_window_y_start + correlationWindowWidth - 1;
3072 
3073  /* Estimating the intensity vector X direction */
3074 
3075  int_x_dir = 0;
3076 
3077  for( curr_y = curr_window_y_start ; curr_y <= curr_window_y_end ;
3078  ++curr_y )
3079  {
3080  for( curr_offset = 0 ; curr_offset < wind_radius ;
3081  ++curr_offset )
3082  {
3083  int_x_dir += rasterData( curr_y, curr_window_x_end - curr_offset ) -
3084  rasterData( curr_y, curr_window_x_start + curr_offset );
3085  }
3086  }
3087 
3088  /* Estimating the intensity vector y direction */
3089 
3090  int_y_dir = 0;
3091 
3092  for( curr_x = curr_window_x_start ; curr_x <= curr_window_x_end ;
3093  ++curr_x )
3094  {
3095  for( curr_offset = 0 ; curr_offset < wind_radius ; ++curr_offset )
3096  {
3097  int_y_dir += rasterData( curr_window_y_start + curr_offset, curr_x ) -
3098  rasterData( curr_window_y_end - curr_offset, curr_x );
3099  }
3100  }
3101 
3102  /* Calculating the rotation parameters -
3103  */
3104  int_norm = std::sqrt( ( int_x_dir * int_x_dir ) +
3105  ( int_y_dir * int_y_dir ) );
3106 
3107  if( int_norm != 0.0 ) {
3108  rot_cos = int_x_dir / int_norm;
3109  rot_sin = int_y_dir / int_norm;
3110  } else {
3111  /* No rotation */
3112  rot_cos = 1.0;
3113  rot_sin = 0.0;
3114  }
3115 
3116  assert( ( rot_cos >= -1.0 ) && ( rot_cos <= 1.0 ) );
3117  assert( ( rot_sin >= -1.0 ) && ( rot_sin <= 1.0 ) );
3118 
3119  /* Generating the rotated window data and inserting it into
3120  the img_features_matrix by setting the intensity vector
3121  to the direction (1,0)
3122 
3123  counterclockwise rotation
3124  | u | |cos -sin| |X|
3125  | v | == |sin cos| x |Y|
3126 
3127  clockwise rotation
3128  | u | |cos sin| |X|
3129  | v | == |-sin cos| x |Y|
3130  */
3131 
3132  memset( auxFeatureBufferPtr, 0, featureSizeBytes );
3133  featureElementIdx = 0;
3134  featureElementMaxValue = -1.0 * FLT_MAX;
3135  featureElementMinValue = FLT_MAX;
3136 
3137  for( curr_y = 0 ; curr_y < correlationWindowWidth ; ++curr_y )
3138  {
3139  for( curr_x = 0 ; curr_x < correlationWindowWidth ; ++curr_x )
3140  {
3141  /* briging the window to the coord system center */
3142 
3143  curr_x_minus_radius = ((float)curr_x) -
3144  wind_radius_double;
3145  curr_y_minus_radius = ((float)curr_y) -
3146  wind_radius_double;
3147 
3148  /* rotating the centered window */
3149 
3150  rotated_curr_x =
3151  ( rot_cos * curr_x_minus_radius ) +
3152  ( rot_sin * curr_y_minus_radius );
3153 
3154  rotated_curr_y =
3155  ( rot_cos * curr_y_minus_radius )
3156  - ( rot_sin * curr_x_minus_radius );
3157 
3158  /* bringing the window back to its original
3159  location with the correct new scale */
3160 
3161  rotated_curr_x += wind_radius_double;
3162  rotated_curr_y += wind_radius_double;
3163 
3164  /* copy the new rotated window to the output vector */
3165 
3166  rotated_curr_x_img = curr_window_x_start +
3167  (unsigned int)ROUND( rotated_curr_x );
3168  rotated_curr_y_img = curr_window_y_start +
3169  (unsigned int)ROUND( rotated_curr_y );
3170 
3171  featureElementValue = rasterData( rotated_curr_y_img,
3172  rotated_curr_x_img );
3173 
3174  auxFeatureBufferPtr[ featureElementIdx++ ] = featureElementValue;
3175 
3176  if( featureElementMaxValue < featureElementValue )
3177  featureElementMaxValue = featureElementValue;
3178 
3179  if( featureElementMinValue > featureElementValue )
3180  featureElementMinValue = featureElementValue;
3181 
3182  }
3183  }
3184 
3185  // feature normaliztion
3186 
3187  if( featureElementMaxValue == featureElementMinValue )
3188  featureElementsNormalizeFactor = 0.0;
3189  else
3190  featureElementsNormalizeFactor = 1.0f / ( featureElementMaxValue -
3191  featureElementMinValue );
3192 
3193  featurePtr = features[ validInteresPointsIndex ];
3194 
3195  for( featureElementIdx = 0 ; featureElementIdx < featureElemsNmb ;
3196  ++featureElementIdx )
3197  {
3198  featurePtr[ featureElementIdx ] = (
3199  ( auxFeatureBufferPtr[ featureElementIdx ] - featureElementMinValue )
3200  * featureElementsNormalizeFactor );
3201  assert( featurePtr[ featureElementIdx ] >= 0.0 );
3202  assert( featurePtr[ featureElementIdx ] <= 1.0 );
3203  }
3204 
3205  ++validInteresPointsIndex;
3206  ++viPointsIt;
3207  }
3208 
3209  return true;
3210  }
3211 
3213  const InterestPointsSetT& interestPoints,
3214  const FloatsMatrix& integralRasterData,
3215  InterestPointsSetT& validInterestPoints,
3216  FloatsMatrix& features )
3217  {
3218  // Discovering the valid interest points
3219 
3220  validInterestPoints.clear();
3221 
3222  {
3223  InterestPointsSetT::const_iterator iPointsIt = interestPoints.begin();
3224  const InterestPointsSetT::const_iterator iPointsItEnd = interestPoints.end();
3225 
3226  while( iPointsIt != iPointsItEnd )
3227  {
3228  // Calculating the current interest point variables
3229 
3230  const unsigned int& currIPointCenterX = iPointsIt->m_x;
3231  const unsigned int& currIPointCenterY = iPointsIt->m_y;
3232  const float currIPointScale = 1.2f * iPointsIt->m_feature2 / 9.0f;
3233 
3234  unsigned int featureWindowWidth = (unsigned int)( 20.0 * currIPointScale );
3235  featureWindowWidth += ( ( featureWindowWidth % 2 ) ? 0 : 1 );
3236 
3237  const unsigned int feature90DegreeRotatedWindowRadius = (unsigned int)
3238  (
3239  std::ceil(
3240  std::sqrt(
3241  2.0
3242  *
3243  (
3244  ( (double)featureWindowWidth )
3245  *
3246  ( (double)featureWindowWidth )
3247  )
3248  )
3249  ) / 2.0
3250  );
3251 
3252  const unsigned int featureElementHaarWindowRadius =
3253  ((unsigned int)( 2.0 * currIPointScale )) / 2;
3254 
3255  const unsigned int currIPointCenterXAllowedMin = featureElementHaarWindowRadius +
3256  feature90DegreeRotatedWindowRadius + 1;
3257  const unsigned int currIPointCenterXAllowedMax = integralRasterData.getColumnsNumber() -
3258  currIPointCenterXAllowedMin - 1;
3259  const unsigned int currIPointCenterYAllowedMin = currIPointCenterXAllowedMin;
3260  const unsigned int currIPointCenterYAllowedMax = integralRasterData.getLinesNumber() -
3261  currIPointCenterXAllowedMin - 1;
3262 
3263  if( ( currIPointCenterX > currIPointCenterXAllowedMin ) &&
3264  ( currIPointCenterX < currIPointCenterXAllowedMax ) &&
3265  ( currIPointCenterY > currIPointCenterYAllowedMin ) &&
3266  ( currIPointCenterY < currIPointCenterYAllowedMax ) )
3267 
3268  {
3269  validInterestPoints.insert( *iPointsIt );
3270  }
3271 
3272  ++iPointsIt;
3273  }
3274  }
3275 
3276  TERP_TRUE_OR_RETURN_FALSE( features.reset( validInterestPoints.size(), 65 ),
3277  "Cannot allocate features matrix" );
3278 
3279  // globals
3280 
3281  float auxFeaturesBuffer[ 65 ];
3282 
3283  // iterating over each input innterest point
3284 
3285  InterestPointsSetT::const_iterator iPointsIt = validInterestPoints.begin();
3286  const InterestPointsSetT::const_iterator iPointsItEnd = validInterestPoints.end();
3287  unsigned int interestPointIdx = 0;
3288  while( iPointsIt != iPointsItEnd )
3289  {
3290  // Calculating the current interest point variables
3291 
3292  const unsigned int& currIPointCenterX = iPointsIt->m_x;
3293  const unsigned int& currIPointCenterY = iPointsIt->m_y;
3294  const float currIPointScale = 1.2f * iPointsIt->m_feature2 / 9.0f;
3295 
3296  unsigned int featureWindowWidth = (unsigned int)( 20.0 * currIPointScale );
3297  featureWindowWidth += ( ( featureWindowWidth % 2 ) ? 0 : 1 );
3298 
3299  const unsigned int featureWindowRadius = featureWindowWidth / 2;
3300  const float featureWindowRadiusDouble = (float)featureWindowRadius;
3301 
3302  const unsigned int featureSubWindowWidth = featureWindowWidth / 4;
3303 
3304  const unsigned int featureElementHaarWindowRadius =
3305  ((unsigned int)( 2.0 * currIPointScale )) / 2;
3306 
3307  const unsigned int featureWindowRasterXStart = currIPointCenterX -
3308  featureWindowRadius;
3309  const unsigned int featureWindowRasterYStart = currIPointCenterY -
3310  featureWindowRadius;
3311 
3312  // Initiating the features vector
3313 
3314  unsigned int currentFeaturePtrStartIdx = 0;
3315 
3316  for( currentFeaturePtrStartIdx = 0; currentFeaturePtrStartIdx < 65 ;
3317  ++currentFeaturePtrStartIdx )
3318  auxFeaturesBuffer[ currentFeaturePtrStartIdx ] = 0.0;
3319 
3320  // Estimating the intensity vectors
3321 
3322  assert( ((long int)currIPointCenterX) -
3323  ((long int)featureWindowRadius) >= 0 );
3324  assert( ((long int)currIPointCenterY) -
3325  ((long int)featureWindowRadius) >= 0 );
3326  assert( currIPointCenterX +
3327  featureWindowRadius < integralRasterData.getColumnsNumber() );
3328  assert( currIPointCenterY +
3329  featureWindowRadius < integralRasterData.getLinesNumber() );
3330 
3331  const float currIPointXIntensity = getHaarXVectorIntensity( integralRasterData, currIPointCenterX,
3332  currIPointCenterY, featureWindowRadius );
3333  const float currIPointYIntensity = getHaarYVectorIntensity( integralRasterData, currIPointCenterX,
3334  currIPointCenterY, featureWindowRadius );
3335 
3336  // Calculating the rotation parameters
3337 
3338  const float currIPointRotationNorm = std::sqrt( ( currIPointXIntensity * currIPointXIntensity ) +
3339  ( currIPointYIntensity * currIPointYIntensity ) );
3340 
3341  float currIPointRotationSin = 0; // default: no rotation
3342  float currIPointRotationCos = 1.0; // default: no rotation
3343 
3344  if( currIPointRotationNorm != 0.0 )
3345  {
3346  currIPointRotationCos = currIPointXIntensity / currIPointRotationNorm;
3347  currIPointRotationSin = currIPointYIntensity / currIPointRotationNorm;
3348  }
3349 
3350  assert( ( currIPointRotationCos >= -1.0 ) && ( currIPointRotationCos <= 1.0 ) );
3351  assert( ( currIPointRotationSin >= -1.0 ) && ( currIPointRotationSin <= 1.0 ) );
3352 
3353 // std::cout << "angle:";
3354 // std::cout << std::atan2( currIPointRotationSin, currIPointRotationCos ) * 180.0 / M_PI << std::endl;
3355 
3356  /* The region surrounding the interest point is split up regularly
3357  into smaller 44 square rotated by the haar intensity vectors
3358  calculated above
3359 
3360  counterclockwise rotation
3361  | u | |cos -sin| |X|
3362  | v | == |sin cos| x |Y|
3363 
3364  clockwise rotation
3365  | u | |cos sin| |X|
3366  | v | == |-sin cos| x |Y|
3367  */
3368 
3369  unsigned int featureWindowYOffset = 0;
3370  unsigned int featureWindowXOffset = 0;
3371  float featureElementZeroCenteredOriginalXIdx = 0;
3372  float featureElementZeroCenteredOriginalYIdx = 0;
3373  float featureElementZeroCenteredRotatedXIdx = 0;
3374  float featureElementZeroCenteredRotatedYIdx = 0;
3375  float featureElementRotatedXIdx = 0;
3376  float featureElementRotatedYIdx = 0;
3377  unsigned int featureElementRasterRotatedXIdx = 0;
3378  unsigned int featureElementRasterRotatedYIdx = 0;
3379  float featureElementOriginalHaarXIntensity = 0;
3380  float featureElementOriginalHaarYIntensity = 0;
3381  float featureElementZeroCenteredOriginalHaarXIntensity = 0;
3382  float featureElementZeroCenteredOriginalHaarYIntensity = 0;
3383  float featureElementRotatedHaarXIntensity = 0;
3384  float featureElementRotatedHaarYIntensity = 0;
3385  float featureElementZeroCenteredRotatedHaarXIntensity = 0;
3386  float featureElementZeroCenteredRotatedHaarYIntensity = 0;
3387  unsigned int featureSubWindowYIdx = 0;
3388  unsigned int featureSubWindowXIdx = 0;
3389 
3390  for( featureWindowYOffset = 0 ; featureWindowYOffset < featureWindowWidth ;
3391  featureWindowYOffset += 5 )
3392  {
3393  featureElementZeroCenteredOriginalYIdx = ((float)featureWindowYOffset)
3394  - featureWindowRadiusDouble;
3395 
3396  featureSubWindowYIdx = featureWindowYOffset / featureSubWindowWidth;
3397 
3398  for( featureWindowXOffset = 0 ; featureWindowXOffset < featureWindowWidth ;
3399  featureWindowXOffset += 5 )
3400  {
3401  featureSubWindowXIdx = featureWindowXOffset / featureSubWindowWidth;
3402 
3403  currentFeaturePtrStartIdx = ( featureSubWindowYIdx * 4 ) +
3404  featureSubWindowXIdx;
3405 
3406  featureElementZeroCenteredOriginalXIdx = ((float)featureWindowXOffset)
3407  - featureWindowRadiusDouble;
3408 
3409  /* finding the correspondent point over the original raster
3410  using a clockwize rotation */
3411 
3412  featureElementZeroCenteredRotatedXIdx =
3413  ( currIPointRotationCos * featureElementZeroCenteredOriginalXIdx ) +
3414  ( currIPointRotationSin * featureElementZeroCenteredOriginalYIdx );
3415  featureElementZeroCenteredRotatedYIdx =
3416  ( currIPointRotationCos * featureElementZeroCenteredOriginalYIdx )
3417  - ( currIPointRotationSin * featureElementZeroCenteredOriginalXIdx );
3418 
3419  featureElementRotatedXIdx = featureElementZeroCenteredRotatedXIdx +
3420  featureWindowRadiusDouble;
3421  featureElementRotatedYIdx = featureElementZeroCenteredRotatedYIdx +
3422  featureWindowRadiusDouble;
3423 
3424  featureElementRasterRotatedXIdx = featureWindowRasterXStart +
3425  (unsigned int)ROUND( featureElementRotatedXIdx );
3426  featureElementRasterRotatedYIdx = featureWindowRasterYStart +
3427  (unsigned int)ROUND( featureElementRotatedYIdx );
3428 
3429  assert( ((long int)featureElementRasterRotatedXIdx) -
3430  ((long int)featureElementHaarWindowRadius) >= 0 );
3431  assert( ((long int)featureElementRasterRotatedYIdx) -
3432  ((long int)featureElementHaarWindowRadius) >= 0 );
3433  assert( featureElementRasterRotatedXIdx +
3434  featureElementHaarWindowRadius < integralRasterData.getColumnsNumber() );
3435  assert( featureElementRasterRotatedYIdx +
3436  featureElementHaarWindowRadius < integralRasterData.getLinesNumber() );
3437 
3438  // Finding the original haar intesity vectors
3439 
3440  featureElementOriginalHaarXIntensity = getHaarXVectorIntensity( integralRasterData,
3441  featureElementRasterRotatedXIdx, featureElementRasterRotatedYIdx,
3442  featureElementHaarWindowRadius );
3443  featureElementOriginalHaarYIntensity = getHaarYVectorIntensity( integralRasterData,
3444  featureElementRasterRotatedXIdx, featureElementRasterRotatedYIdx,
3445  featureElementHaarWindowRadius );
3446 
3447  // Rotating the intensities by the central point haar intensities vectors
3448  // usigng a counterclockwise rotation
3449 
3450  featureElementZeroCenteredOriginalHaarXIntensity = featureElementOriginalHaarXIntensity +
3451  featureElementZeroCenteredOriginalXIdx;
3452  featureElementZeroCenteredOriginalHaarYIntensity = featureElementOriginalHaarYIntensity +
3453  featureElementZeroCenteredOriginalYIdx;
3454 
3455  featureElementZeroCenteredRotatedHaarXIntensity =
3456  ( currIPointRotationCos * featureElementZeroCenteredOriginalHaarXIntensity ) +
3457  ( currIPointRotationSin * featureElementZeroCenteredOriginalHaarYIntensity );
3458  featureElementZeroCenteredRotatedHaarYIntensity =
3459  ( currIPointRotationCos * featureElementZeroCenteredOriginalHaarYIntensity )
3460  - ( currIPointRotationSin * featureElementZeroCenteredOriginalHaarXIntensity );
3461 
3462  featureElementRotatedHaarXIntensity = featureElementZeroCenteredRotatedHaarXIntensity
3463  - featureElementZeroCenteredRotatedXIdx;
3464  featureElementRotatedHaarYIntensity = featureElementZeroCenteredRotatedHaarYIntensity
3465  - featureElementZeroCenteredRotatedYIdx;
3466 
3467  // Generating the related portion inside the output features vector
3468 
3469  assert( currentFeaturePtrStartIdx < 61 );
3470 
3471  auxFeaturesBuffer[ currentFeaturePtrStartIdx ] +=
3472  featureElementRotatedHaarXIntensity;
3473  auxFeaturesBuffer[ currentFeaturePtrStartIdx + 1 ] +=
3474  featureElementRotatedHaarYIntensity;
3475  auxFeaturesBuffer[ currentFeaturePtrStartIdx + 2 ] +=
3476  std::abs( featureElementRotatedHaarXIntensity );
3477  auxFeaturesBuffer[ currentFeaturePtrStartIdx + 3 ] +=
3478  std::abs( featureElementRotatedHaarYIntensity );
3479  }
3480  }
3481 
3482  // turning the descriptor into a unit vector.(Invariance to contrast)
3483 
3484  float* currentFeaturePtr = features[ interestPointIdx ];
3485 
3486  float featureElementsNormalizeFactor = 0.0;
3487 
3488  for( currentFeaturePtrStartIdx = 0 ; currentFeaturePtrStartIdx < 64 ;
3489  ++currentFeaturePtrStartIdx )
3490  {
3491  featureElementsNormalizeFactor += ( auxFeaturesBuffer[ currentFeaturePtrStartIdx ]
3492  * auxFeaturesBuffer[ currentFeaturePtrStartIdx ] );
3493  }
3494 
3495  featureElementsNormalizeFactor = std::sqrt( featureElementsNormalizeFactor );
3496 
3497  if( featureElementsNormalizeFactor != 0.0 )
3498  {
3499  featureElementsNormalizeFactor = 1.0f / featureElementsNormalizeFactor;
3500  }
3501 
3502  for( currentFeaturePtrStartIdx = 0 ; currentFeaturePtrStartIdx < 64 ;
3503  ++currentFeaturePtrStartIdx )
3504  {
3505  currentFeaturePtr[ currentFeaturePtrStartIdx ] = (
3506  auxFeaturesBuffer[ currentFeaturePtrStartIdx ] *
3507  featureElementsNormalizeFactor );
3508  TERP_DEBUG_TRUE_OR_THROW( ( currentFeaturePtr[ currentFeaturePtrStartIdx ] <= 1.0 ),
3509  currentFeaturePtr[ currentFeaturePtrStartIdx ] );
3510  TERP_DEBUG_TRUE_OR_THROW( ( currentFeaturePtr[ currentFeaturePtrStartIdx ] >= -1.0 ),
3511  currentFeaturePtr[ currentFeaturePtrStartIdx ] );
3512  }
3513 
3514  // Adding an attribute based on the sign of the Laplacian to
3515  // distinguishes bright blobs
3516  // on dark backgrounds from the reverse situation.
3517 
3518  currentFeaturePtr[ 64 ] = ( iPointsIt->m_feature3 * 64.0f );
3519 
3520  ++interestPointIdx;
3521  ++iPointsIt;
3522  }
3523 
3524  return true;
3525  }
3526 
3528  const InterestPointsSetT& interestPoints,
3529  const std::string& fileNameBeginning )
3530  {
3531  const unsigned int tifLinesNumber = (unsigned int)std::sqrt( (double)
3532  features.getColumnsNumber() );
3533  const unsigned int featuresColsNumber = features.getColumnsNumber();
3534 
3535  double const* featureLinePtr = 0;
3536 
3537  InterestPointsSetT::const_iterator iIt = interestPoints.begin();
3538 
3539  for( unsigned int featuresIdx = 0 ; featuresIdx < features.getLinesNumber() ;
3540  ++featuresIdx )
3541  {
3542  featureLinePtr = features[ featuresIdx ];
3543 
3544  std::vector<te::rst::BandProperty*> bandsProperties;
3545  bandsProperties.push_back(new te::rst::BandProperty( 0, te::dt::UCHAR_TYPE, "" ));
3546  bandsProperties[0]->m_colorInterp = te::rst::RedCInt;
3547  bandsProperties[0]->m_noDataValue = 0;
3548 
3549  std::map<std::string, std::string> rInfo;
3550  rInfo["URI"] = fileNameBeginning + "_" + boost::lexical_cast< std::string >( iIt->m_x )
3551  + "_" + boost::lexical_cast< std::string >( iIt->m_y ) + ".tif";
3552 
3553  te::rst::Grid* newgrid = new te::rst::Grid( tifLinesNumber,
3554  tifLinesNumber, 0, -1 );
3555 
3556  std::auto_ptr< te::rst::Raster > outputRasterPtr(
3557  te::rst::RasterFactory::make( "GDAL", newgrid, bandsProperties, rInfo, 0, 0));
3558  TERP_TRUE_OR_THROW( outputRasterPtr.get(), "Output raster creation error");
3559 
3560  unsigned int line = 0;
3561  unsigned int col = 0;
3562  double value = 0;
3563  double min = 0;
3564  double max = 0;
3565  double gain = 1.0;
3566 
3567  for( col = 0 ; col < featuresColsNumber ; ++col )
3568  {
3569  if( min > featureLinePtr[ col ] ) min = featureLinePtr[ col ];
3570  if( max < featureLinePtr[ col ] ) max = featureLinePtr[ col ];
3571  }
3572 
3573  gain = 255.0 / ( max - min );
3574 
3575  for( line = 0 ; line < tifLinesNumber ; ++line )
3576  for( col = 0 ; col < tifLinesNumber ; ++col )
3577  {
3578  value = featureLinePtr[ ( line * tifLinesNumber ) + col ];
3579  value *= gain;
3580  value -= min;
3581  value = MIN( 255.0, value );
3582  value = MAX( 0.0, value );
3583 
3584  outputRasterPtr->setValue( col, line, value, 0 );
3585  }
3586 
3587  ++iIt;
3588  }
3589  }
3590 
3592  const FloatsMatrix& featuresSet1,
3593  const FloatsMatrix& featuresSet2,
3594  const InterestPointsSetT& interestPointsSet1,
3595  const InterestPointsSetT& interestPointsSet2,
3596  const unsigned int maxPt1ToPt2Distance,
3597  const unsigned int enableMultiThread,
3598  const double minAllowedAbsCorrelation,
3599  MatchedInterestPointsSetT& matchedPoints )
3600  {
3601  matchedPoints.clear();
3602 
3603  const unsigned int interestPointsSet1Size = interestPointsSet1.size();
3604  if( interestPointsSet1Size == 0 ) return true;
3605 
3606  const unsigned int interestPointsSet2Size = interestPointsSet2.size();
3607  if( interestPointsSet2Size == 0 ) return true;
3608 
3609  assert( featuresSet1.getColumnsNumber() == featuresSet2.getColumnsNumber() );
3610  assert( featuresSet1.getLinesNumber() == interestPointsSet1Size );
3611  assert( featuresSet2.getLinesNumber() == interestPointsSet2Size );
3612 
3613  // Creating internal objects
3614 
3615  InterestPointsSetT::const_iterator it1 = interestPointsSet1.begin();
3616  boost::scoped_array< InterestPointT > internalInterestPointsSet1(
3617  new InterestPointT[ interestPointsSet1Size ] );
3618  for( unsigned int idx1 = 0 ; idx1 < interestPointsSet1Size ; ++idx1 )
3619  {
3620  internalInterestPointsSet1[ idx1 ] = *it1;
3621 
3622  ++it1;
3623  }
3624 
3625  InterestPointsSetT::const_iterator it2 = interestPointsSet2.begin();
3626  boost::scoped_array< InterestPointT > internalInterestPointsSet2(
3627  new InterestPointT[ interestPointsSet2Size ] );
3628  for( unsigned int idx2 = 0 ; idx2 < interestPointsSet2Size ; ++idx2 )
3629  {
3630  internalInterestPointsSet2[ idx2 ] = *it2;
3631 
3632  ++it2;
3633  }
3634 
3635  // Creating the correlation matrix
3636 
3637  FloatsMatrix corrMatrix;
3638  TERP_TRUE_OR_RETURN_FALSE( corrMatrix.reset( interestPointsSet1Size,
3639  interestPointsSet2Size, FloatsMatrix::RAMMemPol ),
3640  "Error crearting the correlation matrix" );
3641 
3642  unsigned int col = 0;
3643  unsigned int line = 0;
3644  float* linePtr = 0;
3645 
3646  for( line = 0 ; line < interestPointsSet1Size ; ++line )
3647  {
3648  linePtr = corrMatrix[ line ];
3649 
3650  for( col = 0 ; col < interestPointsSet2Size ; ++col )
3651  {
3652  linePtr[ col ] = 0;
3653  }
3654  }
3655 
3656  boost::mutex syncMutex;
3657  unsigned int nextFeatureIdx1ToProcess = 0;
3658 // unsigned int nextFeatureIdx2ToProcess = 0;
3659 
3661  params.m_featuresSet1Ptr = &featuresSet1;
3662  params.m_featuresSet2Ptr = &featuresSet2;
3663  params.m_interestPointsSet1Ptr = internalInterestPointsSet1.get();
3664  params.m_interestPointsSet2Ptr = internalInterestPointsSet2.get();
3665  params.m_nextFeatureIdx1ToProcessPtr = &nextFeatureIdx1ToProcess;
3666  params.m_corrMatrixPtr = &corrMatrix;
3667  params.m_syncMutexPtr = &syncMutex;
3668  params.m_maxPt1ToPt2Distance = maxPt1ToPt2Distance;
3669 
3670  if( enableMultiThread )
3671  {
3672  TERP_TRUE_OR_RETURN_FALSE( featuresSet1.getMemPolicy() ==
3673  FloatsMatrix::RAMMemPol, "Invalid memory policy" )
3674  TERP_TRUE_OR_RETURN_FALSE( featuresSet2.getMemPolicy() ==
3675  FloatsMatrix::RAMMemPol, "Invalid memory policy" )
3676 
3677  const unsigned int procsNumber = te::common::GetPhysProcNumber();
3678 
3679  boost::thread_group threads;
3680 
3681  for( unsigned int threadIdx = 0 ; threadIdx < procsNumber ;
3682  ++threadIdx )
3683  {
3684  threads.add_thread( new boost::thread(
3686  }
3687 
3688  threads.join_all();
3689 
3690  }
3691  else
3692  {
3694  }
3695 
3696  // finding the correlation matrix maximas for each line and column
3697 
3698  std::vector< float > eachLineMaxABSValues( interestPointsSet1Size,
3699  0.0 );
3700  std::vector< unsigned int > eachLineMaxABSIndexes( interestPointsSet1Size,
3701  interestPointsSet2Size );
3702  std::vector< float > eachColMaxABSValues( interestPointsSet2Size,
3703  0.0 );
3704  std::vector< unsigned int > eachColMaxABSIndexes( interestPointsSet2Size,
3705  interestPointsSet1Size );
3706  float absValue = 0;
3707 
3708  for( line = 0 ; line < interestPointsSet1Size ; ++line )
3709  {
3710  linePtr = corrMatrix[ line ];
3711 
3712  for( col = 0 ; col < interestPointsSet2Size ; ++col )
3713  {
3714  absValue = std::abs( linePtr[ col ] );
3715 
3716  if( absValue >= minAllowedAbsCorrelation )
3717  {
3718  if( absValue > eachLineMaxABSValues[ line ] )
3719  {
3720  eachLineMaxABSValues[ line ] = absValue;
3721  eachLineMaxABSIndexes[ line ] = col;
3722  }
3723 
3724  if( absValue > eachColMaxABSValues[ col ] )
3725  {
3726  eachColMaxABSValues[ col ] = absValue;
3727  eachColMaxABSIndexes[ col ] = line;
3728  }
3729  }
3730  }
3731  }
3732 
3733  // Finding tiepoints
3734 
3735  MatchedInterestPointsT auxMatchedPoints;
3736 
3737  for( line = 0 ; line < interestPointsSet1Size ; ++line )
3738  {
3739  col = eachLineMaxABSIndexes[ line ];
3740 
3741  if( ( col < interestPointsSet2Size ) &&
3742  ( eachColMaxABSIndexes[ col ] == line ) )
3743  {
3744  auxMatchedPoints.m_point1 = internalInterestPointsSet1[ line ];
3745  auxMatchedPoints.m_point2 = internalInterestPointsSet2[ col ];
3746  auxMatchedPoints.m_feature = std::abs( corrMatrix( line, col ) );
3747 
3748  matchedPoints.insert( auxMatchedPoints );
3749  }
3750  }
3751 
3752  return true;
3753  }
3754 
3757  {
3758  assert( paramsPtr->m_featuresSet1Ptr->getMemPolicy() ==
3760  assert( paramsPtr->m_featuresSet2Ptr->getMemPolicy() ==
3762  assert( paramsPtr->m_corrMatrixPtr->getMemPolicy() ==
3764 
3765  // globals
3766 
3767  const unsigned int featureElementsNmb = paramsPtr->m_featuresSet1Ptr->getColumnsNumber();
3768  unsigned int feat2Idx = 0;
3769  float const* feat1Ptr = 0;
3770  float const* feat2Ptr = 0;
3771  float* corrMatrixLinePtr = 0;
3772  unsigned int featCol = 0;
3773  float sumAA = 0;
3774  float sumBB = 0;
3775  float cc_norm = 0;
3776  float ccorrelation = 0;
3777  te::gm::Envelope auxEnvelope;
3778 
3779  // Indexing tree building
3780 
3781  const unsigned int featuresSet1Size =
3782  paramsPtr->m_featuresSet1Ptr->getLinesNumber();
3783  const unsigned int featuresSet2Size =
3784  paramsPtr->m_featuresSet2Ptr->getLinesNumber();
3785 
3786  te::sam::rtree::Index< unsigned int > interestPointsSet2RTree;
3787 
3788  std::vector< unsigned int > selectedFeaturesSet2Indexes;
3789  unsigned int selectedFeaturesSet2IndexesSize = 0;
3790 
3791  if( paramsPtr->m_maxPt1ToPt2Distance )
3792  {
3793  for( unsigned int feat2Idx = 0 ; feat2Idx < featuresSet2Size ; ++feat2Idx )
3794  {
3795  interestPointsSet2RTree.insert(
3797  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_x,
3798  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_y,
3799  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_x,
3800  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_y ),
3801  feat2Idx );
3802  }
3803  }
3804  else
3805  {
3806  selectedFeaturesSet2Indexes.resize( featuresSet2Size );
3807  selectedFeaturesSet2IndexesSize = featuresSet2Size;
3808  for( unsigned int feat2Idx = 0 ; feat2Idx < featuresSet2Size ; ++feat2Idx )
3809  {
3810  selectedFeaturesSet2Indexes[ feat2Idx ] = feat2Idx;
3811  }
3812  }
3813 
3814  // Analysing each feature
3815 
3816  for( unsigned int feat1Idx = 0 ; feat1Idx < featuresSet1Size ; ++feat1Idx )
3817  {
3818  paramsPtr->m_syncMutexPtr->lock();
3819 
3820  if( feat1Idx == (*paramsPtr->m_nextFeatureIdx1ToProcessPtr) )
3821  {
3822  ++(*paramsPtr->m_nextFeatureIdx1ToProcessPtr);
3823 
3824  paramsPtr->m_syncMutexPtr->unlock();
3825 
3826  if( paramsPtr->m_maxPt1ToPt2Distance )
3827  {
3828  auxEnvelope.m_llx = auxEnvelope.m_urx =
3829  paramsPtr->m_interestPointsSet1Ptr[ feat1Idx ].m_x;
3830  auxEnvelope.m_llx -= (double)paramsPtr->m_maxPt1ToPt2Distance;
3831  auxEnvelope.m_urx += (double)paramsPtr->m_maxPt1ToPt2Distance;
3832  auxEnvelope.m_lly = auxEnvelope.m_ury =
3833  paramsPtr->m_interestPointsSet1Ptr[ feat1Idx ].m_y;
3834  auxEnvelope.m_lly -= (double)paramsPtr->m_maxPt1ToPt2Distance;;
3835  auxEnvelope.m_ury += (double)paramsPtr->m_maxPt1ToPt2Distance;;
3836 
3837  selectedFeaturesSet2Indexes.clear();
3838  interestPointsSet2RTree.search( auxEnvelope,
3839  selectedFeaturesSet2Indexes );
3840 
3841  selectedFeaturesSet2IndexesSize = selectedFeaturesSet2Indexes.size();
3842  }
3843 
3844  corrMatrixLinePtr = paramsPtr->m_corrMatrixPtr->operator[]( feat1Idx );
3845 
3846  feat1Ptr = paramsPtr->m_featuresSet1Ptr->operator[]( feat1Idx );
3847 
3848  for( unsigned int selectedFSIIdx = 0 ; selectedFSIIdx <
3849  selectedFeaturesSet2IndexesSize ; ++selectedFSIIdx )
3850  {
3851  feat2Idx = selectedFeaturesSet2Indexes[ selectedFSIIdx ];
3852 
3853  feat2Ptr = paramsPtr->m_featuresSet2Ptr->operator[]( feat2Idx );
3854 
3855  sumAA = 0.0;
3856  sumBB = 0.0;
3857  for( featCol = 0 ; featCol < featureElementsNmb ; ++featCol )
3858  {
3859  sumAA += feat1Ptr[ featCol ] * feat1Ptr[ featCol ];
3860  sumBB += feat2Ptr[ featCol ] * feat2Ptr[ featCol ];
3861  }
3862 
3863  cc_norm = std::sqrt( sumAA * sumBB );
3864 
3865  if( cc_norm == 0.0 )
3866  {
3867  corrMatrixLinePtr[ feat2Idx ] = 0;
3868  }
3869  else
3870  {
3871  ccorrelation = 0.0;
3872  for( featCol = 0 ; featCol < featureElementsNmb ; ++featCol )
3873  {
3874  ccorrelation += ( feat1Ptr[ featCol ] * feat2Ptr[ featCol ] ) /
3875  cc_norm;
3876  }
3877 
3878  corrMatrixLinePtr[ feat2Idx ] = ccorrelation;
3879  }
3880  }
3881  }
3882  else
3883  {
3884  paramsPtr->m_syncMutexPtr->unlock();
3885  }
3886  }
3887  }
3888 
3890  const FloatsMatrix& featuresSet1,
3891  const FloatsMatrix& featuresSet2,
3892  const InterestPointsSetT& interestPointsSet1,
3893  const InterestPointsSetT& interestPointsSet2,
3894  const unsigned int maxPt1ToPt2PixelDistance,
3895  const double maxEuclideanDist,
3896  const unsigned int enableMultiThread,
3897  MatchedInterestPointsSetT& matchedPoints )
3898  {
3899  matchedPoints.clear();
3900 
3901  const unsigned int interestPointsSet1Size = interestPointsSet1.size();
3902  if( interestPointsSet1Size == 0 ) return true;
3903 
3904  const unsigned int interestPointsSet2Size = interestPointsSet2.size();
3905  if( interestPointsSet2Size == 0 ) return true;
3906 
3907  assert( featuresSet1.getColumnsNumber() == featuresSet2.getColumnsNumber() );
3908  assert( featuresSet1.getLinesNumber() == interestPointsSet1Size );
3909  assert( featuresSet2.getLinesNumber() == interestPointsSet2Size );
3910 
3911  // Creating internal objects
3912 
3913  InterestPointsSetT::const_iterator it1 = interestPointsSet1.begin();
3914  boost::scoped_array< InterestPointT > internalInterestPointsSet1(
3915  new InterestPointT[ interestPointsSet1Size ] );
3916  for( unsigned int idx1 = 0 ; idx1 < interestPointsSet1Size ; ++idx1 )
3917  {
3918  internalInterestPointsSet1[ idx1 ] = *it1;
3919  ++it1;
3920  }
3921 
3922  InterestPointsSetT::const_iterator it2 = interestPointsSet2.begin();
3923  boost::scoped_array< InterestPointT > internalInterestPointsSet2(
3924  new InterestPointT[ interestPointsSet2Size ] );
3925  for( unsigned int idx2 = 0 ; idx2 < interestPointsSet2Size ; ++idx2 )
3926  {
3927  internalInterestPointsSet2[ idx2 ] = *it2;
3928  ++it2;
3929  }
3930 
3931  // Creating the distances matrix
3932 
3933  FloatsMatrix distMatrix;
3934  TERP_TRUE_OR_RETURN_FALSE( distMatrix.reset( interestPointsSet1Size,
3935  interestPointsSet2Size, FloatsMatrix::RAMMemPol ),
3936  "Error crearting the correlation matrix" );
3937 
3938  unsigned int col = 0;
3939  unsigned int line = 0;
3940  float* linePtr = 0;
3941 
3942  for( line = 0 ; line < interestPointsSet1Size ; ++line )
3943  {
3944  linePtr = distMatrix[ line ];
3945 
3946  for( col = 0 ; col < interestPointsSet2Size ; ++col )
3947  {
3948  linePtr[ col ] = FLT_MAX;
3949  }
3950  }
3951 
3952  boost::mutex syncMutex;
3953  unsigned int nextFeatureIdx1ToProcess = 0;
3954 
3956  params.m_featuresSet1Ptr = &featuresSet1;
3957  params.m_featuresSet2Ptr = &featuresSet2;
3958  params.m_interestPointsSet1Ptr = internalInterestPointsSet1.get();
3959  params.m_interestPointsSet2Ptr = internalInterestPointsSet2.get();
3960  params.m_nextFeatureIdx1ToProcessPtr = &nextFeatureIdx1ToProcess;
3961  params.m_distMatrixPtr = &distMatrix;
3962  params.m_syncMutexPtr = &syncMutex;
3963  params.m_maxPt1ToPt2Distance = maxPt1ToPt2PixelDistance;
3964 
3965  if( enableMultiThread )
3966  {
3967  TERP_TRUE_OR_RETURN_FALSE( featuresSet1.getMemPolicy() ==
3968  FloatsMatrix::RAMMemPol, "Invalid memory policy" )
3969  TERP_TRUE_OR_RETURN_FALSE( featuresSet2.getMemPolicy() ==
3970  FloatsMatrix::RAMMemPol, "Invalid memory policy" )
3971 
3972  const unsigned int procsNumber = te::common::GetPhysProcNumber();
3973 
3974  boost::thread_group threads;
3975 
3976  for( unsigned int threadIdx = 0 ; threadIdx < procsNumber ;
3977  ++threadIdx )
3978  {
3979  threads.add_thread( new boost::thread(
3981  }
3982 
3983  threads.join_all();
3984 
3985  }
3986  else
3987  {
3989  }
3990 
3991  // finding the distances matrix minimum for each line and column
3992 
3993  std::vector< float > eachLineMinValues( interestPointsSet1Size,
3994  FLT_MAX );
3995  std::vector< unsigned int > eachLineMinIndexes( interestPointsSet1Size,
3996  interestPointsSet2Size );
3997  std::vector< float > eachColMinValues( interestPointsSet2Size,
3998  FLT_MAX );
3999  std::vector< unsigned int > eachColMinIndexes( interestPointsSet2Size,
4000  interestPointsSet1Size );
4001  float maxDistValue = FLT_MAX * (-1.0);
4002 
4003  for( line = 0 ; line < interestPointsSet1Size ; ++line )
4004  {
4005  linePtr = distMatrix[ line ];
4006 
4007  for( col = 0 ; col < interestPointsSet2Size ; ++col )
4008  {
4009  const float& value = linePtr[ col ];
4010 
4011  if( value <= maxEuclideanDist )
4012  {
4013  if( value < eachLineMinValues[ line ] )
4014  {
4015  eachLineMinValues[ line ] = value;
4016  eachLineMinIndexes[ line ] = col;
4017  }
4018 
4019  if( value < eachColMinValues[ col ] )
4020  {
4021  eachColMinValues[ col ] = value;
4022  eachColMinIndexes[ col ] = line;
4023  }
4024 
4025  if( value > maxDistValue ) maxDistValue = value;
4026  }
4027  }
4028  }
4029 
4030  if( maxDistValue == 0.0 ) maxDistValue = 1.0;
4031 
4032  // Finding tiepoints
4033 
4034  MatchedInterestPointsT auxMatchedPoints;
4035 
4036  for( line = 0 ; line < interestPointsSet1Size ; ++line )
4037  {
4038  col = eachLineMinIndexes[ line ];
4039 
4040  if( ( col < interestPointsSet2Size ) &&
4041  ( eachColMinIndexes[ col ] == line ) )
4042  {
4043  const float& distValue = distMatrix( line, col );
4044 
4045  auxMatchedPoints.m_point1 = internalInterestPointsSet1[ line ];
4046  auxMatchedPoints.m_point2 = internalInterestPointsSet2[ col ],
4047  auxMatchedPoints.m_feature = ( maxDistValue - distValue ) /
4048  maxDistValue;
4049 
4050  matchedPoints.insert( auxMatchedPoints );
4051  }
4052  }
4053 
4054  return true;
4055  }
4056 
4059  {
4060  assert( paramsPtr->m_featuresSet1Ptr->getMemPolicy() ==
4062  assert( paramsPtr->m_featuresSet2Ptr->getMemPolicy() ==
4064  assert( paramsPtr->m_distMatrixPtr->getMemPolicy() ==
4066  assert( paramsPtr->m_featuresSet1Ptr->getColumnsNumber() ==
4067  paramsPtr->m_featuresSet2Ptr->getColumnsNumber() );
4068 
4069  // Glogals
4070 
4071  const unsigned int featureElementsNmb = paramsPtr->m_featuresSet1Ptr->getColumnsNumber();
4072  unsigned int feat2Idx = 0;
4073  float const* feat1Ptr = 0;
4074  float const* feat2Ptr = 0;
4075  float* corrMatrixLinePtr = 0;
4076  unsigned int featCol = 0;
4077  te::gm::Envelope auxEnvelope;
4078  float diff = 0;
4079  float euclideanDist = 0;
4080 
4081  // initializing the features 2 indexing
4082 
4083  const unsigned int featuresSet1Size =
4084  paramsPtr->m_featuresSet1Ptr->getLinesNumber();
4085  const unsigned int featuresSet2Size =
4086  paramsPtr->m_featuresSet2Ptr->getLinesNumber();
4087 
4088  te::sam::rtree::Index< unsigned int > interestPointsSet2RTree;
4089 
4090  std::vector< unsigned int > selectedFeaturesSet2Indexes;
4091  unsigned int selectedFeaturesSet2IndexesSize = 0;
4092 
4093  if( paramsPtr->m_maxPt1ToPt2Distance )
4094  {
4095  for( unsigned int feat2Idx = 0 ; feat2Idx < featuresSet2Size ; ++feat2Idx )
4096  {
4097  interestPointsSet2RTree.insert(
4099  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_x,
4100  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_y,
4101  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_x,
4102  paramsPtr->m_interestPointsSet2Ptr[ feat2Idx ].m_y ),
4103  feat2Idx );
4104  }
4105  }
4106  else
4107  {
4108  selectedFeaturesSet2Indexes.resize( featuresSet2Size );
4109  selectedFeaturesSet2IndexesSize = featuresSet2Size;
4110  for( unsigned int feat2Idx = 0 ; feat2Idx < featuresSet2Size ; ++feat2Idx )
4111  {
4112  selectedFeaturesSet2Indexes[ feat2Idx ] = feat2Idx;
4113  }
4114  }
4115 
4116  // Analysing each feature
4117 
4118  for( unsigned int feat1Idx = 0 ; feat1Idx < featuresSet1Size ; ++feat1Idx )
4119  {
4120  paramsPtr->m_syncMutexPtr->lock();
4121 
4122  if( feat1Idx == (*paramsPtr->m_nextFeatureIdx1ToProcessPtr) )
4123  {
4124  ++(*paramsPtr->m_nextFeatureIdx1ToProcessPtr);
4125 
4126  paramsPtr->m_syncMutexPtr->unlock();
4127 
4128  if( paramsPtr->m_maxPt1ToPt2Distance )
4129  {
4130  auxEnvelope.m_llx = auxEnvelope.m_urx =
4131  paramsPtr->m_interestPointsSet1Ptr[ feat1Idx ].m_x;
4132  auxEnvelope.m_llx -= (double)paramsPtr->m_maxPt1ToPt2Distance;
4133  auxEnvelope.m_urx += (double)paramsPtr->m_maxPt1ToPt2Distance;
4134  auxEnvelope.m_lly = auxEnvelope.m_ury =
4135  paramsPtr->m_interestPointsSet1Ptr[ feat1Idx ].m_y;
4136  auxEnvelope.m_lly -= (double)paramsPtr->m_maxPt1ToPt2Distance;;
4137  auxEnvelope.m_ury += (double)paramsPtr->m_maxPt1ToPt2Distance;;
4138 
4139  selectedFeaturesSet2Indexes.clear();
4140  interestPointsSet2RTree.search( auxEnvelope,
4141  selectedFeaturesSet2Indexes );
4142 
4143  selectedFeaturesSet2IndexesSize = selectedFeaturesSet2Indexes.size();
4144  }
4145 
4146  corrMatrixLinePtr = paramsPtr->m_distMatrixPtr->operator[]( feat1Idx );
4147 
4148  feat1Ptr = paramsPtr->m_featuresSet1Ptr->operator[]( feat1Idx );
4149 
4150  for( unsigned int selectedFSIIdx = 0 ; selectedFSIIdx <
4151  selectedFeaturesSet2IndexesSize ; ++selectedFSIIdx )
4152  {
4153  feat2Idx = selectedFeaturesSet2Indexes[ selectedFSIIdx ];
4154 
4155  feat2Ptr = paramsPtr->m_featuresSet2Ptr->operator[]( feat2Idx );
4156 
4157  euclideanDist = 0.0;
4158 
4159  for( featCol = 0 ; featCol < featureElementsNmb ; ++featCol )
4160  {
4161  diff = feat1Ptr[ featCol ] - feat2Ptr[ featCol ];
4162  euclideanDist += ( diff * diff );
4163  }
4164 
4165  euclideanDist = std::sqrt( euclideanDist );
4166 
4167  corrMatrixLinePtr[ feat2Idx ] = euclideanDist;
4168  }
4169  }
4170  else
4171  {
4172  paramsPtr->m_syncMutexPtr->unlock();
4173  }
4174  }
4175  }
4176 
4177  void TiePointsLocator::printBuffer( double** buffer, const unsigned int nLines,
4178  const unsigned int nCols )
4179  {
4180  std::cout << std::endl;
4181 
4182  for( unsigned int line = 0 ; line < nLines ; ++line )
4183  {
4184  std::cout << std::endl << "[";
4185 
4186  for( unsigned int col = 0 ; col < nCols ; ++col )
4187  {
4188  std::cout << " " << buffer[ line ][ col ];
4189  }
4190 
4191  std::cout << "]";
4192  }
4193 
4194  std::cout << std::endl;
4195  }
4196 
4197  } // end namespace rp
4198 } // end namespace te
4199 
static float getSurfDyyDerivative(float **bufferPtr, const unsigned int &centerX, const unsigned int &centerY, const unsigned int &lobeWidth, const unsigned int &lobeRadius)
Return a SURF box filter Dxx derivative centered over the given position from the given integral imag...
boost::mutex * m_interestPointsAccessMutexPtr
A pointer to a valid mutex to control the output interest points container access.
double m_moravecMinAbsCorrelation
The minimum acceptable absolute correlation value when matching features (when applicable), default:0.5, valid range: [0,1].
unsigned int m_moravecGaussianFilterIterations
The number of noise Gaussin iterations, when applicable (used to remove image noise, zero will disable the Gaussian Filter, default:1).
unsigned int m_moravecCorrelationWindowWidth
The correlation window width used to correlate points between the images (minimum 3...
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:356
unsigned int m_maxInterestPointsPerRasterLinesBlock
The maximum number of points to find for each raster lines block.
te::rst::Interpolator::Method m_interpMethod
The raster interpolator method (default:NearestNeighbor).
const OutputParameters & operator=(const OutputParameters &params)
bool m_enableProgress
Enable/Disable the progress interface (default:false).
static unsigned int getSurfFilterSize(const unsigned int &octaveIndex, const unsigned int &scaleIndex)
Return the surf octave filter size (width).
std::vector< te::gm::GTParameters::TiePoint > m_tiePoints
The generated tie-pionts (te::gm::GTParameters::TiePoint::first are raster 1 line/column indexes...
static bool generateSurfFeatures(const InterestPointsSetT &interestPoints, const FloatsMatrix &integralRasterData, InterestPointsSetT &validInterestPoints, FloatsMatrix &features)
Generate a Surf features matrix for the given interes points.
#define TERP_LOG_AND_RETURN_FALSE(message)
Logs a warning message will and return false.
Definition: Macros.h:236
unsigned int m_maxInterestPointsPerRasterLinesBlock
The maximum number of points to find for each raster lines block for each scale.
bool executeSurf(const double raster1XRescFact, const double raster1YRescFact, const double raster2XRescFact, const double raster2YRescFact, te::common::TaskProgress *progressPtr, TiePointsLocator::OutputParameters *outParamsPtr, std::vector< double > &tiePointsWeights)
Executes the SURF algorithm using the supplied parameters.
Blue channel color interpretation.
Definition: Enums.h:61
unsigned int getNumberOfRows() const
Returns the raster number of rows.
Definition: Raster.cpp:208
static float getSurfDxxDerivative(float **bufferPtr, const unsigned int &centerX, const unsigned int &centerY, const unsigned int &lobeWidth, const unsigned int &lobeRadius)
Return a SURF box filter Dyy derivative centered over the given position from the given integral imag...
InterestPointsSetT * m_interestPointsPtr
A pointer to a valid interest points container.
te::rst::Raster const * m_inMaskRaster2Ptr
Optional one band input mask raster 2 (tie-points will not be generated inside mask image areas marke...
bool locateSurfInterestPoints(const FloatsMatrix &integralRasterData, UCharsMatrix const *maskRasterDataPtr, InterestPointsSetT &interestPoints) const
SURF interest points locator.
boost::mutex * m_rastaDataAccessMutexPtr
A pointer to a valid mutex to controle raster data access.
unsigned int m_moravecWindowWidth
The Moravec window width used to locate canditate tie-points (minimum 3, default: 5 )...
void clear()
Clear all allocated resources and go back to the initial default parameters.
Definition: Matrix.h:636
unsigned int m_raster2TargetAreaWidth
The raster 2 target area width (default:0 - The entire raster will be considered).
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
TiePointsLocator locator.
std::auto_ptr< te::gm::GeometricTransformation > m_transformationPtr
The generated geometric transformation with the base mininum required tie-points set ( depending on t...
unsigned int * m_nextRasterLinesBlockToProcessValuePtr
A pointer to a valid counter to control the blocks processing sequence.
std::vector< unsigned int > m_inRaster1Bands
Bands to be used from the input raster 1.
FloatsMatrix const * m_integralRasterDataPtr
The integral image raster data.
static bool applyMeanFilter(const FloatsMatrix &inputData, FloatsMatrix &outputData, const unsigned int iterationsNumber)
Mean Filter.
bool m_enableGeometryFilter
Enable/disable the geometry filter/outliers remotion (default:true).
unsigned int m_raster2TargetAreaColStart
The first column of the raster 2 target area to process (default:0 - The entire raster will be consid...
static Raster * make()
It creates and returns an empty raster with default raster driver.
float m_feature3
Interest point feature 3 value.
unsigned int getLinesNumber() const
The number of current matrix lines.
Definition: Matrix.h:665
unsigned int m_maxPt1ToPt2Distance
Zero (disabled) or the maximum distance between a point from set 1 to a point from set 1 (points beyo...
A class that represents an R-tree.
Definition: Index.h:56
static bool locateMoravecInterestPoints(const FloatsMatrix &rasterData, UCharsMatrix const *maskRasterDataPtr, const unsigned int moravecWindowWidth, const unsigned int maxInterestPoints, const unsigned int enableMultiThread, InterestPointsSetT &interestPoints)
Moravec interest points locator.
virtual void getValue(unsigned int c, unsigned int r, double &value) const =0
Returns the cell attribute value.
static float getHaarYVectorIntensity(BufferType &buffer, const unsigned int &centerX, const unsigned int &centerY, const unsigned int &radius)
Return a Haar Y intesity vector for the window centered at the given point.
InterestPointsSetT * m_interestPointsPtr
A pointer to a valid interest points container.
unsigned int GetPhysProcNumber()
Returns the number of physical processors.
unsigned int m_scalesNumber
Thread return value pointer.
void getValue(const double &c, const double &r, std::complex< double > &v, const std::size_t &b)
Get the interpolated value at specific band.
Definition: Interpolator.h:84
virtual std::size_t getNumberOfBands() const =0
Returns the number of bands (dimension of cells attribute values) in the raster.
unsigned int m_maxPt1ToPt2Distance
Zero (disabled) or the maximum distance between a point from set 1 to a point from set 1 (points beyo...
It interpolates one pixel based on a selected algorithm. Methods currently available are Nearest Neig...
Definition: Interpolator.h:51
unsigned int m_maxRasterLinesBlockMaxSize
The maximum lines number of each raster block to process.
static GeometricTransformation * make(const std::string &factoryKey)
It creates an object with the appropriated factory.
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...
static bool createIntegralImage(const FloatsMatrix &inputData, FloatsMatrix &outputData)
Create an integral image.
UCharsMatrix const * m_maskRasterDataPtr
The loaded mask raster data pointer (or zero if no mask is avaliable).
The parameters passed to the executeMatchingByEuclideanDistThreadEntry method.
bool execute(AlgorithmOutputParameters &outputParams)
Executes the algorithm using the supplied parameters.
const InputParameters & operator=(const InputParameters &params)
static void features2Tiff(const DoublesMatrix &features, const InterestPointsSetT &interestPoints, const std::string &fileNameBeginning)
Save the generated features to tif files.
double m_geomTransfMaxError
The maximum allowed transformation error (pixel units, default:2).
Method
Allowed interpolation methods.
Definition: Interpolator.h:58
std::multiset< InterestPointT > InterestPointsSetT
#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
boost::mutex * m_rastaDataAccessMutexPtr
A pointer to a valid mutex to controle raster data access.
double m_pixelSizeXRelation
The pixel resolution relation m_pixelSizeXRelation = raster1_pixel_res_x / raster2_pixel_res_x (defau...
static void printBuffer(double **buffer, const unsigned int nLines, const unsigned int nCols)
Print the given buffer to std::out.
Red channel color interpretation.
Definition: Enums.h:59
2D Geometric transformation tie-points filter (outliers remotion).
Definition: GTFilter.h:52
Abstract parameters base interface.
std::vector< TiePoint > m_tiePoints
Tie points.
Definition: GTParameters.h:95
static const factory_type * find(const std::string &factoryKey)
A rectified grid is the spatial support for raster data.
Definition: Grid.h:55
A raster band description.
Definition: Band.h:63
TiePointsLocator input parameters.
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 rescaleFactorX, const double rescaleFactorY, const te::rst::Interpolator::Method rasterInterpMethod, const unsigned char maxMemPercentUsage, std::vector< boost::shared_ptr< FloatsMatrix > > &loadedRasterData, UCharsMatrix &loadedMaskRasterData)
Load rasters data (normalized between 0 and 1).
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
static void locateSurfInterestPointsThreadEntry(SurfLocatorThreadParams *paramsPtr)
Surf locator thread entry.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
bool applyRansac(const std::string &transfName, const GTParameters &inputParams, const double maxDirectMapError, const double maxInverseMapError, const RansacItCounterT &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
bool isInitialized() const
Returns true if the algorithm instance is initialized and ready for execution.
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
unsigned int m_maxR1ToR2Offset
The maximum offset (pixels units) between a raster 1 point end the respective raster 2 point (default...
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_raster1TargetAreaLineStart
The first line of the raster 1 target area to process (default:0 - The entire raster will be consider...
TemplateElementType ElementTypeT
Public matrix element type definition.
Definition: Matrix.h:56
unsigned int m_surfOctavesNumber
The number of octaves to generate, when applicable (default: 3, minimum:1).
float m_feature2
Interest point feature 2 value.
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
unsigned int m_raster2TargetAreaHeight
The raster 2 target area height (default:0 - The entire raster will be considered).
#define ROUND(x)
Minimum of two values.
Definition: Macros.h:395
unsigned int m_octavesNumber
The number of octaves to generate (minimum:1).
unsigned int m_moravecWindowWidth
Thread return value pointer.
std::string m_geomTransfName
The name of the geometric transformation used to ensure tie-points consistency (see each te::gm::GTFa...
AbstractParameters * clone() const
Create a clone copy of this instance.
static float getHaarXVectorIntensity(BufferType &buffer, const unsigned int &centerX, const unsigned int &centerY, const unsigned int &radius)
Return a Haar X intesity vector for the window centered at the given point.
unsigned long int GetTotalPhysicalMemory()
Returns the amount of total physical memory (bytes).
bool executeMoravec(const double raster1XRescFact, const double raster1YRescFact, const double raster2XRescFact, const double raster2YRescFact, te::common::TaskProgress *progressPtr, TiePointsLocator::OutputParameters *outParamsPtr, std::vector< double > &tiePointsWeights)
Executes the Moravec algorithm using the supplied parameters.
unsigned int getNumberOfColumns() const
Returns the raster number of columns.
Definition: Raster.cpp:213
const Algorithm & operator=(const Algorithm &)
Definition: Algorithm.cpp:43
InteresPointsLocationStrategyType m_interesPointsLocationStrategy
The strategy used to locate interest points (default:SurfStrategyT).
boost::mutex * m_interestPointsAccessMutexPtr
A pointer to a valid mutex to control the output interest points container access.
static void executeMatchingByEuclideanDistThreadEntry(ExecuteMatchingByEuclideanDistThreadEntryParams *paramsPtr)
Correlation/Euclidean match thread entry.
static void roolUpBuffer(BufferElementT **bufferPtr, const unsigned int &bufferLinesNumber)
RoolUp a buffer of lines.
A raster band description.
Definition: BandProperty.h:61
std::vector< unsigned int > m_inRaster2Bands
Bands to be used from the input raster 2.
The parameters passed to the matchCorrelationEuclideanThreadEntry method.
#define MIN(a, b)
Macro that returns min between two values.
A generic template matrix.
Definition: Matrix.h:50
double m_geometryFilterAssurance
Geometry assurance (the error-free selection percent assurance) - valid range (0-1) - default:0...
The parameters passed to the surfLocatorThreadEntry method.
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
Definition: Macros.h:149
float m_feature1
Interest point feature 1 value.
bool initialize(const AlgorithmInputParameters &inputParams)
Initialize the algorithm instance making it ready for execution.
unsigned int getColumnsNumber() const
The number of current matrix columns.
Definition: Matrix.h:672
double m_pixelSizeYRelation
The pixel resolution relation m_pixelSizeYRelation = raster1_pixel_res_y / raster2_pixel_res_y (defau...
double m_surfMaxNormEuclideanDist
The maximum acceptable euclidean distance when matching features (when applicable), default:0.5, valid range: [0,1].
static bool executeMatchingByEuclideanDist(const FloatsMatrix &featuresSet1, const FloatsMatrix &featuresSet2, const InterestPointsSetT &interestPointsSet1, const InterestPointsSetT &interestPointsSet2, const unsigned int maxPt1ToPt2PixelDistance, const double maxEuclideanDist, const unsigned int enableMultiThread, MatchedInterestPointsSetT &matchedPoints)
Match each feature using eucliean distance.
void reset()
Clear all internal allocated objects and reset the algorithm to its initial state.
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 output parameters base interface.
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
static bool executeMatchingByCorrelation(const FloatsMatrix &featuresSet1, const FloatsMatrix &featuresSet2, const InterestPointsSetT &interestPointsSet1, const InterestPointsSetT &interestPointsSet2, const unsigned int maxPt1ToPt2PixelDistance, const unsigned int enableMultiThread, const double minAllowedAbsCorrelation, MatchedInterestPointsSetT &matchedPoints)
Match each feature using correlation.
static void locateMoravecInterestPointsThreadEntry(MoravecLocatorThreadParams *paramsPtr)
Movavec locator thread entry.
void reset()
Reset (clear) the active instance data.
Definition: Matrix.h:474
An abstract class for raster data strucutures.
Definition: Raster.h:70
virtual const Band * getBand(std::size_t i) const =0
Returns the raster i-th band.
This class can be used to inform the progress of a task.
Definition: TaskProgress.h:53
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 m_maxRasterLinesBlockMaxSize
The maximum lines number of each raster block to process.
#define TERP_LOG_AND_THROW(message)
Logs a error message and throws.
Definition: Macros.h:138
unsigned long int GetUsedVirtualMemory()
Returns the amount of used virtual memory (bytes) for the current process (physical + swapped)...
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
Definition: Index.h:326
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
Definition: Index.h:313
unsigned long int GetTotalVirtualMemory()
Returns the amount of total virtual memory (bytes) that can be claimed by the current process (physic...
static float getSurfDxyDerivative(float **bufferPtr, const unsigned int &centerX, const unsigned int &centerY, const unsigned int &lobeWidth)
Return a SURF box filter Dxy derivative centered over the given position from the given integral imag...
unsigned int m_raster1TargetAreaWidth
The raster 1 target area width (default:0 - The entire raster will be considered).
UCharsMatrix const * m_maskRasterDataPtr
The loaded mask raster data pointer (or zero if no mask is avaliable).
2D Geometric transformation parameters.
Definition: GTParameters.h:50
AbstractParameters * clone() const
Create a clone copy of this instance.
std::pair< Coord2D, Coord2D > TiePoint
Tie point type definition.
Definition: GTParameters.h:59
te::rst::Raster const * m_inRaster1Ptr
Input raster 1.
bool m_enableMultiThread
Enable/Disable the use of multi-threads (default:true).
unsigned int m_maxTiePoints
The maximum number of tie-points to generate (default=0 - Automatically found).
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
Near neighborhood interpolation method.
Definition: Interpolator.h:60
unsigned int m_surfScalesNumber
The number of sub-sampling scales to generate, when applicable (default:4, minimum:3).
unsigned int m_raster1TargetAreaHeight
The raster 1 target area height (default:0 - The entire raster will be considered).
MemoryPolicy getMemPolicy() const
Returns the current memory policy.
Definition: Matrix.h:711
double m_rastersRescaleFactor
Global rescale factor to apply to all input rasters (default:1, valid range: non-zero positive values...
Green channel color interpretation.
Definition: Enums.h:60
#define MAX(a, b)
Macro that returns max between two values.
te::rst::Raster const * m_inRaster2Ptr
Input raster 2.
std::multiset< MatchedInterestPointsT > MatchedInterestPointsSetT
The parameters passed to the moravecLocatorThreadEntry method.
FloatsMatrix const * m_rasterDataPtr
The loaded raster data.
unsigned int * m_nextRasterLinesBlockToProcessValuePtr
A pointer to a valid counter to control the blocks processing sequence.
te::common::AccessPolicy getAccessPolicy() const
Returns the raster access policy.
Definition: Raster.cpp:89
static void createTifFromMatrix(const DoublesMatrix &rasterData, const InterestPointsSetT &interestPoints, const std::string &tifFileName)
Moravec interest points locator.
static bool applyGaussianFilter(const DoublesMatrix &inputData, DoublesMatrix &outputData, const unsigned int iterationsNumber)
Gaussian Filter.
TiePointsLocator::InputParameters m_inputParameters
TiePointsLocator input execution parameters.
Raster Processing algorithm input parameters base interface.
bool m_isInitialized
Tells if this instance is initialized.
TiePointsLocator output parameters.
static void executeMatchingByCorrelationThreadEntry(ExecuteMatchingByCorrelationThreadEntryParams *paramsPtr)
Correlation/Euclidean match thread entry.