27 #include "../common/progress/TaskProgress.h" 28 #include "../common/MathUtils.h" 35 TiePointsLocatorMoravecStrategyFactoryInstance;
101 const double subSampleOptimizationRescaleFactor,
103 std::unique_ptr< TiePointsLocatorStrategyParameters >& subSampledSpecParamsPtr )
const 110 Parameters* subSampledSpecParamsNakedPtr =
dynamic_cast< Parameters*
>( subSampledSpecParamsPtr.get() );
120 subSampleOptimizationRescaleFactor
133 subSampleOptimizationRescaleFactor
141 std::unique_ptr< TiePointsLocatorStrategyParameters >& defaultSpecParamsPtr )
const 143 defaultSpecParamsPtr.reset(
new Parameters() );
152 == 1,
"Invalid number of raster 1 bands" );
154 == 1,
"Invalid number of raster 2 bands" );
163 "Invalid m_moravecCorrelationWindowWidth (should be an odd number)" );
165 "Invalid m_moravecCorrelationWindowWidth" );
168 "Invalid m_moravecWindowWidth (should be an odd number)" );
170 "Invalid m_moravecWindowWidth" );
173 ( specParsPtr->m_moravecMinAbsCorrelation <= 1.0 ),
174 "Invalid m_moravecMinAbsCorrelation" );
198 const double raster1ToRaster2TransfDMapError,
201 matchedInterestPoints.clear();
211 double raster1XRescFact = 1.0;
212 double raster1YRescFact = 1.0;
213 double raster2XRescFact = 1.0;
214 double raster2YRescFact = 1.0;
267 const double area1 = width1 * height1;
268 const double area2 = width2 * height2;
272 maxInterestPoints1 = (
unsigned int)( ((
double)maxInterestPoints1)*( area1 / area2 ) );
276 maxInterestPoints2 = (
unsigned int)( ((
double)maxInterestPoints2)*( area2 / area1 ) );
282 std::unique_ptr< te::common::TaskProgress > progressPtr;
286 progressPtr->setTotalSteps( 11 );
287 progressPtr->setMessage(
"Locating tie points" );
288 progressPtr->pulse();
289 if( ! progressPtr->isActive() )
return false;
298 std::vector< boost::shared_ptr< FloatsMatrix > > raster1Data;
300 double achievedRescaleFactorX = 0;
301 double achievedRescaleFactorY = 0;
318 achievedRescaleFactorX,
319 achievedRescaleFactorY ) )
324 raster1XRescFact = achievedRescaleFactorX;
325 raster1YRescFact = achievedRescaleFactorY;
331 progressPtr->pulse();
332 if( ! progressPtr->isActive() )
return false;
339 boost::shared_ptr< FloatsMatrix > tempMatrix(
342 "Cannot allocate image matrix" );
351 raster1Data[ 0 ]->reset();
352 raster1Data[ 0 ] = tempMatrix;
359 progressPtr->pulse();
360 if( ! progressPtr->isActive() )
return false;
369 raster1InterestPoints ) )
383 progressPtr->pulse();
384 if( ! progressPtr->isActive() )
return false;
393 raster1InterestPoints,
398 "Error generating raster 1 features" );
404 raster1InterestPoints.clear();
407 InterestPointsSetT::iterator itB = auxInterestPoints.begin();
408 const InterestPointsSetT::iterator itE = auxInterestPoints.end();
414 auxIP.
m_x =
static_cast<unsigned int>((auxIP.
m_x / raster1XRescFact) +
416 auxIP.
m_y =
static_cast<unsigned int>((auxIP.
m_y / raster1YRescFact) +
419 raster1InterestPoints.insert( auxIP );
427 progressPtr->pulse();
428 if( ! progressPtr->isActive() )
return false;
439 std::vector< boost::shared_ptr< FloatsMatrix > > raster2Data;
441 double achievedRescaleFactorX = 0;
442 double achievedRescaleFactorY = 0;
459 achievedRescaleFactorX,
460 achievedRescaleFactorY ) )
465 raster2XRescFact = achievedRescaleFactorX;
466 raster2YRescFact = achievedRescaleFactorY;
470 progressPtr->pulse();
471 if( ! progressPtr->isActive() )
return false;
478 boost::shared_ptr< FloatsMatrix > tempMatrix(
484 "Cannot allocate image matrix" );
492 raster2Data[ 0 ] = tempMatrix;
499 progressPtr->pulse();
500 if( ! progressPtr->isActive() )
return false;
509 raster2InterestPoints ) )
523 progressPtr->pulse();
524 if( ! progressPtr->isActive() )
return false;
533 raster2InterestPoints,
538 "Error generating raster 2 features" );
545 raster2InterestPoints.clear();
548 InterestPointsSetT::iterator itB = auxInterestPoints.begin();
549 const InterestPointsSetT::iterator itE = auxInterestPoints.end();
555 auxIP.
m_x =
static_cast<unsigned int>((auxIP.
m_x / raster2XRescFact) +
557 auxIP.
m_y =
static_cast<unsigned int>((auxIP.
m_y / raster2YRescFact) +
560 raster2InterestPoints.insert( auxIP );
568 progressPtr->pulse();
569 if( ! progressPtr->isActive() )
return false;
580 raster1InterestPoints,
581 raster2InterestPoints,
582 raster1ToRaster2TransfPtr,
583 raster1ToRaster2TransfDMapError,
584 internalMatchedInterestPoints ),
585 "Error matching features" );
589 progressPtr->pulse();
590 if( ! progressPtr->isActive() )
return false;
595 raster1Features.
reset();
596 raster2Features.
reset();
597 raster1InterestPoints.clear();
598 raster2InterestPoints.clear();
604 MatchedInterestPointsSetT::const_iterator itB = internalMatchedInterestPoints.begin();
605 const MatchedInterestPointsSetT::const_iterator itE = internalMatchedInterestPoints.end();
607 float minFeatureValue1 = FLT_MAX;
608 float maxFeatureValue1 = (-1.0) * FLT_MAX;
609 float minFeatureValue2 = FLT_MAX;
610 float maxFeatureValue2 = (-1.0) * FLT_MAX;
611 float minCorrelationValue = FLT_MAX;
612 float maxCorrelationValue = (-1.0) * FLT_MAX;
614 itB = internalMatchedInterestPoints.begin();
617 if( minFeatureValue1 > itB->m_point1.m_feature1 )
619 if( maxFeatureValue1 < itB->m_point1.m_feature1 )
620 maxFeatureValue1 = itB->m_point1.m_feature1;
622 if( minFeatureValue2 > itB->m_point2.m_feature1 )
623 minFeatureValue2 = itB->m_point2.m_feature1;
624 if( maxFeatureValue2 < itB->m_point2.m_feature1 )
625 maxFeatureValue2 = itB->m_point2.m_feature1;
627 if( minCorrelationValue > itB->m_feature )
628 minCorrelationValue = itB->m_feature;
629 if( maxCorrelationValue < itB->m_feature )
630 maxCorrelationValue = itB->m_feature;
635 float featureValue1Range = maxFeatureValue1 - minFeatureValue1;
636 float featureValue2Range = maxFeatureValue2 - minFeatureValue2;
637 float correlationValueRange = maxCorrelationValue - minCorrelationValue;
639 if( ( featureValue1Range == 0.0 ) || ( featureValue2Range == 0.0 ) ||
640 ( correlationValueRange == 0.0 ) )
642 itB = internalMatchedInterestPoints.begin();
646 auxMatchedPoints = *itB;
648 matchedInterestPoints.insert( auxMatchedPoints );
655 itB = internalMatchedInterestPoints.begin();
659 auxMatchedPoints = *itB;
663 ( auxMatchedPoints.
m_feature - minCorrelationValue )
665 correlationValueRange
681 static_cast<float>(3.0);
683 matchedInterestPoints.insert( auxMatchedPoints );
692 progressPtr->pulse();
693 if( ! progressPtr->isActive() )
return false;
703 unsigned int returnValue = 0;
705 const unsigned int maxRastersArea = (
unsigned int)
728 returnValue = maxRastersArea /
737 const double freeVMem = 0.75 * std::min( totalPhysMem, ( totalVMem - usedVMem ) );
739 const double featureElementsNumber = (double)(
743 double maxFeaturesMemory =
748 (-2.0) * featureElementsNumber
751 ( 4.0 * featureElementsNumber * featureElementsNumber )
753 ( 4.0 * freeVMem / ((
double)
sizeof(
float ) ) )
762 (-2.0) * featureElementsNumber
765 ( 4.0 * featureElementsNumber * featureElementsNumber )
767 ( 4.0 * freeVMem / ((
double)
sizeof(
float ) ) )
772 returnValue = std::min( returnValue, (
unsigned int)maxFeaturesMemory );
778 FloatsMatrix& outputData,
const unsigned int iterationsNumber )
780 if( iterationsNumber == 0 )
782 outputData = inputData;
800 const unsigned int lastLineIndex = nLines - 1;
801 const unsigned int lastColIndex = nCols - 1;
802 unsigned int currLine = 0;
803 unsigned int currCol = 0;
809 if( iterationsNumber > 1 )
813 "Cannot allocate image matrix" );
818 for( currLine = 0 ; currLine <
nLines ; ++currLine ) {
819 outputData( currLine, 0 ) = 0.0;
820 outputData( currLine, lastColIndex ) = 0.0;
823 for( currCol = 0 ; currCol <
nCols ; ++currCol ) {
824 outputData( 0, currCol ) = 0.0;
825 outputData( lastLineIndex, currCol ) = 0.0;
833 float* outputLinePtr =
nullptr;
834 unsigned int prevLine = 0;
835 unsigned int prevCol = 0;
836 unsigned int nextLine = 0;
837 unsigned int nextCol = 0;
839 for(
unsigned int iteration = 0 ; iteration < iterationsNumber ;
844 inputPtr = &inputData;
846 if( iterationsNumber > 1 )
847 outputPtr = &tempMatrix;
849 outputPtr = &outputData;
851 else if( iteration == iterationsNumber - 1 )
853 inputPtr = outputPtr;
854 outputPtr = &outputData;
859 inputPtr = outputPtr;
865 for( currLine = 1 ; currLine < lastLineIndex ; ++currLine )
867 prevLine = currLine - 1;
868 nextLine = currLine + 1;
870 outputLinePtr = outputPtr->operator[]( currLine );
872 for( currCol = 1 ; currCol < lastColIndex ; ++currCol )
874 prevCol = currCol - 1;
875 nextCol = currCol + 1;
877 outputLinePtr[ currCol ] =
879 internalInputMatrix( prevLine, prevCol )
880 + internalInputMatrix( prevLine, currCol )
881 + internalInputMatrix( prevLine, nextCol )
882 + internalInputMatrix( currLine, prevCol )
883 + internalInputMatrix( currLine, nextCol )
884 + internalInputMatrix( nextLine, prevCol )
885 + internalInputMatrix( nextLine, currCol )
886 + internalInputMatrix( nextLine, nextCol )
897 const unsigned int maxInterestPoints,
902 interestPoints.clear();
904 const unsigned int minRasterWidthAndHeight =
908 if( rasterData.
getLinesNumber() < minRasterWidthAndHeight )
return true;
910 bool returnValue =
true;
911 boost::mutex rastaDataAccessMutex;
912 boost::mutex interestPointsAccessMutex;
913 unsigned int nextRasterLinesBlockToProcess = 0;
914 std::vector< InterestPointsSetT > interestPointsSubSectors(
923 &nextRasterLinesBlockToProcess;
937 boost::thread_group threads;
942 threads.add_thread(
new boost::thread(
957 const unsigned int interestPointsSubSectorsSize =
static_cast<unsigned int>(interestPointsSubSectors.size());
959 for(
unsigned int interestPointsSubSectorsIdx = 0 ; interestPointsSubSectorsIdx <
960 interestPointsSubSectorsSize ; ++interestPointsSubSectorsIdx )
962 interestPoints.insert(
963 interestPointsSubSectors[ interestPointsSubSectorsIdx ].begin(),
964 interestPointsSubSectors[ interestPointsSubSectorsIdx ].end() );
987 const unsigned int moravecWindowRadius = moravecWindowWidth / 2;
989 const unsigned int rowsBySubSector = (
unsigned int)std::ceil(
992 ((
double)tiePointsSubSectorsSplitFactor) );
993 const unsigned int colsBySubSector = (
unsigned int)std::ceil(
996 ((
double)tiePointsSubSectorsSplitFactor) );
999 const unsigned int lastBufferLineIdx = moravecWindowWidth - 1;
1001 const unsigned int rasterBufferLineSizeBytes =
sizeof(
1003 const unsigned int maskRasterBufferLineSizeBytes =
sizeof(
1007 const unsigned int maxLinesPerProcessingBlock = (
unsigned int)
1009 ((
double)rasterLines)
1011 ((
double)processingBlocksNumber)
1020 if( ! rasterBufferDataHandler.
reset( moravecWindowWidth, bufferCols,
1029 boost::scoped_array< float* > rasterBufferHandler(
new float*[ moravecWindowWidth ] );
1030 for(
unsigned int rasterBufferDataHandlerLine = 0 ; rasterBufferDataHandlerLine <
1031 moravecWindowWidth ; ++rasterBufferDataHandlerLine )
1033 rasterBufferHandler[ rasterBufferDataHandlerLine ] = rasterBufferDataHandler[
1034 rasterBufferDataHandlerLine ];
1037 float** rasterBufferPtr = rasterBufferHandler.get();
1043 boost::scoped_array< unsigned char* > maskRasterBufferHandler(
new unsigned char*[ moravecWindowWidth ] );
1045 unsigned char** maskRasterBufferPtr =
nullptr;
1049 if( ! maskRasterBufferDataHandler.
reset( moravecWindowWidth, bufferCols,
1058 for(
unsigned int maskRasterBufferDataHandlerLine = 0 ; maskRasterBufferDataHandlerLine <
1059 moravecWindowWidth ; ++maskRasterBufferDataHandlerLine )
1061 maskRasterBufferHandler[ maskRasterBufferDataHandlerLine ] = maskRasterBufferDataHandler[
1062 maskRasterBufferDataHandlerLine ];
1065 maskRasterBufferPtr = maskRasterBufferHandler.get();
1071 if( ! maximasBufferDataHandler.
reset( moravecWindowWidth, bufferCols,
1080 boost::scoped_array< float* > maximasBufferHandler(
new float*[ moravecWindowWidth ] );
1081 float** maximasBufferPtr = maximasBufferHandler.get();
1082 unsigned int bufferCol = 0;
1083 for(
unsigned int maximasBufferDataHandlerLine = 0 ; maximasBufferDataHandlerLine <
1084 moravecWindowWidth ; ++maximasBufferDataHandlerLine )
1086 maximasBufferHandler[ maximasBufferDataHandlerLine ] = maximasBufferDataHandler[
1087 maximasBufferDataHandlerLine ];
1088 for( bufferCol = 0 ; bufferCol < bufferCols ; ++bufferCol )
1090 maximasBufferPtr[ maximasBufferDataHandlerLine ][ bufferCol ] = 0;
1096 std::vector< InterestPointsSetT > interestPointsSubSectors(
1100 for(
unsigned int rasterLinesBlockIdx = 0; rasterLinesBlockIdx <
1101 processingBlocksNumber ; ++rasterLinesBlockIdx )
1113 const unsigned int rasterLinesStart =
1119 (
int)(rasterLinesBlockIdx * maxLinesPerProcessingBlock )
1121 (
int)( 2 * moravecWindowRadius )
1124 const unsigned int rasterLinesEndBound =
1130 ( rasterLinesBlockIdx + 1 )
1132 maxLinesPerProcessingBlock
1135 ( 2 * moravecWindowRadius )
1138 const unsigned int varianceCalcStartRasterLineStart = rasterLinesStart +
1139 moravecWindowRadius;
1140 const unsigned int maximasLocationStartRasterLineStart = rasterLinesStart +
1141 4 * moravecWindowRadius;
1142 unsigned int windowStartBufCol = 0;
1143 const unsigned int windowEndBufColsBound = bufferCols -
1145 unsigned int windowStartBufOffset = 0;
1146 unsigned int windowStartBufXOffset = 0;
1147 unsigned int windowStartBufYOffset = 0;
1152 float diffValue = 0;
1153 bool isLocalMaxima =
false;
1155 float neighborMaximaDif = 0;
1156 unsigned int interestPointsSubSectorsIdx = 0;
1158 for(
unsigned int rasterLine = rasterLinesStart; rasterLine < rasterLinesEndBound ;
1166 memcpy( rasterBufferPtr[ lastBufferLineIdx ],
1168 rasterBufferLineSizeBytes );
1173 roolUpBuffer( maskRasterBufferPtr, moravecWindowWidth );
1174 memcpy( maskRasterBufferPtr[ lastBufferLineIdx ],
1176 maskRasterBufferLineSizeBytes );
1183 if( rasterLine >= varianceCalcStartRasterLineStart )
1187 for( windowStartBufCol = 0 ; windowStartBufCol < windowEndBufColsBound ;
1188 ++windowStartBufCol )
1190 const float& windowCenterPixelValue = rasterBufferPtr[
1191 moravecWindowRadius ][ windowStartBufCol +
1192 moravecWindowRadius ];
1198 for( windowStartBufOffset = 0 ; windowStartBufOffset <
1199 moravecWindowWidth ; ++windowStartBufOffset )
1201 diffValue = windowCenterPixelValue - rasterBufferPtr[
1202 moravecWindowRadius ][ windowStartBufCol +
1203 windowStartBufOffset ];
1204 horVar += ( diffValue * diffValue );
1206 diffValue = windowCenterPixelValue - rasterBufferPtr[
1207 windowStartBufOffset ][ windowStartBufCol +
1208 moravecWindowRadius ];
1209 verVar += ( diffValue * diffValue );
1211 diffValue = windowCenterPixelValue - rasterBufferPtr[
1212 windowStartBufOffset ][ windowStartBufCol +
1213 windowStartBufOffset ];
1214 diagVar += ( diffValue * diffValue );
1216 diffValue = windowCenterPixelValue - rasterBufferPtr[
1217 moravecWindowWidth - 1 - windowStartBufOffset ][ windowStartBufCol +
1218 windowStartBufOffset ];
1219 adiagVar += ( diffValue * diffValue );
1222 maximasBufferPtr[ lastBufferLineIdx ][ windowStartBufCol +
1223 moravecWindowRadius ] = std::min( horVar, std::min(
1224 verVar, std::min( diagVar, adiagVar ) ) );
1230 if( rasterLine >= maximasLocationStartRasterLineStart )
1232 for( windowStartBufCol = 0 ; windowStartBufCol < windowEndBufColsBound ;
1233 ++windowStartBufCol )
1235 isLocalMaxima =
true;
1236 const float& windowCenterPixelValue = maximasBufferPtr[
1237 moravecWindowRadius ][ windowStartBufCol +
1238 moravecWindowRadius ];
1241 for( windowStartBufYOffset = 0 ; windowStartBufYOffset <
1242 moravecWindowWidth ; ++windowStartBufYOffset )
1244 for( windowStartBufXOffset = 0 ; windowStartBufXOffset <
1245 moravecWindowWidth ; ++windowStartBufXOffset )
1247 neighborMaximaDif = windowCenterPixelValue - maximasBufferPtr[
1248 windowStartBufYOffset ][ windowStartBufCol +
1249 windowStartBufXOffset ];
1251 if( neighborMaximaDif < 0.0 )
1253 isLocalMaxima =
false;
1254 windowStartBufYOffset = moravecWindowWidth;
1258 auxInterestPoint.
m_feature1 += std::abs( neighborMaximaDif );
1264 auxInterestPoint.
m_x = windowStartBufCol +
1265 moravecWindowRadius;
1266 auxInterestPoint.
m_y = rasterLine - ( 2 * moravecWindowRadius );
1267 assert( auxInterestPoint.
m_x <
1269 assert( auxInterestPoint.
m_y <
1273 ( maskRasterBufferPtr ==
nullptr )
1275 ( maskRasterBufferPtr[ 0 ][ auxInterestPoint.
m_x ] )
1278 interestPointsSubSectorsIdx = ( ( auxInterestPoint.
m_y /
1279 rowsBySubSector ) * tiePointsSubSectorsSplitFactor ) +
1280 ( auxInterestPoint.
m_x / colsBySubSector );
1281 assert( interestPointsSubSectorsIdx < interestPointsSubSectors.size() );
1283 interestPointsSubSectors[ interestPointsSubSectorsIdx ].insert(
1286 if( interestPointsSubSectors[ interestPointsSubSectorsIdx ].size() >
1287 maxInterestPointsBySubSector )
1289 interestPointsSubSectors[ interestPointsSubSectorsIdx ].erase(
1290 interestPointsSubSectors[ interestPointsSubSectorsIdx ].begin() );
1310 for(
unsigned int interestPointsSubSectorsIdx = 0 ; interestPointsSubSectorsIdx <
1311 interestPointsSubSectors.size() ; ++interestPointsSubSectorsIdx )
1314 interestPointsSubSectorsIdx ).
insert(
1315 interestPointsSubSectors[ interestPointsSubSectorsIdx ].begin(),
1316 interestPointsSubSectors[ interestPointsSubSectorsIdx ].end() );
1319 interestPointsSubSectorsIdx ).size() >
1320 maxInterestPointsBySubSector )
1323 interestPointsSubSectorsIdx ).erase(
1325 interestPointsSubSectorsIdx ).begin() );
1335 const unsigned int correlationWindowWidth,
1340 validInteresPoints.clear();
1345 const unsigned int rotated90CorralationWindowRadius = (
unsigned int)
1352 ( (
double)correlationWindowWidth )
1354 ( (
double)correlationWindowWidth )
1367 const unsigned int rasterDataLines = rasterData.
getLinesNumber();
1368 const unsigned int firstValidInterestPointX =
1369 rotated90CorralationWindowRadius + 1;
1370 const unsigned int lastValidInterestPointX = rasterDataCols
1371 - rotated90CorralationWindowRadius - 2;
1372 const unsigned int firstValidInterestPointY =
1373 rotated90CorralationWindowRadius + 1;
1374 const unsigned int lastValidInterestPointY = rasterDataLines
1375 - rotated90CorralationWindowRadius - 2;
1378 InterestPointsSetT::const_iterator iPointsIt = interestPoints.begin();
1379 const InterestPointsSetT::const_iterator iPointsItEnd = interestPoints.end();
1381 while( iPointsIt != iPointsItEnd )
1383 if( ( iPointsIt->m_x >= firstValidInterestPointX ) &&
1384 ( iPointsIt->m_x <= lastValidInterestPointX ) &&
1385 ( iPointsIt->m_y >= firstValidInterestPointY ) &&
1386 ( iPointsIt->m_y <= lastValidInterestPointY ) )
1388 validInteresPoints.insert( *iPointsIt );
1398 const unsigned int featureElemsNmb = correlationWindowWidth *
1399 correlationWindowWidth;
1400 const unsigned int featureSizeBytes =
sizeof( float ) *
1404 static_cast<unsigned int>(validInteresPoints.size()), featureElemsNmb),
1405 "Cannot allocate features matrix" );
1409 boost::scoped_array< float > auxFeatureBufferHandler(
1410 new float[ featureElemsNmb ] );
1411 float* auxFeatureBufferPtr = auxFeatureBufferHandler.get();
1415 unsigned int curr_window_x_start = 0;
1416 unsigned int curr_window_y_start = 0;
1417 unsigned int curr_window_x_center = 0;
1418 unsigned int curr_window_y_center = 0;
1419 unsigned int curr_window_x_end = 0;
1420 unsigned int curr_window_y_end = 0;
1421 const unsigned int wind_radius = correlationWindowWidth / 2;
1422 const float wind_radius_double = (float)wind_radius;
1423 unsigned int curr_x = 0;
1424 unsigned int curr_y = 0;
1425 float curr_x_minus_radius = 0;
1426 float curr_y_minus_radius = 0;
1427 unsigned int curr_offset = 0;
1428 float int_x_dir = 0;
1429 float int_y_dir = 0;
1431 float rotated_curr_x = 0;
1432 float rotated_curr_y = 0;
1435 unsigned int rotated_curr_x_img = 0;
1436 unsigned int rotated_curr_y_img = 0;
1437 float featureElementsNormalizeFactor = 0.0;
1438 unsigned int featureElementIdx = 0;
1439 float* featurePtr =
nullptr;
1440 float featureElementValue = 0.0;
1441 float featureElementMaxValue = 0.0;
1442 float featureElementMinValue = 0.0;
1444 InterestPointsSetT::const_iterator viPointsIt = validInteresPoints.begin();
1445 const InterestPointsSetT::const_iterator viPointsItEnd = validInteresPoints.end();
1446 unsigned int validInteresPointsIndex = 0 ;
1448 while( viPointsIt != viPointsItEnd )
1452 curr_window_x_center = viPointsIt->m_x;
1453 assert( curr_window_x_center >= rotated90CorralationWindowRadius );
1455 rotated90CorralationWindowRadius ) );
1456 curr_window_y_center = viPointsIt->m_y;
1457 assert( curr_window_y_center >= rotated90CorralationWindowRadius );
1458 assert( curr_window_y_center < ( rasterData.
getLinesNumber() - 1 -
1459 rotated90CorralationWindowRadius ) );
1461 curr_window_x_start = curr_window_x_center - wind_radius;
1462 curr_window_y_start = curr_window_y_center - wind_radius;
1463 curr_window_x_end = curr_window_x_start + correlationWindowWidth - 1;
1464 curr_window_y_end = curr_window_y_start + correlationWindowWidth - 1;
1470 for( curr_y = curr_window_y_start ; curr_y <= curr_window_y_end ;
1473 for( curr_offset = 0 ; curr_offset < wind_radius ;
1476 int_x_dir += rasterData( curr_y, curr_window_x_end - curr_offset ) -
1477 rasterData( curr_y, curr_window_x_start + curr_offset );
1485 for( curr_x = curr_window_x_start ; curr_x <= curr_window_x_end ;
1488 for( curr_offset = 0 ; curr_offset < wind_radius ; ++curr_offset )
1490 int_y_dir += rasterData( curr_window_y_start + curr_offset, curr_x ) -
1491 rasterData( curr_window_y_end - curr_offset, curr_x );
1497 int_norm = std::sqrt( ( int_x_dir * int_x_dir ) +
1498 ( int_y_dir * int_y_dir ) );
1500 if( int_norm != 0.0 ) {
1501 rot_cos = int_x_dir / int_norm;
1502 rot_sin = int_y_dir / int_norm;
1509 assert( ( rot_cos >= -1.0 ) && ( rot_cos <= 1.0 ) );
1510 assert( ( rot_sin >= -1.0 ) && ( rot_sin <= 1.0 ) );
1525 memset( auxFeatureBufferPtr, 0, featureSizeBytes );
1526 featureElementIdx = 0;
1527 featureElementMaxValue = -1.0 * FLT_MAX;
1528 featureElementMinValue = FLT_MAX;
1530 for( curr_y = 0 ; curr_y < correlationWindowWidth ; ++curr_y )
1532 for( curr_x = 0 ; curr_x < correlationWindowWidth ; ++curr_x )
1536 curr_x_minus_radius = ((float)curr_x) -
1538 curr_y_minus_radius = ((float)curr_y) -
1544 ( rot_cos * curr_x_minus_radius ) +
1545 ( rot_sin * curr_y_minus_radius );
1548 ( rot_cos * curr_y_minus_radius )
1549 - ( rot_sin * curr_x_minus_radius );
1554 rotated_curr_x += wind_radius_double;
1555 rotated_curr_y += wind_radius_double;
1559 rotated_curr_x_img = curr_window_x_start +
1560 (
unsigned int)te::common::Round< float, unsigned int >( rotated_curr_x );
1561 rotated_curr_y_img = curr_window_y_start +
1562 (
unsigned int)te::common::Round< float, unsigned int >( rotated_curr_y );
1564 featureElementValue = rasterData( rotated_curr_y_img,
1565 rotated_curr_x_img );
1567 auxFeatureBufferPtr[ featureElementIdx++ ] = featureElementValue;
1569 if( featureElementMaxValue < featureElementValue )
1570 featureElementMaxValue = featureElementValue;
1572 if( featureElementMinValue > featureElementValue )
1573 featureElementMinValue = featureElementValue;
1580 if( featureElementMaxValue == featureElementMinValue )
1581 featureElementsNormalizeFactor = 0.0;
1583 featureElementsNormalizeFactor = 1.0f / ( featureElementMaxValue -
1584 featureElementMinValue );
1586 featurePtr = features[ validInteresPointsIndex ];
1588 for( featureElementIdx = 0 ; featureElementIdx < featureElemsNmb ;
1589 ++featureElementIdx )
1591 featurePtr[ featureElementIdx ] = (
1592 ( auxFeatureBufferPtr[ featureElementIdx ] - featureElementMinValue )
1593 * featureElementsNormalizeFactor );
1594 assert( featurePtr[ featureElementIdx ] >= 0.0 );
1595 assert( featurePtr[ featureElementIdx ] <= 1.0 );
1598 ++validInteresPointsIndex;
1611 const double raster1ToRaster2TransfDMapError,
1614 matchedPoints.clear();
1616 const unsigned int interestPointsSet1Size =
static_cast<unsigned int>(interestPointsSet1.size());
1617 if( interestPointsSet1Size == 0 )
return true;
1619 const unsigned int interestPointsSet2Size =
static_cast<unsigned int>(interestPointsSet2.size());
1620 if( interestPointsSet2Size == 0 )
return true;
1623 assert( featuresSet1.
getLinesNumber() == interestPointsSet1Size );
1624 assert( featuresSet2.
getLinesNumber() == interestPointsSet2Size );
1628 InterestPointsSetT::const_iterator it1 = interestPointsSet1.begin();
1629 boost::scoped_array< InterestPointT > internalInterestPointsSet1(
1631 for(
unsigned int idx1 = 0 ; idx1 < interestPointsSet1Size ; ++idx1 )
1633 internalInterestPointsSet1[ idx1 ] = *it1;
1638 InterestPointsSetT::const_iterator it2 = interestPointsSet2.begin();
1639 boost::scoped_array< InterestPointT > internalInterestPointsSet2(
1641 for(
unsigned int idx2 = 0 ; idx2 < interestPointsSet2Size ; ++idx2 )
1643 internalInterestPointsSet2[ idx2 ] = *it2;
1653 "Error crearting the correlation matrix" );
1655 unsigned int col = 0;
1656 unsigned int line = 0;
1657 float* linePtr =
nullptr;
1659 for( line = 0 ; line < interestPointsSet1Size ; ++
line )
1661 linePtr = corrMatrix[
line ];
1663 for( col = 0 ; col < interestPointsSet2Size ; ++
col )
1669 boost::mutex syncMutex;
1670 unsigned int nextFeatureIdx1ToProcess = 0;
1692 boost::thread_group threads;
1694 for(
unsigned int threadIdx = 0 ; threadIdx < procsNumber ;
1697 threads.add_thread(
new boost::thread(
1711 std::vector< float > eachLineMaxABSValues( interestPointsSet1Size,
1713 std::vector< unsigned int > eachLineMaxABSIndexes( interestPointsSet1Size,
1714 interestPointsSet2Size );
1715 std::vector< float > eachColMaxABSValues( interestPointsSet2Size,
1717 std::vector< unsigned int > eachColMaxABSIndexes( interestPointsSet2Size,
1718 interestPointsSet1Size );
1720 const double moravecMinAbsCorrelation =
1723 for( line = 0 ; line < interestPointsSet1Size ; ++
line )
1725 linePtr = corrMatrix[
line ];
1727 for( col = 0 ; col < interestPointsSet2Size ; ++
col )
1729 absValue = std::abs( linePtr[ col ] );
1731 if( absValue >= moravecMinAbsCorrelation )
1733 if( absValue > eachLineMaxABSValues[ line ] )
1735 eachLineMaxABSValues[
line ] = absValue;
1736 eachLineMaxABSIndexes[
line ] =
col;
1739 if( absValue > eachColMaxABSValues[ col ] )
1741 eachColMaxABSValues[
col ] = absValue;
1742 eachColMaxABSIndexes[
col ] =
line;
1752 for( line = 0 ; line < interestPointsSet1Size ; ++
line )
1754 col = eachLineMaxABSIndexes[
line ];
1756 if( ( col < interestPointsSet2Size ) &&
1757 ( eachColMaxABSIndexes[ col ] == line ) )
1759 auxMatchedPoints.
m_point1 = internalInterestPointsSet1[
line ];
1760 auxMatchedPoints.
m_point2 = internalInterestPointsSet2[
col ];
1761 auxMatchedPoints.
m_feature = std::abs( corrMatrix( line, col ) );
1763 matchedPoints.insert( auxMatchedPoints );
1784 unsigned int feat2Idx = 0;
1785 float const* feat1Ptr =
nullptr;
1786 float const* feat2Ptr =
nullptr;
1787 float* corrMatrixLinePtr =
nullptr;
1788 unsigned int featCol = 0;
1792 float ccorrelation = 0;
1797 std::unique_ptr< te::gm::GeometricTransformation > raster1ToRaster2TransfPtr;
1807 const unsigned int featuresSet1Size =
1809 const unsigned int featuresSet2Size =
1814 std::vector< unsigned int > selectedFeaturesSet2Indexes;
1815 unsigned int selectedFeaturesSet2IndexesSize = 0;
1819 for(
unsigned int feat2Idx = 0 ; feat2Idx < featuresSet2Size ; ++feat2Idx )
1821 interestPointsSet2RTree.
insert(
1832 selectedFeaturesSet2Indexes.resize( featuresSet2Size );
1833 selectedFeaturesSet2IndexesSize = featuresSet2Size;
1834 for(
unsigned int feat2Idx = 0 ; feat2Idx < featuresSet2Size ; ++feat2Idx )
1836 selectedFeaturesSet2Indexes[ feat2Idx ] = feat2Idx;
1842 for(
unsigned int feat1Idx = 0 ; feat1Idx < featuresSet1Size ; ++feat1Idx )
1854 raster1ToRaster2TransfPtr->directMap(
1858 auxEnvelope.
m_lly );
1863 auxEnvelope.
m_llx -= interestPointsSet2RTreeSearchRadius;
1864 auxEnvelope.
m_lly -= interestPointsSet2RTreeSearchRadius;
1865 auxEnvelope.
m_urx += interestPointsSet2RTreeSearchRadius;
1866 auxEnvelope.
m_ury += interestPointsSet2RTreeSearchRadius;
1868 selectedFeaturesSet2Indexes.clear();
1869 interestPointsSet2RTree.
search( auxEnvelope,
1870 selectedFeaturesSet2Indexes );
1872 selectedFeaturesSet2IndexesSize =
static_cast<unsigned int>(selectedFeaturesSet2Indexes.size());
1875 corrMatrixLinePtr = paramsPtr->
m_corrMatrixPtr->operator[]( feat1Idx );
1879 for(
unsigned int selectedFSIIdx = 0 ; selectedFSIIdx <
1880 selectedFeaturesSet2IndexesSize ; ++selectedFSIIdx )
1882 feat2Idx = selectedFeaturesSet2Indexes[ selectedFSIIdx ];
1888 for( featCol = 0 ; featCol < featureElementsNmb ; ++featCol )
1890 sumAA += feat1Ptr[ featCol ] * feat1Ptr[ featCol ];
1891 sumBB += feat2Ptr[ featCol ] * feat2Ptr[ featCol ];
1894 cc_norm = std::sqrt( sumAA * sumBB );
1896 if( cc_norm == 0.0 )
1898 corrMatrixLinePtr[ feat2Idx ] = 0;
1903 for( featCol = 0 ; featCol < featureElementsNmb ; ++featCol )
1905 ccorrelation += ( feat1Ptr[ featCol ] * feat2Ptr[ featCol ] ) /
1909 corrMatrixLinePtr[ feat2Idx ] = ccorrelation;
te::rp::TiePointsLocatorInputParameters m_inputParameters
Input parameters.
std::vector< InterestPointsSetT > * m_interestPointsSubSectorsPtr
A pointer to a valid interest points container (one element by subsector)..
TiePointsLocatorMoravecStrategy()
TECOMMONEXPORT unsigned long long int GetTotalVirtualMemory()
Returns the amount of total virtual memory (bytes) that can be claimed by the current process (physic...
void reset()
Clear all internal allocated resources and go back to the initial not-initialized state...
A class that represents an R-tree.
Base exception class for plugin module.
unsigned int m_y
Point Y coord.
FloatsMatrix const * m_featuresSet2Ptr
static bool applyMeanFilter(const FloatsMatrix &inputData, FloatsMatrix &outputData, const unsigned int iterationsNumber)
Mean Filter.
unsigned int * m_nextFeatureIdx1ToProcessPtr
bool initialize(const te::rp::TiePointsLocatorInputParameters &inputParameters)
Initialize the strategy.
FloatsMatrix const * m_rasterDataPtr
The loaded raster data.
This class can be used to inform the progress of a task.
Tie-points locator Moravec strategy.
double m_urx
Upper right corner x-coordinate.
unsigned int m_moravecWindowWidth
Thread return value pointer.
unsigned int m_moravecWindowWidth
The Moravec window width used to locate canditate tie-points (minimum 3, default: 21...
float m_feature
Matched interest feature.
~TiePointsLocatorMoravecStrategy()
te::rp::TiePointsLocatorStrategy * build()
Concrete factories (derived from this one) must implement this method in order to create objects...
Moravec tie-points locator strategy factory.
FloatsMatrix const * m_featuresSet1Ptr
void getSubSampledSpecStrategyParams(const double subSampleOptimizationRescaleFactor, const TiePointsLocatorStrategyParameters &inputSpecParams, std::unique_ptr< TiePointsLocatorStrategyParameters > &subSampledSpecParamsPtr) const
Returns a sub-sampled version of the given locator strategy specific input parameters.
te::gm::GeometricTransformation const * m_raster1ToRaster2TransfPtr
A pointer to a transformation direct mapping raster 1 indexed coords into raster 2 indexed coords...
MemoryPolicy getMemPolicy() const
Returns the current memory policy.
unsigned int m_x
Point X coord.
#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...
Tie-Pointsr locator Moravec strategy.
unsigned int unsigned int nCols
static bool generateCorrelationFeatures(const InterestPointsSetT &interestPoints, const unsigned int correlationWindowWidth, const FloatsMatrix &rasterData, FloatsMatrix &features, InterestPointsSetT &validInteresPoints)
Generate correlation features ( normalized - unit vector ) matrix for the given interes points...
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
InterestPointT const * m_interestPointsSet1Ptr
TECOMMONEXPORT unsigned int GetPhysProcNumber()
Returns the number of physical processors.
~TiePointsLocatorMoravecStrategyFactory()
double m_llx
Lower left corner x-coordinate.
unsigned int m_processingBlocksNumber
The raster data will be splitted into this number of blocks for processing.
const Parameters & operator=(const Parameters ¶ms)
TiePointsLocator strategy parameters.
AbstractParameters * clone() const
Create a clone copy of this instance.
An Envelope defines a 2D rectangular region.
InterestPointT const * m_interestPointsSet2Ptr
static void locateMoravecInterestPointsThreadEntry(MoravecLocatorThreadParams *paramsPtr)
Movavec locator thread entry.
unsigned int getColumnsNumber() const
The number of current matrix columns.
mydialect insert("+", new te::da::BinaryOpEncoder("+"))
virtual void reset()
Clear all internal allocated resources and go back to the initial not-initialized state...
TiePointsLocator Moravec strategy parameters.
std::multiset< InterestPointT > InterestPointsSetT
bool m_isInitialized
true if this instance is initialized.
unsigned int m_moravecCorrelationWindowWidth
The correlation window width used to correlate points between the images (minimum 3...
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
unsigned int m_maxInterestPointsBySubSector
The maximum number of interest points by sub-sector.
The parameters passed to the matchCorrelationEuclideanThreadEntry method.
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.
Tie-points locator strategy.
double m_lly
Lower left corner y-coordinate.
bool getMatchedInterestPoints(te::gm::GeometricTransformation const *const raster1ToRaster2TransfPtr, const double raster1ToRaster2TransfDMapError, MatchedInterestPointsSetT &matchedInterestPoints)
Try to find matched interest points.
unsigned int getAutoMaxTiePointsNumber() const
Returns a automatically calculated optimum maximum amount tie-points following the current parameters...
TECOMMONEXPORT unsigned long long int GetTotalPhysicalMemory()
Returns the amount of total physical memory (bytes).
Abstract parameters base interface.
bool locateMoravecInterestPoints(const unsigned int maxInterestPoints, const FloatsMatrix &rasterData, UCharsMatrix const *maskRasterDataPtr, InterestPointsSetT &interestPoints) const
Moravec interest points locator.
static void roolUpBuffer(BufferElementT **bufferPtr, const unsigned int &bufferLinesNumber)
RoolUp a buffer of lines.
unsigned int m_moravecNoiseFilterIterations
The number of noise filter iterations, when applicable (used to remove image noise, zero will disable the noise Filter, default:1).
void getDefaultSpecStrategyParams(std::unique_ptr< TiePointsLocatorStrategyParameters > &defaultSpecParamsPtr) const
Returns a sub-sampled version of the given locator strategy specific input parameters.
TiePointsLocatorMoravecStrategyFactory()
The parameters passed to the moravecLocatorThreadEntry method.
void insert(const te::gm::Envelope &mbr, const DATATYPE &data)
It inserts an item into the tree.
double m_ury
Upper right corner y-coordinate.
unsigned int m_tiePointsSubSectorsSplitFactor
The number of sectors along each direction.
A generic template matrix.
TemplateElementType ElementTypeT
Public matrix element type definition.
InterestPointT m_point2
Interest point 2.
boost::mutex * m_interestPointsAccessMutexPtr
A pointer to a valid mutex to control the output interest points container access.
boost::mutex * m_syncMutexPtr
double m_searchOptTreeSearchRadius
Optimization tree search radius (pixels).
static void executeMatchingByCorrelationThreadEntry(ExecuteMatchingByCorrelationThreadEntryParams *paramsPtr)
Correlation/Euclidean match thread entry.
UCharsMatrix const * m_maskRasterDataPtr
The loaded mask raster data pointer (or zero if no mask is avaliable).
bool executeMatchingByCorrelation(const FloatsMatrix &featuresSet1, const FloatsMatrix &featuresSet2, const InterestPointsSetT &interestPointsSet1, const InterestPointsSetT &interestPointsSet2, te::gm::GeometricTransformation const *const raster1ToRaster2TransfPtr, const double raster1ToRaster2TransfDMapError, MatchedInterestPointsSetT &matchedPoints)
Match each feature using correlation.
Raster tie-points locator strategy factory base class.
TECOMMONEXPORT unsigned long long int GetUsedVirtualMemory()
Returns the amount of used virtual memory (bytes) for the current process (physical + swapped)...
unsigned int * m_nextRasterLinesBlockToProcessValuePtr
A pointer to a valid counter to control the blocks processing sequence.
#define TERP_INSTANCE_TRUE_OR_RETURN_FALSE(value, message)
Checks if value is true. For false values a warning message will be logged, the current instance erro...
unsigned int getLinesNumber() const
The number of current matrix lines.
std::multiset< MatchedInterestPointsT > MatchedInterestPointsSetT
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
double m_moravecMinAbsCorrelation
The minimum acceptable absolute correlation value when matching features (when applicable), default:0.25, valid range: [0,1].
InterestPointT m_point1
Interest point 1.
FloatsMatrix * m_corrMatrixPtr
virtual AbstractParameters * clone() const =0
Create a clone copy of this instance.
float m_feature1
Interest point feature 1 value.
boost::mutex * m_rastaDataAccessMutexPtr
A pointer to a valid mutex to controle raster data access.