Skip to content
Snippets Groups Projects
Commit 64b264b8 authored by Julien Michel's avatar Julien Michel
Browse files

MRG

parents 8d88fbd8 d49f55c8
No related branches found
No related tags found
No related merge requests found
Showing
with 1284 additions and 269 deletions
......@@ -7,6 +7,8 @@
set(CTEST_PROJECT_NAME "OTB")
set(CTEST_NIGHTLY_START_TIME "20:00:00 CEST")
set(CTEST_NIGHTLY_IDENT_LOCATION "http://www.orfeo-toolbox.org/nightly/libNightlyNumber")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "www.orfeo-toolbox.org")
set(CTEST_DROP_LOCATION "/Dashboard/submit.php?project=OTB")
......
......@@ -31,7 +31,10 @@ namespace otb
* ObjectListSource is the base class for all process objects that output ObjectList data.
* Specifically, this class defines the GetOutput() method that returns a pointer to the
* output ObjectList.
*
*
* Be aware that this class is templated over the list type, not the object type. It will
* be typically something like otb::ObjectList<ObjectType>. This is to enable the use of
* class derived from ObjectList or other implementations.
*
* \ingroup ObjectListFilter
*/
......@@ -56,17 +59,117 @@ namespace otb
typedef typename TOutputList::Pointer OutputListPointer;
typedef itk::DataObject::Pointer DataObjectPointer;
/** Make a DataObject of the correct type to used as the specified
* output. Every ProcessObject subclass must be able to create a
* DataObject that can be used as a specified output. This method
* is automatically called when DataObject::DisconnectPipeline() is
* called. DataObject::DisconnectPipeline, disconnects a data object
* from being an output of its current source. When the data object
* is disconnected, the ProcessObject needs to construct a replacement
* output data object so that the ProcessObject is in a valid state.
* So DataObject::DisconnectPipeline eventually calls
* ProcessObject::MakeOutput. Note that MakeOutput always returns a
* SmartPointer to a DataObject. If a subclass of ImageSource has
* multiple outputs of different types, then that class must provide
* an implementation of MakeOutput(). */
virtual DataObjectPointer MakeOutput(unsigned int idx);
/** Graft the specified DataObject onto this ProcessObject's output.
* This method grabs a handle to the specified DataObject's path
* data to use as its output's own path data. It also copies the
* region ivars (RequestedRegion, BufferedRegion,
* LargestPossibleRegion) and meta-data (Spacing, Origin) from the
* specified data object into this filter's output data object. Most
* importantly, however, it leaves the Source ivar untouched so the
* original pipeline routing is intact. This method is used when a
* process object is implemented using a mini-pipeline which is
* defined in its GenerateData() method. The usage is:
*
* \code
* // setup the mini-pipeline to process the input to this filter
* firstFilterInMiniPipeline->SetInput( this->GetInput() );
*
* // setup the mini-pipeline to calculate the correct regions
* // and write to the appropriate bulk data block
* lastFilterInMiniPipeline->GraftOutput( this->GetOutput() );
*
* // execute the mini-pipeline
* lastFilterInMiniPipeline->Update();
*
* // graft the mini-pipeline output back onto this filter's output.
* // this is needed to get the appropriate regions passed back.
* this->GraftOutput( lastFilterInMiniPipeline->GetOutput() );
* \endcode
*
* For proper pipeline execution, a filter using a mini-pipeline
* must implement the GeneratseInputRequestedRegion(),
* GenerateOutputRequestedRegion(), GenerateOutputInformation() and
* EnlargeOutputRequestedRegion() methods as necessary to reflect
* how the mini-pipeline will execute (in other words, the outer
* filter's pipeline mechanism must be consistent with what the
* mini-pipeline will do). */
void GraftOutput(itk::DataObject *graft);
/** Graft the specified data object onto this ProcessObject's idx'th
* output. This is the similar to GraftOutput method except is
* allows you specify which output is affected. The specified index
* must be a valid output number (less than
* ProcessObject::GetNumberOfOutputs()). See the GraftOutput for
* general usage information. */
void GraftNthOutput(unsigned int idx, itk::DataObject *graft);
/** Get the output data of this process object. The output of this
* function is not valid until an appropriate Update() method has
* been called, either explicitly or implicitly. Both the filter
* itself and the data object have Update() methods, and both
* methods update the data. Here are three ways to use
* GetOutput() and make sure the data is valid. In these
* examples, \a image is a pointer to some Image object, and the
* particular ProcessObjects involved are filters. The same
* examples apply to non-image (e.g. Mesh) data as well.
*
* \code
* anotherFilter->SetInput( someFilter->GetOutput() );
* anotherFilter->Update();
* \endcode
*
* In this situation, \a someFilter and \a anotherFilter are said
* to constitute a \b pipeline.
*
* \code
* image = someFilter->GetOutput();
* image->Update();
* \endcode
*
* \code
* someFilter->Update();
* image = someFilter->GetOutput();
* \endcode
* (In the above example, the two lines of code can be in
* either order.)
*
* Note that Update() is not called automatically except within a
* pipeline as in the first example. When \b streaming (using a
* StreamingImageFilter) is activated, it may be more efficient to
* use a pipeline than to call Update() once for each filter in
* turn.
*
* For an image, the data generated is for the requested
* Region, which can be set using ImageBase::SetRequestedRegion().
* By default, the largest possible region is requested.
*/
OutputListType * GetOutput(void);
OutputListType * GetOutput(unsigned int idx);
protected:
/** Constructor */
ObjectListSource();
/** Destructor */
virtual ~ObjectListSource() {};
/**PrintSelf method */
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
/** ObjectListSource can be implemented as a multithreaded filter.
* Therefore, this implementation provides a ThreadedGenerateData() routine
......
......@@ -35,11 +35,14 @@ namespace otb
// output must be of type TOutputImage
typename TOutputList::Pointer output
= static_cast<TOutputList*>(this->MakeOutput(0).GetPointer());
this->itk::ProcessObject::SetNumberOfRequiredOutputs(1);
this->itk::ProcessObject::SetNthOutput(0, output.GetPointer());
this->Superclass::SetNumberOfRequiredOutputs(1);
this->Superclass::SetNthOutput(0, output.GetPointer());
}
/**
*
*/
template<class TOutputList>
typename ObjectListSource<TOutputList>::DataObjectPointer
ObjectListSource<TOutputList>
......@@ -48,7 +51,9 @@ namespace otb
return static_cast<itk::DataObject*>(TOutputList::New().GetPointer());
}
/**
*
*/
template <class TOutputList>
typename ObjectListSource<TOutputList>::OutputListType *
ObjectListSource<TOutputList>
......@@ -60,9 +65,24 @@ namespace otb
}
return static_cast<TOutputList*>
(this->ProcessObject::GetOutput(0));
(this->Superclass::GetOutput(0));
}
/**
*
*/
template <class TOutputList>
typename ObjectListSource<TOutputList>::OutputListType *
ObjectListSource<TOutputList>
::GetOutput(unsigned int idx)
{
return static_cast<TOutputList*>
(this->Superclass::GetOutput(idx));
}
/**
*
*/
template<class TOutputList>
void
ObjectListSource<TOutputList>
......@@ -71,7 +91,9 @@ namespace otb
this->GraftNthOutput(0, graft);
}
/**
*
*/
template<class TOutputList>
void
ObjectListSource<TOutputList>
......@@ -105,7 +127,17 @@ namespace otb
{
itkExceptionMacro("subclass should override this method!!!");
}
/**
* PrintSelf Method
*/
template <class TOutputList>
void
ObjectListSource<TOutputList>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os,indent);
}
} // end namespace otb
#endif
......@@ -29,6 +29,10 @@ namespace otb
* ObjectListToObjectListFilter is the base class for all process objects that output
* ObjectList data and require ObjectList data as input. Specifically, this class
* defines the SetInput() method for defining the input to a filter.
*
* Be aware that this class is templated over the list type, not the object type. It will
* be typically something like otb::ObjectList<ObjectType>. This is to enable the use of
* class derived from ObjectList or other implementations.
*
*
* \ingroup ObjectListFilter
......@@ -55,6 +59,8 @@ namespace otb
typedef typename TInputList::ConstPointer InputListPointer;
typedef typename TOutputList::Pointer OutputListPointer;
typedef typename TInputList::ConstIterator InputListIterator;
typedef typename InputListType::ObjectType InputObjectType;
typedef typename OutputListType::ObjectType OutputObjectType;
typedef itk::DataObject::Pointer DataObjectPointer;
......@@ -64,9 +70,12 @@ namespace otb
protected:
/** Constructor */
ObjectListToObjectListFilter();
/** Destructor */
virtual ~ObjectListToObjectListFilter() {};
/**PrintSelf method */
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
private:
ObjectListToObjectListFilter(const Self&); //purposely not implemented
......
......@@ -60,7 +60,16 @@ namespace otb
(this->itk::ProcessObject::GetInput(0) );
}
/**
* PrintSelf Method
*/
template <class TInputList, class TOutputList>
void
ObjectListToObjectListFilter<TInputList,TOutputList>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
} // end namespace otb
......
......@@ -18,9 +18,9 @@
#ifndef __otbPathListSource_h
#define __otbPathListSource_h
#include "itkProcessObject.h"
#include "itkDataObject.h"
#include "otbObjectList.h"
// #include "itkProcessObject.h"
// #include "itkDataObject.h"
#include "otbObjectListSource.h"
namespace otb
{
......@@ -37,12 +37,12 @@ namespace otb
*/
template <class TOutputPath >
class ITK_EXPORT PathListSource : public itk::ProcessObject
class ITK_EXPORT PathListSource : public ObjectListSource<ObjectList<TOutputPath> >
{
public:
/** Standard class typedefs. */
typedef PathListSource Self;
typedef itk::ProcessObject Superclass;
typedef ObjectListSource<ObjectList<TOutputPath> > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
......@@ -50,14 +50,14 @@ public:
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(PathListSource,itk::ProcessObject);
itkTypeMacro(PathListSource,ObjectListSource);
/** Some convenient typedefs. */
typedef itk::DataObject::Pointer DataObjectPointer;
typedef TOutputPath OutputPathType;
typedef typename OutputPathType::Pointer OutputPathPointerType;
typedef otb::ObjectList<OutputPathType> OutputPathListType;
typedef typename Superclass::OutputListType OutputPathListType;
typedef typename OutputPathListType::Pointer OutputPathListPointerType;
typedef typename OutputPathListType::ConstPointer OutputPathListConstPointerType;
......@@ -101,8 +101,8 @@ public:
* Region, which can be set using ImageBase::SetRequestedRegion().
* By default, the largest possible region is requested.
*/
OutputPathListType * GetOutput(void);
OutputPathListType * GetOutput(unsigned int idx);
// OutputPathListType * GetOutput(void);
// OutputPathListType * GetOutput(unsigned int idx);
/** Graft the specified DataObject onto this ProcessObject's output.
* This method grabs a handle to the specified DataObject's path
......@@ -139,7 +139,7 @@ public:
* filter's pipeline mechanism must be consistent with what the
* mini-pipeline will do). */
// just calls GraftNthOutput()
virtual void GraftOutput(OutputPathListType *output);
// virtual void GraftOutput(OutputPathListType *output);
/** Graft the specified data object onto this ProcessObject's idx'th
* output. This is the similar to GraftOutput method except is
......@@ -147,7 +147,7 @@ public:
* must be a valid output number (less than
* ProcessObject::GetNumberOfOutputs()). See the GraftOutput for
* general usage information. */
virtual void GraftNthOutput(unsigned int idx, OutputPathListType *output);
// virtual void GraftNthOutput(unsigned int idx, OutputPathListType *output);
/** Make a DataObject of the correct type to used as the specified
* output. Every ProcessObject subclass must be able to create a
......@@ -162,14 +162,14 @@ public:
* SmartPointer to a DataObject. If a subclass of ImageSource has
* multiple outputs of different types, then that class must provide
* an implementation of MakeOutput(). */
virtual DataObjectPointer MakeOutput(unsigned int idx);
// virtual DataObjectPointer MakeOutput(unsigned int idx);
protected:
PathListSource();
PathListSource() {};
virtual ~PathListSource() {}
void PrintSelf(std::ostream& os, itk::Indent indent) const;
// void PrintSelf(std::ostream& os, itk::Indent indent) const;
private:
PathListSource(const Self&); //purposely not implemented
......@@ -178,8 +178,8 @@ private:
} // end namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbPathListSource.txx"
#endif
// #ifndef OTB_MANUAL_INSTANTIATION
// #include "otbPathListSource.txx"
// #endif
#endif
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef __otbPathListSource_txx
#define __otbPathListSource_txx
#include "otbPathListSource.h"
namespace otb
{
/**
* Constructor
*/
template<class TOutputPath>
PathListSource<TOutputPath>
::PathListSource()
{
OutputPathListPointerType output
= static_cast<OutputPathListType*>(this->MakeOutput(0).GetPointer());
this->Superclass::SetNumberOfRequiredOutputs(1);
this->Superclass::SetNthOutput(0,output.GetPointer());
}
/**
*
*/
template<class TOutputPath>
void
PathListSource<TOutputPath>
::GraftOutput(OutputPathListType *graft)
{
this->GraftNthOutput(0, graft);
}
/**
*
*/
template<class TOutputPath>
void
PathListSource<TOutputPath>
::GraftNthOutput(unsigned int idx, OutputPathListType *graft)
{
/* if (idx < this->GetNumberOfOutputs())
{
OutputPathListType * output = this->GetOutput(idx);
if (output && graft)
{
// Paths do not have a generic pointer to their bulk data
itkWarningMacro( << "Warning: GraftNthOutput() is broken" );
}
}
*/
if ( idx >= this->GetNumberOfOutputs() )
{
itkExceptionMacro(<<"Requested to graft output " << idx <<
" but this filter only has " << this->GetNumberOfOutputs() << " Outputs.");
}
if ( !graft )
{
itkExceptionMacro(<<"Requested to graft output that is a NULL pointer" );
}
OutputPathListType * output = this->GetOutput( idx );
// Call Graft on the Mesh in order to copy meta-information, and containers.
// output->Graft( graft );
output = graft;
}
/**
*
*/
template<class TOutputPath>
typename PathListSource<TOutputPath>::DataObjectPointer
PathListSource<TOutputPath>
::MakeOutput(unsigned int)
{
return (static_cast<itk::DataObject*>(OutputPathListType::New()));
}
/**
*
*/
template<class TOutputPath>
typename PathListSource<TOutputPath>::OutputPathListType *
PathListSource<TOutputPath>
::GetOutput(void)
{
if (this->GetNumberOfOutputs() < 1)
{
return 0;
}
return static_cast<OutputPathListType*>
(this->Superclass::GetOutput(0));
}
/**
*
*/
template<class TOutputPath>
typename PathListSource<TOutputPath>::OutputPathListType *
PathListSource<TOutputPath>
::GetOutput(unsigned int idx)
{
return static_cast<OutputPathListType*>
(this->Superclass::GetOutput(idx));
}
template<class TOutputPath>
void
PathListSource<TOutputPath>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os,indent);
}
} // end namespace otb
#endif
......@@ -18,7 +18,8 @@ PURPOSE. See the above copyright notices for more information.
#ifndef __otbPathListToPathListFilter_h
#define __otbPathListToPathListFilter_h
#include "otbPathListSource.h"
#include "otbObjectListToObjectListFilter.h"
#include "otbObjectList.h"
namespace otb
{
......@@ -27,12 +28,12 @@ namespace otb
*/
template <class TPath>
class ITK_EXPORT PathListToPathListFilter
: public PathListSource<TPath>
: public ObjectListToObjectListFilter<ObjectList<TPath>, ObjectList<TPath> >
{
public:
/** Standard typedefs */
typedef PathListToPathListFilter Self;
typedef PathListSource<TPath> Superclass;
typedef ObjectListToObjectListFilter<ObjectList<TPath>, ObjectList<TPath> > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
......@@ -40,45 +41,29 @@ class ITK_EXPORT PathListToPathListFilter
itkNewMacro(Self);
/** Creation through object factory macro */
itkTypeMacro(PathListToPathListFilter, PathListSource);
itkTypeMacro(PathListToPathListFilter, ObjectListToObjectListFilter);
/** Template parameters typedefs */
typedef typename Superclass::OutputPathType PathType;
typedef typename Superclass::OutputPathListType PathListType;
typedef typename Superclass::InputObjectType PathType;
typedef typename Superclass::InputListType PathListType;
typedef typename PathType::Pointer PathPointerType;
typedef typename PathListType::Pointer PathListPointerType;
typedef typename PathListType::ConstPointer PathListConstPointerType;
typedef typename Superclass::OutputPathType OutputPathType;
typedef typename Superclass::OutputPathPointerType OutputPathPointerType;
typedef typename Superclass::OutputPathListType OutputPathListType;
typedef typename Superclass::OutputPathListPointerType OutputPathListPointerType;
typedef typename Superclass::OutputPathListConstPointerType OutputPathListConstPointerType;
/**
* Set the input path list.
* \param pathList The input path list.
*/
void SetInput( const PathListType * pathList);
/**
* Get the input path list.
* \return the input path list.
*/
const PathListType * GetInput(void);
typedef typename Superclass::OutputObjectType OutputPathType;
typedef typename PathType::Pointer OutputPathPointerType;
typedef typename Superclass::OutputListType OutputPathListType;
typedef typename Superclass::OutputListPointer OutputPathListPointerType;
protected:
/** Constructor */
PathListToPathListFilter();
PathListToPathListFilter(){};
/** Destructor */
virtual ~PathListToPathListFilter() {};
/**PrintSelf method */
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
private:
PathListToPathListFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
};
}// End namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbPathListToPathListFilter.txx"
#endif
#endif
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef __otbPathListToPathListFilter_txx
#define __otbPathListToPathListFilter_txx
#include "otbPathListToPathListFilter.h"
namespace otb
{
/**
* Constructor
*/
template <class TPath>
PathListToPathListFilter<TPath>
::PathListToPathListFilter()
{
this->SetNumberOfRequiredInputs(1);
}
template <class TPath>
void
PathListToPathListFilter<TPath>
::SetInput(const PathListType * pathList)
{
this->itk::ProcessObject::SetNthInput(0,const_cast<PathListType *>(pathList));
}
template <class TPath>
const typename PathListToPathListFilter<TPath>
::PathListType *
PathListToPathListFilter<TPath>
::GetInput(void)
{
if(this->GetNumberOfInputs()<1)
{
return 0;
}
return static_cast<const PathListType *>(this->itk::ProcessObject::GetInput(0));
}
/**
* PrintSelf Method
*/
template <class TPath>
void
PathListToPathListFilter<TPath>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
} // End namespace otb
#endif
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef _otbParallelLinePathListFilter_h
#define _otbParallelLinePathListFilter_h
#include "otbPathListToPathListFilter.h"
#include "otbMacro.h"
namespace otb
{
/** \class ParallelLinePathListFilter
* \brief Description needed
*
*
*/
template <class TPath>
class ITK_EXPORT ParallelLinePathListFilter
: public PathListToPathListFilter<TPath>
{
public:
/** Standard typedefs */
typedef ParallelLinePathListFilter Self;
typedef PathListToPathListFilter<TPath> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Type macro */
itkNewMacro(Self);
/** Creation through object factory macro */
itkTypeMacro(ParallelLinePathListFilter, PathListToPathListFilter);
/** Template parameters typedefs */
typedef typename Superclass::PathType PathType;
typedef typename Superclass::PathListType PathListType;
typedef typename Superclass::PathPointerType PathPointerType;
typedef typename PathListType::Pointer PathListPointerType;
typedef typename PathListType::ConstIterator IteratorType;
typedef typename PathType::VertexType VertexType;
typedef typename PathType::VertexListType VertexListType;
typedef typename VertexListType::ConstIterator VertexIteratorType;
typedef double RealType;
itkSetMacro(AngularThreshold,RealType);
itkGetMacro(AngularThreshold,RealType);
itkSetMacro(DistanceThreshold,RealType);
itkGetMacro(DistanceThreshold,RealType);
itkSetMacro(CommonDistanceThreshold,RealType);
itkGetMacro(CommonDistanceThreshold,RealType);
protected:
/** Constructor */
ParallelLinePathListFilter();
/** Destructor */
virtual ~ParallelLinePathListFilter() {};
/** GenerateData method */
virtual void GenerateData();
/** PrintSelf method */
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
/**
* Verify the angular condition to find parallel lines.
* This function verifies if two lines are parallel by
* computing the angle in relation to the y-axis.
* First line segment: v1 is the first vertex, v2 the second one
* (not necessarily the path ending).
* Second line segment: v3 is the first vertex, v4 the second one
* (not necessarily the path ending).
* Return true if the condition is verified.
*
* This is the first criteria to be fullfilled.
**/
bool VerifyAngularCondition(VertexType v1, VertexType v2, VertexType v3, VertexType v4);
/**
* Verify the maximum distance condition to find parallel lines.
* The orthogonal distance between two parallel lines is calculated.
* First line segment: v1 is the first vertex, v2 the second one
* (not necessarily the path ending).
* Second line segment: v3 is the first vertex, v4 the second one
* (not necessarily the path ending).
* Return true if the condition is verified.
*
* This is the second criteria to be fullfilled.
**/
bool VerifyMaxDistanceCondition(VertexType v1, VertexType v2, VertexType v3, VertexType v4);
/**
* Verify the common distance condition to find parallel lines.
* The overlapping part of the parallel lines is computed. In case
* no overlapping part exists or the value is below the specified
* threshold, false is returned.
* First line segment: v1 is the first vertex, v2 the second one
* (not necessarily the path ending).
* Second line segment: v3 is the first vertex, v4 the second one
* (not necessarily the path ending).
* Return true if the condition is verified.
*
* This is the third criteria to be fullfilled.
**/
bool VerifyCommonDistanceCondition(VertexType v1, VertexType v2, VertexType v3, VertexType v4);
/**
* Write the first parallel path.
* p1: First parallel path (line segment),
*/
PathPointerType WriteParallelPath(PathPointerType p1);
private:
ParallelLinePathListFilter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
RealType m_AngularThreshold;
RealType m_DistanceThreshold;
RealType m_CommonDistanceThreshold;
};
}// End namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbParallelLinePathListFilter.txx"
#endif
#endif
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef _otbParallelLinePathListFilter_txx
#define _otbParallelLinePathListFilter_txx
#include "otbParallelLinePathListFilter.h"
#include "otbMath.h"
namespace otb
{
/**
* Constructor
*/
template <class TPath>
ParallelLinePathListFilter<TPath>
::ParallelLinePathListFilter()
{
m_DistanceThreshold = 100.;
m_CommonDistanceThreshold = 10.;
m_AngularThreshold = 3.14;
}
template <class TPath>
void
ParallelLinePathListFilter<TPath>
::GenerateData()
{
// IO
const PathListType * inputPtr = this->GetInput();
PathListType * outputPtr = this->GetOutput();
// Input iterator
IteratorType inputIt = inputPtr->Begin();
std::vector<bool> eraseFlagVector1;
std::vector<unsigned int> parallelLineIndex;
// First we copy all input path to output
while( inputIt != inputPtr->End())
{
// Write the next input path always to the
// last element of the list. This last element is
// newly created.
outputPtr->PushBack(inputIt.Get());
// If a new element is copied to the output vector,
// "false" is written to the corresponding index of
// the vector eraseFlagVector.
eraseFlagVector1.push_back(false);
++inputIt;
}
int VectorSize = eraseFlagVector1.size();
std::cout<<" Number of Lines: "<< VectorSize <<std::endl;
IteratorType outputIt1 = outputPtr->Begin();
unsigned int index1 = 0;
unsigned int firstLineCounter = 0, parallelLineCounter = 0;
unsigned int commonDistCounter = 0, maxDistCounter = 0;
// Iterate through all lines of the pathlist
while(firstLineCounter < VectorSize)
{
if(!eraseFlagVector1[index1])
{
IteratorType outputIt2 = outputIt1;
++outputIt2;
unsigned int index2 = index1+1;
// Check if any of the following lines are parallel
while(outputIt2!=outputPtr->End())
{
if(!eraseFlagVector1[index2])
{ // Read the first and the last vertex of each line pair that is checked
VertexIteratorType vSourceIt = outputIt1.Get()->GetVertexList()->Begin();
VertexType v1 = vSourceIt.Value();
vSourceIt = outputIt1.Get()->GetVertexList()->End();
--vSourceIt;
VertexType v2 = vSourceIt.Value();
VertexIteratorType vTargetIt = outputIt2.Get()->GetVertexList()->Begin();
VertexType v3 = vTargetIt.Value();
vTargetIt = outputIt2.Get()->GetVertexList()->End();
--vTargetIt;
VertexType v4 = vTargetIt.Value();
// Check for parallel lines
if(VerifyAngularCondition(v1,v2,v3,v4))
{
++parallelLineCounter;
if(VerifyMaxDistanceCondition(v1,v2,v3,v4))
{
++maxDistCounter;
if(VerifyCommonDistanceCondition(v1,v2,v3,v4))
{
++commonDistCounter;
// Write index of first parallel path
parallelLineIndex.push_back(index1);
// Write index of second parallel path
parallelLineIndex.push_back(index2);
}
}
}
}
++index2;
++outputIt2;
}
}
// mark the old path as erased
eraseFlagVector1[index1]=true;
++firstLineCounter;
++index1;
++outputIt1;
}// end of for loop
std::cout<< "Number of line pairs that pass the angular condition: " << parallelLineCounter <<std::endl;
std::cout<< "Number of line pairs that pass the maximum distance condition: " << maxDistCounter <<std::endl;
std::cout<< "Number of line pairs that pass the common distance condition: " << commonDistCounter <<std::endl;
// Write all parallel lines and set the non-erase flagg.
typename std::vector<unsigned int>::iterator lineIt1 = parallelLineIndex.begin();
unsigned int sortLineIndex = 0;
while(lineIt1!=parallelLineIndex.end())
{
IteratorType outputIt3 = outputPtr->Begin() + parallelLineIndex[sortLineIndex];
PathPointerType newPath1 = this->WriteParallelPath(outputIt3.Get());
outputPtr->PushBack(newPath1);
// add a non-erase flag for the new path
eraseFlagVector1.push_back(false);
++sortLineIndex;
std::cout<<"Number of lines written in the path list: "<< sortLineIndex<<std::endl;
++lineIt1;
}
// Search ended, now removing the erased path from the first line pointer
typename std::vector<bool>::reverse_iterator it1 = eraseFlagVector1.rbegin();
index1 = eraseFlagVector1.size()-1;
while(it1!=eraseFlagVector1.rend())
{
if(eraseFlagVector1[index1])
{ outputPtr->Erase(index1); }
--index1;
++it1;
}
}
/**
* Verify the angular condition to find parallel lines.
* This function verifies if two lines are parallel by
* computing the angle in relation to the y-axis.
* First line segment: v1 is the first vertex, v2 the second one
* (not necessarily the path ending).
* Second line segment: v3 is the first vertex, v4 the second one
* (not necessarily the path ending).
* Return true if the condition is verified.
*
* This is the first criteria to be fullfilled.
**/
template <class TPath>
bool
ParallelLinePathListFilter<TPath>
::VerifyAngularCondition(VertexType v1, VertexType v2, VertexType v3, VertexType v4)
{
double alpha1 = vcl_atan2((v2[1]-v1[1]),(v2[0]-v1[0]));
double alpha2 = vcl_atan2((v4[1]-v3[1]),(v4[0]-v3[0]));
alpha1 = (alpha1 >= 0)?alpha1:(alpha1+M_PI);
alpha2 = (alpha2 >= 0)?alpha2:(alpha2+M_PI);
// Return true if the angle between the two lines is smaller than
// the specified threshold.
bool angle = (vcl_abs(alpha1-alpha2) < static_cast<double>(m_AngularThreshold));
return angle;
}
/**
* Verify the maximum distance condition to find parallel lines.
* The orthogonal distance between two parallel lines is calculated.
* First line segment: v1 is the first vertex, v2 the second one
* (not necessarily the path ending).
* Second line segment: v3 is the first vertex, v4 the second one
* (not necessarily the path ending).
* Return true if the condition is verified.
*
* This is the second criteria to be fullfilled.
**/
template <class TPath>
bool
ParallelLinePathListFilter<TPath>
::VerifyMaxDistanceCondition(VertexType v1, VertexType v2, VertexType v3, VertexType v4)
{
// Compute the direction vector of the first line
VertexType vectorDir12;
vectorDir12[0] = v2[0]-v1[0];
vectorDir12[1] = v2[1]-v1[1];
// Compute the orthogonal distance between the two parallel lines
// with equation d = |(v3 - v1)X(v2 - v1)|/|v2 - v1|
double distance = 0., denominator =0., nominator = 0.;
denominator = vcl_abs( (v3[0]-v1[0])*vectorDir12[1] - (v3[1]-v1[1])*vectorDir12[0] );
nominator = sqrt(pow(vectorDir12[0],2) + pow(vectorDir12[1],2));
distance = denominator/nominator;
//std::cout<< "Distance between two parallel lines: " << distance <<std::endl;
// Check if the orthogonal distance between the lines
// is beneath the chosen threshold.
bool dist = (distance <= static_cast<double>(m_DistanceThreshold));
return dist;
}
/**
* Verify the common distance condition to find parallel lines.
* The overlapping part of the parallel lines is computed. In case
* no overlapping part exists or the value is below the specified
* threshold, false is returned.
* First line segment: v1 is the first vertex, v2 the second one
* (not necessarily the path ending).
* Second line segment: v3 is the first vertex, v4 the second one
* (not necessarily the path ending).
* Return true if the condition is verified.
*
* This is the third criteria to be fullfilled.
**/
template <class TPath>
bool
ParallelLinePathListFilter<TPath>
::VerifyCommonDistanceCondition(VertexType v1, VertexType v2, VertexType v3, VertexType v4)
{
// Compute the length of each line
double length12 = 0., length34 = 0.;
length12 = sqrt( pow((v2[0]-v1[0]),2) + pow((v2[1]-v1[1]),2) );
length34 = sqrt( pow((v4[0]-v3[0]),2) + pow((v4[1]-v3[1]),2) );
// Set v1[0] to zero and align the y-axis of
// the new coordinate system with line one (v1 and v2).
// Compute the coordinates of the first and of the
// second line in the new coordinate system.
VertexType tempv1, tempv2, tempv3, tempv4;
if (v1[1] == v2[1])
{
if (v1[0] < v2[0])
{
tempv1[0] = 0., tempv1[1] = 0.;
tempv2[0] = 0., tempv2[1] = length12;
tempv3[0] = v3[0]-v1[0], tempv3[1] = v3[1]-v1[1];
tempv4[0] = v4[0]-v1[0], tempv4[1] = v4[1]-v1[1];
}
else
{
tempv2[0] = 0., tempv2[1] = 0.;
tempv1[0] = 0., tempv1[1] = length12;
tempv3[0] = v3[0]-v2[0], tempv3[1] = v3[1]-v2[1];
tempv4[0] = v4[0]-v2[0], tempv4[1] = v4[1]-v2[1];
}
}
// Check the direction of the line (vector).
// The origin of the new coordinate system is
// set to the smaller of the two vertices.
// Then, a rotation and translation of the vertices
// of the second line (v3 and v4) to the new coordinate
// system is performed.
VertexType temptransv3, temptransv4;
if (v1[1] < v2[1])
{
if (v1[0] == v2[0])
{
tempv1[0] = 0., tempv1[1] = 0.;
tempv2[0] = 0., tempv2[1] = length12;
tempv3[0] = v3[0]-v1[0], tempv3[1] = v3[1]-v1[1];
tempv4[0] = v4[0]-v1[0], tempv4[1] = v4[1]-v1[1];
}
else
{
// Coordinates of the first line in the new coordinate system
tempv1[0] = 0.;
tempv1[1] = 0.;
tempv2[0] = 0.;
tempv2[1] = length12;
// Rotate the system clockwise
double sinealpha;
if (v2[0] > v1[0])
{ sinealpha = (v2[0]-v1[0])/length12; }
else
{ sinealpha = (v1[0]-v2[0])/length12; }
double alpha1 = vcl_asin(sinealpha);
// Translation
temptransv3[0] = v3[0] - v1[0];
temptransv3[1] = v3[1] - v1[1];
temptransv4[0] = v4[0] - v1[0];
temptransv4[1] = v4[1] - v1[1];
// Rotation
tempv3[0] = temptransv3[0]*cos(alpha1)+temptransv3[1]*sin(alpha1);
tempv3[1] = temptransv3[1]*cos(alpha1)-temptransv3[0]*sin(alpha1);
tempv4[0] = temptransv4[0]*cos(alpha1)+temptransv4[1]*sin(alpha1);
tempv4[1] = temptransv4[1]*cos(alpha1)-temptransv4[0]*sin(alpha1);
std::cout<< "tempv1[0], tempv1[1], tempv2[0], tempv2[1]: ";
std::cout<< tempv1[0] <<", " << tempv1[1] <<", " << tempv2[0] <<", " <<tempv2[1] << std::endl;
std::cout<< "Alpha: "<< alpha1 << std::endl;
std::cout<< "tempv3[0], tempv3[1], tempv4[0], tempv4[1]: ";
std::cout<< tempv3[0] <<", " << tempv3[1] <<", " << tempv4[0] <<", " <<tempv4[1] << std::endl;
std::cout<< "Calculated length of the second line: " << sqrt( pow((tempv4[0]-tempv3[0]),2) + pow((tempv4[1]-tempv3[1]),2) ) <<std::endl;
std::cout<< "Original length of line 1: " << length12 <<std::endl;
}
}
if (v2[1] < v1[1])
{
if (v1[0] == v2[0])
{
tempv2[0] = 0., tempv2[1] = 0.;
tempv1[0] = 0., tempv1[1] = length12;
tempv3[0] = v3[0]-v2[0], tempv3[1] = v3[1]-v2[1];
tempv4[0] = v4[0]-v2[0], tempv4[1] = v4[1]-v2[1];
}
else
{
tempv1[0] = 0.;
tempv1[1] = 0.;
tempv2[0] = 0.;
tempv2[1] = length12;
// Rotate the system clockwise
double sinealpha;
if (v2[0] > v1[0])
{ sinealpha = (v2[0]-v1[0])/length12; }
else
{ sinealpha = (v1[0]-v2[0])/length12; }
double alpha1 = vcl_asin(sinealpha);
// Translation
temptransv3[0] = v3[0] - v2[0];
temptransv3[1] = v3[1] - v2[1];
temptransv4[0] = v4[0] - v2[0];
temptransv4[1] = v4[1] - v2[1];
// Rotation
tempv3[0] = temptransv3[0]*cos(alpha1)+temptransv3[1]*sin(alpha1);
tempv3[1] = temptransv3[1]*cos(alpha1)-temptransv3[0]*sin(alpha1);
tempv4[0] = temptransv4[0]*cos(alpha1)+temptransv4[1]*sin(alpha1);
tempv4[1] = temptransv4[1]*cos(alpha1)-temptransv4[0]*sin(alpha1);
std::cout<< "tempv1[0], tempv1[1], tempv2[0], tempv2[1]: ";
std::cout<< tempv1[0] <<", " << tempv1[1] <<", " << tempv2[0] <<", " <<tempv2[1] << std::endl;
std::cout<< "Alpha: "<< alpha1 << std::endl;
std::cout<< "tempv3[0], tempv3[1], tempv4[0], tempv4[1]: ";
std::cout<< tempv3[0] <<", " << tempv3[1] <<", " << tempv4[0] <<", " <<tempv4[1] << std::endl;
std::cout<< "Calculated length of the second line: " << sqrt( pow((tempv4[0]-tempv3[0]),2) + pow((tempv4[1]-tempv3[1]),2) ) <<std::endl;
std::cout<< "Original length of line 1: " << length12 <<std::endl;
}
}
// Compute the length of the overlapping part
// of the two lines. This is done by simply
// comparing the y-values of the lines (remember
// that both lines are parallel and also parallel
// to the new y-axis).
double commonDist = 0.;
if (tempv3[1] >= tempv4[1])
{
if (tempv3[1] >=0 && tempv3[1] <= tempv2[1])
{
if (tempv4[1] >=0)
{commonDist = vcl_abs(tempv4[1]-tempv3[1]);}
else if (tempv4[1] < 0)
{commonDist = tempv3[1];}
}
else if (tempv3[1] >= 0 && tempv3[1] >= tempv2[1])
{
if (tempv4[1] >=0)
{commonDist = tempv2[1]-tempv4[1];}
else if (tempv4[1] < 0)
{commonDist = tempv2[1];}
}
else if (tempv4[1] >= tempv2[1])
{ // No overlapping parts exist. The (negative) distance
// between the two closest endpoints is calculated.
commonDist = -vcl_abs(tempv4[1]-tempv2[1]);
}
else if (tempv3[1] < 0)
{ // No overlapping parts exist. The (negative) distance
// between the two closest endpoints is calculated.
commonDist = tempv3[1];
}
}
else
{
if (tempv4[1] >=0 && tempv4[1] <= tempv2[1])
{
if (tempv3[1] >=0)
{commonDist = vcl_abs(tempv3[1]-tempv4[1]);}
else if (tempv3[1] < 0)
{commonDist = tempv4[1];}
}
else if (tempv4[1] >= 0 && tempv4[1] >= tempv2[1])
{
if (tempv3[1] >=0)
{commonDist = tempv2[1]-tempv3[1];}
else if (tempv3[1] < 0)
{commonDist = tempv2[1];}
}
else if (tempv3[1] >= tempv2[1])
{ // No overlapping parts exist. The (negative) distance
// between the two closest endpoints is calculated.
commonDist = -vcl_abs(tempv3[1]-tempv2[1]);
}
else if (tempv4[1] < 0)
{ // No overlapping parts exist. The (negative) distance
// between the two closest endpoints is calculated.
commonDist = tempv4[1];
}
}
// The common parallel parts of the two lines have to be greater than
// the provided threshold.
std::cout<< "Calculated common distance of the parallel lines: " << commonDist <<std::endl;
bool common = (commonDist >= static_cast<double>(m_CommonDistanceThreshold));
return common;
}
/**
* Write parallel line in a new path list.
* p1: First parallel path (line segment)
*/
template <class TPath>
typename ParallelLinePathListFilter<TPath>
::PathPointerType
ParallelLinePathListFilter<TPath>
::WriteParallelPath(PathPointerType p1)
{
PathPointerType resp = PathType::New();
VertexIteratorType it;
for(it=p1->GetVertexList()->Begin();it!=p1->GetVertexList()->End();++it)
{ resp->AddVertex((it).Value()); }
return resp;
}
/**
* PrintSelf Method
*/
template <class TPath>
void
ParallelLinePathListFilter<TPath>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
} // End namespace otb
#endif
......@@ -18,7 +18,6 @@ PURPOSE. See the above copyright notices for more information.
#ifndef __otbRemoveTortuousPathListFilter_h
#define __otbRemoveTortuousPathListFilter_h
// #include "otbPathListToPathListFilter.h"
#include "otbUnaryFunctorObjectListBooleanFilter.h"
#include "otbPathMeanDistanceFunctor.h"
#include "otbObjectList.h"
......@@ -31,7 +30,8 @@ namespace otb
* A path is considered to be tortuous if the mean distance between each consecutive vertices
* is strictly lower than the user provided threshold.
*
*
* This class is just a shortcut to the UnaryFunctorObjectListBooleanFilter with
* the PathMeanDistanceFunctor.
*
*<b>Recent API changes:</b>
* Now part of the UnaryFunctorObjectListBooleanFilter hierachy, replace call to SetMeanDistanceThreshold()
......@@ -42,6 +42,7 @@ namespace otb
* \sa BreakAngularPathListFilter
* \sa SimplifyPathFilter
* \sa UnaryFunctorObjectListBooleanFilter
* \sa PathMeanDistanceFunctor
*
* \example FeatureExtraction/ExtractRoadByStepsExample.cxx
*
......@@ -57,8 +58,6 @@ namespace otb
{};
}// End namespace otb
// #ifndef OTB_MANUAL_INSTANTIATION
// #include "otbRemoveTortuousPathListFilter.txx"
// #endif
#endif
......@@ -20,6 +20,7 @@ PURPOSE. See the above copyright notices for more information.
#include "otbUnaryFunctorObjectListFilter.h"
#include "otbSimplifyPathFunctor.h"
#include "otbObjectList.h"
namespace otb
{
......@@ -41,6 +42,9 @@ namespace otb
*
* This filter is part of the road extraction framework.
*
* This class is just a shortcut to the UnaryFunctorObjectListFilter with
* the SimplifyPathFunctor.
*
* <b>Recent API changes:</b>
* Now part of the UnaryFunctorObjectListFilter hierachy, replace call to SetTolerance()
* by GetFunctor.SetTolerance().
......@@ -49,6 +53,7 @@ namespace otb
* \sa BreakAngularPathListFilter
* \sa RemoveTortuousPathFilter.
* \sa UnaryFunctorObjectListFilter
* \sa SimplifyPathFunctor
*
* \example FeatureExtraction/ExtractRoadByStepsExample.cxx
*
......@@ -63,8 +68,5 @@ namespace otb
{};
}// End namespace otb
// #ifndef OTB_MANUAL_INSTANTIATION
// #include "otbSimplifyPathListFilter.txx"
// #endif
#endif
......@@ -69,6 +69,11 @@ ADD_EXECUTABLE(SIFTExample SIFTExample.cxx)
TARGET_LINK_LIBRARIES(SIFTExample OTBIO OTBCommon OTBFeatureExtraction
ITKCommon ITKBasicFilters)
ADD_EXECUTABLE(ParallelLineDetectionExample ParallelLineDetectionExample.cxx)
TARGET_LINK_LIBRARIES(ParallelLineDetectionExample OTBIO OTBCommon OTBFeatureExtraction
ITKCommon ITKBasicFilters)
IF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING )
SET(BASELINE ${OTB_DATA_ROOT}/Baseline/Examples/FeatureExtraction)
......
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif
// Software Guide : BeginCommandLineArgs
// OUTPUTS: {Lines.png}, {ParallelLines.png}
// 20 2 10
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// This example illustrates the details of the \doxygen{otb}{ParallelLinePathListFilter}.
//
//
// Software Guide : EndLatex
#include "itkPolyLineParametricPath.h"
#include "otbDrawPathListFilter.h"
#include "otbParallelLinePathListFilter.h"
#include "otbImage.h"
#include "otbImageFileWriter.h"
int main( int argc, char * argv[] )
{
if( argc !=6 )
{
std::cerr << "Usage: " << std::endl;
std::cerr << argv[0] << " outputImage ";
std::cerr << " outputParallelLineImage ";
std::cerr << " distThreshParallel angThreshParallel commonDistThreshParallel"<< std::endl;
return EXIT_FAILURE;
}
double distThreshParallel = atof(argv[3]);
double angThreshParallel = atof(argv[4]);
double commonDistThreshParallel = atof(argv[5]);
//We start by creating an empty image
const unsigned int Dimension = 2;
typedef unsigned char PixelType;
typedef otb::Image<PixelType, Dimension> ImageType;
ImageType::Pointer image = ImageType::New();
ImageType::IndexType start;
start[0] = 0;
start[1] = 0;
ImageType::SizeType size;
size[0] = 600;
size[1] = 300;
ImageType::RegionType region;
region.SetSize( size );
region.SetIndex( start );
image->SetRegions( region );
image->Allocate();
image->FillBuffer(itk::NumericTraits<PixelType>::Zero);
// We create some lines
typedef itk::PolyLineParametricPath< Dimension > PathType;
typedef otb::ObjectList< PathType > PathListType;
PathListType::Pointer lineList = PathListType::New();
typedef PathType::ContinuousIndexType ContinuousIndexType;
ContinuousIndexType cindex;
/*-----*/
PathType::Pointer aLine = PathType::New();
aLine->Initialize();
cindex[0] = 1;
cindex[1] = 41;
aLine->AddVertex( cindex );
cindex[0] = 175;
cindex[1] = 204;
aLine->AddVertex( cindex );
lineList->PushBack( aLine );
/*-----*/
aLine = PathType::New();
aLine->Initialize();
cindex[0] = 60;
cindex[1] = 18;
aLine->AddVertex( cindex );
cindex[0] = 203;
cindex[1] = 164;
aLine->AddVertex( cindex );
lineList->PushBack( aLine );
/*-----*/
aLine = PathType::New();
aLine->Initialize();
cindex[0] = 174;
cindex[1] = 99;
aLine->AddVertex( cindex );
cindex[0] = 281;
cindex[1] = 1;
aLine->AddVertex( cindex );
lineList->PushBack( aLine );
/*-----*/
aLine = PathType::New();
aLine->Initialize();
cindex[0] = 3;
cindex[1] = 233;
aLine->AddVertex( cindex );
cindex[0] = 191;
cindex[1] = 227;
aLine->AddVertex( cindex );
lineList->PushBack( aLine );
/*-----*/
aLine = PathType::New();
aLine->Initialize();
cindex[0] = 254;
cindex[1] = 279;
aLine->AddVertex( cindex );
cindex[0] = 351;
cindex[1] = 110;
aLine->AddVertex( cindex );
lineList->PushBack( aLine );
/*-----*/
aLine = PathType::New();
aLine->Initialize();
cindex[0] = 270;
cindex[1] = 287;
aLine->AddVertex( cindex );
cindex[0] = 368;
cindex[1] = 120;
aLine->AddVertex( cindex );
lineList->PushBack( aLine );
/*-----*/
aLine = PathType::New();
aLine->Initialize();
cindex[0] = 355;
cindex[1] = 204;
aLine->AddVertex( cindex );
cindex[0] = 528;
cindex[1] = 199;
aLine->AddVertex( cindex );
lineList->PushBack( aLine );
/*-----*/
aLine = PathType::New();
aLine->Initialize();
cindex[0] = 437;
cindex[1] = 243;
aLine->AddVertex( cindex );
cindex[0] = 591;
cindex[1] = 237;
aLine->AddVertex( cindex );
lineList->PushBack( aLine );
// Polylines are drawn on a black
typedef otb::DrawPathListFilter<ImageType,PathType,ImageType> DrawPathType;
DrawPathType::Pointer drawPathListFilter = DrawPathType::New();
drawPathListFilter->SetInput(image);
drawPathListFilter->SetInputPath(lineList);
drawPathListFilter->SetPathValue( itk::NumericTraits<PixelType>::max() );
typedef otb::ImageFileWriter< ImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
writer->SetInput( drawPathListFilter->GetOutput() );
writer->SetFileName( argv[1] );
writer->Update();
// Parallel lines are detected. A minimum common length, an angular
// threshold and a maximum distance threshold have to specified.
// The input is a pathList of the previously extracted line segments.
typedef otb::ParallelLinePathListFilter<PathType> ParallelLinePathType;
ParallelLinePathType::Pointer parallelLinePathListFilter = ParallelLinePathType::New();
parallelLinePathListFilter->SetDistanceThreshold(distThreshParallel);
parallelLinePathListFilter->SetAngularThreshold(angThreshParallel);
parallelLinePathListFilter->SetCommonDistanceThreshold(commonDistThreshParallel);
parallelLinePathListFilter->SetInput(lineList);
parallelLinePathListFilter->Update();
// A black background image is built to draw the path on.
ImageType::Pointer outputParallel = ImageType::New();
outputParallel->SetRegions(image->GetLargestPossibleRegion());
outputParallel->Allocate();
outputParallel->FillBuffer(itk::NumericTraits<PixelType>::Zero);
// Parallel lines are drawn on a black background image with \doxygen{otb}{DrawPathListFilter}.
// The \code{SetUseIternalValues()} tells the drawing filter to draw the path with its likelihood
// value.
//typedef otb::DrawPathListFilter<ImageType,PathType,ImageType> DrawPathType;
DrawPathType::Pointer drawPathListFilterParallel = DrawPathType::New();
drawPathListFilterParallel->SetInput(outputParallel);
drawPathListFilterParallel->SetInputPath(parallelLinePathListFilter->GetOutput());
drawPathListFilter->SetPathValue( itk::NumericTraits<PixelType>::max() );
drawPathListFilterParallel->SetUseInternalPathValue(false);
// Write the Line image
WriterType::Pointer writerParallel = WriterType::New();
writerParallel->SetInput( drawPathListFilterParallel->GetOutput() );
writerParallel->SetFileName( argv[2] );
writerParallel->Update();
return EXIT_SUCCESS;
}
......@@ -669,6 +669,14 @@ ADD_TEST(feTvLikelihoodPathListFilter ${FEATUREEXTRACTION_TESTS8}
73 160 126 173
)
# ------- otb::ParallelLinePathListFilter -------------
ADD_TEST(feTuParallelLinePathListFilterNew ${FEATUREEXTRACTION_TESTS8}
otbParallelLinePathListFilterNew)
ADD_TEST(feTvParallelLinePathListFilter ${FEATUREEXTRACTION_TESTS8}
otbParallelLinePathListFilter)
# ------- otb::RoadExtractionFilter -------------
......@@ -906,6 +914,8 @@ otbLinkPathListFilterNew.cxx
otbLinkPathListFilter.cxx
otbLikelihoodPathListFilterNew.cxx
otbLikelihoodPathListFilter.cxx
otbParallelLinePathListFilterNew.cxx
otbParallelLinePathListFilter.cxx
otbRoadExtractionFilterNew.cxx
otbRoadExtractionFilter.cxx
otbAddCarvingPathFilterNew.cxx
......
......@@ -33,6 +33,8 @@ REGISTER_TEST(otbLinkPathListFilterNew);
REGISTER_TEST(otbLinkPathListFilter);
REGISTER_TEST(otbLikelihoodPathListFilterNew);
REGISTER_TEST(otbLikelihoodPathListFilter);
REGISTER_TEST(otbParallelLinePathListFilterNew);
REGISTER_TEST(otbParallelLinePathListFilter);
REGISTER_TEST(otbRoadExtractionFilterNew);
REGISTER_TEST(otbRoadExtractionFilter);
REGISTER_TEST(otbAddCarvingPathFilterNew);
......
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "itkExceptionObject.h"
#include "otbParallelLinePathListFilter.h"
#include "itkPolyLineParametricPath.h"
#include <cstdlib>
int otbParallelLinePathListFilter(int argc, char * argv[])
{
// We create some lines
const unsigned int Dimension = 2;
typedef itk::PolyLineParametricPath< Dimension > PathType;
typedef otb::ObjectList< PathType > PathListType;
PathListType::Pointer lineList = PathListType::New();
PathListType::Pointer parallelList = PathListType::New();
typedef PathType::ContinuousIndexType ContinuousIndexType;
ContinuousIndexType cindex;
/*-----*/
PathType::Pointer aLine = PathType::New();
aLine->Initialize();
cindex[0] = 1;
cindex[1] = 1;
aLine->AddVertex( cindex );
cindex[0] = 1;
cindex[1] = 100;
aLine->AddVertex( cindex );
lineList->PushBack( aLine );
parallelList->PushBack( aLine );
/*-----*/
aLine = PathType::New();
aLine->Initialize();
cindex[0] = 10;
cindex[1] = 1;
aLine->AddVertex( cindex );
cindex[0] = 10;
cindex[1] = 100;
aLine->AddVertex( cindex );
parallelList->PushBack( aLine );
lineList->PushBack( aLine );
/*-----*/
aLine = PathType::New();
aLine->Initialize();
cindex[0] = 174;
cindex[1] = 99;
aLine->AddVertex( cindex );
cindex[0] = 281;
cindex[1] = 1;
aLine->AddVertex( cindex );
lineList->PushBack( aLine );
// Parallel lines are detected.
typedef otb::ParallelLinePathListFilter<PathType> ParallelLinePathType;
ParallelLinePathType::Pointer parallelLinePathListFilter = ParallelLinePathType::New();
parallelLinePathListFilter->SetDistanceThreshold(10);
parallelLinePathListFilter->SetAngularThreshold(10);
parallelLinePathListFilter->SetCommonDistanceThreshold(10);
parallelLinePathListFilter->SetInput(lineList);
parallelLinePathListFilter->Update();
PathListType::Pointer pathList = parallelLinePathListFilter->GetOutput();
PathListType::Iterator listIt = pathList->Begin();
PathListType::Iterator parListIt = parallelList->Begin();
// A path is a line segment in this case.
while (listIt != pathList->End() && parListIt != parallelList->End())
{
PathType::VertexListType::ConstPointer vertexList = (listIt.Get())->GetVertexList();
PathType::VertexListType::ConstPointer parVertexList = (parListIt.Get())->GetVertexList();
PathType::VertexListType::ConstIterator pathIt = vertexList->Begin();
PathType::VertexListType::ConstIterator parPathIt = parVertexList->Begin();
// Loop over all the vertices in one path
while (pathIt != vertexList->End() &&
parPathIt != parVertexList->End())
{
if( pathIt.Value() != parPathIt.Value() )
{
std::cout << pathIt.Index() << pathIt.Value() << std::endl;
return EXIT_FAILURE;
}
++pathIt;
++parPathIt;
}
++listIt;
++parListIt;
}
return EXIT_SUCCESS;
}
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "itkExceptionObject.h"
#include "otbParallelLinePathListFilter.h"
#include "itkPolyLineParametricPath.h"
#include <cstdlib>
int otbParallelLinePathListFilterNew(int argc, char * argv[])
{
const unsigned int Dimension =2;
typedef itk::PolyLineParametricPath<Dimension> PathType;
typedef otb::ParallelLinePathListFilter<PathType> ParallelLinePathType;
// Instantiating object
ParallelLinePathType::Pointer parallelLinePathListFilter =
ParallelLinePathType::New();
return EXIT_SUCCESS;
}
File mode changed from 100755 to 100644
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