Skip to content
Snippets Groups Projects
Commit 6dcdb9ee authored by Jordi Inglada's avatar Jordi Inglada
Browse files

DOC: typos for SURF and SIFT examples and wip for SIFT disparity map

parent 968b99ee
No related branches found
No related tags found
No related merge requests found
...@@ -9,6 +9,10 @@ ADD_EXECUTABLE(NCCRegistrationFilterExample NCCRegistrationFilterExample.cxx ) ...@@ -9,6 +9,10 @@ ADD_EXECUTABLE(NCCRegistrationFilterExample NCCRegistrationFilterExample.cxx )
TARGET_LINK_LIBRARIES(NCCRegistrationFilterExample OTBFeatureExtraction OTBCommon OTBIO ITKCommon TARGET_LINK_LIBRARIES(NCCRegistrationFilterExample OTBFeatureExtraction OTBCommon OTBIO ITKCommon
ITKIO) ITKIO)
ADD_EXECUTABLE(SIFTDisparityMapEstimation SIFTDisparityMapEstimation.cxx )
TARGET_LINK_LIBRARIES(SIFTDisparityMapEstimation OTBFeatureExtraction OTBCommon OTBIO ITKCommon
ITKIO)
IF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING ) IF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING )
......
...@@ -49,7 +49,8 @@ ...@@ -49,7 +49,8 @@
// Software Guide : BeginCodeSnippet // Software Guide : BeginCodeSnippet
#include "otbKeyPointSetsMatchingFilter.h" #include "otbKeyPointSetsMatchingFilter.h"
#include "otbNearestPointDeformationFieldGenerator.h" #include "otbSiftFastImageFilter.h"
#include "itkDeformationFieldSource.h"
#include "itkWarpImageFilter.h" #include "itkWarpImageFilter.h"
// Software Guide : EndCodeSnippet // Software Guide : EndCodeSnippet
...@@ -59,7 +60,8 @@ ...@@ -59,7 +60,8 @@
#include "otbImageFileReader.h" #include "otbImageFileReader.h"
#include "otbImageFileWriter.h" #include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h" #include "itkRescaleIntensityImageFilter.h"
#include "otbMultiToMonoChannelExtractROI.h" #include "itkPointSet.h"
int main (int argc, char* argv[]) int main (int argc, char* argv[])
{ {
...@@ -177,16 +179,36 @@ int main (int argc, char* argv[]) ...@@ -177,16 +179,36 @@ int main (int argc, char* argv[])
movingReader->UpdateOutputInformation(); movingReader->UpdateOutputInformation();
// Software Guide : EndCodeSnippet // Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We will now instantiate the 2 SIFT filters and the filter used
// for the matching of the points.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
ImageToSIFTKeyPointSetFilterType::Pointer filter1 =
ImageToSIFTKeyPointSetFilterType::New();
ImageToSIFTKeyPointSetFilterType::Pointer filter2 =
ImageToSIFTKeyPointSetFilterType::New();
EuclideanDistanceMatchingFilterType::Pointer euclideanMatcher =
EuclideanDistanceMatchingFilterType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We plug the pipeline and set the parameters.
//
// Software Guide : EndLatex
ImageToSIFTKeyPointSetFilterType::Pointer filter1 = ImageToSIFTKeyPointSetFilterType::New(); // Software Guide : BeginCodeSnippet
ImageToSIFTKeyPointSetFilterType::Pointer filter2 = ImageToSIFTKeyPointSetFilterType::New();
EuclideanDistanceMatchingFilterType::Pointer euclideanMatcher = EuclideanDistanceMatchingFilterType::New();
double secondOrderThreshold = 0.5;
bool useBackMatching = 0;
filter1->SetInput( fixedReader->GetOutput() );
filter2->SetInput( movingReader->GetOutput() );
euclideanMatcher->SetInput1(filter1->GetOutput()); euclideanMatcher->SetInput1(filter1->GetOutput());
euclideanMatcher->SetInput2(filter2->GetOutput()); euclideanMatcher->SetInput2(filter2->GetOutput());
euclideanMatcher->SetDistanceThreshold(secondOrderThreshold); euclideanMatcher->SetDistanceThreshold(secondOrderThreshold);
...@@ -197,7 +219,7 @@ int main (int argc, char* argv[]) ...@@ -197,7 +219,7 @@ int main (int argc, char* argv[])
euclideanMatcher->Update(); euclideanMatcher->Update();
MatchVectorType trueSecondOrder; MatchVectorType trueSecondOrder;
for(LandmarkListType::Iterator it = landmarkList->Begin(); it != landmarkList->End();++it) for(LandmarkListType::Iterator it = landmarkList->Begin(); it != landmarkList->End();++it)
{ {
...@@ -208,25 +230,22 @@ int main (int argc, char* argv[]) ...@@ -208,25 +230,22 @@ int main (int argc, char* argv[])
} }
// Displaying the matches // Displaying the matches
typedef otb::PrintableImageFilter<VectorImageType> PrintableFilterType; typedef itk::RescaleIntensityImageFilter<ImageType, OutputImageType>
typedef PrintableFilterType::OutputImageType OutputImageType; PrintableFilterType;
PrintableFilterType::Pointer printable1 = PrintableFilterType::New(); PrintableFilterType::Pointer printable1 = PrintableFilterType::New();
PrintableFilterType::Pointer printable2 = PrintableFilterType::New(); PrintableFilterType::Pointer printable2 = PrintableFilterType::New();
printable1->SetInput(inputImage1); printable1->SetInput(fixedReader->GetOutput());
printable1->SetChannel(3); printable1->SetOutputMinimum(0);
printable1->SetChannel(2); printable1->SetOutputMaximum(255);
printable1->SetChannel(1);
printable1->Update(); printable1->Update();
printable2->SetInput(inputImage2); printable2->SetInput(movingReader->GetOutput());
printable2->SetChannel(3); printable2->SetOutputMinimum(0);
printable2->SetChannel(2); printable2->SetOutputMaximum(255);
printable2->SetChannel(1);
printable2->Update(); printable2->Update();
// Always the same VariableLenghtVector compatibility problem ...
typedef otb::Image<itk::RGBPixel<unsigned char>,2> RGBImageType; typedef otb::Image<itk::RGBPixel<unsigned char>,2> RGBImageType;
...@@ -240,9 +259,9 @@ int main (int argc, char* argv[]) ...@@ -240,9 +259,9 @@ int main (int argc, char* argv[])
while(!inIt1.IsAtEnd() && !outIt1.IsAtEnd()) while(!inIt1.IsAtEnd() && !outIt1.IsAtEnd())
{ {
itk::RGBPixel<unsigned char> pixel; itk::RGBPixel<unsigned char> pixel;
pixel.SetRed(inIt1.Get()[0]); pixel.SetRed(inIt1.Get());
pixel.SetGreen(inIt1.Get()[1]); pixel.SetGreen(inIt1.Get());
pixel.SetBlue(inIt1.Get()[2]); pixel.SetBlue(inIt1.Get());
outIt1.Set(pixel); outIt1.Set(pixel);
++inIt1; ++inIt1;
++outIt1; ++outIt1;
...@@ -258,9 +277,9 @@ int main (int argc, char* argv[]) ...@@ -258,9 +277,9 @@ int main (int argc, char* argv[])
while(!inIt2.IsAtEnd() && !outIt2.IsAtEnd()) while(!inIt2.IsAtEnd() && !outIt2.IsAtEnd())
{ {
itk::RGBPixel<unsigned char> pixel; itk::RGBPixel<unsigned char> pixel;
pixel.SetRed(inIt2.Get()[0]); pixel.SetRed(inIt2.Get());
pixel.SetGreen(inIt2.Get()[1]); pixel.SetGreen(inIt2.Get());
pixel.SetBlue(inIt2.Get()[2]); pixel.SetBlue(inIt2.Get());
outIt2.Set(pixel); outIt2.Set(pixel);
++inIt2; ++inIt2;
++outIt2; ++outIt2;
...@@ -268,233 +287,129 @@ int main (int argc, char* argv[]) ...@@ -268,233 +287,129 @@ int main (int argc, char* argv[])
typedef float VectorComponentType;
typedef itk::Vector< VectorComponentType, Dimension > VectorType;
typedef otb::Image< VectorType, Dimension > DeformationFieldType;
typedef itk::DeformationFieldSource<
DeformationFieldType
> DeformationSourceType;
DeformationSourceType::Pointer deformer = DeformationSourceType::New();
// Software Guide : BeginLatex
//
// Once the estimation has been performed by the \doxygen{otb}{DisparityMapEstimationMethod}, one can generate
// the associated deformation field (that means translation in first and second image direction).
// It will be represented as a \doxygen{otb}{VectorImage}.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::VectorImage<PixelType,Dimension> DeformationFieldType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// For the deformation field estimation, we will use the \doxygen{otb}{NearestPointDeformationFieldGenerator}.
// This filter will perform a nearest neighbor interpolation on the deformation values in the point set data.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::NearestPointDeformationFieldGenerator<PointSetType,
DeformationFieldType> GeneratorType;
// Software GUide : EndCodeSnippet ImageType::ConstPointer fixedImage = fixedReader->GetOutput();
// Software Guide : BeginLatex
//
// The disparity map estimation filter is instanciated.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
GeneratorType::Pointer generator = GeneratorType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We must then specify the input point set using the \code{SetPointSet()} method.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
generator->SetPointSet(dmestimator->GetOutput());
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// One must also specify the origin, size and spacing of the output deformation field.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
generator->SetOutputOrigin(fixedReader->GetOutput()->GetOrigin());
generator->SetOutputSpacing(fixedReader->GetOutput()->GetSpacing());
generator->SetOutputSize(fixedReader->GetOutput()
->GetLargestPossibleRegion().GetSize());
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The local registration process can lead to wrong deformation values and transform parameters. To Select only
// points in point set for which the registration process was succesful, one can set a threshold on the final metric
// value : points for which the absolute final metric value is below this threshold will be discarded. This
// threshold can be set with the \code{SetMetricThreshold()} method.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet deformer->SetOutputSpacing( fixedImage->GetSpacing() );
deformer->SetOutputOrigin( fixedImage->GetOrigin() );
deformer->SetOutputRegion( fixedImage->GetLargestPossibleRegion() );
generator->SetMetricThreshold(atof(argv[11])); typedef DeformationSourceType::LandmarkContainerPointer
LandmarkContainerPointer;
typedef DeformationSourceType::LandmarkContainer
LandmarkContainerType;
typedef DeformationSourceType::LandmarkPointType LandmarkPointType;
// Software Guide : EndCodeSnippet LandmarkContainerType::Pointer sourceLandmarks = LandmarkContainerType::New();
LandmarkContainerType::Pointer targetLandmarks = LandmarkContainerType::New();
// Software Guide : BeginLatex LandmarkPointType sourcePoint;
// LandmarkPointType targetPoint;
// \relatedClasses
// \begin{itemize}
// \item \doxygen{otb}{NNearestPointsLinearInterpolateDeformationFieldGenerator}
// \item \doxygen{otb}{BSplinesInterpolateDeformationFieldGenerator}
// \item \doxygen{otb}{NearestTransformDeformationFieldGenerator}
// \item \doxygen{otb}{NNearestTransformsLinearInterpolateDeformationFieldGenerator}
// \item \doxygen{otb}{BSplinesInterpolateTransformDeformationFieldGenerator}
// \end{itemize}
//
// Software Guide : EndLatex
// Software Guide : BeginLatex
// unsigned int pointId = 0;
// Now we can warp our fixed image according to the estimated deformation field. This will be performed by the
// \doxygen{itk}{WarpImageFilter}. First, we define this filter.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef itk::WarpImageFilter<ImageType,ImageType, for(LandmarkListType::Iterator it = landmarkList->Begin(); it != landmarkList->End();++it)
DeformationFieldType> ImageWarperType; {
PointType point1 = it.Get()->GetPoint1();
PointType point2 = it.Get()->GetPoint2();
sourcePoint[0] = point1[0];
sourcePoint[1] = point1[1];
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Then we instantiate it.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet targetPoint[0] = point2[0];
targetPoint[1] = point2[1];
sourceLandmarks->InsertElement( pointId, sourcePoint );
targetLandmarks->InsertElement( pointId, targetPoint );
ImageWarperType::Pointer warper = ImageWarperType::New(); ++pointId;
}
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex deformer->SetSourceLandmarks( sourceLandmarks.GetPointer() );
// deformer->SetTargetLandmarks( targetLandmarks.GetPointer() );
// We set the input image to warp using the \code{SetInput()} method, and the deformation field
// using the \code{SetDeformationField()} method.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet try
{
deformer->UpdateLargestPossibleRegion();
}
catch( itk::ExceptionObject & excp )
{
std::cerr << "Exception thrown " << std::endl;
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
warper->SetInput(movingReader->GetOutput()); DeformationFieldType::ConstPointer deformationField = deformer->GetOutput();
warper->SetDeformationField(generator->GetOutput());
warper->SetOutputOrigin(fixedReader->GetOutput()->GetOrigin());
warper->SetOutputSpacing(fixedReader->GetOutput()->GetSpacing());
// Software Guide : EndCodeSnippet deformer->Update();
// Software Guide : BeginLatex std::cout << "Image Resampling" << std::endl;
// typedef itk::WarpImageFilter< ImageType,
// In order to write the result to a PNG file, we will rescale it on a proper range. ImageType,
// DeformationFieldType > FilterType;
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet FilterType::Pointer warper = FilterType::New();
typedef itk::RescaleIntensityImageFilter<ImageType, typedef itk::LinearInterpolateImageFunction<
OutputImageType> RescalerType; ImageType, double > InterpolatorType;
RescalerType::Pointer outputRescaler = RescalerType::New(); InterpolatorType::Pointer interpolator = InterpolatorType::New();
outputRescaler->SetInput(warper->GetOutput());
outputRescaler->SetOutputMaximum(255);
outputRescaler->SetOutputMinimum(0);
// Software Guide : EndCodeSnippet warper->SetInterpolator( interpolator );
// Software Guide : BeginLatex
//
// We can now write the image to a file. The filters are executed by invoking
// the \code{Update()} method.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet warper->SetOutputSpacing( deformationField->GetSpacing() );
warper->SetOutputOrigin( deformationField->GetOrigin() );
typedef otb::ImageFileWriter<OutputImageType> WriterType; warper->SetDeformationField( deformationField );
WriterType::Pointer outputWriter = WriterType::New(); warper->SetInput( movingReader->GetOutput() );
outputWriter->SetInput(outputRescaler->GetOutput());
outputWriter->SetFileName(argv[4]);
outputWriter->Update();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex typedef otb::ImageFileWriter< ImageType > WriterType;
// WriterType::Pointer movingWriter = WriterType::New();
// We also want to write the deformation field along the first direction to a file.
// To achieve this we will use the \doxygen{otb}{MultiToMonoChannelExtractROI} filter.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet movingWriter->SetFileName( argv[6] );
movingWriter->SetInput( warper->GetOutput() );
typedef otb::MultiToMonoChannelExtractROI<PixelType,
PixelType> ChannelExtractionFilterType;
ChannelExtractionFilterType::Pointer channelExtractor
= ChannelExtractionFilterType::New(); try
{
movingWriter->Update();
}
catch( itk::ExceptionObject & excp )
{
std::cerr << "Exception thrown " << std::endl;
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
channelExtractor->SetInput(generator->GetOutput()); typedef otb::ImageFileWriter< DeformationFieldType > DeformationWriterType;
channelExtractor->SetChannel(1);
RescalerType::Pointer fieldRescaler = RescalerType::New(); DeformationWriterType::Pointer defWriter = DeformationWriterType::New();
fieldRescaler->SetInput(channelExtractor->GetOutput());
fieldRescaler->SetOutputMaximum(255);
fieldRescaler->SetOutputMinimum(0);
WriterType::Pointer fieldWriter = WriterType::New(); defWriter->SetFileName( "deformation.mhd" );
fieldWriter->SetInput(fieldRescaler->GetOutput()); defWriter->SetInput( deformationField );
fieldWriter->SetFileName(argv[3]); defWriter->Update();
fieldWriter->Update();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Figure~\ref{fig:SIMPLEDISPARITYMAPESTIMATIONOUTPUT} shows the result of applying disparity map estimation on
// a regular point set, followed by deformation field estimation and fixed image resampling on an Ikonos image.
// The moving image is the fixed image warped with a sinusoidal deformation with a 3-pixels amplitude and a 170-pixels
// period. Please note that there are more efficient ways to interpolate the deformation field than nearest neighbor,
// including BSplines fitting.
//
// \begin{figure}
// \center
// \includegraphics[width=0.40\textwidth]{ROI_IKO_PAN_LesHalles_pos_spacing.eps}
// \includegraphics[width=0.40\textwidth]{ROI_IKO_PAN_LesHalles_warped_pos_spacing.eps}
// \includegraphics[width=0.40\textwidth]{SIFTdeformationFieldOutput.eps}
// \includegraphics[width=0.40\textwidth]{SIFTresampledMovingOutput.eps}
// \itkcaption[Deformation field and resampling from disparity map estimation]{From left
// to right and top to bottom: fixed input image, moving image with a sinusoid deformation,
// estimated deformation field in the horizontal direction, resampled moving image.}
// \label{fig:SIMPLEDISPARITYMAPESTIMATIONOUTPUT}
// \end{figure}
//
// Software Guide : EndLatex
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
......
...@@ -383,6 +383,7 @@ int main(int argc, char * argv[]) ...@@ -383,6 +383,7 @@ int main(int argc, char * argv[])
// image.} // image.}
// \label{fig:SIFTFast} // \label{fig:SIFTFast}
// \end{figure} // \end{figure}
// Software Guide : EndLatex
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
...@@ -381,6 +381,6 @@ int main(int argc, char * argv[]) ...@@ -381,6 +381,6 @@ int main(int argc, char * argv[])
// image.} // image.}
// \label{fig:SURFFast} // \label{fig:SURFFast}
// \end{figure} // \end{figure}
// Software Guide : EndLatex
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment