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