Commit 409a68ca authored by Julien Michel's avatar Julien Michel
Browse files

REFAC: Remove otb::VectorizationPathListFilter which was part of the road extraction framework

No related merge requests found
Showing with 0 additions and 1349 deletions
+0 -1349
This diff is collapsed.
Data/Baseline/OTB/Images/feTvVectorizationPathListOutput.png

130 Bytes

/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbVectorizationPathListFilter_h
#define otbVectorizationPathListFilter_h
#include "otbPathListSource.h"
#include "itkImageRegionIterator.h"
#include "itkNeighborhoodIterator.h"
#include "itkConstantBoundaryCondition.h"
#include "otbImage.h"
namespace otb
{
/** \class VectorizationPathListFilter
* \brief This filter performs a vectorization from a line detector modulus and direction outputs.
*
* The output of this filter is an otb::ObjectList<TOutputPath>.
*
* This filter performs vectorization at non-grid position by using the barycenter of the few pixels with
* non-null intensity in the given direction. A threshold can be set to tune the sensibility of the first point
* detection. Path with less than three vertices are not kept by the filter.
*
* \ingroup PathListSource
*
* \ingroup OTBPath
*/
template <class TInputModulus, class TInputDirection, class TOutputPath>
class ITK_EXPORT VectorizationPathListFilter
: public PathListSource<TOutputPath>
{
public:
/** Standard typedefs */
typedef VectorizationPathListFilter Self;
typedef PathListSource<TOutputPath> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Type macro */
itkNewMacro(Self);
/** Creation through object factory macro */
itkTypeMacro(VectorizationPathListFilter, PathListSource);
/** Template parameters typedefs */
typedef TInputModulus InputModulusType;
typedef typename InputModulusType::ConstPointer InputModulusConstPointerType;
typedef typename InputModulusType::PixelType InputPixelType;
typedef typename InputModulusType::PointType PointType;
typedef typename InputModulusType::IndexType IndexType;
typedef TInputDirection InputDirectionType;
typedef typename InputDirectionType::ConstPointer InputDirectionConstPointerType;
typedef TOutputPath OutputPathType;
typedef typename OutputPathType::Pointer OutputPathPointerType;
typedef typename OutputPathType::ContinuousIndexType VertexType;
/** Derived typedefs */
typedef typename Superclass::OutputPathListType OutputPathListType;
typedef typename Superclass::OutputPathListPointerType OutputPathListPointerType;
/** Set/get the input modulus */
using Superclass::SetInput;
void SetInput(InputModulusType * inputModulus);
const InputModulusType * GetInput(void);
/** Set/get the input direction */
void SetInputDirection(InputDirectionType * inputDirection);
const InputDirectionType * GetInputDirection(void);
itkSetMacro(AmplitudeThreshold, InputPixelType);
itkGetMacro(AmplitudeThreshold, InputPixelType);
protected:
/** Other internal useful typedefs */
typedef otb::Image<bool, InputModulusType::ImageDimension> FlagImageType;
typedef typename FlagImageType::Pointer FlagImagePointerType;
typedef itk::ImageRegionConstIterator<InputModulusType> ModRegionIteratorType;
typedef itk::ImageRegionConstIterator<InputDirectionType> DirRegionIteratorType;
typedef itk::ImageRegionIterator<FlagImageType> FlagRegionIteratorType;
typedef itk::ConstantBoundaryCondition<InputModulusType> ModBCType;
typedef itk::ConstantBoundaryCondition<InputDirectionType> DirBCType;
typedef itk::ConstantBoundaryCondition<FlagImageType> FlagBCType;
typedef itk::ConstNeighborhoodIterator<InputModulusType, ModBCType> ModNeighborhoodIteratorType;
typedef itk::ConstNeighborhoodIterator<InputDirectionType, ModBCType> DirNeighborhoodIteratorType;
typedef itk::NeighborhoodIterator<FlagImageType, FlagBCType> FlagNeighborhoodIteratorType;
typedef typename ModNeighborhoodIteratorType::RadiusType RadiusType;
typedef typename ModNeighborhoodIteratorType::OffsetType OffsetType;
typedef std::vector<OffsetType> OffsetVectorType;
typedef typename OutputPathType::VertexListType VertexListType;
typedef typename VertexListType::ConstPointer VertexListPointerType;
typedef typename VertexListType::ConstIterator VertexIteratorType;
/** Constructor */
VectorizationPathListFilter();
/** Destructor */
~VectorizationPathListFilter() override {}
/**PrintSelf method */
void PrintSelf(std::ostream& os, itk::Indent indent) const override;
/** Main computation method */
void GenerateData(void) override;
/**
* Compute a vector of the 8 neighbors to explore from the direction and the type of search (forward or backward).
* \param direction The direction
* \param flagReverse The type of search
* \return The neighborhood vector
*/
OffsetVectorType GetEightNeighborOffsetFromDirection(double direction, unsigned int flagReverse);
/**
* Compute a vector of the 3 neighbors to explore from the direction and the type of search (forward or backward).
* \param direction The direction
* \param flagReverse The type of search
* \return The neighborhood vector
*/
OffsetVectorType GetThreeNeighborOffsetFromDirection(double direction, unsigned int flagReverse);
private:
VectorizationPathListFilter(const Self &) = delete;
void operator =(const Self&) = delete;
/** Amplitude threshold to start following a path */
InputPixelType m_AmplitudeThreshold;
};
} // End namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbVectorizationPathListFilter.hxx"
#endif
#endif
/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otbVectorizationPathListFilter_hxx
#define otbVectorizationPathListFilter_hxx
#include "otbVectorizationPathListFilter.h"
#include "otbMacro.h"
#include "otbMath.h"
namespace otb
{
/**
* Constructor
*/
template <class TInputModulus, class TInputDirection, class TOutputPath>
VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::VectorizationPathListFilter()
{
this->SetNumberOfRequiredInputs(2);
this->SetNumberOfRequiredInputs(2);
m_AmplitudeThreshold = 1.0;
}
template <class TInputModulus, class TInputDirection, class TOutputPath>
void
VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::SetInput(InputModulusType * inputModulus)
{
this->itk::ProcessObject::SetNthInput(0, const_cast<InputModulusType *>(inputModulus));
}
template <class TInputModulus, class TInputDirection, class TOutputPath>
const typename VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::InputModulusType *
VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::GetInput(void)
{
if (this->GetNumberOfInputs() < 1)
{
return nullptr;
}
return static_cast<const TInputModulus*>(this->itk::ProcessObject::GetInput(0));
}
template <class TInputModulus, class TInputDirection, class TOutputPath>
void
VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::SetInputDirection(InputDirectionType * inputDirection)
{
this->itk::ProcessObject::SetNthInput(1, const_cast<InputDirectionType *>(inputDirection));
}
template <class TInputModulus, class TInputDirection, class TOutputPath>
const typename VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::InputDirectionType *
VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::GetInputDirection(void)
{
if (this->GetNumberOfInputs() < 2)
{
return nullptr;
}
return static_cast<const TInputDirection *>(this->itk::ProcessObject::GetInput(1));
}
/**
* Main computation method
*/
template <class TInputModulus, class TInputDirection, class TOutputPath>
void
VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::GenerateData(void)
{
InputModulusConstPointerType modPtr = this->GetInput();
InputDirectionConstPointerType dirPtr = this->GetInputDirection();
OutputPathListPointerType outPtr = this->GetOutput();
typedef typename OffsetVectorType::iterator OffsetIteratorType;
RadiusType radius;
radius.Fill(2);
OffsetVectorType offsetVector;
// Creation of the flag image
FlagImagePointerType flagImage = FlagImageType::New();
flagImage->SetRegions(modPtr->GetLargestPossibleRegion());
flagImage->Allocate();
flagImage->FillBuffer(false);
// Iterators instantiation
ModRegionIteratorType modIt(modPtr, modPtr->GetLargestPossibleRegion());
DirRegionIteratorType dirIt(dirPtr, dirPtr->GetLargestPossibleRegion());
FlagRegionIteratorType flagIt(flagImage, flagImage->GetLargestPossibleRegion());
for (modIt.GoToBegin(), dirIt.GoToBegin(), flagIt.GoToBegin();
(!modIt.IsAtEnd()) && (!dirIt.IsAtEnd()) && (!flagIt.IsAtEnd());
++modIt, ++dirIt, ++flagIt)
{
if ((modIt.Get() > m_AmplitudeThreshold) && (!flagIt.Get()))
{
//this is a beginning, to follow in two directions
OutputPathPointerType pathTempDirect = OutputPathType::New();
OutputPathPointerType pathTempReverse = OutputPathType::New();
OutputPathPointerType path = OutputPathType::New();
bool flagFinish;
int flagReverse = 0;
double totalAmplitude = 0;
ModNeighborhoodIteratorType nModIt(radius, modPtr, modPtr->GetLargestPossibleRegion());
DirNeighborhoodIteratorType nDirIt(radius, dirPtr, dirPtr->GetLargestPossibleRegion());
FlagNeighborhoodIteratorType nFlagIt(radius, flagImage, flagImage->GetLargestPossibleRegion());
for (flagReverse = 0; flagReverse < 2; ++flagReverse)
{
nModIt.SetLocation(modIt.GetIndex());
nDirIt.SetLocation(dirIt.GetIndex());
nFlagIt.SetLocation(flagIt.GetIndex());
// temporary point
PointType point;
VertexType vertex;
modPtr->TransformIndexToPhysicalPoint(nModIt.GetIndex(), point);
modPtr->TransformPhysicalPointToContinuousIndex(point, vertex);
if (flagReverse == 0)
{
flagIt.Set(true);
// otbMsgDebugMacro(<<"Adding new vertex: "<<vertex);
pathTempDirect->AddVertex(vertex);
}
flagFinish = false;
while (!flagFinish)
{
offsetVector = GetThreeNeighborOffsetFromDirection(nDirIt.GetCenterPixel(), flagReverse);
OffsetIteratorType vecIt = offsetVector.begin();
bool flagFound = false;
while (vecIt != offsetVector.end() && !flagFound)
{
flagFound = nModIt.GetPixel(*vecIt) > 0
&& !nFlagIt.GetPixel(*vecIt);
++vecIt;
}
if (flagFound)
{
point.Fill(0);
PointType tmpPoint;
totalAmplitude = 0;
for (vecIt = offsetVector.begin(); vecIt != offsetVector.end(); ++vecIt)
{
double currentAmplitude = nModIt.GetPixel(*vecIt);
modPtr->TransformIndexToPhysicalPoint(nModIt.GetIndex(*vecIt), tmpPoint);
point[0] += currentAmplitude * tmpPoint[0];
point[1] += currentAmplitude * tmpPoint[1];
totalAmplitude += currentAmplitude;
}
point[0] = point[0] / totalAmplitude;
point[1] = point[1] / totalAmplitude;
modPtr->TransformPhysicalPointToContinuousIndex(point, vertex);
if (flagReverse == 0)
{
// otbMsgDevMacro(<<"Adding new vertex (direct): "<<vertex);
pathTempDirect->AddVertex(vertex);
}
else
{
// otbMsgDevMacro(<<"Adding new vertex (reverse): "<<vertex);
pathTempReverse->AddVertex(vertex);
}
// flag the pixel use
nFlagIt.SetCenterPixel(true);
//update the neighbor iterators so they are centered on the nearest pixel to the barycenter
IndexType newIndex;
if (modPtr->TransformPhysicalPointToIndex(point, newIndex))
{
// otbMsgDevMacro(<<"Moving to new center: " << newIndex);
nModIt.SetLocation(newIndex);
nDirIt.SetLocation(newIndex);
nFlagIt.SetLocation(newIndex);
if (nModIt.GetCenterPixel() == 0)
{
//we need to check that in case the barycenter is out...
flagFinish = true;
}
if (nFlagIt.GetCenterPixel())
{
//we don't want to go back to the same pixels
flagFinish = true;
}
}
else
{
//new point outside image
flagFinish = true;
}
}
else
{
flagFinish = true;
}
}
}
VertexListPointerType vertexDirect = pathTempDirect->GetVertexList();
VertexListPointerType vertexReverse = pathTempReverse->GetVertexList();
unsigned int numberVertex = 0;
VertexIteratorType vertexReverseIt = vertexReverse->End();
if (vertexReverseIt != vertexReverse->Begin())
{
--vertexReverseIt;
while (vertexReverseIt != vertexReverse->Begin())
{
path->AddVertex(vertexReverseIt.Value());
++numberVertex;
--vertexReverseIt;
}
path->AddVertex(vertexReverseIt.Value());
}
VertexIteratorType vertexDirectIt = vertexDirect->Begin();
while (vertexDirectIt != vertexDirect->End())
{
path->AddVertex(vertexDirectIt.Value());
++vertexDirectIt;
++numberVertex;
}
// otbMsgDebugMacro(<<"Path number of vertices: "<<numberVertex);
if (numberVertex > 3)
{
outPtr->PushBack(path);
}
}
}
}
/**
* Compute the 8 neighbors to explore from the direction and the type of search (forward or backward).
* \param direction The direction
* \param flagReverse The type of search
* \return The neighborhood
*/
template <class TInputModulus, class TInputDirection, class TOutputPath>
typename VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::OffsetVectorType
VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::GetEightNeighborOffsetFromDirection(double direction, unsigned int flagReverse)
{
int neighborhoodNumber = 0;
OffsetVectorType offset;
offset.reserve(8);
if (direction > 0)
{
//find the direction in terms of 0, 1, 2, 3
neighborhoodNumber = (int) (direction / (CONST_PI_4) -1);
}
else
{
neighborhoodNumber = (int) ((direction + CONST_PI) / (CONST_PI_4) -1);
neighborhoodNumber = (neighborhoodNumber + 4);
//if the direction was <0 need to convert to 4, 5, 6, 7
}
if (flagReverse)
{
//if the reverse flag is activated we need to look on the other side
neighborhoodNumber = (neighborhoodNumber + 4) % 8;
}
OffsetType tmpOffset;
switch (neighborhoodNumber)
{
case 0:
tmpOffset[0] = 1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
break;
case 1:
tmpOffset[0] = 1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
break;
case 2:
tmpOffset[0] = 0;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
break;
case 3:
tmpOffset[0] = -1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
break;
case 4:
tmpOffset[0] = -1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
break;
case 5:
tmpOffset[0] = -1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = -2;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
break;
case 6:
tmpOffset[0] = 0;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
break;
case 7:
tmpOffset[0] = 1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = -2;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = 2;
tmpOffset[1] = 2;
offset.push_back(tmpOffset);
break;
}
return offset;
}
/**
* Compute the 3 neighbors to explore from the direction and the type of search (forward or backward).
* \param direction The direction
* \param flagReverse The type of search
* \return The neighborhood
*/
template <class TInputModulus, class TInputDirection, class TOutputPath>
typename VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::OffsetVectorType
VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::GetThreeNeighborOffsetFromDirection(double direction, unsigned int flagReverse)
{
int neighborhoodNumber = 0;
OffsetVectorType offset;
offset.reserve(3);
if (direction > 0)
{
//find the direction in terms of 0, 1, 2, 3
neighborhoodNumber = (int) (direction / (CONST_PI_4) -1);
}
else
{
neighborhoodNumber = (int) ((direction + CONST_PI) / (CONST_PI_4) -1);
neighborhoodNumber = (neighborhoodNumber + 4);
//if the direction was <0 need to convert to 4, 5, 6, 7
}
if (flagReverse)
{
//if the reverse flag is activated we need to look on the other side
neighborhoodNumber = (neighborhoodNumber + 4) % 8;
}
OffsetType tmpOffset;
// otbMsgDevMacro(<<"Direction: " << neighborhoodNumber)
switch (neighborhoodNumber)
{
case 0:
tmpOffset[0] = 1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
break;
case 1:
tmpOffset[0] = 1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
break;
case 2:
tmpOffset[0] = 0;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
break;
case 3:
tmpOffset[0] = -1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
break;
case 4:
tmpOffset[0] = -1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = -1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
break;
case 5:
tmpOffset[0] = -1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 0;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
break;
case 6:
tmpOffset[0] = 0;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
break;
case 7:
tmpOffset[0] = 1;
tmpOffset[1] = -1;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = 0;
offset.push_back(tmpOffset);
tmpOffset[0] = 1;
tmpOffset[1] = 1;
offset.push_back(tmpOffset);
break;
}
return offset;
}
/**
* PrintSelf Method
*/
template <class TInputModulus, class TInputDirection, class TOutputPath>
void
VectorizationPathListFilter<TInputModulus, TInputDirection, TOutputPath>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
} // End namespace otb
#endif
...@@ -36,7 +36,6 @@ otbDrawPathFilter.cxx ...@@ -36,7 +36,6 @@ otbDrawPathFilter.cxx
otbOrientationPath.cxx otbOrientationPath.cxx
otbPolyLineImageConstIterator.cxx otbPolyLineImageConstIterator.cxx
otbRegionImageToRectangularPathListFilter.cxx otbRegionImageToRectangularPathListFilter.cxx
otbVectorizationPathListFilter.cxx
otbClosePathFunctor.cxx otbClosePathFunctor.cxx
otbPolyLineImageIterator.cxx otbPolyLineImageIterator.cxx
) )
...@@ -165,31 +164,6 @@ otb_add_test(NAME feTvRegionImageToRectangularPathListFilter COMMAND otbPathTest ...@@ -165,31 +164,6 @@ otb_add_test(NAME feTvRegionImageToRectangularPathListFilter COMMAND otbPathTest
0.9 #fit score 0.9 #fit score
10) #minimum size 10) #minimum size
otb_add_test(NAME feTvVectorizationPathListFilterImageOutput COMMAND otbPathTestDriver
--compare-image ${EPSILON_8}
${BASELINE}/feTvVectorizationPathListOutput.png
${TEMP}/feTvVectorizationPathListOutput.png
otbVectorizationPathListFilter
${INPUTDATA}/InputForRoadDetection_NonMaxRem.raw.hdr
${INPUTDATA}/InputForRoadDetectionScalarProductDir.raw.hdr
${TEMP}/feTvVectorizationPathListOutputIgnored.txt
${TEMP}/feTvVectorizationPathListOutput.png
0.0001
)
otb_add_test(NAME feTvVectorizationPathListFilterAsciiOutput COMMAND otbPathTestDriver
--compare-ascii ${EPSILON_3}
${BASELINE_FILES}/feTvVectorizationPathListOutput.txt
${TEMP}/feTvVectorizationPathListOutput.txt
otbVectorizationPathListFilter
${INPUTDATA}/InputForRoadDetection_NonMaxRem.raw.hdr
${INPUTDATA}/InputForRoadDetectionScalarProductDir.raw.hdr
${TEMP}/feTvVectorizationPathListOutput.txt
${TEMP}/feTvVectorizationPathListOutputIgnored.png
0.0005
)
otb_add_test(NAME bfTvClosePathFunctor COMMAND otbPathTestDriver otb_add_test(NAME bfTvClosePathFunctor COMMAND otbPathTestDriver
--compare-ascii ${NOTOL} --compare-ascii ${NOTOL}
${BASELINE_FILES}/bfClosePathFunctorTest.txt ${BASELINE_FILES}/bfClosePathFunctorTest.txt
......
...@@ -36,7 +36,6 @@ void RegisterTests() ...@@ -36,7 +36,6 @@ void RegisterTests()
REGISTER_TEST(otbOrientationPath); REGISTER_TEST(otbOrientationPath);
REGISTER_TEST(otbPolyLineImageConstIterator); REGISTER_TEST(otbPolyLineImageConstIterator);
REGISTER_TEST(otbRegionImageToRectangularPathListFilter); REGISTER_TEST(otbRegionImageToRectangularPathListFilter);
REGISTER_TEST(otbVectorizationPathListFilter);
REGISTER_TEST(otbClosePathFunctor); REGISTER_TEST(otbClosePathFunctor);
REGISTER_TEST(otbPolyLineImageIterator); REGISTER_TEST(otbPolyLineImageIterator);
} }
/*
* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "itkMacro.h"
#include "otbVectorizationPathListFilter.h"
#include "itkPolyLineParametricPath.h"
#include "otbImageFileReader.h"
#include <fstream>
#include "otbDrawPathListFilter.h"
#include "otbImageFileWriter.h"
int otbVectorizationPathListFilter(int itkNotUsed(argc), char * argv[])
{
const char * modfname = argv[1];
const char * dirfname = argv[2];
const char * outfname = argv[3];
const char * outImagefname = argv[4];
const double thresh = atof(argv[5]);
const unsigned int Dimension = 2;
typedef double PixelType;
typedef unsigned char OutputPixelType;
typedef otb::Image<PixelType, Dimension> ImageType;
typedef otb::Image<OutputPixelType, Dimension> OutputImageType;
typedef otb::ImageFileWriter<OutputImageType> WriterType;
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef itk::PolyLineParametricPath<Dimension> PathType;
typedef otb::DrawPathListFilter<OutputImageType, PathType, OutputImageType> DrawFilterType;
typedef otb::VectorizationPathListFilter<ImageType, ImageType, PathType> VectorizationPathListFilterType;
typedef VectorizationPathListFilterType::OutputPathListType PathListType;
typedef PathListType::ConstIterator PathListIteratorType;
typedef PathType::VertexListType VertexListType;
typedef VertexListType::ConstIterator VertexIteratorType;
// Instantiating objects
VectorizationPathListFilterType::Pointer filter = VectorizationPathListFilterType::New();
ReaderType::Pointer modReader = ReaderType::New();
ReaderType::Pointer dirReader = ReaderType::New();
modReader->SetFileName(modfname);
dirReader->SetFileName(dirfname);
filter->SetInput(modReader->GetOutput());
filter->SetInputDirection(dirReader->GetOutput());
filter->SetAmplitudeThreshold(thresh);
filter->Update();
PathListType::Pointer pathList = filter->GetOutput();
PathListIteratorType pathListIt = pathList->Begin();
std::ofstream file;
file.open(outfname);
unsigned int counter = 0;
while (pathListIt != pathList->End())
{
file << "Path " << counter << ": ";
for (VertexIteratorType vIt = pathListIt.Get()->GetVertexList()->Begin();
vIt != pathListIt.Get()->GetVertexList()->End();
++vIt)
{
if (vIt != pathListIt.Get()->GetVertexList()->Begin())
{
file << ", ";
}
file << vIt.Value();
}
file << std::endl;
++pathListIt;
++counter;
}
file.close();
OutputImageType::Pointer output = OutputImageType::New();
output->SetRegions(modReader->GetOutput()->GetLargestPossibleRegion());
output->Allocate();
output->FillBuffer(255);
DrawFilterType::Pointer drawer = DrawFilterType::New();
drawer->SetInput(output);
drawer->SetInputPath(filter->GetOutput());
drawer->SetPathValue(0);
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(outImagefname);
writer->SetInput(drawer->GetOutput());
writer->Update();
return EXIT_SUCCESS;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment