From 7084219fe05f2900357954dd9abb44748d85e38c Mon Sep 17 00:00:00 2001 From: Mathieu Deltorre <mathieu.deltorre@c-s.fr> Date: Wed, 14 May 2008 13:58:36 +0000 Subject: [PATCH] *Integration exemple itkScaleInvariantFeature insight journal --- Examples/FeatureExtraction/CMakeLists.txt | 31 +++ .../ScaleInvariantFeatureImageFilter.cxx | 252 ++++++++++++++++++ .../otbFeatureExtractionExamplesTests.cxx | 10 + 3 files changed, 293 insertions(+) create mode 100644 Examples/FeatureExtraction/ScaleInvariantFeatureImageFilter.cxx diff --git a/Examples/FeatureExtraction/CMakeLists.txt b/Examples/FeatureExtraction/CMakeLists.txt index caa8f98d55..a78112534a 100644 --- a/Examples/FeatureExtraction/CMakeLists.txt +++ b/Examples/FeatureExtraction/CMakeLists.txt @@ -248,6 +248,37 @@ ADD_TEST(SeamCarvingOtherExampleTest ${EXE_TESTS} 50 ) +ADD_TEST(ImageToSIFTKeyPointSetFilterTest ${EXE_TESTS} + --compare-image ${TOL} + ${BASELINE}/ImageToSIFTKeyPointSetFilterOutput.png + ${TEMP}/ImageToSIFTKeyPointSetFilterOutput.png + ImageToSIFTKeyPointSetFilterTest + ${INPUTDATA}/Scene.png + ${TEMP}/ImageToSIFTKeyPointSetFilterOutput.png + 6 3 0.08 10 +) + +ADD_TEST(ScaleInvariantFeatureImageFilterTest ${EXE_TESTS} + --compare-n-image ${TOL} 4 + ${BASELINE}/ScaleInvariantFeatureImageFilterOutput1.png + ${TEMP}/ScaleInvariantFeatureImageFilterOutput1.png + ${BASELINE}/ScaleInvariantFeatureImageFilterOutput2.png + ${TEMP}/ScaleInvariantFeatureImageFilterOutput2.png + ${BASELINE}/ScaleInvariantFeatureImageFilterOutputKeys1.png + ${TEMP}/ScaleInvariantFeatureImageFilterOutputKeys1.png + ${BASELINE}/ScaleInvariantFeatureImageFilterOutputKeys2.png + ${TEMP}/ScaleInvariantFeatureImageFilterOutputKeys2.png + + ScaleInvariantFeatureImageFilterTest + + ${INPUTDATA}/Scene.png + ${TEMP}/ScaleInvariantFeatureImageFilterOutput1.png + ${TEMP}/ScaleInvariantFeatureImageFilterOutput2.png + ${TEMP}/ScaleInvariantFeatureImageFilterOutputKeys1.png + ${TEMP}/ScaleInvariantFeatureImageFilterOutputKeys2.png + 1 10 0.5 0 +) + INCLUDE_DIRECTORIES("${OTBTesting_BINARY_DIR}") ADD_EXECUTABLE(otbFeatureExtractionExamplesTests otbFeatureExtractionExamplesTests.cxx) diff --git a/Examples/FeatureExtraction/ScaleInvariantFeatureImageFilter.cxx b/Examples/FeatureExtraction/ScaleInvariantFeatureImageFilter.cxx new file mode 100644 index 0000000000..269e6a3cbd --- /dev/null +++ b/Examples/FeatureExtraction/ScaleInvariantFeatureImageFilter.cxx @@ -0,0 +1,252 @@ +/*========================================================================= + +Program: ITK nSIFT Implemention - Command Line Wrapper +Language: C++ +Date: $Date$ +Version: $Revision$ +Copyright (c) 2005,2006,2007 Warren Cheung + +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +* Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. +* The name of the Insight Consortium, nor the names of any consortium members, +nor of any contributors, may be used to endorse or promote products derived +from this software without specific prior written permission. +* Modified source versions must be plainly marked as such, and must not be +misrepresented as being the original software. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=========================================================================*/ +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#ifdef __BORLANDC__ +#define ITK_LEAN_AND_MEAN +#endif + +// Software Guide : BeginCommandLineArgs +// INPUTS: {Scene.png} +// OUTPUTS: {ScaleInvariantFeatureImageFilterOutput.png} +// 1 10 0.5 0 +// Software Guide : EndCommandLineArgs + +#define GENERATE_KEYS +#define VERBOSE +#define CROP + +// Software Guide : BeginCodeSnippet +#include "itkScaleInvariantFeatureImageFilter.h" +// Software Guide : EndCodeSnippet + +#include "itkImageSeriesReader.h" +#include "itkNumericSeriesFileNames.h" +#include "itkPointSetToImageFilter.h" +#include "itkImageFileWriter.h" + +int main( int argc, char **argv) +{ + if( argc < 6 ) + { + std::cerr << "Usage: " << std::endl; + std::cerr << argv[0] << " inputImageFile outputImageFile " \ + << "scaleFactor angle cropFactor rotateMiddle" << std::endl; + return EXIT_FAILURE; + } + + const unsigned int Dimension = 2; + + const char* inputImage1 = argv[1]; + const char* outputImage1 = argv[2]; + const char* outputImage2 = argv[3]; + const char* outputImageKeys1 = argv[4]; + const char* outputImageKeys2 = argv[5]; + + // Default parametres + // scale is 1.0 + // rotate is 0 degrees + // crop is 0.5 + // rotate_middle is 0 (rotating around the origin + // mode is s (synthetic) + + double test_scale = atof(argv[6]); + float test_rotate = atof(argv[7])* M_PI * 2.0 / 360.0; + double test_crop = atof(argv[8]); + int rotate_middle= atoi(argv[9]); + int mode = 's'; + + typedef float PixelType; + typedef itk::Image<PixelType, Dimension> FixedImageType; + typedef itk::ScaleInvariantFeatureImageFilter<FixedImageType, Dimension> SiftFilterType; + typedef itk::Image<unsigned char, Dimension> OutputImageType; + + typedef itk::ImageSource<FixedImageType> ImageSourceType; + + ImageSourceType::Pointer fixedImageReader, fixedImageReader2; + + typedef itk::PointSetToImageFilter<SiftFilterType::PointSetType, OutputImageType> PointSetFilterType; + + std::cerr << "Dimension = " << Dimension << "\n"; + std::cerr << "Test Scale = " << test_scale << "\n"; + std::cerr << "Test Rotate = " << test_rotate << "\n"; + std::cerr << "Image Crop Ratio (first 3D) = " << test_crop << "\n"; + std::cerr << "Mode = " << (char) mode << "\n"; + std::cerr << "ImageFile1 = " << inputImage1 << "\n"; + std::cerr << "SIFT Feature\n" << std::endl; + + typedef itk::ImageFileReader< FixedImageType > FixedImageReaderType; + FixedImageReaderType::Pointer tmpImageReader = FixedImageReaderType::New(); + tmpImageReader = FixedImageReaderType::New(); + + tmpImageReader->SetFileName( inputImage1 ); + fixedImageReader=tmpImageReader; + fixedImageReader->Update(); + + typedef itk::ScalableAffineTransform< double, Dimension > ScaleType; +#ifdef CROP + ScaleType::Pointer no_transform = ScaleType::New(); + no_transform->SetIdentity(); + + SiftFilterType::ResampleFilterType::Pointer cropper = SiftFilterType::ResampleFilterType::New(); + cropper->SetInput(fixedImageReader->GetOutput()); + FixedImageType::SizeType cropsize = + fixedImageReader->GetOutput()->GetLargestPossibleRegion().GetSize(); + for (unsigned int k = 0; k < Dimension; ++k) { + if (k < 4) + cropsize[k] = (int) (cropsize[k] * test_crop); + } + cropper->SetSize( cropsize ); + cropper->SetOutputSpacing(fixedImageReader->GetOutput()->GetSpacing()); + cropper->SetTransform(no_transform); + cropper->Update(); + FixedImageType::Pointer fixedImage = cropper->GetOutput(); +#else + FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); +#endif + + SiftFilterType::PointSetTypePointer keypoints1, keypoints2; + PointSetFilterType::Pointer pointSet1 = PointSetFilterType::New(); + PointSetFilterType::Pointer pointSet2 = PointSetFilterType::New(); + + SiftFilterType siftFilter1, siftFilter2; + + siftFilter1.writeImage(fixedImage, outputImage1); + std::cout << std::endl << "Starting SIFT Feature Extraction...\n"; + keypoints1 = siftFilter1.getSiftFeatures(fixedImage); + + pointSet1->SetInput(keypoints1); + pointSet1->SetOutsideValue(0); + pointSet1->SetInsideValue(255); + pointSet1->SetSize(fixedImage->GetLargestPossibleRegion().GetSize()); + + typedef itk::ImageFileWriter<OutputImageType> WriterType; + + WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(outputImageKeys1); + writer->SetInput(pointSet1->GetOutput()); + writer->Update(); + + typedef itk::ScalableAffineTransform< double, Dimension > TestTransformType; + TestTransformType::Pointer inv_test_transform; + + // Synthetic test image + if (mode=='s') { + std::cerr << std::endl << "Synthetic image mode\n"; + TestTransformType::Pointer test_transform = TestTransformType::New(); + + inv_test_transform = TestTransformType::New(); + + TestTransformType::InputPointType translate_vector; + + test_transform->SetIdentity(); + test_transform->Scale( 1.0 / test_scale); + if (rotate_middle) { + std::cerr << "Rotation centred at middle of image." << std::endl; + /* Cycle through each dimension and shift by half*/ + FixedImageType::SizeType size = + fixedImage->GetLargestPossibleRegion().GetSize(); + for (unsigned int k = 0; k < Dimension; ++k) + translate_vector[k] = size[k]/2.0; + test_transform->SetCenter( translate_vector); + } else { + std::cerr << "Rotation centred at origin." << std::endl; + } +#if 0 + if (rotate_middle) { + std::cerr << "Rotation centred at middle of image." << std::endl; + /* Cycle through each dimension and shift by half*/ + FixedImageType::SizeType size = + fixedImage->GetLargestPossibleRegion().GetSize(); + for (unsigned int k = 0; k < Dimension; ++k) + translate_vector[k] = size[k]/2.0; + test_transform->Translate( translate_vector); + } else { + std::cerr << "Rotation centred at origin." << std::endl; + } +#endif + + test_transform->Rotate(0,1,test_rotate); +#if 0 + if (rotate_middle) { + /* Cycle through each dimension and shift back*/ + for (unsigned int k = 0; k < Dimension; ++k) + translate_vector[k] = -translate_vector[k]; + test_transform->Translate( translate_vector); + } +#endif + + test_transform->GetInverse(inv_test_transform); + + { + FixedImageType::Pointer scaledImage; + + SiftFilterType::ResampleFilterType::Pointer scaler = SiftFilterType::ResampleFilterType::New(); + scaler->SetInput(fixedImage); + FixedImageType::SizeType size = + fixedImage->GetLargestPossibleRegion().GetSize(); + for (unsigned int k = 0; k < Dimension; ++k) + size[k] = (unsigned int) floor(size[k] * test_scale); + scaler->SetSize( size ); + scaler->SetOutputSpacing(fixedImage->GetSpacing()); + scaler->SetTransform(test_transform); + scaler->Update(); + scaledImage = scaler->GetOutput(); + + siftFilter2.writeImage(scaledImage, outputImage2); + std::cout << std::endl; + + keypoints2 = siftFilter2.getSiftFeatures(scaledImage); + + pointSet2->SetInput(keypoints2); + pointSet1->SetOutsideValue(0); + pointSet1->SetInsideValue(255); + pointSet1->SetSize(scaledImage->GetLargestPossibleRegion().GetSize()); + + WriterType::Pointer writer2 = WriterType::New(); + writer2->SetFileName(outputImageKeys2); + writer2->SetInput(pointSet2->GetOutput()); + writer2->Update(); + } + + std::cerr << "Test Image Scale: " << test_scale << std::endl; + std::cerr << "Test Image Rotate: " << test_rotate << std::endl; + std::cerr << std::endl << "Matching Keypoints\n"; + + siftFilter2.MatchKeypointsPos(keypoints1, keypoints2, inv_test_transform); + siftFilter2.MatchKeypointsFeatures(keypoints1, keypoints2, inv_test_transform); + } + return 0; +} diff --git a/Examples/FeatureExtraction/otbFeatureExtractionExamplesTests.cxx b/Examples/FeatureExtraction/otbFeatureExtractionExamplesTests.cxx index f4566d28e2..c768f3e118 100644 --- a/Examples/FeatureExtraction/otbFeatureExtractionExamplesTests.cxx +++ b/Examples/FeatureExtraction/otbFeatureExtractionExamplesTests.cxx @@ -38,6 +38,8 @@ REGISTER_TEST(ExtractRoadByStepsExampleTest); REGISTER_TEST(ExtractRoadExampleTest); REGISTER_TEST(SeamCarvingExampleTest); REGISTER_TEST(SeamCarvingOtherExampleTest); +REGISTER_TEST(ImageToSIFTKeyPointSetFilterTest); +REGISTER_TEST(ScaleInvariantFeatureImageFilterTest); } #undef main @@ -91,3 +93,11 @@ REGISTER_TEST(SeamCarvingOtherExampleTest); #undef main #define main SeamCarvingOtherExampleTest #include "SeamCarvingOtherExample.cxx" + +#undef main +#define main ImageToSIFTKeyPointSetFilterTest +#include "ImageToSIFTKeyPointSetFilter.cxx" + +#undef main +#define main ScaleInvariantFeatureImageFilterTest +#include "ScaleInvariantFeatureImageFilter.cxx" -- GitLab