Skip to content
Snippets Groups Projects
Commit 3e75ec57 authored by Aurélien Bricier's avatar Aurélien Bricier
Browse files

ENH: better testing and compatibility regarding to ImageFunctionAdapter of FlusserImageFunction

parent f51bb6c6
No related branches found
No related tags found
No related merge requests found
......@@ -90,24 +90,24 @@ public:
typedef typename Superclass::ContinuousIndexType ContinuousIndexType;
typedef typename Superclass::PointType PointType;
typedef typename Superclass::OutputType RealType;
typedef typename RealType::ValueType ScalarRealType;
typedef typename Superclass::OutputType OutputType;
typedef typename OutputType::ValueType ScalarRealType;
/** Dimension of the underlying image. */
itkStaticConstMacro(ImageDimension, unsigned int,
InputImageType::ImageDimension);
/** Evalulate the function at specified index */
virtual RealType EvaluateAtIndex(const IndexType& index) const;
virtual OutputType EvaluateAtIndex(const IndexType& index) const;
/** Evaluate the function at non-integer positions */
virtual RealType Evaluate(const PointType& point) const
virtual OutputType Evaluate(const PointType& point) const
{
IndexType index;
this->ConvertPointToNearestIndex(point, index);
return this->EvaluateAtIndex(index);
}
virtual RealType EvaluateAtContinuousIndex(
virtual OutputType EvaluateAtContinuousIndex(
const ContinuousIndexType& cindex) const
{
IndexType index;
......
......@@ -47,12 +47,12 @@ FlusserImageFunction<TInputImage, TCoordRep>
}
template <class TInputImage, class TCoordRep>
typename FlusserImageFunction<TInputImage,TCoordRep>::RealType
typename FlusserImageFunction<TInputImage,TCoordRep>::OutputType
FlusserImageFunction<TInputImage,TCoordRep>
::EvaluateAtIndex(const IndexType& index) const
{
// Build moments vector
RealType moments;
OutputType moments;
// Initialize moments
moments.Fill( itk::NumericTraits< ScalarRealType >::Zero );
......
......@@ -75,7 +75,7 @@ int main(int argc, char * argv[])
// Software Guide : BeginCodeSnippet
typedef otb::FlusserImageFunction<InputImageType> FlusserType;
typedef FlusserType::RealType MomentType;
typedef FlusserType::OutputType MomentType;
FlusserType::Pointer fmFunction = FlusserType::New();
// Software Guide : EndCodeSnippet
......
......@@ -131,25 +131,25 @@ ADD_TEST(feTuHuImageRotationInvariant ${FEATUREEXTRACTION_TESTS1}
90
)
ADD_TEST(feTuFlusserImage ${FEATUREEXTRACTION_TESTS1}
--compare-ascii ${EPSILON_8} ${BASELINE_FILES}/feFlusserImage.txt
${TEMP}/feFlusserImage.txt
ADD_TEST(feTuFlusserImageNew ${FEATUREEXTRACTION_TESTS1}
otbFlusserImageNew
)
ADD_TEST(feTvFlusserImage ${FEATUREEXTRACTION_TESTS1}
--compare-ascii ${EPSILON_8} ${BASELINE_FILES}/feTvFlusserImage.txt
${TEMP}/feTvFlusserImage.txt
otbFlusserImage
${INPUTDATA}/poupees.png
${TEMP}/feFlusserImage.txt)
${TEMP}/feTvFlusserImage.txt)
ADD_TEST(feTuFlusserImageScaleInvariant ${FEATUREEXTRACTION_TESTS1}
otbFlusserImageScaleInvariant
${INPUTDATA}/poupees.png
${TEMP}/feFlusserImageScaleInvariant.txt
${TEMP}/feFlusserImageScaleInvariant.tiff
)
ADD_TEST(feTuFlusserImageRotationInvariant ${FEATUREEXTRACTION_TESTS1}
otbFlusserImageRotationInvariant
${INPUTDATA}/poupees.png
${TEMP}/feFlusserImageRotationInvariant.txt
${TEMP}/feFlusserImageRotationInvariant.tiff
90
)
......
......@@ -39,6 +39,7 @@ void RegisterTests()
REGISTER_TEST(otbHuImage);
REGISTER_TEST(otbHuImageRotationInvariant);
REGISTER_TEST(otbHuImageScaleInvariant);
REGISTER_TEST(otbFlusserImageNew);
REGISTER_TEST(otbFlusserImage);
REGISTER_TEST(otbFlusserImageRotationInvariant);
REGISTER_TEST(otbFlusserImageScaleInvariant);
......
......@@ -31,10 +31,25 @@
#include "otbBCOInterpolateImageFunction.h"
#include "itkLinearInterpolateImageFunction.h"
#include "otbStreamingResampleImageFilter.h"
#include "otbStreamingImageFileWriter.h"
#include "itkResampleImageFilter.h"
int otbFlusserImageNew(int argc, char * argv[])
{
typedef unsigned char InputPixelType;
const unsigned int Dimension = 2;
typedef otb::Image<InputPixelType, Dimension> InputImageType;
typedef otb::FlusserImageFunction<InputImageType> FunctionType;
// Instantiating object
FunctionType::Pointer function = FunctionType::New();
std::cout << function << std::endl;
return EXIT_SUCCESS;
}
int otbFlusserImage(int argc, char * argv[])
{
const char * inputFilename = argv[1];
......@@ -44,10 +59,10 @@ int otbFlusserImage(int argc, char * argv[])
typedef unsigned char InputPixelType;
const unsigned int Dimension = 2;
typedef itk::Image<InputPixelType, Dimension> InputImageType;
typedef otb::Image<InputPixelType, Dimension> InputImageType;
typedef otb::ImageFileReader<InputImageType> ReaderType;
typedef otb::FlusserImageFunction<InputImageType> FunctionType;
typedef FunctionType::RealType RealType;
typedef FunctionType::OutputType OutputType;
ReaderType::Pointer reader = ReaderType::New();
FunctionType::Pointer function = FunctionType::New();
......@@ -61,7 +76,7 @@ int otbFlusserImage(int argc, char * argv[])
index[1] = 100;
function->SetNeighborhoodRadius(3);
RealType Result;
OutputType Result;
Result = function->EvaluateAtIndex(index);
std::ofstream outputStream(outputFilename);
......@@ -80,10 +95,7 @@ int otbFlusserImage(int argc, char * argv[])
int otbFlusserImageScaleInvariant(int argc, char * argv[])
{
const char * inputFilename = argv[1];
const char * outputFilename = argv[2];
const char * outputImageName = argv[3];
typedef double InputPixelType;
const unsigned int Dimension = 2;
typedef otb::Image<InputPixelType, Dimension> InputImageType;
......@@ -94,15 +106,13 @@ int otbFlusserImageScaleInvariant(int argc, char * argv[])
typedef otb::BCOInterpolateImageFunction<InputImageType,
double> InterpolatorType;
typedef otb::FlusserImageFunction<InputImageType> FunctionType;
typedef FunctionType::RealType RealType;
typedef otb::StreamingImageFileWriter<InputImageType> WriterType;
typedef FunctionType::OutputType OutputType;
ReaderType::Pointer reader = ReaderType::New();
StreamingResampleImageFilterType::Pointer resampler = StreamingResampleImageFilterType::New();
InterpolatorType::Pointer interpolator = InterpolatorType::New();
FunctionType::Pointer function1 = FunctionType::New();
FunctionType::Pointer function2 = FunctionType::New();
WriterType::Pointer writer = WriterType::New();
reader->SetFileName(inputFilename);
reader->Update();
......@@ -119,47 +129,42 @@ int otbFlusserImageScaleInvariant(int argc, char * argv[])
resampler->SetOutputSize(size);
resampler->SetOutputSpacing(0.5);
resampler->Update();
writer->SetInput(resampler->GetOutput());
writer->SetFileName(outputImageName);
writer->Update();
function1->SetInputImage(reader->GetOutput());
InputImageType::IndexType index1;
index1[0] = 100;
index1[1] = 100;
function1->SetNeighborhoodRadius(2);
RealType Result1 = function1->EvaluateAtIndex(index1);
index1[0] = 256;
index1[1] = 256;
function1->SetNeighborhoodRadius(3);
OutputType Result1 = function1->EvaluateAtIndex(index1);
function2->SetInputImage(resampler->GetOutput());
InputImageType::IndexType index2;
index2[0] = 200;
index2[1] = 200;
function2->SetNeighborhoodRadius(4);
RealType Result2 = function2->EvaluateAtIndex(index2);
index2[0] = 512;
index2[1] = 512;
function2->SetNeighborhoodRadius(6);
OutputType Result2 = function2->EvaluateAtIndex(index2);
std::ofstream outputStream(outputFilename);
outputStream << std::setprecision(10);
double error = 0.0;
for (unsigned int j = 1; j < 12; j++)
{
double error = 2*vcl_abs( Result1[j-1] - Result2[j-1]) / vcl_abs(Result1[j-1] + Result2[j-1]);
error += vcl_pow(vcl_abs( Result1[j-1] - Result2[j-1]), 2);
outputStream << "Error = " << error << std::endl
<< "Original Image - Flusser Moment #" << j << " : " << Result1[j-1] << std::endl
<< "Scaled Image - Flusser Moment #" << j << " : " << Result2[j-1] << std::endl
<< std::endl;
std::cout << "Original -F" << j
<< " : " << Result1[j]
<< " / Scaled - F" << j
<< " : " << Result2[j] << std::endl;
}
if (error > 1)
{
itkGenericExceptionMacro( <<std::endl
<< "Error = " << error
<< " > 1 -> TEST FAILLED" << std::endl
<< "Original Image - Flusser Moment #" << j << " : " << Result1[j-1] << std::endl
<< "Scaled Image - Flusser Moment #" << j << " : " << Result2[j-1] << std::endl
<< std::endl;)
}
error = vcl_sqrt(error)/11.0;
std::cout << "Error : " << error << std::endl
<< std::endl;
if (error > 1E-3)
{
itkGenericExceptionMacro( << "Error = " << error
<< " > 1E-3 -> TEST FAILLED" << std::endl );
}
outputStream.close();
return EXIT_SUCCESS;
}
......@@ -167,9 +172,7 @@ int otbFlusserImageScaleInvariant(int argc, char * argv[])
int otbFlusserImageRotationInvariant(int argc, char * argv[])
{
const char * inputFilename = argv[1];
const char * outputFilename = argv[2];
const char * outputImageName = argv[3];
const double angleInDegrees = atoi(argv[4]);
const double angleInDegrees = atoi(argv[2]);
typedef double InputPixelType;
......@@ -178,11 +181,11 @@ int otbFlusserImageRotationInvariant(int argc, char * argv[])
typedef otb::ImageFileReader<InputImageType> ReaderType;
typedef itk::ResampleImageFilter<
InputImageType, InputImageType > FilterType;
typedef itk::LinearInterpolateImageFunction<InputImageType, double> InterpolatorType;
typedef otb::BCOInterpolateImageFunction<InputImageType,
double> InterpolatorType;
typedef otb::FlusserImageFunction<InputImageType> FunctionType;
typedef FunctionType::RealType RealType;
typedef otb::StreamingImageFileWriter<InputImageType> WriterType;
typedef itk::AffineTransform< double, Dimension > TransformType;
typedef FunctionType::OutputType OutputType;
typedef itk::AffineTransform< double, Dimension > TransformType;
ReaderType::Pointer reader = ReaderType::New();
......@@ -191,11 +194,14 @@ int otbFlusserImageRotationInvariant(int argc, char * argv[])
InterpolatorType::Pointer interpolator = InterpolatorType::New();
FunctionType::Pointer function1 = FunctionType::New();
FunctionType::Pointer function2 = FunctionType::New();
WriterType::Pointer writer = WriterType::New();
reader->SetFileName(inputFilename);
reader->Update();
interpolator->SetInputImage(reader->GetOutput());
interpolator->SetRadius(2);
interpolator->SetAlpha(-0.5);
filter->SetInterpolator(interpolator);
filter->SetDefaultPixelValue( 100 );
......@@ -209,7 +215,6 @@ int otbFlusserImageRotationInvariant(int argc, char * argv[])
filter->SetOutputDirection( reader->GetOutput()->GetDirection() );
filter->SetSize( size );
filter->SetInput(reader->GetOutput());
TransformType::OutputVectorType translation1;
......@@ -231,47 +236,41 @@ int otbFlusserImageRotationInvariant(int argc, char * argv[])
filter->SetTransform( transform );
filter->Update();
writer->SetInput(filter->GetOutput());
writer->SetFileName(outputImageName);
writer->Update();
function1->SetInputImage(reader->GetOutput());
InputImageType::IndexType index1;
index1[0] = 256;
index1[1] = 256;
function1->SetNeighborhoodRadius(4);
RealType Result1 = function1->EvaluateAtIndex(index1);
OutputType Result1 = function1->EvaluateAtIndex(index1);
function2->SetInputImage(filter->GetOutput());
InputImageType::IndexType index2;
index2[0] = 256;
index2[1] = 256;
function2->SetNeighborhoodRadius(4);
RealType Result2 = function2->EvaluateAtIndex(index2);
OutputType Result2 = function2->EvaluateAtIndex(index2);
std::ofstream outputStream(outputFilename);
outputStream << std::setprecision(10);
double error = 0.0;
for (unsigned int j = 1; j < 12; j++)
{
double error = vcl_abs( Result1[j-1] - Result2[j-1]);
error += vcl_pow(vcl_abs( Result1[j-1] - Result2[j-1]), 2);
outputStream << "Error = " << error << std::endl
<< "Original Image - Flusser Moment #" << j << " : " << Result1[j-1] << std::endl
<< "Rotated Image - Flusser Moment #" << j << " : " << Result2[j-1] << std::endl
<< "Rotation angle : " << angleInDegrees << std::endl;
std::cout << "Original -F" << j
<< " : " << Result1[j]
<< " / Rotated - F" << j
<< " : " << Result2[j] << std::endl;
}
if (error > 1E-9)
{
itkGenericExceptionMacro( <<std::endl
<< "Error = " << error
<< " > 1E-9 -> TEST FAILLED" << std::endl
<< "Original Image - Flusser Moment #" << j << " : " << Result1[j-1] << std::endl
<< " Rotated Image - Flusser Moment #" << j << " : " << Result2[j-1] << std::endl
<< "Rotation angle : " << angleInDegrees << std::endl );
}
error = vcl_sqrt(error)/11.0;
std::cout << "Error : " << error << std::endl
<< std::endl;
if (error > 1E-3)
{
itkGenericExceptionMacro( << "Error = " << error
<< " > 1E-3 -> TEST FAILLED" << std::endl );
}
outputStream.close();
return EXIT_SUCCESS;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment