Commit bb243214 authored by Otmane Lahlou's avatar Otmane Lahlou
Browse files

ENH: Correct the DrawLineSpatialObjectFilter and the...

ENH: Correct the DrawLineSpatialObjectFilter and the DrawLineSpatialObjectListFilter and  tests using them
parent 2da426a3
......@@ -350,43 +350,40 @@ INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIRS})
# Check if ${GDAL_LIBRARY} has tiff library
SET(TIFF_LIBRARY ${GDAL_LIBRARY})
IF(NOT DEFINED GDAL_HAS_TIFF)
TRY_COMPILE(GDAL_HAS_TIFF
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/CMake/TestGDALHasTiff.cxx
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:PATH=${TIFF_INCLUDE_DIRS};${GDAL_INCLUDE_DIRS}" "-DLINK_DIRECTORIES:PATH=${GDAL_LIBRARY_DIRS}" "-DLINK_LIBRARIES:STRING=${GDAL_LIBRARY}"
OUTPUT_VARIABLE OUTPUT)
IF(GDAL_HAS_TIFF)
MESSAGE(STATUS "Testing if GDAL has tiff -- yes.")
MESSAGE("-- Testing if GDAL has tiff -- yes.")
ELSE(GDAL_HAS_TIFF)
MESSAGE(STATUS "Testing if GDAL has tiff -- no.")
MESSAGE("-- Testing if GDAL has tiff -- no.")
FIND_LIBRARY(TIFF_LIBRARY tiff PATHS)
IF (NOT TIFF_LIBRARY)
MESSAGE(FATAL_ERROR
"Cannot find tiff library. Please set TIFF_LIBRARY.")
ENDIF (NOT TIFF_LIBRARY)
ENDIF(GDAL_HAS_TIFF)
ENDIF(NOT DEFINED GDAL_HAS_TIFF)
# Check if ${GDAL_LIBRARY} has geotiff library
SET(GEOTIFF_LIBRARY ${GDAL_LIBRARY})
IF(NOT DEFINED GDAL_HAS_GEOTIFF)
TRY_COMPILE(GDAL_HAS_GEOTIFF
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/CMake/TestGDALHasGeoTiff.cxx
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:PATH=${GEOTIFF_INCLUDE_DIRS};${GDAL_INCLUDE_DIRS}" "-DLINK_DIRECTORIES:PATH=${GDAL_LIBRARY_DIRS}" "-DLINK_LIBRARIES:STRING=${GDAL_LIBRARY}"
OUTPUT_VARIABLE OUTPUT)
IF(GDAL_HAS_GEOTIFF)
MESSAGE(STATUS "Testing if GDAL has geotiff -- yes.")
MESSAGE("-- Testing if GDAL has geotiff -- yes.")
ELSE(GDAL_HAS_GEOTIFF)
MESSAGE(STATUS "Testing if GDAL has geotiff -- no.")
MESSAGE("-- Testing if GDAL has geotiff -- no.")
FIND_LIBRARY(GEOTIFF_LIBRARY geotiff PATHS)
IF (NOT GEOTIFF_LIBRARY)
MESSAGE(FATAL_ERROR
"Cannot find geotiff library. Please set GEOTIFF_LIBRARY.")
ENDIF (NOT GEOTIFF_LIBRARY)
ENDIF(GDAL_HAS_GEOTIFF)
ENDIF(NOT DEFINED GDAL_HAS_GEOTIFF)
# Include jpeg headers (FLTK ones)
INCLUDE_DIRECTORIES(${OTB_SOURCE_DIR}/Utilities/FLTK/jpeg)
......
......@@ -20,8 +20,10 @@
#include "itkSpatialObjectToImageFilter.h"
#include "itkLineSpatialObject.h"
#include "otbLineSpatialObjectList.h"
#include "otbDrawLineSpatialObjectListFilter.h"
#include <list>
//#include <list>
namespace otb
{
......@@ -38,7 +40,8 @@ namespace otb
template <class TInputImage, class TOutputImage>
class ITK_EXPORT DrawLineSpatialObjectFilter :
public itk::SpatialObjectToImageFilter< itk::LineSpatialObject<2>, TOutputImage >
//public itk::SpatialObjectToImageFilter< itk::LineSpatialObject<2>, TOutputImage >
public itk::ImageToImageFilter<TInputImage, TOutputImage >
{
public:
/** Extract dimensions as well of the images of entry of exit. */
......@@ -49,54 +52,51 @@ public:
unsigned int,
TOutputImage::ImageDimension);
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
/** typedef for the classes standards. */
typedef DrawLineSpatialObjectFilter Self;
typedef itk::SpatialObjectToImageFilter< itk::LineSpatialObject<2>, TOutputImage > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef typename Superclass::InputSpatialObjectType InputLineType;
typedef typename InputLineType::PointListType PointListType;
typedef itk::ProcessObject ProcessObjectType;
typedef DrawLineSpatialObjectFilter Self;
//typedef itk::ImageTo< itk::LineSpatialObject<2>, TOutputImage > Superclass;
typedef itk::ImageToImageFilter< TInputImage, TOutputImage > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Method for management of the "object factory". */
itkNewMacro(Self);
/** Return the name of the class. */
itkTypeMacro(DrawLineSpatialObjectFilter, SpatialObjectToImageFilter);
/** Definition of the input and output images */
typedef typename InputImageType::PixelType InputPixelType;
typedef typename OutputImageType::PixelType OutputPixelType;
typedef typename InputImageType::RegionType InputImageRegionType;
typedef typename OutputImageType::RegionType OutputImageRegionType;
/** Definition of the size of the images. */
typedef typename InputImageType::SizeType SizeType;
typedef typename OutputImageType::IndexType IndexType;
itkTypeMacro(DrawLineSpatialObjectFilter, /*SpatialObjectToImageFilter*/itk::ImageToImageFilter);
/** typedef Support for input & output image*/
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
typedef typename OutputImageType::PixelType OutputPixelType;
/** Support typedef for input & Output*/
typedef itk::LineSpatialObject<2> InputLineType;
typedef itk::ProcessObject ProcessObjectType;
/** Typedef Support for lineList Type*/
typedef LineSpatialObjectList LineSpatialObjectListType;
typedef typename LineSpatialObjectListType::Pointer LineSpatialObjectListPointer;
/** Typedef Support for drawLineSpatialObjectListFilter*/
typedef otb::DrawLineSpatialObjectListFilter<InputImageType,OutputImageType > DrawLineSpatialObjectListFilterType;
typedef typename DrawLineSpatialObjectListFilterType::Pointer DrawLineSpatialObjectListFilterPointerType;
/** Set/Get the image input of this process object. */
virtual void SetInputImage(const InputImageType *image);
const InputImageType * GetInputImage(void);
/* virtual void SetInputImage(const InputImageType *image); */
/* const InputImageType * GetInputImage(void); */
/** Get the input LineSpatialObjet (not const) */
virtual void SetInputLine(const InputLineType *line);
InputLineType * GetInput(void);
InputLineType * GetInputLine(void);
// Set/Get pixel value
/** Set/Get pixel value */
itkSetMacro(Value, OutputPixelType);
itkGetConstReferenceMacro(Value, OutputPixelType);
protected:
DrawLineSpatialObjectFilter();
virtual ~DrawLineSpatialObjectFilter() {};
......@@ -110,6 +110,7 @@ private:
OutputPixelType m_Value;
DrawLineSpatialObjectListFilterPointerType m_DrawLineListFilter;
};
} // end namespace otb
......
......@@ -20,6 +20,7 @@
#include "otbDrawLineSpatialObjectFilter.h"
#include "itkDataObject.h"
#include "itkExceptionObject.h"
#include "itkImageRegionIterator.h"
......@@ -42,7 +43,7 @@ DrawLineSpatialObjectFilter<TInputImage, TOutputImage>::DrawLineSpatialObjectFil
this->SetNumberOfRequiredOutputs(1);
m_Value = static_cast<OutputPixelType>(255.0);
m_DrawLineListFilter = DrawLineSpatialObjectListFilterType::New();
}
template <class TInputImage, class TOutputImage>
......@@ -50,7 +51,7 @@ void
DrawLineSpatialObjectFilter<TInputImage, TOutputImage>
::SetInputLine(const InputLineType *line)
{
this->ProcessObjectType::SetNthInput(0,
this->ProcessObjectType::SetNthInput(1,
const_cast< InputLineType * >( line ) );
}
......@@ -58,155 +59,39 @@ DrawLineSpatialObjectFilter<TInputImage, TOutputImage>
template <class TInputImage, class TOutputImage>
typename DrawLineSpatialObjectFilter<TInputImage, TOutputImage>::InputLineType *
DrawLineSpatialObjectFilter<TInputImage, TOutputImage>
::GetInput(void)
::GetInputLine(void)
{
return static_cast<InputLineType *>
(this->ProcessObjectType::GetInput(0) );
}
template <class TInputImage, class TOutputImage>
void
DrawLineSpatialObjectFilter<TInputImage, TOutputImage>
::SetInputImage(const InputImageType *image)
{
this->ProcessObjectType::SetNthInput(1,
const_cast< InputImageType * >( image ) );
}
template <class TInputImage, class TOutputImage>
const typename DrawLineSpatialObjectFilter<TInputImage, TOutputImage>::InputImageType *
DrawLineSpatialObjectFilter<TInputImage, TOutputImage>
::GetInputImage(void)
{
if (this->GetNumberOfInputs() < 2)
{
return 0;
}
return static_cast<const InputImageType *>
(this->ProcessObjectType::GetInput(1) );
}
template <class TInputImage, class TOutputImage>
void
DrawLineSpatialObjectFilter<TInputImage, TOutputImage>
::GenerateData(void)
{
typename InputImageType::ConstPointer input = this->GetInputImage();
typename OutputImageType::Pointer output = this->GetOutput();
// Get the region
typename OutputImageType::RegionType region;
region.SetSize(input->GetLargestPossibleRegion().GetSize());
region.SetIndex(input->GetLargestPossibleRegion().GetIndex());
output->SetRegions( region );
output->SetOrigin(input->GetOrigin());
output->SetSpacing(input->GetSpacing());
output->Allocate();
typedef itk::ImageRegionIteratorWithIndex< OutputImageType > OutputIteratorType;
typedef itk::ImageRegionConstIteratorWithIndex< InputImageType > InputIteratorType;
OutputIteratorType outputIt( output, output->GetRequestedRegion() );
InputIteratorType inputIt( input, input->GetRequestedRegion() );
outputIt.GoToBegin();
inputIt.GoToBegin();
// Copy the input image in the output image
for ( outputIt.GoToBegin(); !outputIt.IsAtEnd(); ++outputIt,++inputIt)
outputIt.Set( static_cast<OutputPixelType>(inputIt.Get()) );
// Get the LineSpatialObject
InputLineType * inputLine = this->GetInput();
// Get the list of points which consists of two points to represent a
// straight line
PointListType & pointsList = inputLine->GetPoints();
typename PointListType::const_iterator itPoints = pointsList.begin();
IndexType outputIndex;
double x1, y1;
x1 = (*itPoints).GetPosition()[0];
y1 = (*itPoints).GetPosition()[1];
itPoints++;
double x2, y2;
x2 = (*itPoints).GetPosition()[0];
y2 = (*itPoints).GetPosition()[1];
// Distance between two points
double DeltaX, DeltaY;
DeltaX = fabs(x2-x1);
DeltaY = fabs(y2-y1);
// To draw the line, we seek in which direction the number
// of pixels between the two points is most important
if ( (DeltaX >= DeltaY) && (DeltaX > 0.) )
{
double Xmin, Xmax;
/*Xmin = std::min(x1,x2);
Xmax = std::max(x1,x2);*/
Xmin = x1 < x2 ? x1 : x2;
Xmax = x1 > x2 ? x1 : x2;
// Slope of the line y=slope*(x-x1)+y1
double Slope = (y2-y1) / (x2-x1);
// Set a point for each x value between xmin and xmax
for ( double x = Xmin; x <= Xmax; x++)
{
outputIndex[0] = static_cast<unsigned long>( x );
outputIndex[1] = static_cast<unsigned long>( Slope*(x-x1) + y1 );
// Set the point if the pixel index belongs to the output image
if ( region.IsInside( outputIndex ) )
output->SetPixel( outputIndex, m_Value);
}
}
else if ( DeltaX < DeltaY )
{
double Ymin, Ymax;
/*Ymin = std::min(y1,y2);
Ymax = std::max(y1,y2);*/
Ymin = y1 < y2 ? y1 : y2;
Ymax = y1 > y2 ? y1 : y2;
double SlopeInv = (x2-x1) / (y2-y1);
for ( double y = Ymin; y <= Ymax; y++)
{
outputIndex[0] = static_cast<unsigned long>( SlopeInv * (y-y1) + x1 );
outputIndex[1] = static_cast<unsigned long>( y );
if ( region.IsInside( outputIndex ) )
output->SetPixel( outputIndex, m_Value);
typename InputImageType::ConstPointer input = this->GetInput();
InputLineType * line = this->GetInputLine();
typename OutputImageType::Pointer output = this->GetOutput();
/** Create a new list line with one line*/
LineSpatialObjectListPointer lineList = LineSpatialObjectListType::New();
lineList->push_back(line);
/** Invoke the DrawLineSpatialObjectListFilter to draw the line */
m_DrawLineListFilter->SetInput(input);
m_DrawLineListFilter->SetInputLineSpatialObjectList(lineList);
m_DrawLineListFilter->GraftOutput(this->GetOutput());
m_DrawLineListFilter->Update();
this->GraftOutput(m_DrawLineListFilter->GetOutput());
}
}
}
// Exception
/* else
{
itkExceptionMacro(<< "otb::DrawLineSpatialObjectFilter::GenerateData : "
<< "the line is defined by one point : deltaX = deltaY = 0.");
}
*/
}
/**
* Standard "PrintSelf" method
......
......@@ -19,22 +19,17 @@
#define __otbDrawLineSpatialObjectListFilter_h
#include "itkImageToImageFilter.h"
#include "itkLineSpatialObject.h"
#include "otbLineSpatialObjectList.h"
#include "otbDrawLineSpatialObjectFilter.h"
#include "itkRescaleIntensityImageFilter.h"
namespace otb
{
/** \class DrawLineSpatialObjectListFilter
* \brief Composite filter which draw lines in a binary image.
* \brief Composite filter which draw lines in an image.
*
* This class implements a composite filter that draws a list of line in
* a binary image by using the otb::DrawLineSpatialObjectFilter that
* draws each line of the list.
* This class implements a composite filter that draws a list of lines in
* an input Image. This class
*
*
*
*/
......@@ -52,28 +47,24 @@ public:
unsigned int,
TOutputImage::ImageDimension);
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
/** typedefs support for inputs & outputs*/
typedef TInputImage InputImageType;
typedef TOutputImage OutputImageType;
typedef typename OutputImageType::RegionType OutputImageRegionType;
/** typedef for the classes standards. */
typedef DrawLineSpatialObjectListFilter Self;
typedef itk::ImageToImageFilter< TInputImage, TOutputImage > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef DrawLineSpatialObjectListFilter Self;
typedef itk::ImageToImageFilter< TInputImage, TOutputImage > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
typedef LineSpatialObjectList LinesListType;
typedef LinesListType::LineType LineType;
typedef typename LinesListType::const_iterator LineListIterator;
typedef LinesListType::LineType LineType;
typedef LineType::PointListType PointListType;
typedef typename LinesListType::const_iterator LineListIterator;
typedef DrawLineSpatialObjectFilter< OutputImageType, OutputImageType > DrawLineType;
typedef itk::RescaleIntensityImageFilter< InputImageType,
OutputImageType > RescalerType;
typedef itk::ProcessObject ProcessObjectType;
typedef itk::ProcessObject ProcessObjectType;
/** Method for management of the "object factory". */
itkNewMacro(Self);
......@@ -82,34 +73,33 @@ public:
itkTypeMacro(DrawLineSpatialObjectListFilter, ImageToImageFilter);
/** Definition of the input and output images */
typedef typename InputImageType::PixelType InputPixelType;
typedef typename OutputImageType::PixelType OutputPixelType;
typedef typename InputImageType::PixelType InputPixelType;
typedef typename OutputImageType::PixelType OutputPixelType;
typedef typename OutputImageType::IndexType OutputIndexType;
typedef typename InputImageType::RegionType InputImageRegionType;
typedef typename OutputImageType::RegionType OutputImageRegionType;
/** Definition of the size of the images. */
typedef typename InputImageType::SizeType SizeType;
/** Set/Get the image input of this process object. */
virtual void SetInputLineSpatialObjectList(const LinesListType * list);
LinesListType * GetInputLineSpatialObjectList(void);
/** Get/Set m_Value*/
itkGetMacro(Value,OutputPixelType );
itkSetMacro(Value,OutputPixelType );
protected:
DrawLineSpatialObjectListFilter();
virtual ~DrawLineSpatialObjectListFilter() {};
void PrintSelf(std::ostream& os, itk::Indent indent) const;
virtual void GenerateData();
virtual void ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread, int threadId ) ;
private:
DrawLineSpatialObjectListFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
typename DrawLineType::Pointer m_DrawLineFilter;
typename RescalerType::Pointer m_RescaleFilter;
OutputPixelType m_Value;
};
} // end namespace otb
......
......@@ -20,13 +20,13 @@
#include "otbDrawLineSpatialObjectListFilter.h"
#include "itkLineIterator.h"
#include "itkDataObject.h"
#include "itkExceptionObject.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionConstIterator.h"
#include <math.h>
namespace otb
{
......@@ -34,17 +34,15 @@ namespace otb
*
*/
template <class TInputImage, class TOutputImage>
DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>::DrawLineSpatialObjectListFilter()
DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>
::DrawLineSpatialObjectListFilter()
{
this->SetNumberOfRequiredInputs(2);
this->SetNumberOfRequiredOutputs(1);
m_DrawLineFilter = DrawLineType::New();
m_RescaleFilter = RescalerType::New();
m_Value = static_cast<OutputPixelType>(255.);
}
template <class TInputImage, class TOutputImage>
void
DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>
......@@ -55,7 +53,6 @@ DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>
}
template <class TInputImage, class TOutputImage>
typename DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>::LinesListType *
DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>
......@@ -69,53 +66,61 @@ DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>
template <class TInputImage, class TOutputImage>
void
DrawLineSpatialObjectListFilter<TInputImage, TOutputImage>
::GenerateData(void)
{
::ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread, int threadId )
{
typename InputImageType::ConstPointer input = this->GetInput();
typename OutputImageType::Pointer output = this->GetOutput();
typename LinesListType::Pointer list = this->GetInputLineSpatialObjectList();
typename OutputImageType::RegionType region;
region.SetSize(input->GetLargestPossibleRegion().GetSize());
region.SetIndex(input->GetLargestPossibleRegion().GetIndex());
output->SetRegions( region );
output->SetOrigin(input->GetOrigin());
output->SetSpacing(input->GetSpacing());
output->Allocate();
output->FillBuffer(0);
m_RescaleFilter->SetOutputMinimum( itk::NumericTraits< OutputPixelType >::min());
m_RescaleFilter->SetOutputMaximum( itk::NumericTraits< OutputPixelType >::max());
m_RescaleFilter->SetInput( input );
LineListIterator itList = list->begin();
m_DrawLineFilter->SetInputImage( m_RescaleFilter->GetOutput() );
m_DrawLineFilter->SetInputLine( *itList );
m_DrawLineFilter->GraftOutput( this->GetOutput() );
m_DrawLineFilter->Update();
++itList;
// Draw each line of the list
while ( itList != list->end() )
{
m_DrawLineFilter->SetInputImage( this->GetOutput() );
m_DrawLineFilter->SetInputLine( *itList );
m_DrawLineFilter->Update();
++itList;
}
this->GraftOutput( m_DrawLineFilter->GetOutput() );
/** Copy the input requested region in the output requested region*/
typedef itk::ImageRegionIterator< OutputImageType > OutputIteratorType;
typedef itk::ImageRegionConstIterator< InputImageType > InputIteratorType;
OutputIteratorType outputIt( output, outputRegionForThread);
InputIteratorType inputIt( input, outputRegionForThread);
outputIt.GoToBegin();
inputIt.GoToBegin();
for (outputIt.GoToBegin(); !outputIt.IsAtEnd() ; ++outputIt,++inputIt)
outputIt.Set( static_cast<OutputPixelType>(inputIt.Get()) );
/** Draw the lines in the ouput image using lineIterator*/
typedef itk::LineIterator<OutputImageType> LineIteratorFilter;
OutputIndexType indexBeginLine, indexEndLine;
LineListIterator itList = list->begin();
while(itList != list->end())
{
PointListType & pointsList = (*itList)->GetPoints();
typename PointListType::const_iterator itPoints = pointsList.begin();
indexBeginLine[0] = static_cast<unsigned int>((*itPoints).GetPosition()[0]);
indexBeginLine[1] = static_cast<unsigned int>((*itPoints).GetPosition()[1]);
++itPoints; //Get the second extremity of the segment
indexEndLine[0] = static_cast<unsigned int>((*itPoints).GetPosition()[0]);
indexEndLine[1] = static_cast<unsigned int>((*itPoints).GetPosition()[1]);
/** Instanciation of the line iterator with begin and ending index*/
LineIteratorFilter itLine(output,indexBeginLine ,indexEndLine );
/** Iteration over the line and writing white lines */
while(!itLine.IsAtEnd())
{
if(output->GetRequestedRegion().IsInside(itLine.GetIndex()))
itLine.Set(m_Value);
++itLine;
}
++itList;
}
}
/**
* Standard "PrintSelf" method