diff --git a/Modules/Feature/Descriptors/test/CMakeLists.txt b/Modules/Feature/Descriptors/test/CMakeLists.txt
index 01e15723f36c1d542e6822989db9dfffeb4b4c69..0fe85ecd942620afc349c8150998d3dc3f4b3cc2 100644
--- a/Modules/Feature/Descriptors/test/CMakeLists.txt
+++ b/Modules/Feature/Descriptors/test/CMakeLists.txt
@@ -22,54 +22,19 @@ otb_module_test()
 
 set(OTBDescriptorsTests
 otbDescriptorsTestDriver.cxx
-otbImageToSURFKeyPointSetFilterOutputDescriptorAscii.cxx
-otbImageToSIFTKeyPointSetFilterOutputInterestPointAscii.cxx
 otbHistogramOfOrientedGradientCovariantImageFunction.cxx
-otbImageToSURFKeyPointSetFilterOutputInterestPointAscii.cxx
-otbKeyPointSetsMatchingFilter.cxx
-otbImageToSIFTKeyPointSetFilterOutputDescriptorAscii.cxx
-otbImageToSIFTKeyPointSetFilterOutputAscii.cxx
 otbFourierMellinImageFilter.cxx
 otbImageToHessianDeterminantImageFilter.cxx
-otbImageToSIFTKeyPointSetFilterOutputImage.cxx
 otbFourierMellinDescriptors.cxx
-otbImageToSIFTKeyPointSetFilterDistanceMap.cxx
+otbKeyPointsAlgorithmsTest.cxx
 )
 
-if(OTB_USE_SIFTFAST)
-  list(APPEND OTBDescriptorsTests
-       otbImageToFastSIFTKeyPointSetFilterOutputInterestPointAscii.cxx
-       otbImageToFastSIFTKeyPointSetFilterOutputDescriptorAscii.cxx
-       )
-endif()
-
 add_executable(otbDescriptorsTestDriver ${OTBDescriptorsTests})
 target_link_libraries(otbDescriptorsTestDriver ${OTBDescriptors-Test_LIBRARIES})
 otb_module_target_label(otbDescriptorsTestDriver)
 
 # Tests Declaration
 
