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

ENH: added LabeledSampleLocalizationGenerator class

parent ffadd140
Branches
Tags
No related merge requests found
......@@ -14,6 +14,7 @@ ADD_SUBDIRECTORY(Markov)
ADD_SUBDIRECTORY(SARPolarimetry)
ADD_SUBDIRECTORY(Testing)
ADD_SUBDIRECTORY(OBIA)
ADD_SUBDIRECTORY(ObjectDetection)
IF(OTB_USE_VISU_GUI)
ADD_SUBDIRECTORY(Visu)
......
# Sources of non-templated classes.
FILE(GLOB OTBObjectDetection_SRCS "*.cxx" )
ADD_LIBRARY(OTBObjectDetection ${OTBObjectDetection_SRCS})
TARGET_LINK_LIBRARIES (OTBObjectDetection OTBCommon)
IF(OTB_LIBRARY_PROPERTIES)
SET_TARGET_PROPERTIES(OTBObjectDetection PROPERTIES ${OTB_LIBRARY_PROPERTIES})
ENDIF(OTB_LIBRARY_PROPERTIES)
IF(NOT OTB_INSTALL_NO_LIBRARIES)
INSTALL(TARGETS OTBObjectDetection
RUNTIME DESTINATION ${OTB_INSTALL_BIN_DIR_CM24} COMPONENT RuntimeLibraries
LIBRARY DESTINATION ${OTB_INSTALL_LIB_DIR_CM24} COMPONENT RuntimeLibraries
ARCHIVE DESTINATION ${OTB_INSTALL_LIB_DIR_CM24} COMPONENT Development)
ENDIF(NOT OTB_INSTALL_NO_LIBRARIES)
IF(NOT OTB_INSTALL_NO_DEVELOPMENT)
FILE(GLOB __files1 "${CMAKE_CURRENT_SOURCE_DIR}/*.h")
FILE(GLOB __files2 "${CMAKE_CURRENT_SOURCE_DIR}/*.txx")
INSTALL(FILES ${__files1} ${__files2}
DESTINATION ${OTB_INSTALL_INCLUDE_DIR_CM24}/OTBObjectDetection
COMPONENT Development)
ENDIF(NOT OTB_INSTALL_NO_DEVELOPMENT)
/*=========================================================================
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 __otbLabeledSampleLocalizationGenerator_h
#define __otbLabeledSampleLocalizationGenerator_h
#include "otbVectorDataSource.h"
#include "otbVectorData.h"
#include "itkPreOrderTreeIterator.h"
#include "itkMersenneTwisterRandomVariateGenerator.h"
#include "itkEuclideanDistance.h"
namespace otb
{
/** \class LabeledSampleLocalizationGenerator
* \brief Produces a VectorData from potentialy multiple VectorData
*
* This generator produces a unique vector data containing labeled positions
* extracted from inputs.
*
* Input points are transmited to the output. In addition, 'no class'
* points are randomly picked inside input polygons making sure
* they are at least at a given distance (InhibitionRadius) of every
* known points.
*
* Classes are specified by the VectorData with a metadata identified by
* a specific key. This key can be provided by the SetClassKey() method
* (using "Class" as a default key).
* Features associated with
*
*/
template <class TVectorData>
class ITK_EXPORT LabeledSampleLocalizationGenerator :
public VectorDataSource<TVectorData>
{
public:
/** Standard class typedefs */
typedef LabeledSampleLocalizationGenerator Self;
typedef VectorDataSource<TVectorData> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods). */
itkTypeMacro(LabeledSampleLocalizationGenerator, VectorDataSource);
/** Method for creation through the object factory. */
itkNewMacro(Self);
typedef TVectorData VectorDataType;
typedef typename VectorDataType::Pointer VectorDataPointerType;
typedef typename VectorDataType::DataNodeType DataNodeType;
typedef typename DataNodeType::PolygonType::RegionType RegionType;
typedef typename DataNodeType::PointType PointType;
typedef typename DataNodeType::PolygonType::VertexType VertexType;
typedef typename std::vector<PointType> PointVectorType;
typedef itk::PreOrderTreeIterator<typename VectorDataType::DataTreeType> TreeIteratorType;
typedef itk::Statistics::MersenneTwisterRandomVariateGenerator RandomGeneratorType;
typedef itk::Statistics::EuclideanDistance<PointType> EuclideanDistanceType;
/** Connects the vector data from which the localizations are going to be extracted.
* This is the only input vector data, both the positive and
* negative sample localizations come from it */
void SetInput(const VectorDataType *);
const VectorDataType * GetInput(unsigned int idx) const;
virtual void Update();
/** Accessors */
itkGetConstMacro(ClassKey, std::string);
itkSetMacro(ClassKey, std::string);
itkGetConstMacro(NoClassIdentifier, std::string);
itkSetMacro(NoClassIdentifier, std::string);
itkGetConstMacro(RandomLocalizationDensity, double);
itkSetMacro(RandomLocalizationDensity, double);
itkGetConstMacro(InhibitionRadius, double);
itkSetMacro(InhibitionRadius, double);
itkGetConstMacro(PseudoRandom, bool);
itkSetMacro(PseudoRandom, bool);
protected:
LabeledSampleLocalizationGenerator();
virtual ~LabeledSampleLocalizationGenerator() {}
void PrintSelf(std::ostream& os, itk::Indent indent) const;
/** Triggers the Computation of the sample list */
void GenerateData(void);
/** Create a dictionary containing all differente values of ClassKey
* field */
void ClassKeyValuesCollector();
PointVectorType RandomPointsGenerator(DataNodeType * node);
private:
LabeledSampleLocalizationGenerator(const Self &); //purposely not implemented
void operator =(const Self&); //purposely not implemented
typename VectorDataType::Pointer m_OutputVectorData;
RandomGeneratorType::Pointer m_RandomGenerator;
std::string m_ClassKey;
std::vector<std::string> m_ClassKeyDictionary;
std::string m_NoClassIdentifier;
double m_RandomLocalizationDensity;
double m_InhibitionRadius;
bool m_PseudoRandom;
};
} // end namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbLabeledSampleLocalizationGenerator.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 __otbLabeledSampleLocalizationGenerator_txx
#define __otbLabeledSampleLocalizationGenerator_txx
#include "otbLabeledSampleLocalizationGenerator.h"
#include "otbMath.h"
namespace otb
{
template<class TVectorData>
LabeledSampleLocalizationGenerator<TVectorData>
::LabeledSampleLocalizationGenerator() :
m_ClassKey("Class"),
m_NoClassIdentifier("NoClass"),
m_RandomLocalizationDensity(.05),
m_InhibitionRadius(5.0),
m_PseudoRandom(false)
{
this->SetNumberOfRequiredInputs(1);
this->SetNumberOfRequiredOutputs(1);
m_OutputVectorData = VectorDataType::New();
this->SetNthOutput(0, m_OutputVectorData);
m_RandomGenerator = RandomGeneratorType::New();
}
template <class TVectorData>
void
LabeledSampleLocalizationGenerator<TVectorData>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
this->Superclass::PrintSelf(os, indent);
os << indent << "Class Key: " << m_ClassKey << std::endl;
os << indent << "Negative Class Identifier: " << m_NoClassIdentifier << std::endl;
os << indent << "Sampling Density: " << m_RandomLocalizationDensity << std::endl;
os << indent << "Inhibition Radius: " << m_InhibitionRadius << std::endl;
}
template <class TVectorData>
void
LabeledSampleLocalizationGenerator<TVectorData>
::SetInput(const VectorDataType * vectorData)
{
this->Superclass::SetNthInput(this->GetNumberOfInputs(), const_cast<VectorDataType *>(vectorData));
}
template <class TVectorData>
const TVectorData *
LabeledSampleLocalizationGenerator<TVectorData>
::GetInput(unsigned int idx) const
{
if (this->GetNumberOfInputs() < idx)
{
return 0;
}
return static_cast<const VectorDataType *>(this->Superclass::GetInput(idx));
}
template <class TVectorData>
void
LabeledSampleLocalizationGenerator<TVectorData>
::ClassKeyValuesCollector()
{
unsigned int nbInputs = this->GetNumberOfInputs();
for (unsigned int i=0; i<nbInputs; i++)
{
typename VectorDataType::ConstPointer vectorData = static_cast<const VectorDataType *>(this->GetInput(i));
TreeIteratorType itVector(vectorData->GetDataTree());
itVector.GoToBegin();
while (!itVector.IsAtEnd())
{
std::string tmpString;
if (itVector.Get()->IsPolygonFeature() || itVector.Get()->IsPointFeature())
{
tmpString = itVector.Get()->GetFieldAsString(this->GetClassKey());
bool duplication = true;
for (unsigned j=0; j<m_ClassKeyDictionary.size(); j++)
{
duplication = duplication * (m_ClassKeyDictionary.at(j) != tmpString);
}
if (duplication == true)
{
m_ClassKeyDictionary.push_back(tmpString);
}
}
++itVector;
}
}
}
template <class TVectorData>
typename LabeledSampleLocalizationGenerator<TVectorData>
::PointVectorType
LabeledSampleLocalizationGenerator<TVectorData>
::RandomPointsGenerator(DataNodeType * node)
{
// Output
PointVectorType vPoint;
// Euclidean distance
typename EuclideanDistanceType::Pointer euclideanDistance = EuclideanDistanceType::New();
// Enable 'pseudo randomness'
if (this->GetPseudoRandom())
{
this->m_RandomGenerator->SetSeed((unsigned int)0);
}
// Gathering Information
RegionType generatorRegion = node->GetPolygonExteriorRing()->GetBoundingRegion();
typename RegionType::SizeType generatorRegionSize = generatorRegion.GetSize();
typename RegionType::IndexType generatorRegionIndex = generatorRegion.GetIndex();
typename RegionType::IndexType generatorRegionOrigin = generatorRegion.GetOrigin();
// Identify inside known points
std::vector<PointType> insiders;
typename VectorDataType::ConstPointer vectorData = static_cast<const VectorDataType *>(this->GetOutput(0));
TreeIteratorType itVector(vectorData->GetDataTree());
itVector.GoToBegin();
while (!itVector.IsAtEnd())
{
if (itVector.Get()->IsPointFeature())
{
VertexType vertex;
vertex[0] = itVector.Get()->GetPoint()[0];
vertex[1] = itVector.Get()->GetPoint()[1];
if(node->GetPolygonExteriorRing()->IsInside(vertex))
{
insiders.push_back(itVector.Get()->GetPoint());
}
}
++itVector;
}
//std::cout << "insiders: " << insiders.size() << std::endl;
// Search parametrization
unsigned int nbMaxIter = (unsigned int)((node->GetPolygonExteriorRing()->GetArea()
- insiders.size() * CONST_PI * vcl_pow(this->GetInhibitionRadius(), 2))
/ (CONST_PI * vcl_pow(this->GetInhibitionRadius(), 2)));
//std::cout << "nbMaxIter: " << nbMaxIter << std::endl;
unsigned int nbMaxPosition = (unsigned int)(nbMaxIter * this->GetRandomLocalizationDensity());
//std::cout << "nbMaxPosition: " << nbMaxPosition << std::endl;
// Generation
unsigned int nbIter = nbMaxIter;
unsigned int nbPosition = nbMaxPosition;
PointType rangeMin,rangeMax;
for(unsigned int dim = 0; dim < 2; ++dim)
{
rangeMin[dim] = generatorRegionIndex[dim];
rangeMax[dim] = generatorRegionIndex[dim] + generatorRegionSize[dim];
}
while(nbIter > 0 && nbPosition > 0)
{
VertexType candidate;
for(unsigned int dim = 0; dim < 2; ++dim)
{
candidate[dim] = this->m_RandomGenerator->GetUniformVariate(rangeMin[dim],rangeMax[dim]);
}
if(node->GetPolygonExteriorRing()->IsInside(candidate))
{
typename PointVectorType::const_iterator pit = insiders.begin();
bool valid = true;
while(valid && pit!=insiders.end())
{
valid = (euclideanDistance->Evaluate(candidate,*pit) > this->GetInhibitionRadius());
++pit;
}
if(valid)
{
PointType point;
point[0] = candidate[0];
point[1] = candidate[1];
vPoint.push_back(point);
insiders.push_back(point);
nbPosition --;
}
}
nbIter --;
}
return vPoint;
}
template <class TVectorData>
void
LabeledSampleLocalizationGenerator<TVectorData>
::Update()
{
this->GenerateData();
}
template <class TVectorData>
void
LabeledSampleLocalizationGenerator<TVectorData>
::GenerateData()
{
unsigned int nbInputs = this->GetNumberOfInputs();
this->ClassKeyValuesCollector();
this->GetOutput(0)->SetMetaDataDictionary(this->GetInput(0)->GetMetaDataDictionary());
// Retrieving root node
typename DataNodeType::Pointer root = this->GetOutput(0)->GetDataTree()->GetRoot()->Get();
// Create the document node
typename DataNodeType::Pointer document = DataNodeType::New();
document->SetNodeType(otb::DOCUMENT);
// Adding the layer to the data tree
this->GetOutput(0)->GetDataTree()->Add(document, root);
for (unsigned int i=0; i<nbInputs; i++)
{
typename VectorDataType::ConstPointer vectorData = static_cast<const VectorDataType *>(this->GetInput(i));
TreeIteratorType itVector(vectorData->GetDataTree());
itVector.GoToBegin();
while (!itVector.IsAtEnd())
{
if (itVector.Get()->IsPointFeature())
{
this->GetOutput(0)->GetDataTree()->Add(itVector.Get(), document);
}
++itVector;
}
}
for (unsigned int i=0; i<nbInputs; i++)
{
typename VectorDataType::ConstPointer vectorData = static_cast<const VectorDataType *>(this->GetInput(i));
TreeIteratorType itVector(vectorData->GetDataTree());
itVector.GoToBegin();
while (!itVector.IsAtEnd())
{
if (itVector.Get()->IsPolygonFeature())
{
PointVectorType vPoint = RandomPointsGenerator(itVector.Get());
for (typename PointVectorType::const_iterator it = vPoint.begin(); it != vPoint.end(); ++it)
{
typename DataNodeType::Pointer CurrentGeometry = DataNodeType::New();
CurrentGeometry->SetNodeId("FEATURE_POINT");
CurrentGeometry->SetNodeType(otb::FEATURE_POINT);
CurrentGeometry->SetPoint(*it);
CurrentGeometry->SetFieldAsString(this->GetClassKey(), this->GetNoClassIdentifier());
this->GetOutput(0)->GetDataTree()->Add(CurrentGeometry, document);
}
}
++itVector;
}
}
}
//m_RandomGenerator->SetSeed(1234); // dans le polygonhandler
// 1- transmit the points
// 2- generate random negative points from polygons regarding to
// declared points...
} // end namespace otb
#endif
......@@ -16,6 +16,8 @@ ADD_SUBDIRECTORY(Markov)
ADD_SUBDIRECTORY(SARPolarimetry)
ADD_SUBDIRECTORY(TestSystem)
ADD_SUBDIRECTORY(OBIA)
ADD_SUBDIRECTORY(ObjectDetection)
IF(OTB_USE_VISU_GUI)
......
IF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING )
SET(BASELINE ${OTB_DATA_ROOT}/Baseline/OTB/Images)
SET(BASELINE_FILES ${OTB_DATA_ROOT}/Baseline/OTB/Files)
SET(INPUTDATA ${OTB_DATA_ROOT}/Input)
SET(TEMP ${OTBTesting_BINARY_DIR}/Temporary)
# Remote sensing images (large images )
IF(OTB_DATA_USE_LARGEINPUT)
SET(LARGEINPUT ${OTB_DATA_LARGEINPUT_ROOT} )
ENDIF(OTB_DATA_USE_LARGEINPUT)
#Tolerance
SET(NOTOL 0.0)
# Common generic tests
SET(OBJECTDETECTION_TESTS1 ${CXX_TEST_PATH}/otbObjectDetectionTests1)
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbObjectDetectionTests1 ~~~~~~~~~~~~~~~~~~~~~~~~
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# ------------------ otb::LabeledSampleLocalizationGenerator -------------------
ADD_TEST(odTuLabeledSampleLocalizationGeneratorNew ${OBJECTDETECTION_TESTS1}
otbLabeledSampleLocalizationGeneratorNew
)
ADD_TEST(odTvLabeledSampleLocalizationGenerator ${OBJECTDETECTION_TESTS1}
--compare-ogr ${NOTOL}
${BASELINE_FILES}/TvLabeledSampleLocalizationGeneratorOutput.shp
${TEMP}/TvLabeledSampleLocalizationGeneratorOutput.shp
otbLabeledSampleLocalizationGenerator
${INPUTDATA}/ObjectReco/Boats/maur_B010202_01LabeledPoints.shp
${INPUTDATA}/ObjectReco/Boats/maur_B010202_01Polygons.shp
${TEMP}/TvLabeledSampleLocalizationGeneratorOutput.shp
)
# A enrichir
SET(ObjectDetection_SRCS1
otbObjectDetectionTests1.cxx
otbLabeledSampleLocalizationGenerator.cxx
)
OTB_ADD_EXECUTABLE(otbObjectDetectionTests1 "${ObjectDetection_SRCS1}" "OTBObjectDetection;OTBIO;OTBTesting")
ENDIF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING )
\ No newline at end of file
/*=========================================================================
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
#include "otbVectorData.h"
#include "otbVectorDataFileReader.h"
#include "otbVectorDataFileWriter.h"
#include "otbLabeledSampleLocalizationGenerator.h"
int otbLabeledSampleLocalizationGeneratorNew(int argc, char* argv[])
{
typedef otb::VectorData<> VectorDataType;
typedef otb::LabeledSampleLocalizationGenerator<VectorDataType> GeneratorType;
// instantiation
GeneratorType::Pointer generator = GeneratorType::New();
std::cout << generator << std::endl;
return EXIT_SUCCESS;
}
int otbLabeledSampleLocalizationGenerator(int argc, char* argv[])
{
const char * inputVD1 = argv[1];
const char * inputVD2 = argv[2];
const char * outputVD = argv[3];
typedef otb::VectorData<> VectorDataType;
typedef otb::VectorDataFileReader<VectorDataType> VectorDataReaderType;
typedef otb::VectorDataFileWriter<VectorDataType> VectorDataWriterType;
typedef otb::LabeledSampleLocalizationGenerator<VectorDataType> GeneratorType;
// instantiation
VectorDataReaderType::Pointer reader1 = VectorDataReaderType::New();
VectorDataReaderType::Pointer reader2 = VectorDataReaderType::New();
VectorDataWriterType::Pointer writer = VectorDataWriterType::New();
GeneratorType::Pointer generator = GeneratorType::New();
reader1->SetFileName(inputVD1);
reader1->Update();
reader2->SetFileName(inputVD2);
reader2->Update();
generator->SetInput(reader1->GetOutput());
generator->SetInput(reader2->GetOutput());
generator->SetPseudoRandom(true);
generator->Update();
std::cout << generator << std::endl;
writer->SetFileName(outputVD);
writer->SetInput(generator->GetOutput());
writer->Update();
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.
=========================================================================*/
// this file defines the otbCommonTest for the test driver
// and all it expects is that you have a function called RegisterTests
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
//
#include "otbTestMain.h"
void RegisterTests()
{
REGISTER_TEST(otbLabeledSampleLocalizationGeneratorNew);
REGISTER_TEST(otbLabeledSampleLocalizationGenerator);
}
......@@ -38,6 +38,7 @@ SET(OTB_INCLUDE_DIRS_BUILD_TREE ${OTB_INCLUDE_DIRS_BUILD_TREE}
${OTB_SOURCE_DIR}/Code/Markov
${OTB_SOURCE_DIR}/Code/MultiScale
${OTB_SOURCE_DIR}/Code/OBIA
${OTB_SOURCE_DIR}/Code/ObjectDetection
${OTB_SOURCE_DIR}/Code/Projections
${OTB_SOURCE_DIR}/Code/Radiometry
${OTB_SOURCE_DIR}/Code/SARPolarimetry
......@@ -302,6 +303,7 @@ SET(OTB_INCLUDE_RELATIVE_DIRS ${OTB_INCLUDE_RELATIVE_DIRS}
GeospatialAnalysis
Testing
OBIA
ObjectDetection
Utilities
Utilities/ITK
Utilities/otbsvm
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment