27 #include "../common/progress/TaskProgress.h" 28 #include "../sam/rtree.h" 32 #include <boost/shared_array.hpp> 37 TiePointsLocatorSURFStrategyFactoryInstance;
101 const double subSampleOptimizationRescaleFactor,
103 std::unique_ptr< TiePointsLocatorStrategyParameters >& subSampledSpecParamsPtr )
const 110 Parameters* subSampledSpecParamsNakedPtr =
dynamic_cast< Parameters*
>( subSampledSpecParamsPtr.get() );
120 subSampleOptimizationRescaleFactor
129 subSampleOptimizationRescaleFactor
134 std::unique_ptr< TiePointsLocatorStrategyParameters >& defaultSpecParamsPtr )
const 136 defaultSpecParamsPtr.reset(
new Parameters() );
145 == 1,
"Invalid number of raster 1 bands" );
147 == 1,
"Invalid number of raster 2 bands" );
154 "Invalid m_surfScalesNumber" );
157 "Invalid m_surfOctavesNumber" );
160 ( specParsPtr->m_surfMaxNormEuclideanDist <= 1.0 ),
161 "Invalid m_surfMaxNormEuclideanDist" );
185 const double raster1ToRaster2TransfDMapError,
188 matchedInterestPoints.clear();
198 double raster1XRescFact = 1.0;
199 double raster1YRescFact = 1.0;
200 double raster2XRescFact = 1.0;
201 double raster2YRescFact = 1.0;
254 const double area1 = width1 * height1;
255 const double area2 = width2 * height2;
259 maxInterestPoints1 = (
unsigned int)( ((
double)maxInterestPoints1)*( area1 / area2 ) );
263 maxInterestPoints2 = (
unsigned int)( ((
double)maxInterestPoints2)*( area2 / area1 ) );
269 std::unique_ptr< te::common::TaskProgress > progressPtr;
273 progressPtr->setTotalSteps( 10 );
274 progressPtr->setMessage(
"Locating tie points" );
275 progressPtr->pulse();
276 if( ! progressPtr->isActive() )
return false;
286 std::vector< boost::shared_ptr< FloatsMatrix > > rasterData;
288 double achievedRescaleFactorX = 0;
289 double achievedRescaleFactorY = 0;
306 achievedRescaleFactorX,
307 achievedRescaleFactorY ) )
312 raster1XRescFact = achievedRescaleFactorX;
313 raster1YRescFact = achievedRescaleFactorY;
320 progressPtr->pulse();
321 if( ! progressPtr->isActive() )
return false;
329 integralRaster ),
"Integral image creation error" );
335 progressPtr->pulse();
336 if( ! progressPtr->isActive() )
return false;
348 raster1InterestPoints ),
349 "Error locating raster 1 interest points" );
355 progressPtr->pulse();
356 if( ! progressPtr->isActive() )
return false;
363 integralRaster, validInterestPoints, raster1Features ),
364 "Error generating raster features" );
368 raster1InterestPoints.clear();
371 InterestPointsSetT::iterator itB = validInterestPoints.begin();
372 const InterestPointsSetT::iterator itE = validInterestPoints.end();
378 auxIP.
m_x =
static_cast<unsigned int>((auxIP.
m_x / raster1XRescFact) +
380 auxIP.
m_y =
static_cast<unsigned int>((auxIP.
m_y / raster1YRescFact) +
383 raster1InterestPoints.insert( auxIP );
391 progressPtr->pulse();
392 if( ! progressPtr->isActive() )
return false;
404 std::vector< boost::shared_ptr< FloatsMatrix > > rasterData;
406 double achievedRescaleFactorX = 0;
407 double achievedRescaleFactorY = 0;
424 achievedRescaleFactorX,
425 achievedRescaleFactorY ) )
430 raster2XRescFact = achievedRescaleFactorX;
431 raster2YRescFact = achievedRescaleFactorY;
438 progressPtr->pulse();
439 if( ! progressPtr->isActive() )
return false;
447 integralRaster ),
"Integral image creation error" );
451 progressPtr->pulse();
452 if( ! progressPtr->isActive() )
return false;
466 raster2InterestPoints ),
467 "Error locating raster interest points" );
473 progressPtr->pulse();
474 if( ! progressPtr->isActive() )
return false;
480 integralRaster, validInterestPoints, raster2Features ),
481 "Error generating raster features" );
485 raster2InterestPoints.clear();
488 InterestPointsSetT::iterator itB = validInterestPoints.begin();
489 const InterestPointsSetT::iterator itE = validInterestPoints.end();
495 auxIP.
m_x =
static_cast<unsigned int>((auxIP.
m_x / raster2XRescFact) +
497 auxIP.
m_y =
static_cast<unsigned int>((auxIP.
m_y / raster2YRescFact) +
500 raster2InterestPoints.insert( auxIP );
508 progressPtr->pulse();
509 if( ! progressPtr->isActive() )
return false;
523 raster1InterestPoints,
524 raster2InterestPoints,
525 raster1ToRaster2TransfPtr,
526 raster1ToRaster2TransfDMapError,
527 internalMatchedInterestPoints ),
528 "Error matching features" );
532 progressPtr->pulse();
533 if( ! progressPtr->isActive() )
return false;
540 MatchedInterestPointsSetT::iterator it1 = internalMatchedInterestPoints.begin();
541 MatchedInterestPointsSetT::iterator it2;
542 MatchedInterestPointsSetT::iterator eraseIt;
544 while( it1 != internalMatchedInterestPoints.end() )
548 eraseIt = internalMatchedInterestPoints.end();
550 while( it2 != internalMatchedInterestPoints.end() )
553 ( it1->m_point1.m_x == it2->m_point1.m_x )
555 ( it1->m_point1.m_y == it2->m_point1.m_y )
557 ( it1->m_point2.m_x == it2->m_point2.m_x )
559 ( it1->m_point2.m_y == it2->m_point2.m_y )
562 if( it1->m_feature < it2->m_feature )
566 else if( it1->m_feature > it2->m_feature )
582 internalMatchedInterestPoints.erase( eraseIt );
584 else if( eraseIt != internalMatchedInterestPoints.end() )
586 internalMatchedInterestPoints.erase( eraseIt );
600 internalMatchedInterestPoints.erase( internalMatchedInterestPoints.begin() );
607 MatchedInterestPointsSetT::const_iterator itB = internalMatchedInterestPoints.begin();
608 const MatchedInterestPointsSetT::const_iterator itE = internalMatchedInterestPoints.end();
610 float minFeature1P1 = FLT_MAX;
611 float maxFeature1P1 = (-1.0) * FLT_MAX;
612 float minFeature1P2 = FLT_MAX;
613 float maxFeature1P2 = (-1.0) * FLT_MAX;
614 float minDist = FLT_MAX;
615 float maxDist = (-1.0 ) *FLT_MAX;
619 if( minFeature1P1 > itB->m_point1.m_feature1 )
621 if( maxFeature1P1 < itB->m_point1.m_feature1 )
622 maxFeature1P1 = itB->m_point1.m_feature1;
624 if( minFeature1P2 > itB->m_point2.m_feature1 )
625 minFeature1P2 = itB->m_point2.m_feature1;
626 if( maxFeature1P2 < itB->m_point2.m_feature1 )
627 maxFeature1P2 = itB->m_point2.m_feature1;
629 if( minDist > itB->m_feature )
630 minDist = itB->m_feature;
631 if( maxDist < itB->m_feature )
632 maxDist = itB->m_feature;
637 float feature1P1Range = maxFeature1P1 - minFeature1P1;
638 float feature1P2Range = maxFeature1P2 - minFeature1P2;
639 float distRange = maxDist - minDist;
641 if( ( feature1P1Range == 0.0 ) || ( feature1P2Range == 0.0 ) ||
642 ( distRange == 0.0 ) )
644 itB = internalMatchedInterestPoints.begin();
648 auxMatchedPoints = *itB;
651 matchedInterestPoints.insert( auxMatchedPoints );
658 itB = internalMatchedInterestPoints.begin();
662 auxMatchedPoints = *itB;
684 static_cast<float>(3.0);
686 matchedInterestPoints.insert( auxMatchedPoints );
700 unsigned int returnValue = 0;
702 const unsigned int maxRastersArea = (
unsigned int)
729 returnValue = maxRastersArea /
730 ( filterWindowSize * filterWindowSize );
737 const double freeVMem = 0.4 * std::min( totalPhysMem, ( totalVMem - usedVMem ) );
739 const double featureElementsNumber = 65 * 65;
741 double maxFeaturesMemory =
746 (-2.0) * featureElementsNumber
749 ( 4.0 * featureElementsNumber * featureElementsNumber )
751 ( 4.0 * freeVMem / ((
double)
sizeof(
float ) ) )
760 (-2.0) * featureElementsNumber
763 ( 4.0 * featureElementsNumber * featureElementsNumber )
765 ( 4.0 * freeVMem / ((
double)
sizeof(
float ) ) )
770 returnValue = std::min( returnValue, (
unsigned int)maxFeaturesMemory );
784 unsigned int outCol = 0;
787 for(
unsigned int outLine = 0 ; outLine <
nLines ; ++outLine )
788 for( outCol = 0; outCol <
nCols ; ++outCol )
790 currSum = inputData[ outLine ][ outCol ];
793 currSum += outputData[ outLine - 1 ][ outCol ];
795 currSum += outputData[ outLine ][ outCol - 1 ];
796 if( outLine && outCol )
797 currSum -= outputData[ outLine - 1 ][ outCol - 1 ];
799 outputData[ outLine ][ outCol ] = currSum;
806 const unsigned int maxInterestPoints,
811 interestPoints.clear();
817 || ( integralRasterData.
getLinesNumber() < minIntegralRasterWidthHeigh ) )
824 bool returnValue =
true;
825 boost::mutex rastaDataAccessMutex;
826 boost::mutex interestPointsAccessMutex;
827 unsigned int nextRasterLinesBlockToProcess = 0;
828 std::vector< InterestPointsSetT > interestPointsSubSectors(
837 &nextRasterLinesBlockToProcess;
852 boost::thread_group threads;
857 threads.add_thread(
new boost::thread(
873 const unsigned int interestPointsSubSectorsSize =
static_cast<unsigned int>(interestPointsSubSectors.size());
875 for(
unsigned int interestPointsSubSectorsIdx = 0 ; interestPointsSubSectorsIdx <
876 interestPointsSubSectorsSize ; ++interestPointsSubSectorsIdx )
878 interestPoints.insert(
879 interestPointsSubSectors[ interestPointsSubSectorsIdx ].begin(),
880 interestPointsSubSectors[ interestPointsSubSectorsIdx ].end() );
907 const unsigned int maxGausFilterRadius = maxGausFilterWidth / 2;
908 const unsigned int rasterBuffersLinesNumber = maxGausFilterWidth;
909 const unsigned int lastRasterBuffersLineIdx = rasterBuffersLinesNumber - 1;
911 const unsigned int rowsBySubSector = (
unsigned int)std::ceil(
914 ((
double)tiePointsSubSectorsSplitFactor) );
915 const unsigned int colsBySubSector = (
unsigned int)std::ceil(
918 ((
double)tiePointsSubSectorsSplitFactor) );
920 const unsigned int maxInterestPointsByScaleSubSector = maxInterestPointsBySubSector
924 const unsigned int rasterBufferLineSizeBytes =
sizeof( float ) *
929 const unsigned int maxLinesPerProcessingBlock = (
unsigned int)
931 ((
double)rasterLines)
933 ((
double)processingBlocksNumber)
941 boost::scoped_array< float* > rasterBufferHandler(
new float*[ rasterBuffersLinesNumber ] );
943 if( ! rasterBufferDataHandler.
reset( rasterBuffersLinesNumber, buffersCols,
952 for(
unsigned int rasterBufferDataHandlerLine = 0 ; rasterBufferDataHandlerLine <
953 rasterBuffersLinesNumber ; ++rasterBufferDataHandlerLine )
955 rasterBufferHandler[ rasterBufferDataHandlerLine ] = rasterBufferDataHandler[
956 rasterBufferDataHandlerLine ];
959 float** rasterBufferPtr = rasterBufferHandler.get();
965 boost::scoped_array< unsigned char* > maskRasterBufferHandler(
new unsigned char*[ rasterBuffersLinesNumber ] );
967 unsigned char** maskRasterBufferPtr =
nullptr;
971 if( ! maskRasterBufferDataHandler.
reset( rasterBuffersLinesNumber, buffersCols,
980 for(
unsigned int maskRasterBufferDataHandlerLine = 0 ; maskRasterBufferDataHandlerLine <
981 rasterBuffersLinesNumber ; ++maskRasterBufferDataHandlerLine )
983 maskRasterBufferHandler[ maskRasterBufferDataHandlerLine ] = maskRasterBufferDataHandler[
984 maskRasterBufferDataHandlerLine ];
987 maskRasterBufferPtr = maskRasterBufferHandler.get();
993 std::vector< std::vector< boost::shared_array< float* > > >
994 octavesBufferHandlers;
996 const unsigned int octavesBufferDataHandlerLines =
998 if( ! octavesBufferDataHandler.
reset( octavesBufferDataHandlerLines ,
1007 unsigned int octavesBufferDataHandlerLine = 0;
1008 unsigned int octavesBufferDataHandlerCol = 0;
1009 float* octavesBufferDataHandlerLinePtr =
nullptr;
1010 for( octavesBufferDataHandlerLine = 0; octavesBufferDataHandlerLine <
1011 octavesBufferDataHandlerLines ; ++octavesBufferDataHandlerLine )
1013 octavesBufferDataHandlerLinePtr = octavesBufferDataHandler[
1014 octavesBufferDataHandlerLine ];
1016 for( octavesBufferDataHandlerCol = 0; octavesBufferDataHandlerCol <
1017 buffersCols ; ++octavesBufferDataHandlerCol )
1019 octavesBufferDataHandlerLinePtr[ octavesBufferDataHandlerCol ] = 0.0;
1023 octavesBufferDataHandlerLine = 0;
1024 unsigned int scaleIdx = 0 ;
1025 unsigned int octaveIdx = 0 ;
1026 for( octaveIdx = 0 ; octaveIdx < paramsPtr->
m_octavesNumber ; ++octaveIdx )
1028 octavesBufferHandlers.push_back( std::vector< boost::shared_array< float* > >() );
1029 std::vector< boost::shared_array< float* > >&
1030 currOctaveBuffersHandler = octavesBufferHandlers[ octaveIdx ];
1032 for( scaleIdx = 0 ; scaleIdx < paramsPtr->
m_scalesNumber ; ++scaleIdx )
1034 currOctaveBuffersHandler.push_back( boost::shared_array< float* >(
1035 new float*[ 3 ] ) );
1036 boost::shared_array< float* >& currOctavesBuffer =
1037 currOctaveBuffersHandler[ scaleIdx ];
1038 for(
unsigned int bufferLine = 0 ; bufferLine < 3 ; ++bufferLine )
1040 assert( octavesBufferDataHandlerLine <
1043 currOctavesBuffer[ bufferLine ] = octavesBufferDataHandler[
1044 octavesBufferDataHandlerLine ];
1046 ++octavesBufferDataHandlerLine;
1055 std::vector< std::vector< boost::shared_array< unsigned char* > > >
1056 laplacianSignBufferHandlers;
1058 const unsigned int laplacianSignBufferDataHandlerLines =
1060 if( ! laplacianSignBufferDataHandler.
reset( laplacianSignBufferDataHandlerLines ,
1069 unsigned int laplacianSignBufferDataHandlerLine = 0;
1070 unsigned int laplacianSignBufferDataHandlerCol = 0;
1071 unsigned char* laplacianSignBufferDataHandlerLinePtr =
nullptr;
1072 for( laplacianSignBufferDataHandlerLine = 0; laplacianSignBufferDataHandlerLine <
1073 laplacianSignBufferDataHandlerLines ; ++laplacianSignBufferDataHandlerLine )
1075 laplacianSignBufferDataHandlerLinePtr = laplacianSignBufferDataHandler[
1076 laplacianSignBufferDataHandlerLine ];
1078 for( laplacianSignBufferDataHandlerCol = 0; laplacianSignBufferDataHandlerCol <
1079 buffersCols ; ++laplacianSignBufferDataHandlerCol )
1081 laplacianSignBufferDataHandlerLinePtr[ laplacianSignBufferDataHandlerCol ] =
1086 laplacianSignBufferDataHandlerLine = 0;
1087 unsigned int scaleIdx = 0 ;
1088 unsigned int octaveIdx = 0 ;
1089 for( octaveIdx = 0 ; octaveIdx < paramsPtr->
m_octavesNumber ; ++octaveIdx )
1091 laplacianSignBufferHandlers.push_back( std::vector< boost::shared_array< unsigned char* > >() );
1092 std::vector< boost::shared_array< unsigned char* > >&
1093 currlaplacianSignBuffersHandler = laplacianSignBufferHandlers[ octaveIdx ];
1095 for( scaleIdx = 0 ; scaleIdx < paramsPtr->
m_scalesNumber ; ++scaleIdx )
1097 currlaplacianSignBuffersHandler.push_back( boost::shared_array< unsigned char* >(
1098 new unsigned char*[ 3 ] ) );
1099 boost::shared_array< unsigned char* >& currlaplacianSignBuffer =
1100 currlaplacianSignBuffersHandler[ scaleIdx ];
1101 for(
unsigned int bufferLine = 0 ; bufferLine < 3 ; ++bufferLine )
1103 assert( laplacianSignBufferDataHandlerLine <
1106 currlaplacianSignBuffer[ bufferLine ] = laplacianSignBufferDataHandler[
1107 laplacianSignBufferDataHandlerLine ];
1109 ++laplacianSignBufferDataHandlerLine;
1117 const unsigned maxGausResponseFilterCenterBufferColBound = buffersCols -
1118 maxGausFilterRadius;
1119 const unsigned maxMaximaDetectionCenterBufferColBound = buffersCols -
1120 maxGausFilterRadius - 1;
1122 unsigned int scaleIdx = 0 ;
1123 unsigned int octaveIdx = 0 ;
1124 unsigned int subSectorIndex = 0;
1125 unsigned int scaleGlobalIndex = 0;
1127 std::vector< std::vector< InterestPointsSetT > > interestPointsSubSectors;
1129 std::vector< InterestPointsSetT > dummyIPointsContainer(
1136 for(
unsigned int rasterLinesBlockIdx = 0; rasterLinesBlockIdx <
1137 processingBlocksNumber ; ++rasterLinesBlockIdx )
1141 std::vector< InterestPointsSetT > blockMaximas( paramsPtr->
m_scalesNumber *
1154 const unsigned int rasterLinesStart =
1160 ((
int)(rasterLinesBlockIdx * maxLinesPerProcessingBlock ))
1162 ((
int)maxGausFilterRadius)
1167 const unsigned int rasterLinesEndBound =
1172 ( ( rasterLinesBlockIdx + 1 ) * maxLinesPerProcessingBlock )
1179 const unsigned int firstRasterLineToGenerateResponse =
1180 rasterLinesStart + maxGausFilterWidth - 1;
1181 const unsigned int firstRasterLineToLookForMaximas =
1182 rasterLinesStart + maxGausFilterWidth + 1;
1183 unsigned int filterWidth = 0;
1184 unsigned int filterLobeWidth = 0;
1185 unsigned int filterLobeRadius = 0;
1186 unsigned int filterCenterBufCol = 0 ;
1191 float** currScaleBufferPtr =
nullptr;
1192 unsigned char** currLaplacianSignBufferPtr =
nullptr;
1193 unsigned int lastScaleIdx = 0;
1194 unsigned int nextScaleIdx = 0;
1195 unsigned int prevResponseBufferColIdx = 0;
1196 unsigned int nextResponseBufferColIdx = 0;
1197 float windowCenterPixelValue = 0.0;
1198 float neighborMaximaDif_0_1 = 0.0;
1199 float neighborMaximaDif_0_2 = 0.0;
1200 float neighborMaximaDif_0_3 = 0.0;
1201 float neighborMaximaDif_0_4 = 0.0;
1202 float neighborMaximaDif_0_5 = 0.0;
1203 float neighborMaximaDif_0_6 = 0.0;
1204 float neighborMaximaDif_0_7 = 0.0;
1205 float neighborMaximaDif_0_8 = 0.0;
1206 float neighborMaximaDif_1_1 = 0.0;
1207 float neighborMaximaDif_1_2 = 0.0;
1208 float neighborMaximaDif_1_3 = 0.0;
1209 float neighborMaximaDif_1_4 = 0.0;
1210 float neighborMaximaDif_1_5 = 0.0;
1211 float neighborMaximaDif_1_6 = 0.0;
1212 float neighborMaximaDif_1_7 = 0.0;
1213 float neighborMaximaDif_1_8 = 0.0;
1214 float neighborMaximaDif_1_9 = 0.0;
1215 float neighborMaximaDif_2_1 = 0.0;
1216 float neighborMaximaDif_2_2 = 0.0;
1217 float neighborMaximaDif_2_3 = 0.0;
1218 float neighborMaximaDif_2_4 = 0.0;
1219 float neighborMaximaDif_2_5 = 0.0;
1220 float neighborMaximaDif_2_6 = 0.0;
1221 float neighborMaximaDif_2_7 = 0.0;
1222 float neighborMaximaDif_2_8 = 0.0;
1223 float neighborMaximaDif_2_9 = 0.0;
1227 for(
unsigned int rasterLine = rasterLinesStart; rasterLine < rasterLinesEndBound ;
1234 roolUpBuffer( rasterBufferPtr, rasterBuffersLinesNumber );
1236 memcpy( rasterBufferPtr[ lastRasterBuffersLineIdx ],
1238 rasterBufferLineSizeBytes );
1243 roolUpBuffer( maskRasterBufferPtr, rasterBuffersLinesNumber );
1244 memcpy( maskRasterBufferPtr[ lastRasterBuffersLineIdx ],
1246 maskRasterBufferLineSizeBytes );
1252 if( rasterLine >= firstRasterLineToGenerateResponse )
1254 for( octaveIdx = 0 ; octaveIdx < paramsPtr->
m_octavesNumber ; ++octaveIdx )
1259 assert( octavesBufferHandlers.size() > octaveIdx );
1260 assert( octavesBufferHandlers[ octaveIdx].size() > scaleIdx );
1261 currScaleBufferPtr = octavesBufferHandlers[ octaveIdx][ scaleIdx ].get();
1262 assert( currScaleBufferPtr );
1264 assert( laplacianSignBufferHandlers.size() > octaveIdx );
1265 assert( laplacianSignBufferHandlers[ octaveIdx].size() > scaleIdx );
1266 currLaplacianSignBufferPtr = laplacianSignBufferHandlers[ octaveIdx][ scaleIdx ].get();
1267 assert( currLaplacianSignBufferPtr );
1277 assert( filterWidth <= maxGausFilterWidth );
1279 filterLobeWidth = filterWidth / 3;
1280 filterLobeRadius = filterLobeWidth / 2;
1282 for( filterCenterBufCol = maxGausFilterRadius ;
1283 filterCenterBufCol < maxGausResponseFilterCenterBufferColBound ;
1284 ++filterCenterBufCol )
1287 maxGausFilterRadius, filterLobeWidth, filterLobeRadius);
1288 dYY /= (float)( filterWidth * filterWidth );
1291 maxGausFilterRadius, filterLobeWidth, filterLobeRadius);
1292 dXX /= (float)( filterWidth * filterWidth );
1295 maxGausFilterRadius, filterLobeWidth );
1296 dXY /= (float)( filterWidth * filterWidth );
1298 currScaleBufferPtr[ 2 ][ filterCenterBufCol ] =
1299 ( dXX * dYY ) - ( 0.81f * dXY * dXY );
1300 currLaplacianSignBufferPtr[ 2 ][ filterCenterBufCol ] =
1301 ( ( dXX + dYY ) >= 0.0 ) ? 1 : 0;
1310 if( rasterLine >= firstRasterLineToLookForMaximas )
1317 for(
unsigned int windCenterCol = maxGausFilterRadius + 1;
1318 windCenterCol < maxMaximaDetectionCenterBufferColBound ; ++windCenterCol )
1320 prevResponseBufferColIdx = windCenterCol - 1;
1321 nextResponseBufferColIdx = windCenterCol + 1;
1322 auxInterestPoint.
m_feature1 = (-1.0) * FLT_MAX;
1324 for( octaveIdx = 0 ; octaveIdx < paramsPtr->
m_octavesNumber ; ++octaveIdx )
1326 std::vector< boost::shared_array< float* > >&
1327 currOctaveBuffersHandler = octavesBufferHandlers[ octaveIdx ];
1329 for( scaleIdx = 1 ; scaleIdx < ( paramsPtr->
m_scalesNumber - 1 );
1332 windowCenterPixelValue = currOctaveBuffersHandler[
1333 scaleIdx ][ 1 ][ windCenterCol ];
1334 lastScaleIdx = scaleIdx - 1;
1335 nextScaleIdx = scaleIdx + 1;
1337 neighborMaximaDif_0_1 = windowCenterPixelValue - currOctaveBuffersHandler[
1338 scaleIdx ][ 0 ][ prevResponseBufferColIdx ];
1339 neighborMaximaDif_0_2 = windowCenterPixelValue - currOctaveBuffersHandler[
1340 scaleIdx ][ 0 ][ windCenterCol ];
1341 neighborMaximaDif_0_3 = windowCenterPixelValue - currOctaveBuffersHandler[
1342 scaleIdx ][ 0 ][ nextResponseBufferColIdx ];
1343 neighborMaximaDif_0_4 = windowCenterPixelValue - currOctaveBuffersHandler[
1344 scaleIdx ][ 1 ][ prevResponseBufferColIdx ];
1345 neighborMaximaDif_0_5 = windowCenterPixelValue - currOctaveBuffersHandler[
1346 scaleIdx ][ 1 ][ nextResponseBufferColIdx ];
1347 neighborMaximaDif_0_6 = windowCenterPixelValue - currOctaveBuffersHandler[
1348 scaleIdx ][ 2 ][ prevResponseBufferColIdx];
1349 neighborMaximaDif_0_7 = windowCenterPixelValue - currOctaveBuffersHandler[
1350 scaleIdx ][ 2 ][ windCenterCol ];
1351 neighborMaximaDif_0_8 = windowCenterPixelValue - currOctaveBuffersHandler[
1352 scaleIdx ][ 2 ][ nextResponseBufferColIdx ];
1355 ( windowCenterPixelValue > 0.0 )
1357 && ( neighborMaximaDif_0_1 > 0.0 )
1358 && ( neighborMaximaDif_0_2 > 0.0 )
1359 && ( neighborMaximaDif_0_3 > 0.0 )
1360 && ( neighborMaximaDif_0_4 > 0.0 )
1361 && ( neighborMaximaDif_0_5 > 0.0 )
1362 && ( neighborMaximaDif_0_6 > 0.0 )
1363 && ( neighborMaximaDif_0_7 > 0.0 )
1364 && ( neighborMaximaDif_0_8 > 0.0 )
1367 neighborMaximaDif_1_1 = windowCenterPixelValue - currOctaveBuffersHandler[
1368 lastScaleIdx ][ 0 ][ prevResponseBufferColIdx ];
1369 neighborMaximaDif_1_2 = windowCenterPixelValue - currOctaveBuffersHandler[
1370 lastScaleIdx ][ 0 ][ windCenterCol ];
1371 neighborMaximaDif_1_3 = windowCenterPixelValue - currOctaveBuffersHandler[
1372 lastScaleIdx ][ 0 ][ nextResponseBufferColIdx ];
1373 neighborMaximaDif_1_4 = windowCenterPixelValue - currOctaveBuffersHandler[
1374 lastScaleIdx ][ 1 ][ prevResponseBufferColIdx ];
1375 neighborMaximaDif_1_5 = windowCenterPixelValue - currOctaveBuffersHandler[
1376 lastScaleIdx ][ 1 ][ windCenterCol ];
1377 neighborMaximaDif_1_6 = windowCenterPixelValue - currOctaveBuffersHandler[
1378 lastScaleIdx ][ 1 ][ nextResponseBufferColIdx ];
1379 neighborMaximaDif_1_7 = windowCenterPixelValue - currOctaveBuffersHandler[
1380 lastScaleIdx ][ 2 ][ prevResponseBufferColIdx];
1381 neighborMaximaDif_1_8 = windowCenterPixelValue - currOctaveBuffersHandler[
1382 lastScaleIdx ][ 2 ][ windCenterCol ];
1383 neighborMaximaDif_1_9 = windowCenterPixelValue - currOctaveBuffersHandler[
1384 lastScaleIdx ][ 2 ][ nextResponseBufferColIdx ];
1388 ( neighborMaximaDif_1_1 > 0.0 )
1389 && ( neighborMaximaDif_1_2 > 0.0 )
1390 && ( neighborMaximaDif_1_3 > 0.0 )
1391 && ( neighborMaximaDif_1_4 > 0.0 )
1392 && ( neighborMaximaDif_1_5 > 0.0 )
1393 && ( neighborMaximaDif_1_6 > 0.0 )
1394 && ( neighborMaximaDif_1_7 > 0.0 )
1395 && ( neighborMaximaDif_1_8 > 0.0 )
1396 && ( neighborMaximaDif_1_9 > 0.0 )
1399 neighborMaximaDif_2_1 = windowCenterPixelValue - currOctaveBuffersHandler[
1400 nextScaleIdx ][ 0 ][ prevResponseBufferColIdx ];
1401 neighborMaximaDif_2_2 = windowCenterPixelValue - currOctaveBuffersHandler[
1402 nextScaleIdx ][ 0 ][ windCenterCol ];
1403 neighborMaximaDif_2_3 = windowCenterPixelValue - currOctaveBuffersHandler[
1404 nextScaleIdx ][ 0 ][ nextResponseBufferColIdx ];
1405 neighborMaximaDif_2_4 = windowCenterPixelValue - currOctaveBuffersHandler[
1406 nextScaleIdx ][ 1 ][ prevResponseBufferColIdx ];
1407 neighborMaximaDif_2_5 = windowCenterPixelValue - currOctaveBuffersHandler[
1408 nextScaleIdx ][ 1 ][ windCenterCol ];
1409 neighborMaximaDif_2_6 = windowCenterPixelValue - currOctaveBuffersHandler[
1410 nextScaleIdx ][ 1 ][ nextResponseBufferColIdx ];
1411 neighborMaximaDif_2_7 = windowCenterPixelValue - currOctaveBuffersHandler[
1412 nextScaleIdx ][ 2 ][ prevResponseBufferColIdx];
1413 neighborMaximaDif_2_8 = windowCenterPixelValue - currOctaveBuffersHandler[
1414 nextScaleIdx ][ 2 ][ windCenterCol ];
1415 neighborMaximaDif_2_9 = windowCenterPixelValue - currOctaveBuffersHandler[
1416 nextScaleIdx ][ 2 ][ nextResponseBufferColIdx ];
1420 ( neighborMaximaDif_2_1 > 0.0 )
1421 && ( neighborMaximaDif_2_2 > 0.0 )
1422 && ( neighborMaximaDif_2_3 > 0.0 )
1423 && ( neighborMaximaDif_2_4 > 0.0 )
1424 && ( neighborMaximaDif_2_5 > 0.0 )
1425 && ( neighborMaximaDif_2_6 > 0.0 )
1426 && ( neighborMaximaDif_2_7 > 0.0 )
1427 && ( neighborMaximaDif_2_8 > 0.0 )
1428 && ( neighborMaximaDif_2_9 > 0.0 )
1432 ( maskRasterBufferPtr[ 0 ][ windCenterCol ] != 0 )
1439 neighborMaximaDif_0_1
1440 + neighborMaximaDif_0_2
1441 + neighborMaximaDif_0_3
1442 + neighborMaximaDif_0_4
1443 + neighborMaximaDif_0_5
1444 + neighborMaximaDif_0_6
1445 + neighborMaximaDif_0_7
1446 + neighborMaximaDif_0_8
1447 + neighborMaximaDif_1_1
1448 + neighborMaximaDif_1_2
1449 + neighborMaximaDif_1_3
1450 + neighborMaximaDif_1_4
1451 + neighborMaximaDif_1_5
1452 + neighborMaximaDif_1_6
1453 + neighborMaximaDif_1_7
1454 + neighborMaximaDif_1_8
1455 + neighborMaximaDif_1_9
1456 + neighborMaximaDif_2_1
1457 + neighborMaximaDif_2_2
1458 + neighborMaximaDif_2_3
1459 + neighborMaximaDif_2_4
1460 + neighborMaximaDif_2_5
1461 + neighborMaximaDif_2_6
1462 + neighborMaximaDif_2_7
1463 + neighborMaximaDif_2_8
1464 + neighborMaximaDif_2_9;
1466 octaveIdx, scaleIdx );
1468 laplacianSignBufferHandlers[ octaveIdx ][ scaleIdx ][
1469 1 ][ windCenterCol ] ;
1471 auxInterestPoint.
m_x = windCenterCol;
1472 auxInterestPoint.
m_y = rasterLine - maxGausFilterRadius - 1;
1473 assert( auxInterestPoint.
m_x <
1475 assert( auxInterestPoint.
m_y <
1478 scaleGlobalIndex = ( octaveIdx *
1480 subSectorIndex = ( ( auxInterestPoint.
m_y /
1481 rowsBySubSector ) * tiePointsSubSectorsSplitFactor ) +
1482 ( auxInterestPoint.
m_x / colsBySubSector );
1483 assert( scaleGlobalIndex < interestPointsSubSectors.size() );
1484 assert( subSectorIndex < interestPointsSubSectors[ scaleGlobalIndex ].size() );
1486 interestPointsSubSectors[ scaleGlobalIndex ][
1487 subSectorIndex ].insert( auxInterestPoint);
1489 if( interestPointsSubSectors[ scaleGlobalIndex ][
1490 subSectorIndex ].size() > maxInterestPointsByScaleSubSector )
1492 interestPointsSubSectors[ scaleGlobalIndex ][
1493 subSectorIndex ].erase( interestPointsSubSectors[
1494 scaleGlobalIndex ][ subSectorIndex ].begin() );
1514 for( scaleGlobalIndex = 0 ; scaleGlobalIndex < interestPointsSubSectors.size() ;
1515 ++scaleGlobalIndex )
1517 for( subSectorIndex = 0 ; subSectorIndex < interestPointsSubSectors[
1518 scaleGlobalIndex ].size() ; ++subSectorIndex )
1522 interestPointsSubSectors[ scaleGlobalIndex ][ subSectorIndex ], x, y ),
1523 "Duplicated tie-points" );
1526 subSectorIndex ).
insert( interestPointsSubSectors[
1527 scaleGlobalIndex ][ subSectorIndex ].begin(),
1528 interestPointsSubSectors[ scaleGlobalIndex ][ subSectorIndex ].end() );
1531 subSectorIndex ).size() >
1532 maxInterestPointsBySubSector )
1535 subSectorIndex ).erase(
1537 subSectorIndex ).begin() );
1554 validInterestPoints.clear();
1557 InterestPointsSetT::const_iterator iPointsIt = interestPoints.begin();
1558 const InterestPointsSetT::const_iterator iPointsItEnd = interestPoints.end();
1560 while( iPointsIt != iPointsItEnd )
1564 const unsigned int& currIPointCenterX = iPointsIt->m_x;
1565 const unsigned int& currIPointCenterY = iPointsIt->m_y;
1566 const float currIPointScale = 1.2f * iPointsIt->m_feature2 / 9.0f;
1568 unsigned int featureWindowWidth = (
unsigned int)( 20.0 * currIPointScale );
1569 featureWindowWidth += ( ( featureWindowWidth % 2 ) ? 0 : 1 );
1571 const unsigned int feature90DegreeRotatedWindowRadius = (
unsigned int)
1578 ( (
double)featureWindowWidth )
1580 ( (double)featureWindowWidth )
1586 const unsigned int featureElementHaarWindowRadius =
1587 ((
unsigned int)( 2.0 * currIPointScale )) / 2;
1589 const unsigned int currIPointCenterXAllowedMin = featureElementHaarWindowRadius +
1590 feature90DegreeRotatedWindowRadius + 1;
1591 const unsigned int currIPointCenterXAllowedMax = integralRasterData.
getColumnsNumber() -
1592 currIPointCenterXAllowedMin - 1;
1593 const unsigned int currIPointCenterYAllowedMin = currIPointCenterXAllowedMin;
1594 const unsigned int currIPointCenterYAllowedMax = integralRasterData.
getLinesNumber() -
1595 currIPointCenterXAllowedMin - 1;
1597 if( ( currIPointCenterX > currIPointCenterXAllowedMin ) &&
1598 ( currIPointCenterX < currIPointCenterXAllowedMax ) &&
1599 ( currIPointCenterY > currIPointCenterYAllowedMin ) &&
1600 ( currIPointCenterY < currIPointCenterYAllowedMax ) )
1603 validInterestPoints.insert( *iPointsIt );
1611 "Cannot allocate features matrix" );
1615 float auxFeaturesBuffer[ 128 ];
1619 InterestPointsSetT::const_iterator iPointsIt = validInterestPoints.begin();
1620 const InterestPointsSetT::const_iterator iPointsItEnd = validInterestPoints.end();
1621 unsigned int interestPointIdx = 0;
1622 while( iPointsIt != iPointsItEnd )
1626 const unsigned int& currIPointCenterX = iPointsIt->m_x;
1627 const unsigned int& currIPointCenterY = iPointsIt->m_y;
1628 const float currIPointScale = 1.2f * iPointsIt->m_feature2 / 9.0f;
1630 unsigned int featureWindowWidth = (
unsigned int)( 20.0 * currIPointScale );
1631 featureWindowWidth += ( ( featureWindowWidth % 2 ) ? 0 : 1 );
1633 const unsigned int featureWindowRadius = featureWindowWidth / 2;
1634 const float featureWindowRadiusDouble = (float)featureWindowRadius;
1636 const unsigned int featureSubWindowWidth = featureWindowWidth / 4;
1638 const unsigned int featureElementHaarWindowRadius =
1639 ((
unsigned int)( 2.0 * currIPointScale )) / 2;
1641 const unsigned int featureWindowRasterXStart = currIPointCenterX -
1642 featureWindowRadius;
1643 const unsigned int featureWindowRasterYStart = currIPointCenterY -
1644 featureWindowRadius;
1648 unsigned int currentFeaturePtrStartIdx = 0;
1650 for( currentFeaturePtrStartIdx = 0; currentFeaturePtrStartIdx < 128 ;
1651 ++currentFeaturePtrStartIdx )
1652 auxFeaturesBuffer[ currentFeaturePtrStartIdx ] = 0.0;
1656 assert( ((
long int)currIPointCenterX) -
1657 ((
long int)featureWindowRadius) >= 0 );
1658 assert( ((
long int)currIPointCenterY) -
1659 ((
long int)featureWindowRadius) >= 0 );
1660 assert( currIPointCenterX +
1662 assert( currIPointCenterY +
1666 currIPointCenterY, featureWindowRadius );
1668 currIPointCenterY, featureWindowRadius );
1672 const float currIPointRotationNorm = std::sqrt( ( currIPointXIntensity * currIPointXIntensity ) +
1673 ( currIPointYIntensity * currIPointYIntensity ) );
1675 float currIPointRotationSin = 0;
1676 float currIPointRotationCos = 1.0;
1678 if( currIPointRotationNorm != 0.0 )
1680 currIPointRotationCos = currIPointXIntensity / currIPointRotationNorm;
1681 currIPointRotationSin = currIPointYIntensity / currIPointRotationNorm;
1684 assert( ( currIPointRotationCos >= -1.0 ) && ( currIPointRotationCos <= 1.0 ) );
1685 assert( ( currIPointRotationSin >= -1.0 ) && ( currIPointRotationSin <= 1.0 ) );
1703 unsigned int featureWindowYOffset = 0;
1704 unsigned int featureWindowXOffset = 0;
1705 float featureElementZeroCenteredOriginalXIdx = 0;
1706 float featureElementZeroCenteredOriginalYIdx = 0;
1707 float featureElementZeroCenteredRotatedXIdx = 0;
1708 float featureElementZeroCenteredRotatedYIdx = 0;
1709 float featureElementRotatedXIdx = 0;
1710 float featureElementRotatedYIdx = 0;
1711 unsigned int featureElementRasterRotatedXIdx = 0;
1712 unsigned int featureElementRasterRotatedYIdx = 0;
1713 float featureElementOriginalHaarXIntensity = 0;
1714 float featureElementOriginalHaarYIntensity = 0;
1715 float featureElementZeroCenteredOriginalHaarXIntensity = 0;
1716 float featureElementZeroCenteredOriginalHaarYIntensity = 0;
1717 float featureElementRotatedHaarXIntensity = 0;
1718 float featureElementRotatedHaarYIntensity = 0;
1719 float featureElementZeroCenteredRotatedHaarXIntensity = 0;
1720 float featureElementZeroCenteredRotatedHaarYIntensity = 0;
1721 unsigned int featureSubWindowYIdx = 0;
1722 unsigned int featureSubWindowXIdx = 0;
1724 for( featureWindowYOffset = 0 ; featureWindowYOffset < featureWindowWidth ;
1725 featureWindowYOffset += 5 )
1727 featureElementZeroCenteredOriginalYIdx = ((float)featureWindowYOffset)
1728 - featureWindowRadiusDouble;
1730 featureSubWindowYIdx = featureWindowYOffset / featureSubWindowWidth;
1732 for( featureWindowXOffset = 0 ; featureWindowXOffset < featureWindowWidth ;
1733 featureWindowXOffset += 5 )
1735 featureSubWindowXIdx = featureWindowXOffset / featureSubWindowWidth;
1737 currentFeaturePtrStartIdx = ( featureSubWindowYIdx * 4 ) +
1738 featureSubWindowXIdx;
1740 featureElementZeroCenteredOriginalXIdx = ((float)featureWindowXOffset)
1741 - featureWindowRadiusDouble;
1746 featureElementZeroCenteredRotatedXIdx =
1747 ( currIPointRotationCos * featureElementZeroCenteredOriginalXIdx ) +
1748 ( currIPointRotationSin * featureElementZeroCenteredOriginalYIdx );
1749 featureElementZeroCenteredRotatedYIdx =
1750 ( currIPointRotationCos * featureElementZeroCenteredOriginalYIdx )
1751 - ( currIPointRotationSin * featureElementZeroCenteredOriginalXIdx );
1753 featureElementRotatedXIdx = featureElementZeroCenteredRotatedXIdx +
1754 featureWindowRadiusDouble;
1755 featureElementRotatedYIdx = featureElementZeroCenteredRotatedYIdx +
1756 featureWindowRadiusDouble;
1758 featureElementRasterRotatedXIdx = featureWindowRasterXStart +
1759 (
unsigned int)te::common::Round< float, unsigned int >( featureElementRotatedXIdx );
1760 featureElementRasterRotatedYIdx = featureWindowRasterYStart +
1761 (
unsigned int)te::common::Round< float, unsigned int >( featureElementRotatedYIdx );
1763 assert( ((
long int)featureElementRasterRotatedXIdx) -
1764 ((
long int)featureElementHaarWindowRadius) >= 0 );
1765 assert( ((
long int)featureElementRasterRotatedYIdx) -
1766 ((
long int)featureElementHaarWindowRadius) >= 0 );
1767 assert( featureElementRasterRotatedXIdx +
1769 assert( featureElementRasterRotatedYIdx +
1770 featureElementHaarWindowRadius < integralRasterData.
getLinesNumber() );
1775 featureElementRasterRotatedXIdx, featureElementRasterRotatedYIdx,
1776 featureElementHaarWindowRadius );
1778 featureElementRasterRotatedXIdx, featureElementRasterRotatedYIdx,
1779 featureElementHaarWindowRadius );
1784 featureElementZeroCenteredOriginalHaarXIntensity = featureElementOriginalHaarXIntensity +
1785 featureElementZeroCenteredOriginalXIdx;
1786 featureElementZeroCenteredOriginalHaarYIntensity = featureElementOriginalHaarYIntensity +
1787 featureElementZeroCenteredOriginalYIdx;
1789 featureElementZeroCenteredRotatedHaarXIntensity =
1790 ( currIPointRotationCos * featureElementZeroCenteredOriginalHaarXIntensity ) +
1791 ( currIPointRotationSin * featureElementZeroCenteredOriginalHaarYIntensity );
1792 featureElementZeroCenteredRotatedHaarYIntensity =
1793 ( currIPointRotationCos * featureElementZeroCenteredOriginalHaarYIntensity )
1794 - ( currIPointRotationSin * featureElementZeroCenteredOriginalHaarXIntensity );
1796 featureElementRotatedHaarXIntensity = featureElementZeroCenteredRotatedHaarXIntensity
1797 - featureElementZeroCenteredRotatedXIdx;
1798 featureElementRotatedHaarYIntensity = featureElementZeroCenteredRotatedHaarYIntensity
1799 - featureElementZeroCenteredRotatedYIdx;
1803 assert( currentFeaturePtrStartIdx < 121 );
1805 auxFeaturesBuffer[ currentFeaturePtrStartIdx ] +=
1806 featureElementRotatedHaarXIntensity;
1807 auxFeaturesBuffer[ currentFeaturePtrStartIdx + 1 ] +=
1808 featureElementRotatedHaarYIntensity;
1809 auxFeaturesBuffer[ currentFeaturePtrStartIdx + 2 ] +=
1810 std::abs( featureElementRotatedHaarXIntensity );
1811 auxFeaturesBuffer[ currentFeaturePtrStartIdx + 3 ] +=
1812 std::abs( featureElementRotatedHaarYIntensity );
1813 if( featureElementRotatedHaarXIntensity < 0.0 )
1815 auxFeaturesBuffer[ currentFeaturePtrStartIdx + 4 ] +=
1816 featureElementRotatedHaarXIntensity;
1820 auxFeaturesBuffer[ currentFeaturePtrStartIdx + 5 ] +=
1821 featureElementRotatedHaarXIntensity;
1823 if( featureElementRotatedHaarYIntensity < 0.0 )
1825 auxFeaturesBuffer[ currentFeaturePtrStartIdx + 6 ] +=
1826 featureElementRotatedHaarYIntensity;
1830 auxFeaturesBuffer[ currentFeaturePtrStartIdx + 7 ] +=
1831 featureElementRotatedHaarYIntensity;
1838 float* currentFeaturePtr = features[ interestPointIdx ];
1840 float featureElementsNormalizeFactor = 0.0;
1842 for( currentFeaturePtrStartIdx = 0 ; currentFeaturePtrStartIdx < 128 ;
1843 ++currentFeaturePtrStartIdx )
1845 featureElementsNormalizeFactor += ( auxFeaturesBuffer[ currentFeaturePtrStartIdx ]
1846 * auxFeaturesBuffer[ currentFeaturePtrStartIdx ] );
1849 featureElementsNormalizeFactor = std::sqrt( featureElementsNormalizeFactor );
1851 if( featureElementsNormalizeFactor != 0.0 )
1853 featureElementsNormalizeFactor = 1.0f / featureElementsNormalizeFactor;
1856 for( currentFeaturePtrStartIdx = 0 ; currentFeaturePtrStartIdx < 128 ;
1857 ++currentFeaturePtrStartIdx )
1859 currentFeaturePtr[ currentFeaturePtrStartIdx ] = (
1860 auxFeaturesBuffer[ currentFeaturePtrStartIdx ] *
1861 featureElementsNormalizeFactor );
1863 currentFeaturePtr[ currentFeaturePtrStartIdx ] );
1865 currentFeaturePtr[ currentFeaturePtrStartIdx ] );
1881 const double raster1ToRaster2TransfDMapError,
1886 matchedPoints.clear();
1891 const unsigned int interestPointsSet1Size =
static_cast<unsigned int>(interestPointsSet1.size());
1892 if( interestPointsSet1Size == 0 )
return true;
1894 const unsigned int interestPointsSet2Size =
static_cast<unsigned int>(interestPointsSet2.size());
1895 if( interestPointsSet2Size == 0 )
return true;
1898 assert( featuresSet1.
getLinesNumber() == interestPointsSet1Size );
1899 assert( featuresSet2.
getLinesNumber() == interestPointsSet2Size );
1903 InterestPointsSetT::const_iterator it1 = interestPointsSet1.begin();
1904 boost::scoped_array< InterestPointT > internalInterestPointsSet1(
1906 for(
unsigned int idx1 = 0 ; idx1 < interestPointsSet1Size ; ++idx1 )
1908 internalInterestPointsSet1[ idx1 ] = *it1;
1912 InterestPointsSetT::const_iterator it2 = interestPointsSet2.begin();
1913 boost::scoped_array< InterestPointT > internalInterestPointsSet2(
1915 for(
unsigned int idx2 = 0 ; idx2 < interestPointsSet2Size ; ++idx2 )
1917 internalInterestPointsSet2[ idx2 ] = *it2;
1926 "Error crearting the correlation matrix" );
1928 unsigned int col = 0;
1929 unsigned int line = 0;
1930 float* linePtr =
nullptr;
1932 for( line = 0 ; line < interestPointsSet1Size ; ++
line )
1934 linePtr = distMatrix[
line ];
1936 for( col = 0 ; col < interestPointsSet2Size ; ++
col )
1938 linePtr[
col ] = std::numeric_limits< float >::max();
1944 boost::mutex syncMutex;
1945 unsigned int nextFeatureIdx1ToProcess = 0;
1967 boost::thread_group threads;
1969 for(
unsigned int threadIdx = 0 ; threadIdx < procsNumber ;
1972 threads.add_thread(
new boost::thread(
1986 std::vector< float > eachLineMinValues( interestPointsSet1Size,
1988 std::vector< unsigned int > eachLineMinIndexes( interestPointsSet1Size,
1989 interestPointsSet2Size );
1990 std::vector< float > eachColMinValues( interestPointsSet2Size,
1992 std::vector< unsigned int > eachColMinIndexes( interestPointsSet2Size,
1993 interestPointsSet1Size );
1995 for( line = 0 ; line < interestPointsSet1Size ; ++
line )
1997 linePtr = distMatrix[
line ];
1999 for( col = 0 ; col < interestPointsSet2Size ; ++
col )
2001 const float& value = linePtr[
col ];
2003 if( value <= maxEuclideanDist )
2005 if( value < eachLineMinValues[ line ] )
2007 eachLineMinValues[
line ] = value;
2008 eachLineMinIndexes[
line ] =
col;
2011 if( value < eachColMinValues[ col ] )
2013 eachColMinValues[
col ] = value;
2014 eachColMinIndexes[
col ] =
line;
2024 for( line = 0 ; line < interestPointsSet1Size ; ++
line )
2026 col = eachLineMinIndexes[
line ];
2028 if( ( col < interestPointsSet2Size ) &&
2029 ( eachColMinIndexes[ col ] == line ) )
2031 auxMatchedPoints.
m_point1 = internalInterestPointsSet1[
line ];
2032 auxMatchedPoints.
m_point2 = internalInterestPointsSet2[
col ],
2033 auxMatchedPoints.
m_feature = distMatrix( line, col );
2035 matchedPoints.insert( auxMatchedPoints );
2058 unsigned int feat2Idx = 0;
2059 float const* feat1Ptr =
nullptr;
2060 float const* feat2Ptr =
nullptr;
2061 float* corrMatrixLinePtr =
nullptr;
2062 unsigned int featCol = 0;
2065 float euclideanDist = 0;
2069 std::unique_ptr< te::gm::GeometricTransformation > raster1ToRaster2TransfPtr;
2079 const unsigned int featuresSet1Size =
2081 const unsigned int featuresSet2Size =
2086 std::vector< unsigned int > selectedFeaturesSet2Indexes;
2087 unsigned int selectedFeaturesSet2IndexesSize = 0;
2091 for(
unsigned int feat2Idx = 0 ; feat2Idx < featuresSet2Size ; ++feat2Idx )
2093 interestPointsSet2RTree.
insert(
2104 selectedFeaturesSet2Indexes.resize( featuresSet2Size );
2105 selectedFeaturesSet2IndexesSize = featuresSet2Size;
2106 for(
unsigned int feat2Idx = 0 ; feat2Idx < featuresSet2Size ; ++feat2Idx )
2108 selectedFeaturesSet2Indexes[ feat2Idx ] = feat2Idx;
2114 for(
unsigned int feat1Idx = 0 ; feat1Idx < featuresSet1Size ; ++feat1Idx )
2126 raster1ToRaster2TransfPtr->directMap(
2130 auxEnvelope.
m_lly );
2135 auxEnvelope.
m_llx -= interestPointsSet2RTreeSearchRadius;
2136 auxEnvelope.
m_lly -= interestPointsSet2RTreeSearchRadius;
2137 auxEnvelope.
m_urx += interestPointsSet2RTreeSearchRadius;
2138 auxEnvelope.
m_ury += interestPointsSet2RTreeSearchRadius;
2140 selectedFeaturesSet2Indexes.clear();
2141 interestPointsSet2RTree.
search( auxEnvelope,
2142 selectedFeaturesSet2Indexes );
2144 selectedFeaturesSet2IndexesSize =
static_cast<unsigned int>(selectedFeaturesSet2Indexes.size());
2147 corrMatrixLinePtr = paramsPtr->
m_distMatrixPtr->operator[]( feat1Idx );
2151 for(
unsigned int selectedFeaturesSet2IndexesIdx = 0 ;
2152 selectedFeaturesSet2IndexesIdx < selectedFeaturesSet2IndexesSize ;
2153 ++selectedFeaturesSet2IndexesIdx )
2155 feat2Idx = selectedFeaturesSet2Indexes[ selectedFeaturesSet2IndexesIdx ];
2167 euclideanDist = 0.0;
2169 for( featCol = 0 ; featCol < featureElementsNmb ; ++featCol )
2171 diff = feat1Ptr[ featCol ] - feat2Ptr[ featCol ];
2172 euclideanDist += ( diff * diff );
2175 euclideanDist = std::sqrt( euclideanDist );
2177 corrMatrixLinePtr[ feat2Idx ] = euclideanDist;
static bool createIntegralImage(const FloatsMatrix &inputData, FloatsMatrix &outputData)
Create an integral image.
AbstractParameters * clone() const
Create a clone copy of this instance.
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.
TECOMMONEXPORT unsigned long long int GetTotalVirtualMemory()
Returns the amount of total virtual memory (bytes) that can be claimed by the current process (physic...
~TiePointsLocatorSURFStrategyFactory()
SURF tie-points locator strategy factory.
static float getSurfDxyDerivative(float **bufferPtr, const unsigned int ¢erX, const unsigned int ¢erY, const unsigned int &lobeWidth)
Return a SURF box filter Dxy derivative centered over the given position from the given integral imag...
void reset()
Clear all internal allocated resources and go back to the initial not-initialized state...
unsigned int m_surfScalesNumber
The number of sub-sampling scales to generate, when applicable (default:3, minimum:3).
te::gm::GeometricTransformation const * m_raster1ToRaster2TransfPtr
A pointer to a transformation direct mapping raster 1 indexed coords into raster 2 indexed coords...
TiePointsLocatorSURFStrategy()
A class that represents an R-tree.
~TiePointsLocatorSURFStrategy()
Base exception class for plugin module.
unsigned int m_y
Point Y coord.
double m_searchOptTreeSearchRadius
Optimization tree search radius (pixels).
This class can be used to inform the progress of a task.
unsigned int m_tiePointsSubSectorsSplitFactor
The number of sectors along each direction.
double m_urx
Upper right corner x-coordinate.
boost::mutex * m_syncMutexPtr
TiePointsLocator SURF strategy parameters.
TiePointsLocatorSURFStrategyFactory()
FloatsMatrix * m_distMatrixPtr
float m_feature
Matched interest feature.
Tie-Pointsr locator SURF strategy.
static float getSurfDyyDerivative(float **bufferPtr, const unsigned int ¢erX, const unsigned int ¢erY, const unsigned int &lobeWidth, const unsigned int &lobeRadius)
Return a SURF box filter Dxx derivative centered over the given position from the given integral imag...
unsigned int m_processingBlocksNumber
The raster data will be splitted into this number of blocks for processing.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
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...
unsigned int m_octavesNumber
The number of octaves to generate (minimum:1).
std::vector< InterestPointsSetT > * m_interestPointsSubSectorsPtr
A pointer to a valid interest points container (one element by subsector)..
static unsigned int getSurfOctaveBaseFilterSize(const unsigned int &octaveIndex)
Return the surf octave base filter size (width).
unsigned int unsigned int nCols
TECOMMONEXPORT unsigned int GetPhysProcNumber()
Returns the number of physical processors.
boost::mutex * m_rastaDataAccessMutexPtr
A pointer to a valid mutex to controle raster data access.
double m_llx
Lower left corner x-coordinate.
TiePointsLocator strategy parameters.
An Envelope defines a 2D rectangular region.
static unsigned int getSurfFilterSize(const unsigned int &octaveIndex, const unsigned int &scaleIndex)
Return the surf octave filter size (width).
te::rp::TiePointsLocatorInputParameters m_inputParameters
Input parameters.
The parameters passed to the executeMatchingByEuclideanDistThreadEntry method.
static bool generateSurfFeatures(const InterestPointsSetT &interestPoints, const FloatsMatrix &integralRasterData, InterestPointsSetT &validInterestPoints, FloatsMatrix &features)
Generate a Surf features matrix for the given interes points.
unsigned int getColumnsNumber() const
The number of current matrix columns.
unsigned int m_surfOctavesNumber
The number of octaves to generate, when applicable (default: 2, minimum:2).
mydialect insert("+", new te::da::BinaryOpEncoder("+"))
virtual void reset()
Clear all internal allocated resources and go back to the initial not-initialized state...
FloatsMatrix const * m_featuresSet2Ptr
std::multiset< InterestPointT > InterestPointsSetT
bool getMatchedInterestPoints(te::gm::GeometricTransformation const *const raster1ToRaster2TransfPtr, const double raster1ToRaster2TransfDMapError, MatchedInterestPointsSetT &matchedInterestPoints)
Try to find matched interest points.
int search(const te::gm::Envelope &mbr, std::vector< DATATYPE > &report) const
Range search query.
InterestPointT const * m_interestPointsSet2Ptr
static void executeMatchingByEuclideanDistThreadEntry(ExecuteMatchingByEuclideanDistThreadEntryParams *paramsPtr)
Correlation/Euclidean match thread entry.
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).
FloatsMatrix const * m_integralRasterDataPtr
The integral image raster data.
void reset()
Reset (clear) the active instance data.
Tie-points locator SURF strategy.
Tie-points locator strategy.
double m_lly
Lower left corner y-coordinate.
void getDefaultSpecStrategyParams(std::unique_ptr< TiePointsLocatorStrategyParameters > &defaultSpecParamsPtr) const
Returns a sub-sampled version of the given locator strategy specific input parameters.
te::rp::TiePointsLocatorStrategy * build()
Concrete factories (derived from this one) must implement this method in order to create objects...
TECOMMONEXPORT unsigned long long int GetTotalPhysicalMemory()
Returns the amount of total physical memory (bytes).
Abstract parameters base interface.
static void roolUpBuffer(BufferElementT **bufferPtr, const unsigned int &bufferLinesNumber)
RoolUp a buffer of lines.
The parameters passed to the surfLocatorThreadEntry 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.
float m_feature3
Interest point feature 3 value.
UCharsMatrix const * m_maskRasterDataPtr
The loaded mask raster data pointer (or zero if no mask is avaliable).
InterestPointT const * m_interestPointsSet1Ptr
bool executeMatchingByEuclideanDist(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 eucliean distance.
A generic template matrix.
TemplateElementType ElementTypeT
Public matrix element type definition.
InterestPointT m_point2
Interest point 2.
float m_feature2
Interest point feature 2 value.
bool initialize(const te::rp::TiePointsLocatorInputParameters &inputParameters)
Initialize the strategy.
const Parameters & operator=(const Parameters ¶ms)
static void locateSurfInterestPointsThreadEntry(SurfLocatorThreadParams *paramsPtr)
Surf locator thread entry.
Raster tie-points locator strategy factory base class.
boost::mutex * m_interestPointsAccessMutexPtr
A pointer to a valid mutex to control the output interest points container access.
#define TERP_DEBUG_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
TECOMMONEXPORT unsigned long long int GetUsedVirtualMemory()
Returns the amount of used virtual memory (bytes) for the current process (physical + swapped)...
bool locateSurfInterestPoints(const unsigned int maxInterestPoints, const FloatsMatrix &integralRasterData, UCharsMatrix const *maskRasterDataPtr, InterestPointsSetT &interestPoints) const
SURF interest points locator.
FloatsMatrix const * m_featuresSet1Ptr
unsigned int m_maxInterestPointsBySubSector
The maximum number of interest points by sub-sector.
bool m_isInitialized
true if this instance is initialized.
unsigned int getAutoMaxTiePointsNumber() const
Returns a automatically calculated optimum maximum amount tie-points following the current parameters...
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 * m_nextFeatureIdx1ToProcessPtr
static float getSurfDxxDerivative(float **bufferPtr, const unsigned int ¢erX, const unsigned int ¢erY, const unsigned int &lobeWidth, const unsigned int &lobeRadius)
Return a SURF box filter Dyy derivative centered over the given position from the given integral imag...
double m_surfMaxNormEuclideanDist
The maximum acceptable euclidean distance when matching features (when applicable), default:0.75, valid range: [0,1].
unsigned int getLinesNumber() const
The number of current matrix lines.
std::multiset< MatchedInterestPointsT > MatchedInterestPointsSetT
static bool checkForDuplicatedInterestPoints(const InterestPointsSetT &interestPoints, double &x, double &y)
Check for duplicated interest points.
#define TERP_TRUE_OR_THROW(value, message)
Checks if value is true and throws an exception if not.
unsigned int m_scalesNumber
Thread return value pointer.
InterestPointT m_point1
Interest point 1.
static float getHaarYVectorIntensity(BufferType &buffer, const unsigned int ¢erX, const unsigned int ¢erY, const unsigned int &radius)
Return a Haar Y intesity vector for the window centered at the given point.
virtual AbstractParameters * clone() const =0
Create a clone copy of this instance.
static float getHaarXVectorIntensity(BufferType &buffer, const unsigned int ¢erX, const unsigned int ¢erY, const unsigned int &radius)
Return a Haar X intesity vector for the window centered at the given point.
float m_feature1
Interest point feature 1 value.