-otb_add_test(NAME feTvImageToSURFKeyPointSetFilterSceneOutputDescriptorAscii COMMAND otbDescriptorsTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSURFKeyPointSetFilterSceneKeysOutputDescriptor.txt
-  ${TEMP}/feTvImageToSURFKeyPointSetFilterSceneKeysOutputDescriptor.txt
-  otbImageToSURFKeyPointSetFilterOutputDescriptorAscii
-  ${INPUTDATA}/scene.png
-  ${TEMP}/feTvImageToSURFKeyPointSetFilterSceneKeysOutputDescriptor.txt
-  3 3
-  )
-
-
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterSceneOutputInterestPointAscii COMMAND otbDescriptorsTestDriver
-  --ignore-order --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSIFTKeyPointSetFilterSceneKeysOutputInterestPoint.txt
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSceneKeysOutputInterestPoint.txt
-  otbImageToSIFTKeyPointSetFilterOutputInterestPointAscii
-  ${INPUTDATA}/scene.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSceneKeysOutputInterestPoint.txt
-  6 3 0.08 10.0
-  )
-
 otb_add_test(NAME feTvHistogramOfOrientedGradientCovariantImageFunction COMMAND otbDescriptorsTestDriver
   --compare-ascii ${EPSILON_8}
   ${BASELINE_FILES}/feTvHistogramOfOrientedGradientCovariantImageFunction.txt
@@ -80,94 +45,7 @@ otb_add_test(NAME feTvHistogramOfOrientedGradientCovariantImageFunction COMMAND
   5 273 64
   )
 
-otb_add_test(NAME feTvImageToSURFKeyPointSetFilterSceneOutputInterestPointAscii COMMAND otbDescriptorsTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSURFKeyPointSetFilterSceneKeysOutputInterestPoint.txt
-  ${TEMP}/feTvImageToSURFKeyPointSetFilterSceneKeysOutputInterestPoint.txt
-  otbImageToSURFKeyPointSetFilterOutputInterestPointAscii
-  ${INPUTDATA}/scene.png
-  ${TEMP}/feTvImageToSURFKeyPointSetFilterSceneKeysOutputInterestPoint.txt
-  3 3
-  )
-
-otb_add_test(NAME feTvKeyPointSetsMatchingFilter COMMAND otbDescriptorsTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvKeyPointSetsMatchingFilterOutputAscii.txt
-  ${TEMP}/feTvKeyPointSetsMatchingFilterOutputAscii.txt
-  otbKeyPointSetsMatchingFilter
-  ${TEMP}/feTvKeyPointSetsMatchingFilterOutputAscii.txt
-  0.6 0
-  )
-
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterSceneDescriptorAscii COMMAND otbDescriptorsTestDriver
-  --ignore-order --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSIFTKeyPointSetFilterSceneKeysOutputDescriptor.txt
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSceneKeysOutputDescriptor.txt
-  otbImageToSIFTKeyPointSetFilterOutputDescriptorAscii
-  ${INPUTDATA}/scene.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSceneKeysOutputDescriptor.txt
-  6 3 0.08 10.0
-  )
 
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterGridOutputAscii COMMAND otbDescriptorsTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSIFTKeyPointSetFilterGridKeysOutput.txt
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterGridKeysOutput.txt
-  otbImageToSIFTKeyPointSetFilterOutputAscii
-  ${INPUTDATA}/damier.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterGridKeysOutput.txt
-  7 3 0.01 10.0
-  )
-
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterSquareRotatedOutputAscii COMMAND otbDescriptorsTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSIFTKeyPointSetFilterSquareRotatedKeysOutput.txt
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSquareRotatedKeysOutput.txt
-  otbImageToSIFTKeyPointSetFilterOutputAscii
-  ${INPUTDATA}/carre_ori.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSquareRotatedKeysOutput.txt
-  7 3 0.01 10.0
-  )
-
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterSquare2OutputAscii COMMAND otbDescriptorsTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSIFTKeyPointSetFilterSquareKeysOutput2.txt
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSquareKeysOutput2.txt
-  otbImageToSIFTKeyPointSetFilterOutputAscii
-  ${INPUTDATA}/carre.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSquareKeysOutput2.txt
-  1 3 0.2 0.9
-  )
-
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterSquareRotated2OutputAscii COMMAND otbDescriptorsTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSIFTKeyPointSetFilterSquareRotatedKeysOutput2.txt
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSquareRotatedKeysOutput2.txt
-  otbImageToSIFTKeyPointSetFilterOutputAscii
-  ${INPUTDATA}/carre_ori.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSquareRotatedKeysOutput2.txt
-  1 3 0.215 10.0
-  )
-
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterSquareOutputAscii COMMAND otbDescriptorsTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSIFTKeyPointSetFilterSquareKeysOutput.txt
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSquareKeysOutput.txt
-  otbImageToSIFTKeyPointSetFilterOutputAscii
-  ${INPUTDATA}/carre.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSquareKeysOutput.txt
-  7 3 0.01 10.0
-  )
-
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterQB_SuburbOutputAscii COMMAND otbDescriptorsTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSIFTKeyPointSetFilterQB_SuburbOutputAscii.txt
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterQB_SuburbOutputAscii.txt
-  otbImageToSIFTKeyPointSetFilterOutputAscii
-  ${INPUTDATA}/QB_Suburb.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterQB_SuburbOutputAscii.txt
-  2 3 5.0 0.0
-  )
 
 otb_add_test(NAME feTvForwardFourierMellinImageFilter COMMAND otbDescriptorsTestDriver
   --compare-n-images ${EPSILON_6} 2
@@ -190,26 +68,6 @@ otb_add_test(NAME feTvImageToHessianDeterminantImageFilter COMMAND otbDescriptor
   1.5
   )
 
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterSquareOutputImage COMMAND otbDescriptorsTestDriver
-  --compare-image ${EPSILON_8}
-  ${BASELINE}/feTvImageToSIFTKeyPointSetFilterSquareImageOutput.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSquareImageOutput.png
-  otbImageToSIFTKeyPointSetFilterOutputImage
-  ${INPUTDATA}/carre.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterSquareImageOutput.png
-  7 3 0.01 10.0
-  )
-
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterGridOutputImage COMMAND otbDescriptorsTestDriver
-  --compare-image ${EPSILON_8}
-  ${BASELINE}/feTvImageToSIFTKeyPointSetFilterGridImageOutput.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterGridImageOutput.png
-  otbImageToSIFTKeyPointSetFilterOutputImage
-  ${INPUTDATA}/damier.png
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterGridImageOutput.png
-  7 3 0.01 10.0
-  )
-
 otb_add_test(NAME feTvFourierMellinDescriptorsRotationInvariant COMMAND otbDescriptorsTestDriver
   otbFourierMellinDescriptorsRotationInvariant
   ${INPUTDATA}/poupees.png
@@ -237,41 +95,7 @@ otb_add_test(NAME feTvFourierMellinDescriptors COMMAND otbDescriptorsTestDriver
   ${TEMP}/feTvFourierMellinDescriptors.txt
   )
 
-otb_add_test(NAME feTvImageToSIFTKeyPointSetFilterDistanceMap COMMAND otbDescriptorsTestDriver
-  --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToSIFTKeyPointSetFilterDistanceMap.txt
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterDistanceMap.txt
-  --ignore-lines-with 2 INFO DEBUG
-  otbImageToSIFTKeyPointSetFilterDistanceMap
-  ${INPUTDATA}/scene.png
-  6 3 0.08 10.0
-  15.0 # rotation
-  1.2 # zoom factor
-  10 255
-  ${TEMP}/feTvImageToSIFTKeyPointSetFilterDistanceMap.txt
-  )
-
-if(OTB_USE_SIFTFAST)
-otb_add_test(NAME feTvImageToFastSIFTKeyPointSetFilterSceneOutputInterestPointAscii COMMAND otbDescriptorsTestDriver
-  --ignore-order --compare-ascii ${EPSILON_3}
-  ${BASELINE_FILES}/feTvImageToFastSIFTKeyPointSetFilterSceneKeysOutputInterestPoint.txt
-  ${TEMP}/feTvImageToFastSIFTKeyPointSetFilterSceneKeysOutputInterestPoint.txt
-  otbImageToFastSIFTKeyPointSetFilterOutputInterestPointAscii
-  ${INPUTDATA}/ROI_IKO_PAN_LesHalles_sub.tif
-  ${TEMP}/feTvImageToFastSIFTKeyPointSetFilterSceneKeysOutputInterestPoint.txt
-  6
-  )
-
-# RK: 06/2016. the root cause of this test having different output on platforms comes from libsiftfast (3rd party code)
-# Until there is a fix, that failure cannot be attributed to OTB or dashboard results
-#  --ignore-order --epsilon-boundary 0.01 --compare-ascii ${EPSILON_2}
-#  ${BASELINE_FILES}/feTvImageToFastSIFTKeyPointSetFilterSceneKeysOutputDescriptor.txt
-#  ${TEMP}/feTvImageToFastSIFTKeyPointSetFilterSceneKeysOutputDescriptor.txt
-
-otb_add_test(NAME feTvImageToFastSIFTKeyPointSetFilterSceneOutputDescriptorAscii COMMAND otbDescriptorsTestDriver
-  otbImageToFastSIFTKeyPointSetFilterOutputDescriptorAscii
-  ${INPUTDATA}/ROI_IKO_PAN_LesHalles_sub.tif
-  ${TEMP}/feTvImageToFastSIFTKeyPointSetFilterSceneKeysOutputDescriptor.txt
-  6
-  )
-endif()
+otb_add_test(NAME feTvKeyPointsAlgorithmsTest COMMAND otbDescriptorsTestDriver
+  otbKeyPointsAlgorithmsTest
+  ${INPUTDATA}/QB_TOULOUSE_RpcTag_100_100.tif
+)
diff --git a/Modules/Feature/Descriptors/test/otbDescriptorsTestDriver.cxx b/Modules/Feature/Descriptors/test/otbDescriptorsTestDriver.cxx
index 9a319d5b1663b957d10725f9da78a89d6321b101..3a6d21657d06621d9b6663e150cfb5bc77514b08 100644
--- a/Modules/Feature/Descriptors/test/otbDescriptorsTestDriver.cxx
+++ b/Modules/Feature/Descriptors/test/otbDescriptorsTestDriver.cxx
@@ -22,22 +22,11 @@
 
 void RegisterTests()
 {
-  REGISTER_TEST(otbImageToSURFKeyPointSetFilterOutputDescriptorAscii);
-  REGISTER_TEST(otbImageToSIFTKeyPointSetFilterOutputInterestPointAscii);
   REGISTER_TEST(otbHistogramOfOrientedGradientCovariantImageFunction);
-  REGISTER_TEST(otbImageToSURFKeyPointSetFilterOutputInterestPointAscii);
-  REGISTER_TEST(otbKeyPointSetsMatchingFilter);
-  REGISTER_TEST(otbImageToSIFTKeyPointSetFilterOutputDescriptorAscii);
-  REGISTER_TEST(otbImageToSIFTKeyPointSetFilterOutputAscii);
   REGISTER_TEST(otbFourierMellinImageFilter);
   REGISTER_TEST(otbImageToHessianDeterminantImageFilter);
-  REGISTER_TEST(otbImageToSIFTKeyPointSetFilterOutputImage);
   REGISTER_TEST(otbFourierMellinDescriptors);
   REGISTER_TEST(otbFourierMellinDescriptorsScaleInvariant);
   REGISTER_TEST(otbFourierMellinDescriptorsRotationInvariant);
-  REGISTER_TEST(otbImageToSIFTKeyPointSetFilterDistanceMap);
-#ifdef OTB_USE_SIFTFAST
-  REGISTER_TEST(otbImageToFastSIFTKeyPointSetFilterOutputInterestPointAscii);
-  REGISTER_TEST(otbImageToFastSIFTKeyPointSetFilterOutputDescriptorAscii);
-#endif
+  REGISTER_TEST(otbKeyPointsAlgorithmsTest);
 }
diff --git a/Modules/Feature/Descriptors/test/otbImageToFastSIFTKeyPointSetFilterOutputDescriptorAscii.cxx b/Modules/Feature/Descriptors/test/otbImageToFastSIFTKeyPointSetFilterOutputDescriptorAscii.cxx
deleted file mode 100644
index a711078ca9fb094924b5088c27433e524a799b37..0000000000000000000000000000000000000000
--- a/Modules/Feature/Descriptors/test/otbImageToFastSIFTKeyPointSetFilterOutputDescriptorAscii.cxx
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <iomanip>
-#include <iostream>
-#include <fstream>
-#include <algorithm>
-
-#include "otbSiftFastImageFilter.h"
-#include "otbImageFileReader.h"
-#include "itkPointSet.h"
-#include "itkVariableLengthVector.h"
-#include "itkRGBPixel.h"
-#include "itkImageRegionIterator.h"
-
-bool CMPData(std::vector<float>  a, std::vector<float>  b)
-{
-  return lexicographical_compare(a.begin(), a.begin() + 2, b.begin(), b.begin() + 2);
-}
-
-int otbImageToFastSIFTKeyPointSetFilterOutputDescriptorAscii(int itkNotUsed(argc), char * argv[])
-{
-  const char * infname = argv[1];
-  const char * outfname = argv[2];
-
-  const unsigned int scales = atoi(argv[3]);
-
-  typedef float RealType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<RealType, Dimension>                   ImageType;
-  typedef itk::VariableLengthVector<RealType>               RealVectorType;
-  typedef otb::ImageFileReader<ImageType>                   ReaderType;
-  typedef itk::PointSet<RealVectorType, Dimension>          PointSetType;
-  typedef otb::SiftFastImageFilter<ImageType, PointSetType> ImageToFastSIFTKeyPointSetFilterType;
-
-  // Iterator types
-  typedef PointSetType::PointsContainer    PointsContainerType;
-  typedef PointsContainerType::Iterator    PointsIteratorType;
-  typedef PointSetType::PointDataContainer PointDataContainerType;
-  typedef PointDataContainerType::Iterator PointDataIteratorType;
-
-  typedef std::vector<float>          siftDataVector;
-  typedef std::vector<siftDataVector> ImageDataType;   //Kind of PointSet with vectors
-
-  // Instantiating object
-  ReaderType::Pointer                           reader = ReaderType::New();
-  ImageToFastSIFTKeyPointSetFilterType::Pointer filter = ImageToFastSIFTKeyPointSetFilterType::New();
-
-  //Instantiation of std::vector for lexicographiacal sorting
-  ImageDataType imageData;
-
-  reader->SetFileName(infname);
-  filter->SetInput(reader->GetOutput());
-  filter->SetScalesNumber(scales);
-  filter->Update();
-
-  PointsIteratorType    pIt = filter->GetOutput()->GetPoints()->Begin();
-  PointDataIteratorType pDataIt = filter->GetOutput()->GetPointData()->Begin();
-
-  std::ofstream outfile(outfname);
-
-  outfile << "Number of scales: " << scales << std::endl;
-  outfile << "Number of SIFT key points: " << filter->GetOutput()->GetNumberOfPoints() << std::endl;
-
-  if (filter->GetOutput()->GetPointData()->Size() != filter->GetOutput()->GetPoints()->Size()) return EXIT_FAILURE;
-  if (filter->GetOutput()->GetPointData()->Size() == 0) return EXIT_FAILURE;
-
-  // Copy the PointSet to std::vector< std::vector >
-  while (pIt != filter->GetOutput()->GetPoints()->End() &&  pDataIt != filter->GetOutput()->GetPointData()->End())
-    {
-    siftDataVector siftData;
-
-    siftData.push_back(pIt.Value()[0]);
-    siftData.push_back(pIt.Value()[1]);
-
-    unsigned int lIterDesc = 0;
-    while (lIterDesc < pDataIt.Value().Size())
-      {
-      siftData.push_back(pDataIt.Value()[lIterDesc]);
-      lIterDesc++;
-      }
-
-    imageData.push_back(siftData);
-    ++pIt;
-    ++pDataIt;
-    }
-
-  //Sorting the vectors
-  ImageDataType::iterator itData;
-  sort(imageData.begin(), imageData.end(), CMPData);
-
-  itData = imageData.begin();
-  unsigned int stopVal = static_cast<unsigned int>(filter->GetOutput()->GetPointData()->Begin().Value().Size());
-
-  while (itData != imageData.end())
-    {
-    unsigned int itDescriptor = 0;
-    outfile << "[ ";
-    while (itDescriptor < stopVal)
-    //while (itDescriptor < static_cast<int>((*itData).size()-2) )
-      {
-      outfile << std::fixed << std::setprecision(4) << (*itData)[itDescriptor + 2] << " ";
-      itDescriptor++;
-      }
-    outfile << "]" << std::endl;
-    ++itData;
-    }
-
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Descriptors/test/otbImageToFastSIFTKeyPointSetFilterOutputInterestPointAscii.cxx b/Modules/Feature/Descriptors/test/otbImageToFastSIFTKeyPointSetFilterOutputInterestPointAscii.cxx
deleted file mode 100644
index 46b8cfcb022ab690337813800049d8c0cc0ed00e..0000000000000000000000000000000000000000
--- a/Modules/Feature/Descriptors/test/otbImageToFastSIFTKeyPointSetFilterOutputInterestPointAscii.cxx
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iomanip>
-#include <iostream>
-#include <fstream>
-#include <algorithm>
-
-#include "otbSiftFastImageFilter.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-#include "itkPointSet.h"
-#include "itkVariableLengthVector.h"
-#include "itkRGBPixel.h"
-#include "itkImageRegionIterator.h"
-
-bool CMP(std::vector<float>  a, std::vector<float>  b)
-{
-  return lexicographical_compare(a.begin(), a.begin() + 2, b.begin(), b.begin() + 2);
-}
-
-int
-otbImageToFastSIFTKeyPointSetFilterOutputInterestPointAscii( int itkNotUsed( argc ), char * argv[] )
-{
-  const char * infname = argv[1];
-  const char * outfname = argv[2];
-
-  const unsigned int scales = atoi(argv[3]);
-  typedef float RealType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<RealType, Dimension>          ImageType;
-  typedef itk::VariableLengthVector<RealType>      RealVectorType;
-  typedef otb::ImageFileReader<ImageType>          ReaderType;
-  typedef itk::PointSet<RealVectorType, Dimension> PointSetType;
-
-  typedef otb::SiftFastImageFilter<ImageType, PointSetType> ImageToFastSIFTKeyPointSetFilterType;
-
-  // PointSet iterator types
-  typedef PointSetType::PointsContainer    PointsContainerType;
-  typedef PointsContainerType::Iterator    PointsIteratorType;
-  typedef PointSetType::PointDataContainer PointDataContainerType;
-  typedef PointDataContainerType::Iterator PointDataIteratorType;
-
-  typedef std::vector< RealType > siftDataVector;
-  typedef std::vector<siftDataVector> ImageDataType;   //Kind of PointSet with vectors
-
-  // Instantiating object
-  ReaderType::Pointer                           reader = ReaderType::New();
-  ImageToFastSIFTKeyPointSetFilterType::Pointer filter = ImageToFastSIFTKeyPointSetFilterType::New();
-
-  //Instantiation of std::vector for lexicographiacal sorting
-  ImageDataType imageData;
-
-  reader->SetFileName(infname);
-  filter->SetInput(reader->GetOutput());
-  filter->SetScalesNumber(scales);
-  filter->Update();
-  PointsIteratorType    pIt = filter->GetOutput()->GetPoints()->Begin();
-  PointDataIteratorType pDataIt = filter->GetOutput()->GetPointData()->Begin();
-
-  assert(
-    filter->GetOutput()->GetPoints()->Size() ==
-    filter->GetOutput()->GetPointData()->Size() );
-
-  std::ofstream outfile(outfname);
-
-  outfile << "Number of scales: " << scales << std::endl;
-
-  outfile << "Number of SIFT key points: "
-	  << filter->GetOutput()->GetNumberOfPoints()
-	  << std::endl;
-
-  outfile << "Number of points: "
-	  << filter->GetOutput()->GetPoints()->Size()
-	  << std::endl;
-
-  outfile << "Number of points data: "
-	  << filter->GetOutput()->GetPointData()->Size()
-	  << std::endl;
-
-  if( filter->GetOutput()->GetPoints()->Size() !=
-      filter->GetOutput()->GetPointData()->Size() )
-    return EXIT_FAILURE;
-
-  // Copy the PointSet to std::vector< std::vector >
-  while (pIt != filter->GetOutput()->GetPoints()->End())
-    {
-    siftDataVector siftData;
-
-    siftData.push_back(pIt.Value()[0]);
-    siftData.push_back(pIt.Value()[1]);
-
-    unsigned int lIterDesc = 0;
-    while (lIterDesc < pDataIt.Value().Size())
-      {
-      siftData.push_back(pDataIt.Value()[lIterDesc]);
-      lIterDesc++;
-      }
-
-    imageData.push_back(siftData);
-    ++pIt;
-    ++pDataIt;
-    }
-
-  //Sorting the vectors
-  ImageDataType::iterator itData;
-  sort(imageData.begin(), imageData.end(), CMP);
-
-  itData = imageData.begin();
-
-  while (itData != imageData.end())
-    {
-    outfile << "[" << std::fixed << std::setprecision(1) << (*itData)[0] << ", " << std::setprecision(1) <<
-      (*itData)[1] << "]" << std::endl;
-
-    ++itData;
-    }
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterDistanceMap.cxx b/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterDistanceMap.cxx
deleted file mode 100644
index 2ca4aa327ac2f9d804724acd6c900dc149cbe824..0000000000000000000000000000000000000000
--- a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterDistanceMap.cxx
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iostream>
-#include <fstream>
-
-#include "itkUnaryFunctorImageFilter.h"
-#include "itkPointSet.h"
-#include "itkVariableLengthVector.h"
-#include "itkResampleImageFilter.h"
-#include "itkDanielssonDistanceMapImageFilter.h"
-#include "itkPointSetToImageFilter.h"
-#include "itkRescaleIntensityImageFilter.h"
-
-#include "otbImageToSIFTKeyPointSetFilter.h"
-#include "otbImage.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-#include "itkAffineTransform.h"
-
-typedef itk::VariableLengthVector<float> RealVectorType;
-typedef itk::PointSet<RealVectorType, 2> PointSetType;
-typedef otb::Image<float, 2>             ImageType;
-typedef otb::Image<unsigned char, 2>     OutputImageType;
-
-// PointSet iterator types
-typedef PointSetType::PointsContainer    PointsContainerType;
-typedef PointsContainerType::Iterator    PointsIteratorType;
-typedef PointSetType::PointDataContainer PointDataContainerType;
-typedef PointDataContainerType::Iterator PointDataIteratorType;
-
-// Filter
-typedef otb::ImageFileReader<ImageType>       ReaderType;
-typedef otb::ImageFileWriter<OutputImageType> WriterType;
-typedef otb::ImageFileWriter<ImageType>       WriterInputType;
-
-OutputImageType::Pointer sift(ImageType::Pointer input,
-                              const unsigned int octaves,
-                              const unsigned int scales,
-                              const float threshold,
-                              const float ratio,
-                              const char* siftFileName)
-{
-  typedef otb::ImageToSIFTKeyPointSetFilter<ImageType, PointSetType> SiftFilterType;
-  typedef itk::PointSetToImageFilter<PointSetType, OutputImageType>  PointSetFilterType;
-
-  SiftFilterType::Pointer     sift = SiftFilterType::New();
-  PointSetFilterType::Pointer pointSetFilter = PointSetFilterType::New();
-
-  sift->SetInput(input);
-  sift->SetOctavesNumber(octaves);
-  sift->SetScalesNumber(scales);
-  sift->SetDoGThreshold(threshold);
-  sift->SetEdgeThreshold(ratio);
-
-  pointSetFilter->SetInput(sift->GetOutput());
-  pointSetFilter->SetOutsideValue(0);
-  pointSetFilter->SetInsideValue(255);
-  pointSetFilter->SetSize(input->GetLargestPossibleRegion().GetSize());
-  pointSetFilter->SetSpacing(input->GetSignedSpacing());
-  pointSetFilter->SetOrigin(input->GetOrigin());
-  pointSetFilter->Update();
-
-  WriterType::Pointer writer = WriterType::New();
-  writer->SetFileName(siftFileName);
-  writer->SetInput(pointSetFilter->GetOutput());
-  //writer->Update();
-
-  return pointSetFilter->GetOutput();
-}
-
-OutputImageType::Pointer ddm(OutputImageType::Pointer input,
-                             const char* ddmFileName)
-{
-  typedef itk::DanielssonDistanceMapImageFilter <OutputImageType, OutputImageType> DDMFilterType;
-  DDMFilterType::Pointer ddmFilter = DDMFilterType::New();
-
-  ddmFilter->SetInput(input);
-  ddmFilter->InputIsBinaryOn();
-  ddmFilter->Update();
-
-  WriterType::Pointer writer = WriterType::New();
-  writer->SetFileName(ddmFileName);
-  writer->SetInput(ddmFilter->GetOutput());
-  //writer->Update();
-
-  return ddmFilter->GetOutput();
-}
-
-ImageType::Pointer rotate(ImageType::Pointer input,
-                          const unsigned int rotation)
-{
-  typedef itk::AffineTransform<double, 2> TransformType;
-  typedef itk::ResampleImageFilter<ImageType, ImageType>
-  ResampleFilterType;
-  ResampleFilterType::Pointer resampler = ResampleFilterType::New();
-
-  TransformType::Pointer          transform = TransformType::New();
-  TransformType::OutputVectorType translation1;
-  TransformType::OutputVectorType translation2;
-
-  const ImageType::SpacingType& spacing = input->GetSignedSpacing();
-  const ImageType::PointType&   origin  = input->GetOrigin();
-  ImageType::SizeType           size = input->GetLargestPossibleRegion().GetSize();
-
-  const double imageCenterX = origin[0] + spacing[0] * size[0] / 2.0;
-  const double imageCenterY = origin[1] + spacing[1] * size[1] / 2.0;
-  const double degreesToRadians = atan(1.0) / 45.0;
-  const double angle = rotation * degreesToRadians;
-
-  translation1[0] = -imageCenterX;
-  translation1[1] = -imageCenterY;
-  translation2[0] = imageCenterX;
-  translation2[1] = imageCenterY;
-
-  transform->Translate(translation1);
-  transform->Rotate2D(-angle, false);
-  transform->Translate(translation2);
-
-  resampler->SetOutputOrigin(origin);
-  resampler->SetOutputSpacing(spacing);
-  resampler->SetSize(size);
-  resampler->SetTransform(transform);
-  resampler->SetInput(input);
-  resampler->Update();
-  return resampler->GetOutput();
-}
-
-OutputImageType::Pointer invRotate(OutputImageType::Pointer input,
-                                   const unsigned int rotation)
-{
-  typedef itk::AffineTransform<double, 2> TransformType;
-  typedef itk::ResampleImageFilter<OutputImageType, OutputImageType>
-  ResampleFilterType;
-  ResampleFilterType::Pointer resampler = ResampleFilterType::New();
-
-  TransformType::Pointer          transform = TransformType::New();
-  TransformType::OutputVectorType translation1;
-  TransformType::OutputVectorType translation2;
-
-  const ImageType::SpacingType& spacing = input->GetSignedSpacing();
-  const ImageType::PointType&   origin  = input->GetOrigin();
-  ImageType::SizeType           size = input->GetLargestPossibleRegion().GetSize();
-
-  const double imageCenterX = origin[0] + spacing[0] * size[0] / 2.0;
-  const double imageCenterY = origin[1] + spacing[1] * size[1] / 2.0;
-
-  const double degreesToRadians = atan(1.0) / 45.0;
-  const double angle = rotation * degreesToRadians;
-
-  translation1[0] = -imageCenterX;
-  translation1[1] = -imageCenterY;
-  translation2[0] = imageCenterX;
-  translation2[1] = imageCenterY;
-
-  transform->Translate(translation1);
-  transform->Rotate2D(angle, false);
-  transform->Translate(translation2);
-
-  resampler->SetOutputOrigin(origin);
-  resampler->SetOutputSpacing(spacing);
-  resampler->SetSize(size);
-  resampler->SetTransform(transform);
-  resampler->SetInput(input);
-  resampler->Update();
-  return resampler->GetOutput();
-}
-
-ImageType::Pointer zoom(ImageType::Pointer input,
-                        const unsigned int zoomFactor)
-{
-  typedef itk::ShrinkImageFilter<ImageType, ImageType> ShrinkFilterType;
-  ShrinkFilterType::Pointer shrink = ShrinkFilterType::New();
-
-  shrink->SetInput(input);
-  shrink->SetShrinkFactors(zoomFactor);
-  shrink->Update();
-
-  return shrink->GetOutput();
-}
-
-OutputImageType::Pointer invZoom(OutputImageType::Pointer input,
-                                 const unsigned int zoomFactor)
-{
-  typedef itk::ExpandImageFilter<OutputImageType, OutputImageType> ExpandFilterType;
-  ExpandFilterType::Pointer expand = ExpandFilterType::New();
-
-  expand->SetInput(input);
-  expand->SetExpandFactors(zoomFactor);
-  expand->Update();
-
-  return expand->GetOutput();
-}
-
-ImageType::Pointer contrast(ImageType::Pointer input,
-                            const unsigned int contrastMin,
-                            const unsigned int contrastMax)
-{
-  typedef itk::RescaleIntensityImageFilter<ImageType, ImageType> RescaleFilterType;
-  RescaleFilterType::Pointer rescaler = RescaleFilterType::New();
-
-  rescaler->SetInput(input);
-  rescaler->SetOutputMinimum(static_cast<RescaleFilterType::OutputPixelType>(contrastMin));
-  rescaler->SetOutputMaximum(static_cast<RescaleFilterType::OutputPixelType>(contrastMax));
-  rescaler->Update();
-  return rescaler->GetOutput();
-}
-
-OutputImageType::Pointer invContrast(OutputImageType::Pointer input,
-                                     const unsigned int itkNotUsed(contrastMin),
-                                     const unsigned int itkNotUsed(contrastMax))
-{
-  return input;
-}
-
-void subtract(OutputImageType::Pointer image1,
-              OutputImageType::Pointer image2,
-              const char* subtractFileName)
-{
-  typedef itk::SubtractImageFilter<OutputImageType, OutputImageType, ImageType> SubtractFilterType;
-  typedef itk::MinimumMaximumImageCalculator<ImageType>                         MaximumCalculatorType;
-  typedef itk::RescaleIntensityImageFilter<ImageType, OutputImageType>          OutputRescaleFilterType;
-
-  SubtractFilterType::Pointer    subtract = SubtractFilterType::New();
-  MaximumCalculatorType::Pointer maximumCalculator = MaximumCalculatorType::New();
-
-  subtract->SetInput1(image1);
-  subtract->SetInput2(image2);
-  subtract->Update();
-
-  OutputRescaleFilterType::Pointer rescaler = OutputRescaleFilterType::New();
-  rescaler->SetInput(subtract->GetOutput());
-  rescaler->SetOutputMinimum(0);
-  rescaler->SetOutputMaximum(255);
-
-  WriterType::Pointer writer = WriterType::New();
-  writer->SetFileName(subtractFileName);
-  writer->SetInput(rescaler->GetOutput());
-  //writer->Update();
-
-  maximumCalculator->SetImage(subtract->GetOutput());
-  maximumCalculator->Compute();
-
-  std::cout << "Mix(sub)= " << maximumCalculator->GetMinimum() << " ";
-  std::cout << "Max(sub)= " << maximumCalculator->GetMaximum() << std::endl;
-}
-
-int otbImageToSIFTKeyPointSetFilterDistanceMap(int argc, char * argv[])
-{
-
-  if (argc < 10)
-    {
-    std::cout << "Missing arguments " << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  // Input Image file name
-  const char * infname = argv[1];
-  const char * outfname = argv[10];
-
-  const unsigned int octaves = atoi(argv[2]);
-  const unsigned int scales = atoi(argv[3]);
-  const float        threshold = atof(argv[4]);
-  const float        ratio = atof(argv[5]);
-
-  // Rotation angle [0, 360[
-  const unsigned int rotation = atoi(argv[6]);
-
-  // Zoom factor
-  const unsigned int zoomFactor = atoi(argv[7]);
-
-  // contrast factor
-  const unsigned int contrastMin = atoi(argv[8]);
-  const unsigned int contrastMax = atoi(argv[9]);
-
-  //redirect cout to a file
-  std::ofstream   file(outfname);
-  std::streambuf* strm_buffer = std::cout.rdbuf(); //save the cout to put it
-                                             //back later
-  std::cout.rdbuf(file.rdbuf());
-
-  ReaderType::Pointer reader = ReaderType::New();
-  reader->SetFileName(infname);
-  reader->Update();
-
-  ImageType::Pointer _rotated =
-    rotate(reader->GetOutput(), rotation);
-  ImageType::Pointer _zoomed =
-    zoom(reader->GetOutput(), zoomFactor);
-  ImageType::Pointer _contrasted =
-    contrast(reader->GetOutput(), contrastMin, contrastMax);
-
-  ImageType::Pointer _combined1 = zoom(_rotated, zoomFactor);
-  ImageType::Pointer _combined2 = contrast(_combined1, contrastMin, contrastMax);
-
-  OutputImageType::Pointer sift_base =
-    sift(reader->GetOutput(), octaves, scales, threshold, ratio, "sift_base.png");
-
-  OutputImageType::Pointer _sift_rotated =
-    sift(_rotated, octaves, scales, threshold, ratio, "sift_rotated.png");
-
-  OutputImageType::Pointer _sift_zoomed =
-    sift(_zoomed, octaves, scales, threshold, ratio, "sift_zoomed.png");
-
-  OutputImageType::Pointer _sift_contrasted =
-    sift(_contrasted, octaves, scales, threshold, ratio, "sift_contrasted.png");
-
-  OutputImageType::Pointer _sift_combined =
-    sift(_combined2, octaves, scales, threshold, ratio, "sift_combined.png");
-
-  OutputImageType::Pointer sift_rotated =
-    invRotate(_sift_rotated, rotation);
-
-  OutputImageType::Pointer sift_zoomed =
-    invZoom(_sift_zoomed, zoomFactor);
-
-  OutputImageType::Pointer sift_contrasted =
-    invContrast(_sift_contrasted, contrastMin, contrastMax);
-
-  OutputImageType::Pointer _sift_combined1 =
-    invContrast(_sift_combined, contrastMin, contrastMax);
-  OutputImageType::Pointer _sift_combined2 =
-    invRotate(_sift_combined1, rotation);
-  OutputImageType::Pointer sift_combined =
-    invZoom(_sift_combined2, zoomFactor);
-
-  OutputImageType::Pointer ddm_base = ddm(sift_base, "ddm_base.png");
-  OutputImageType::Pointer ddm_rotated = ddm(sift_rotated, "ddm_rotated.png");
-  OutputImageType::Pointer ddm_contrasted = ddm(sift_contrasted, "ddm_contrasted.png");
-  OutputImageType::Pointer ddm_zoomed = ddm(sift_zoomed, "ddm_zoomed.png");
-  OutputImageType::Pointer ddm_combined = ddm(sift_combined, "ddm_combined.png");
-
-  subtract(ddm_base, ddm_rotated,
-           "subtract_rotated.png");
-
-  subtract(ddm_base, ddm_zoomed,
-           "subtract_zoomed.png");
-
-  subtract(ddm_base, ddm_contrasted,
-           "subtract_contrasted.png");
-
-  subtract(ddm_base, ddm_combined,
-           "subtract_combined.png");
-
-  std::cout.rdbuf(strm_buffer);
-  file.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputAscii.cxx b/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputAscii.cxx
deleted file mode 100644
index 57da84a5340018e38a86c7a6f1a20c1e7c038900..0000000000000000000000000000000000000000
--- a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputAscii.cxx
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iomanip>
-#include <iostream>
-#include <fstream>
-
-#include "otbImageToSIFTKeyPointSetFilter.h"
-#include "otbImage.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-#include "itkPointSet.h"
-#include "itkVariableLengthVector.h"
-#include "itkRGBPixel.h"
-#include "itkImageRegionIterator.h"
-
-int otbImageToSIFTKeyPointSetFilterOutputAscii(int itkNotUsed(argc), char * argv[])
-{
-  const char * infname = argv[1];
-  const char * outfname = argv[2];
-
-  const unsigned int octaves = atoi(argv[3]);
-  const unsigned int scales = atoi(argv[4]);
-  const float        threshold = atof(argv[5]);
-  const float        ratio = atof(argv[6]);
-
-  typedef float RealType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<RealType, Dimension>                            ImageType;
-  typedef itk::VariableLengthVector<RealType>                        RealVectorType;
-  typedef otb::ImageFileReader<ImageType>                            ReaderType;
-  typedef itk::PointSet<RealVectorType, Dimension>                   PointSetType;
-  typedef otb::ImageToSIFTKeyPointSetFilter<ImageType, PointSetType> ImageToSIFTKeyPointSetFilterType;
-
-  // PointSet iterator type
-  typedef PointSetType::PointsContainer    PointsContainerType;
-  typedef PointsContainerType::Iterator    PointsIteratorType;
-  typedef PointSetType::PointDataContainer PointDataContainerType;
-  typedef PointDataContainerType::Iterator PointDataIteratorType;
-
-  // Instantiating object
-  ReaderType::Pointer                       reader = ReaderType::New();
-  ImageToSIFTKeyPointSetFilterType::Pointer filter = ImageToSIFTKeyPointSetFilterType::New();
-
-  reader->SetFileName(infname);
-  filter->SetInput(reader->GetOutput());
-  filter->SetOctavesNumber(octaves);
-  filter->SetScalesNumber(scales);
-  filter->SetDoGThreshold(threshold);
-  filter->SetEdgeThreshold(ratio);
-  filter->Update();
-
-  PointsIteratorType pIt = filter->GetOutput()->GetPoints()->Begin();
-  if (filter->GetOutput()->GetPointData() == nullptr)
-    {
-    std::cerr << "No sift point found!" << std::endl;
-    return EXIT_FAILURE; //Avoid the subsequent segfault, but need to check if that what the test want to do
-    }
-  PointDataIteratorType pDataIt = filter->GetOutput()->GetPointData()->Begin();
-
-  std::ofstream outfile(outfname);
-
-  outfile << "Number of octaves: " << octaves << std::endl;
-  outfile << "Number of scales: " << scales << std::endl;
-  outfile << "Number of SIFT key points: " << filter->GetOutput()->GetNumberOfPoints() << std::endl;
-  while (pIt != filter->GetOutput()->GetPoints()->End())
-    {
-    outfile << "[" << std::fixed << std::setprecision(2) << pIt.Value()[0] << ", " << std::setprecision(2) <<
-    pIt.Value()[1] << "][";
-
-    unsigned int lIterDesc = 0;
-    while (lIterDesc < pDataIt.Value().Size())
-      {
-      outfile << std::setprecision(3) << pDataIt.Value()[lIterDesc] << " ";
-      lIterDesc++;
-      }
-    outfile << "]" << std::endl;
-    ++pIt;
-    ++pDataIt;
-    }
-
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputDescriptorAscii.cxx b/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputDescriptorAscii.cxx
deleted file mode 100644
index 40c64f7fe6a1983d628e02a1b04b961957ff31aa..0000000000000000000000000000000000000000
--- a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputDescriptorAscii.cxx
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iomanip>
-#include <iostream>
-#include <fstream>
-
-#include "otbImageToSIFTKeyPointSetFilter.h"
-#include "otbImage.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-#include "itkPointSet.h"
-#include "itkVariableLengthVector.h"
-#include "itkRGBPixel.h"
-#include "itkImageRegionIterator.h"
-
-int otbImageToSIFTKeyPointSetFilterOutputDescriptorAscii(int itkNotUsed(argc), char * argv[])
-{
-  const char * infname = argv[1];
-  const char * outfname = argv[2];
-
-  const unsigned int octaves = atoi(argv[3]);
-  const unsigned int scales = atoi(argv[4]);
-  const float        threshold = atof(argv[5]);
-  const float        ratio = atof(argv[6]);
-
-  typedef float RealType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<RealType, Dimension>                            ImageType;
-  typedef itk::VariableLengthVector<RealType>                        RealVectorType;
-  typedef otb::ImageFileReader<ImageType>                            ReaderType;
-  typedef itk::PointSet<RealVectorType, Dimension>                   PointSetType;
-  typedef otb::ImageToSIFTKeyPointSetFilter<ImageType, PointSetType> ImageToSIFTKeyPointSetFilterType;
-
-  // PointSet terator type
-  typedef PointSetType::PointsContainer    PointsContainerType;
-  typedef PointsContainerType::Iterator    PointsIteratorType;
-  typedef PointSetType::PointDataContainer PointDataContainerType;
-  typedef PointDataContainerType::Iterator PointDataIteratorType;
-
-  // Instantiating object
-  ReaderType::Pointer                       reader = ReaderType::New();
-  ImageToSIFTKeyPointSetFilterType::Pointer filter = ImageToSIFTKeyPointSetFilterType::New();
-
-  reader->SetFileName(infname);
-  filter->SetInput(reader->GetOutput());
-  filter->SetOctavesNumber(octaves);
-  filter->SetScalesNumber(scales);
-  filter->SetDoGThreshold(threshold);
-  filter->SetEdgeThreshold(ratio);
-  filter->Update();
-
-  PointsIteratorType    pIt = filter->GetOutput()->GetPoints()->Begin();
-  PointDataIteratorType pDataIt = filter->GetOutput()->GetPointData()->Begin();
-
-  std::ofstream outfile(outfname);
-
-  outfile << "Number of octaves: " << octaves << std::endl;
-  outfile << "Number of scales: " << scales << std::endl;
-  outfile << "Number of SIFT key points: " << filter->GetOutput()->GetNumberOfPoints() << std::endl;
-  while (pIt != filter->GetOutput()->GetPoints()->End())
-    {
-    outfile << "[";
-    unsigned int lIterDesc = 0;
-    while (lIterDesc < pDataIt.Value().Size())
-      {
-      outfile << std::setprecision(3) << pDataIt.Value()[lIterDesc] << " ";
-      lIterDesc++;
-      }
-    outfile << "]" << std::endl;
-    ++pIt;
-    ++pDataIt;
-    }
-
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputImage.cxx b/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputImage.cxx
deleted file mode 100644
index 18a1da214e808e9b588d6b6de2c37c1557bc91ae..0000000000000000000000000000000000000000
--- a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputImage.cxx
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "otbImageToSIFTKeyPointSetFilter.h"
-#include "otbImage.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-#include "itkPointSet.h"
-#include "itkVariableLengthVector.h"
-#include "itkRGBPixel.h"
-#include "itkImageRegionIterator.h"
-
-#include <iostream>
-#include <fstream>
-
-int otbImageToSIFTKeyPointSetFilterOutputImage(int itkNotUsed(argc), char * argv[])
-{
-  const char * infname = argv[1];
-  const char * outputImageFilename = argv[2];
-
-  const unsigned int octaves = atoi(argv[3]);
-  const unsigned int scales = atoi(argv[4]);
-
-  float threshold = atof(argv[5]);
-  float ratio = atof(argv[6]);
-
-  typedef float RealType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<RealType, Dimension>                            ImageType;
-  typedef itk::VariableLengthVector<RealType>                        RealVectorType;
-  typedef otb::ImageFileReader<ImageType>                            ReaderType;
-  typedef itk::PointSet<RealVectorType, Dimension>                   PointSetType;
-  typedef otb::ImageToSIFTKeyPointSetFilter<ImageType, PointSetType> ImageToSIFTKeyPointSetFilterType;
-  typedef PointSetType::PointsContainer PointsContainerType;
-  typedef PointsContainerType::Iterator PointsIteratorType;
-
-  // Instantiating object
-  ReaderType::Pointer                       reader = ReaderType::New();
-  ImageToSIFTKeyPointSetFilterType::Pointer filter = ImageToSIFTKeyPointSetFilterType::New();
-
-  reader->SetFileName(infname);
-  filter->SetInput(reader->GetOutput());
-  filter->SetOctavesNumber(octaves);
-  filter->SetScalesNumber(scales);
-  filter->SetDoGThreshold(threshold);
-  filter->SetEdgeThreshold(ratio);
-
-  filter->Update();
-
-  ImageType::OffsetType t = {{ 0, 1}};
-  ImageType::OffsetType b = {{ 0, -1}};
-  ImageType::OffsetType l = {{ 1, 0}};
-  ImageType::OffsetType r = {{-1, 0}};
-
-  typedef unsigned char            PixelType;
-  typedef itk::RGBPixel<PixelType>    RGBPixelType;
-  typedef otb::Image<RGBPixelType, 2> OutputImageType;
-
-  typedef otb::ImageFileWriter<OutputImageType> WriterType;
-  OutputImageType::Pointer    outputImage = OutputImageType::New();
-  OutputImageType::RegionType region;
-
-  OutputImageType::SizeType outputSize;
-  outputSize[0] = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[0];
-  outputSize[1] = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[1];
-  region.SetSize(outputSize);
-
-  OutputImageType::IndexType indexStart;
-  indexStart[0] = 0;
-  indexStart[1] = 0;
-  region.SetIndex(indexStart);
-
-  outputImage->SetRegions(region);
-  outputImage->Allocate();
-
-  itk::ImageRegionIterator<OutputImageType> iterOutput(outputImage,
-                                                       outputImage->GetLargestPossibleRegion());
-  itk::ImageRegionIterator<ImageType> iterInput(reader->GetOutput(),
-                                                reader->GetOutput()->GetLargestPossibleRegion());
-
-  for (iterOutput.GoToBegin(), iterInput.GoToBegin();
-       !iterOutput.IsAtEnd();
-       ++iterOutput, ++iterInput)
-    {
-    OutputImageType::PixelType rgbPixel;
-    rgbPixel.SetRed(static_cast<PixelType>(iterInput.Get()));
-    rgbPixel.SetGreen(static_cast<PixelType>(iterInput.Get()));
-    rgbPixel.SetBlue(static_cast<PixelType>(iterInput.Get()));
-
-    iterOutput.Set(rgbPixel);
-    }
-
-  WriterType::Pointer writerTmp = WriterType::New();
-  writerTmp->SetFileName(outputImageFilename);
-  writerTmp->SetInput(outputImage);
-  writerTmp->Update();
-
-  std::cout << "Copy Input image in Output image" << std::endl;
-
-  PointsIteratorType        pIt = filter->GetOutput()->GetPoints()->Begin();
-  ImageType::SpacingType    spacing = reader->GetOutput()->GetSignedSpacing();
-  ImageType::PointType      origin = reader->GetOutput()->GetOrigin();
-  //OutputImageType::SizeType size = outputImage->GetLargestPossibleRegion().GetSize();
-
-  while (pIt != filter->GetOutput()->GetPoints()->End())
-    {
-    ImageType::IndexType index;
-
-    index[0] = (unsigned int)
-               (std::floor
-                  ((double) ((pIt.Value()[0] - origin[0]) / spacing[0] + 0.5)));
-
-    index[1] = (unsigned int)
-               (std::floor
-                  ((double) ((pIt.Value()[1] - origin[1]) / spacing[1] + 0.5)));
-
-    OutputImageType::PixelType keyPixel;
-    keyPixel.SetRed(0);
-    keyPixel.SetGreen(255);
-    keyPixel.SetBlue(0);
-
-    if (outputImage->GetLargestPossibleRegion().IsInside(index))
-      {
-      outputImage->SetPixel(index, keyPixel);
-
-      if (outputImage->GetLargestPossibleRegion().IsInside(index + t)) outputImage->SetPixel(index + t, keyPixel);
-
-      if (outputImage->GetLargestPossibleRegion().IsInside(index + b)) outputImage->SetPixel(index + b, keyPixel);
-
-      if (outputImage->GetLargestPossibleRegion().IsInside(index + l)) outputImage->SetPixel(index + l, keyPixel);
-
-      if (outputImage->GetLargestPossibleRegion().IsInside(index + r)) outputImage->SetPixel(index + r, keyPixel);
-      }
-    ++pIt;
-    }
-
-  std::cout << "Copy sift key" << std::endl;
-
-  WriterType::Pointer writer = WriterType::New();
-  writer->SetFileName(outputImageFilename);
-  writer->SetInput(outputImage);
-  writer->Update();
-
-  std::cout << "Write image" << std::endl;
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputInterestPointAscii.cxx b/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputInterestPointAscii.cxx
deleted file mode 100644
index 51d4d3188621e9f615ed8dbab0bc3f88941892a8..0000000000000000000000000000000000000000
--- a/Modules/Feature/Descriptors/test/otbImageToSIFTKeyPointSetFilterOutputInterestPointAscii.cxx
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iomanip>
-#include <iostream>
-#include <fstream>
-
-#include "otbImageToSIFTKeyPointSetFilter.h"
-#include "otbImage.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-#include "itkPointSet.h"
-#include "itkVariableLengthVector.h"
-#include "itkRGBPixel.h"
-#include "itkImageRegionIterator.h"
-
-int otbImageToSIFTKeyPointSetFilterOutputInterestPointAscii(int itkNotUsed(argc), char * argv[])
-{
-  const char * infname = argv[1];
-  const char * outfname = argv[2];
-
-  const unsigned int octaves = atoi(argv[3]);
-  const unsigned int scales = atoi(argv[4]);
-  const float        threshold = atof(argv[5]);
-  const float        ratio = atof(argv[6]);
-
-  typedef float RealType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<RealType, Dimension>                            ImageType;
-  typedef itk::VariableLengthVector<RealType>                        RealVectorType;
-  typedef otb::ImageFileReader<ImageType>                            ReaderType;
-  typedef itk::PointSet<RealVectorType, Dimension>                   PointSetType;
-  typedef otb::ImageToSIFTKeyPointSetFilter<ImageType, PointSetType> ImageToSIFTKeyPointSetFilterType;
-
-  typedef PointSetType::PointsContainer    PointsContainerType;
-  typedef PointsContainerType::Iterator    PointsIteratorType;
-
-  // Instantiating object
-  ReaderType::Pointer                       reader = ReaderType::New();
-  ImageToSIFTKeyPointSetFilterType::Pointer filter = ImageToSIFTKeyPointSetFilterType::New();
-
-  reader->SetFileName(infname);
-  filter->SetInput(reader->GetOutput());
-  filter->SetOctavesNumber(octaves);
-  filter->SetScalesNumber(scales);
-  filter->SetDoGThreshold(threshold);
-  filter->SetEdgeThreshold(ratio);
-  filter->Update();
-
-  PointsIteratorType pIt = filter->GetOutput()->GetPoints()->Begin();
-
-  std::ofstream outfile(outfname);
-
-  outfile << "Number of octaves: " << octaves << std::endl;
-  outfile << "Number of scales: " << scales << std::endl;
-  outfile << "Number of SIFT key points: " << filter->GetOutput()->GetNumberOfPoints() << std::endl;
-
-  while (pIt != filter->GetOutput()->GetPoints()->End())
-    {
-    outfile << "[" << std::fixed << std::setprecision(2) << pIt.Value()[0] << ", " << std::setprecision(2) <<
-    pIt.Value()[1] << "]" << std::endl;
-    ++pIt;
-    }
-
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Descriptors/test/otbImageToSURFKeyPointSetFilterOutputDescriptorAscii.cxx b/Modules/Feature/Descriptors/test/otbImageToSURFKeyPointSetFilterOutputDescriptorAscii.cxx
deleted file mode 100644
index 91b45476551fca96ceae7fd217d3de18c5346bb7..0000000000000000000000000000000000000000
--- a/Modules/Feature/Descriptors/test/otbImageToSURFKeyPointSetFilterOutputDescriptorAscii.cxx
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iomanip>
-#include <iostream>
-#include <fstream>
-
-#include "otbImageToSURFKeyPointSetFilter.h"
-#include "otbImage.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-#include "itkVariableLengthVector.h"
-#include "itkRGBPixel.h"
-#include "itkImageRegionIterator.h"
-
-int otbImageToSURFKeyPointSetFilterOutputDescriptorAscii(int argc, char * argv[])
-{
-
-  if (argc < 5)
-    {
-    std::cout << " Usage : otbSURFTest imageName FileOutName Octave[int] Level[int]" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  const char * infname = argv[1];
-  const char * outfname = argv[2];
-
-  const unsigned int octaves = atoi(argv[3]);
-  const unsigned int scales = atoi(argv[4]);
-
-  typedef float RealType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<RealType, Dimension>                            ImageType;
-  typedef itk::VariableLengthVector<RealType>                        RealVectorType;
-  typedef otb::ImageFileReader<ImageType>                            ReaderType;
-  typedef itk::PointSet<RealVectorType, Dimension>                   PointSetType;
-  typedef otb::ImageToSURFKeyPointSetFilter<ImageType, PointSetType> ImageToSURFKeyPointSetFilterType;
-  typedef PointSetType::PointsContainer    PointsContainerType;
-  typedef PointsContainerType::Iterator    PointsIteratorType;
-  typedef PointSetType::PointDataContainer PointDataContainerType;
-  typedef PointDataContainerType::Iterator PointDataIteratorType;
-
-  // Instantiating object
-  ReaderType::Pointer                       reader = ReaderType::New();
-  ImageToSURFKeyPointSetFilterType::Pointer filter = ImageToSURFKeyPointSetFilterType::New();
-
-  reader->SetFileName(infname);
-  filter->SetInput(reader->GetOutput());
-  filter->SetOctavesNumber(octaves);
-  filter->SetScalesNumber(scales);
-  filter->Update();
-
-  PointsIteratorType    pIt = filter->GetOutput()->GetPoints()->Begin();
-  PointDataIteratorType pDataIt = filter->GetOutput()->GetPointData()->Begin();
-
-  std::ofstream outfile(outfname);
-
-  outfile << "Number of octaves: " << octaves << std::endl;
-  outfile << "Number of scales: " << scales << std::endl;
-  outfile << "Number of SURF key points: " << filter->GetNumberOfPoints() << std::endl;
-
-  while (pIt != filter->GetOutput()->GetPoints()->End())
-    {
-    outfile << "[";
-    unsigned int lIterDesc = 0;
-    while (lIterDesc < pDataIt.Value().Size())
-      {
-      outfile << std::setprecision(3) << pDataIt.Value()[lIterDesc] << " ";
-      lIterDesc++;
-      }
-    outfile << "]" << std::endl;
-    ++pIt;
-    ++pDataIt;
-    }
-
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Descriptors/test/otbImageToSURFKeyPointSetFilterOutputInterestPointAscii.cxx b/Modules/Feature/Descriptors/test/otbImageToSURFKeyPointSetFilterOutputInterestPointAscii.cxx
deleted file mode 100644
index fc40afba0cbf61071291911a35427b447cfa52c5..0000000000000000000000000000000000000000
--- a/Modules/Feature/Descriptors/test/otbImageToSURFKeyPointSetFilterOutputInterestPointAscii.cxx
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include <iomanip>
-#include <iostream>
-#include <fstream>
-
-#include "otbImageToSURFKeyPointSetFilter.h"
-#include "otbImage.h"
-#include "otbImageFileReader.h"
-#include "otbImageFileWriter.h"
-#include "itkVariableLengthVector.h"
-#include "itkRGBPixel.h"
-#include "itkImageRegionIterator.h"
-
-int otbImageToSURFKeyPointSetFilterOutputInterestPointAscii(int argc, char * argv[])
-{
-
-  if (argc < 5)
-    {
-    std::cout << " Usage : otbSURFTest imageName FileOutName Octave[int] Level[int]" << std::endl;
-    return EXIT_FAILURE;
-    }
-
-  const char * infname = argv[1];
-  const char * outfname = argv[2];
-
-  const unsigned int octaves = atoi(argv[3]);
-  const unsigned int scales = atoi(argv[4]);
-
-  typedef float RealType;
-  const unsigned int Dimension = 2;
-
-  typedef otb::Image<RealType, Dimension>                            ImageType;
-  typedef itk::VariableLengthVector<RealType>                        RealVectorType;
-  typedef otb::ImageFileReader<ImageType>                            ReaderType;
-  typedef itk::PointSet<RealVectorType, Dimension>                   PointSetType;
-  typedef otb::ImageToSURFKeyPointSetFilter<ImageType, PointSetType> ImageToSURFKeyPointSetFilterType;
-  typedef PointSetType::PointsContainer    PointsContainerType;
-  typedef PointsContainerType::Iterator    PointsIteratorType;
-
-  // Instantiating object
-  ReaderType::Pointer                       reader = ReaderType::New();
-  ImageToSURFKeyPointSetFilterType::Pointer filter = ImageToSURFKeyPointSetFilterType::New();
-
-  reader->SetFileName(infname);
-  filter->SetInput(reader->GetOutput());
-  filter->SetOctavesNumber(octaves);
-  filter->SetScalesNumber(scales);
-  filter->Update();
-
-  PointsIteratorType    pIt = filter->GetOutput()->GetPoints()->Begin();
-  filter->GetOutput()->GetPointData()->Begin();
-
-  std::ofstream outfile(outfname);
-
-  outfile << "Number of octaves: " << octaves << std::endl;
-  outfile << "Number of scales: " << scales << std::endl;
-  outfile << "Number of SURF key points: " << filter->GetNumberOfPoints() << std::endl;
-
-  while (pIt != filter->GetOutput()->GetPoints()->End())
-    {
-    outfile << "[" << std::fixed << std::setprecision(2) << pIt.Value()[0] << ", " << std::setprecision(2) <<
-    pIt.Value()[1] << "]" << std::endl;
-    ++pIt;
-    }
-
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Descriptors/test/otbKeyPointSetsMatchingFilter.cxx b/Modules/Feature/Descriptors/test/otbKeyPointSetsMatchingFilter.cxx
deleted file mode 100644
index c4d563dc15f87545cae69d9b0ae4a76d05e6b0df..0000000000000000000000000000000000000000
--- a/Modules/Feature/Descriptors/test/otbKeyPointSetsMatchingFilter.cxx
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
- *
- * This file is part of Orfeo Toolbox
- *
- *     https://www.orfeo-toolbox.org/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-
-#include "otbKeyPointSetsMatchingFilter.h"
-
-#include "itkVariableLengthVector.h"
-#include "itkPointSet.h"
-
-#include <iostream>
-#include <fstream>
-
-int otbKeyPointSetsMatchingFilter(int itkNotUsed(argc), char* argv[])
-{
-
-  const char * outfname = argv[1];
-  const double thresh        = atof(argv[2]);
-  const bool   useBackMatching = atoi(argv[3]);
-
-  typedef itk::VariableLengthVector<double>             PointDataType;
-  typedef itk::PointSet<PointDataType, 2>               PointSetType;
-  typedef PointSetType::PointType                       PointType;
-  typedef otb::KeyPointSetsMatchingFilter<PointSetType> MatchingFilterType;
-  typedef MatchingFilterType::LandmarkListType          LandmarkListType;
-
-  // instantiation
-  MatchingFilterType::Pointer filter = MatchingFilterType::New();
-
-  filter->SetUseBackMatching(useBackMatching);
-  filter->SetDistanceThreshold(thresh);
-
-  // Building two pointsets
-  PointSetType::Pointer ps1 = PointSetType::New();
-  PointSetType::Pointer ps2 = PointSetType::New();
-
-  PointType p1, p2, p3;
-
-  p1.Fill(1);
-  p2.Fill(2);
-  p3.Fill(3);
-
-  PointDataType d1(3), d2(3), d3(3), d1b(3), d2b(3), d3b(3);
-
-  d1.Fill(1);
-  d1b.Fill(1);
-
-  d2.Fill(0);
-  d2[0] = 10;
-  d2b.Fill(0);
-  d2b[1] = 10;
-
-  d3.Fill(2);
-  d3b.Fill(10);
-
-  ps1->SetPoint(0, p1);
-  ps1->SetPoint(1, p2);
-  ps1->SetPoint(2, p3);
-
-  ps2->SetPoint(0, p1);
-  ps2->SetPoint(1, p2);
-  ps2->SetPoint(2, p3);
-
-  ps1->SetPointData(0, d1);
-  ps1->SetPointData(1, d2);
-  ps1->SetPointData(2, d3);
-
-  ps2->SetPointData(0, d1b);
-  ps2->SetPointData(1, d2b);
-  ps2->SetPointData(2, d3b);
-
-  filter->SetInput1(ps1);
-  filter->SetInput2(ps2);
-
-  filter->Update();
-
-  LandmarkListType * matching = filter->GetOutput();
-
-  std::ofstream outfile(outfname);
-  outfile << "Matches: " << std::endl;
-
-  for (LandmarkListType::Iterator it = matching->Begin(); it != matching->End(); ++it)
-    {
-    outfile << "Matching: " << it.Get()->GetPoint1() << " " << it.Get()->GetPointData1() << " <- " <<
-    it.Get()->GetLandmarkData() << " -> " << it.Get()->GetPoint2() << " " << it.Get()->GetPointData2() << std::endl;
-    }
-
-  outfile.close();
-
-  return EXIT_SUCCESS;
-}
diff --git a/Modules/Feature/Descriptors/test/otbKeyPointsAlgorithmsTest.cxx b/Modules/Feature/Descriptors/test/otbKeyPointsAlgorithmsTest.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..99dcc44a799a982b76f2f7d7ef9776fd9ad449b2
--- /dev/null
+++ b/Modules/Feature/Descriptors/test/otbKeyPointsAlgorithmsTest.cxx
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
+ *
+ * This file is part of Orfeo Toolbox
+ *
+ *     https://www.orfeo-toolbox.org/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "otbImage.h"
+#include "otbImageFileReader.h"
+#include "otbExtractROI.h"
+#include "itkScalableAffineTransform.h"
+#include "otbStreamingResampleImageFilter.h"
+#include "otbBCOInterpolateImageFunction.h"
+#include "otbKeyPointSetsMatchingFilter.h"
+#include "otbSiftFastImageFilter.h"
+#include "otbImageToSIFTKeyPointSetFilter.h"
+#include "otbImageToSURFKeyPointSetFilter.h"
+#include "itkPointSet.h"
+
+#include <tuple>
+
+using ImageType          = otb::Image<double>;
+using ReaderType         = otb::ImageFileReader<ImageType>;
+using ExtractType        = otb::ExtractROI<double,double>;
+using TransformType      = itk::ScalableAffineTransform<double, 2>;
+using ResamplerType      = otb::StreamingResampleImageFilter<ImageType, ImageType, double>;
+using InterpolatorType   = otb::BCOInterpolateImageFunction<ImageType, double>;
+using VectorType         = itk::VariableLengthVector<double>;
+using PointSetType       = itk::PointSet<VectorType, 2>;
+using SiftFastFilterType = otb::SiftFastImageFilter<ImageType, PointSetType>;
+using SiftFilterType     = otb::ImageToSIFTKeyPointSetFilter<ImageType, PointSetType>;
+using SurfFilterType     = otb::ImageToSURFKeyPointSetFilter<ImageType, PointSetType>;
+using MatchingFilterType = otb::KeyPointSetsMatchingFilter<PointSetType>;
+
+auto printResult = [](bool value) { return value ? "Ok" : "Nok"; };
+
+bool testMatchingFilter()
+{
+  auto ps1 = PointSetType::New();
+  auto ps2 = PointSetType::New();
+
+  PointSetType::PointType p1,p2,p3,p4,p5,p6;
+  p1.Fill(1.);
+  p2.Fill(2.);
+  p3.Fill(3.);
+  p4.Fill(4.);
+  p5.Fill(5.);
+  p6.Fill(6.);
+  ps1->SetPoint(0, p1);
+  ps1->SetPoint(1, p2);
+  ps1->SetPoint(2, p3);
+  ps2->SetPoint(0, p4);
+  ps2->SetPoint(1, p5);
+  ps2->SetPoint(2, p6);
+
+
+  VectorType d1(1), d2(1), d3(1), d4(1),d5(1), d6(1);
+  d1[0]=0.7;
+  d2[0]=0.8;
+  d3[0]=10.;
+  d4[0]=0.;
+  d5[0]=1.;
+  d6[0]=11.;
+
+  ps1->SetPointData(0, d1);
+  ps1->SetPointData(1, d2);
+  ps1->SetPointData(2, d3);
+  ps2->SetPointData(0, d4);
+  ps2->SetPointData(1, d5);
+  ps2->SetPointData(2, d6);
+
+  auto filter1 = MatchingFilterType::New();
+  filter1->SetDistanceThreshold(0.6);
+  filter1->SetUseBackMatching(false);
+  filter1->SetInput1(ps1);  
+  filter1->SetInput2(ps2);
+  filter1->Update();
+
+  auto matches1 = filter1->GetOutput();
+
+  std::cout<<"Matches without backmatching: "<<std::endl;
+
+  for (auto it = matches1->Begin(); it != matches1->End(); ++it)
+    {
+    std::cout<<it.Get()->GetPoint1()<<" <-> "<<it.Get()->GetPoint2()<<std::endl;
+    }
+
+  auto filter2 = MatchingFilterType::New();
+  filter2->SetDistanceThreshold(0.6);
+  filter2->SetUseBackMatching(true);
+  filter2->SetInput1(ps1);  
+  filter2->SetInput2(ps2);
+  filter2->Update();
+
+  auto matches2 = filter2->GetOutput();
+
+  std::cout<<"Matches with backmatching: "<<std::endl;
+
+  for (auto it = matches2->Begin(); it != matches2->End(); ++it)
+    {
+    std::cout<<it.Get()->GetPoint1()<<" <-> "<<it.Get()->GetPoint2()<<std::endl;
+    }
+
+  bool success = true;
+
+  // Without backmatching, matches should be:
+  // p1 <-> p5
+  // p2 <-> p5
+  // p3 <-> p6
+  unsigned int nb_matches = matches1->Size();
+  
+  bool test = nb_matches == 3;
+  std::cout<<"Without backmatching, the number of matches is 3:\t"<<printResult(test)<<std::endl;
+  success = success && test;
+
+  test = nb_matches > 1 && matches1->GetNthElement(0)->GetPoint1() == p1 && matches1->GetNthElement(0)->GetPoint2() == p5;
+  std::cout<<"Without backmatching, p1 matches with p5:\t\t"<<printResult(test)<<std::endl;
+  success = success && test;
+
+  test = nb_matches > 0 && matches1->GetNthElement(1)->GetPoint1() == p2 && matches1->GetNthElement(1)->GetPoint2() == p5;
+  std::cout<<"Without backmatching, p2 matches with p5:\t\t"<<printResult(test)<<std::endl;
+  success = success && test;
+
+
+  test = nb_matches > 2 && matches1->GetNthElement(2)->GetPoint1() == p3 && matches1->GetNthElement(2)->GetPoint2() == p6;
+  std::cout<<"Without backmatching, p3 matches with p6:\t\t"<<printResult(test)<<std::endl;
+  success = success && test;
+
+  // With back-matching there should be only 2 matches: 
+  // p2 <-> p5
+  // p3 <-> p6
+  test = matches2->Size() == 2;
+  std::cout<<"With backmatching, the number of matches is 2:\t"<<printResult(test)<<std::endl;
+  success = success && test;
+
+  test = matches2->GetNthElement(0)->GetPoint1() == p2 && matches2->GetNthElement(0)->GetPoint2() == p5;
+  std::cout<<"With backmatching, p2 matches with p5:\t\t"<<printResult(test)<<std::endl;
+  success = success && test;
+
+  test = matches2->GetNthElement(1)->GetPoint1() == p3 && matches2->GetNthElement(1)->GetPoint2() == p6;
+  std::cout<<"With backmatching, p3 matches with p6:\t\t"<<printResult(test)<<std::endl;
+  success = success && test;
+
+
+
+  return success;
+}
+
+
+/** Generate a pair of images, one beeing slightly warped wrt the
+ * other */
+auto generateImagePair(const std::string& infname, double rotation, double scaling)
+{
+  // Read reference image
+  auto reader = ReaderType::New();
+  reader->SetFileName(infname);
+
+  auto extractor = ExtractType::New();
+  extractor->SetInput(reader->GetOutput());
+  extractor->SetSizeX(50);
+  extractor->SetSizeY(50);
+  extractor->Update();
+
+  ImageType::Pointer reference = extractor->GetOutput();
+
+  // Create secondary image
+
+  // Setup transform
+  auto transform = TransformType::New();
+
+  // Set rotation center as image center
+  auto origin  = reference->GetOrigin();
+  auto spacing = reference->GetSpacing();
+  auto size    = reference->GetLargestPossibleRegion().GetSize();
+  auto center  = origin;
+  center[0] += 0.5 * spacing[0] * size[0];
+  center[1] += 0.5 * spacing[1] * size[1];
+  transform->SetCenter(center);
+
+  // Set rotation angle
+  transform->Rotate2D(rotation * otb::CONST_PI_180);
+
+  // Set scale
+  ImageType::SpacingType scalingVector;
+  scalingVector.Fill(scaling);
+  transform->Scale(scalingVector);
+
+  // Invert transform
+  auto inverse = TransformType::New();
+  bool ok      = transform->GetInverse(inverse);
+  if (!ok)
+    throw std::logic_error("Could not inverse transform");
+  // Setup interpolator
+  auto interpolator = InterpolatorType::New();
+
+  // Setup resampler
+  auto resampler = ResamplerType::New();
+  resampler->SetInput(reference);
+  resampler->SetTransform(transform);
+  resampler->SetInterpolator(interpolator);
+
+  // Since rotation and scaling are small, use same image parameter
+  // for secondary image
+  resampler->SetOutputOrigin(origin);
+  resampler->SetOutputSize(size);
+  resampler->SetOutputSpacing(spacing);
+  resampler->Update();
+  ImageType::Pointer secondary = resampler->GetOutput();
+
+  return std::make_tuple(reference, secondary, transform);
+}
+
+/** Perform checks for one keypoints algorithm */
+template <typename TKeyPointsFilter, typename TParameterSetter>
+bool checkKeyPointsFilter(const ImageType* reference, const ImageType* secondary, const TransformType* transform, const TParameterSetter& configureFilter,
+                          unsigned int nb_points_thresh, double match_rate_thresh, double good_match_rate_thresh)
+{
+  // Keypoints on first image
+  auto filterReference = TKeyPointsFilter::New();
+  filterReference->SetInput(reference);
+  configureFilter(filterReference);
+
+  // Keypoints on secondary image
+  auto filterSecondary = TKeyPointsFilter::New();
+  filterSecondary->SetInput(secondary);
+  configureFilter(filterSecondary);
+
+  // Match keypoints
+  auto matcher = MatchingFilterType::New();
+  matcher->SetUseBackMatching(false);
+  matcher->SetDistanceThreshold(0.6);
+  matcher->SetInput1(filterReference->GetOutput());
+  matcher->SetInput2(filterSecondary->GetOutput());
+  matcher->Update();
+
+  PointSetType::Pointer referencePoints   = filterReference->GetOutput();
+  const size_t          nbReferencePoints = referencePoints->GetPoints()->Size();
+
+  typename PointSetType::Pointer secondaryPoints   = filterSecondary->GetOutput();
+  const size_t                   nbSecondaryPoints = secondaryPoints->GetPoints()->Size();
+
+  std::cout << "Found " << nbReferencePoints << " points in reference image and " << nbSecondaryPoints << " points in secondary image" << std::endl;
+
+  auto         matches    = matcher->GetOutput();
+  const size_t nb_matches = matches->Size();
+
+  size_t       good_matches             = 0;
+  const double threshold_for_good_match = 0.5; // pixels
+
+  // Count good and bad matches
+  for (auto it = matches->Begin(); it != matches->End(); ++it)
+  {
+    const auto p1 = it.Get()->GetPoint1();
+    const auto p2 = it.Get()->GetPoint2();
+
+    const auto p2_mapped = transform->TransformPoint(p2);
+
+    // Check that matches are good up to 0.1 pixel
+    if ((p1[0] - p2_mapped[0]) * (p1[0] - p2_mapped[0]) + (p1[1] - p2_mapped[1]) * (p1[1] - p2_mapped[1]) <=
+        threshold_for_good_match * threshold_for_good_match)
+      ++good_matches;
+  }
+
+  // Performances metrics
+  const float reference_match_rate = nb_matches / static_cast<float>(nbReferencePoints);
+  const float secondary_match_rate = nb_matches / static_cast<float>(nbSecondaryPoints);
+  const float good_match_rate      = good_matches / static_cast<float>(nb_matches);
+
+
+  std::cout << "Found " << nb_matches << " matches with " << good_matches << " valid matches (tolerance of 0.5 pixels)" << std::endl;
+
+  // Quality gate
+  bool current_test   = nbReferencePoints >= nb_points_thresh;
+  std::cout << "More than " << nb_points_thresh << " points found in reference image:\t" << printResult(current_test) << " ("
+            << nbReferencePoints << ")" << std::endl;
+  bool overall_status = current_test;
+
+  current_test = nbSecondaryPoints> nb_points_thresh;
+  std::cout << "More than " << nb_points_thresh << " points found in secondary image:\t" << printResult(current_test) << " ("
+            << nbSecondaryPoints << ")" << std::endl;
+  overall_status = overall_status && current_test;
+
+  current_test   = reference_match_rate > match_rate_thresh;
+  std::cout << "More than " << 100 * match_rate_thresh << "% of reference points have a match:\t" << printResult(current_test) << " ("
+            << 100 * reference_match_rate << "%)" << std::endl;
+  overall_status = overall_status && current_test;
+
+  current_test = secondary_match_rate > match_rate_thresh;
+  std::cout << "More than " << 100 * match_rate_thresh << "% of secondary points have a match:\t" << printResult(current_test) << " ("
+            << 100 * secondary_match_rate << "%)" << std::endl;
+  overall_status = overall_status && current_test;
+
+  current_test = good_match_rate > good_match_rate_thresh;
+  std::cout << "More than " << good_match_rate_thresh * 100 << "% of matches are good:             \t" << printResult(current_test) << " ("
+            << 100 * good_match_rate << "% at 0.5 pixel accuracy)"
+            << "\n";
+  overall_status = overall_status && current_test;
+  return overall_status;
+}
+
+
+int otbKeyPointsAlgorithmsTest(int argc, char* argv[])
+{
+  if (argc != 2)
+  {
+    std::cerr << "Usage: " << argv[0] << " infname" << std::endl;
+    return EXIT_FAILURE;
+  }
+  const char* infname = argv[1];
+
+  // Generate reference and secondary image
+  ImageType::Pointer     reference, secondary;
+  TransformType::Pointer transform;
+
+  // Small rotation and scaling
+  const double rotation = 2.5; // 5°
+  const double scaling  = 0.99;
+  
+  // First test matching filter alone
+  std::cout<<"Checking matching filter:"<<std::endl;
+  std::cout<<"========================="<<std::endl;
+  bool status = testMatchingFilter();
+  
+  std::tie(reference, secondary, transform) = generateImagePair(infname, rotation, scaling);
+
+  std::cout << "Secondary image generated by applying a rotation of " << rotation << " degrees and scaling of " << scaling << "." << std::endl;
+
+  // Test Surf filter
+  std::cout << "Checking Surf implementation:" << std::endl;
+  std::cout << "=============================" << std::endl;
+
+  // Lambda to configure surf algorithm
+  auto configureSurf = [](SurfFilterType* filter) {
+    filter->SetOctavesNumber(4);
+    filter->SetScalesNumber(8);
+  };
+
+  status = checkKeyPointsFilter<SurfFilterType>(reference, secondary, transform, configureSurf, 95, 0.13, 0.64) && status;
+
+  // Test Sift filter
+  std::cout << "Checking Sift implementation:" << std::endl;
+  std::cout << "=============================" << std::endl;
+
+  // Lambda to configure sift algorithm
+  auto configureSift = [](SiftFilterType* filter) {
+    filter->SetOctavesNumber(4);
+    filter->SetScalesNumber(8);
+    filter->SetDoGThreshold(0.01);
+    filter->SetEdgeThreshold(10.);
+  };
+
+  status = checkKeyPointsFilter<SiftFilterType>(reference, secondary, transform, configureSift, 120, 0.44, 0.82) && status;
+
+#ifdef OTB_USE_SIFTFAST
+  // Test SiftFast filter
+  std::cout << "Checking SiftFast implementation:" << std::endl;
+  std::cout << "=================================" << std::endl;
+
+  // lambda to set specific filter parameter
+  auto configureSiftFast = [](SiftFastFilterType* filter) { filter->SetScalesNumber(8); };
+
+  status = checkKeyPointsFilter<SiftFastFilterType>(reference, secondary, transform, configureSiftFast, 100, 0.59, 0.95) && status;
+#endif
+
+  return status ? EXIT_SUCCESS : EXIT_FAILURE;
+}