Skip to content
Snippets Groups Projects
Commit fa2f16c8 authored by Julien Malik's avatar Julien Malik
Browse files

ADD: add a new class to load/save the feature statistics for ObjectDetection

parent 536dcdbd
No related branches found
No related tags found
No related merge requests found
/*=========================================================================
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 __otbStatisticsXMLFileReader_h
#define __otbStatisticsXMLFileReader_h
#include "itkProcessObject.h"
namespace otb {
/** \class StatisticsXMLFileReader
* \brief Read a xml file where are stored several statistics
*
* To get a specific statistic Measurement vector, use the method
* GetStatisticVectorByName(name) which allow you to get the
* Measurement vector for the statistic set as paramater.
*
*
*/
template < class TMeasurementVector>
class StatisticsXMLFileReader :
public itk::Object
{
public:
/** Standard class typedefs */
typedef StatisticsXMLFileReader Self;
typedef itk::Object Superclass;
typedef itk::SmartPointer< Self > Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods). */
itkTypeMacro(StatisticsXMLFileReader,itk::Object);
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** InputSampleList typedefs */
typedef TMeasurementVector MeasurementVectorType;
typedef typename MeasurementVectorType::ValueType InputValueType;
/** Convenient typedef */
typedef std::pair<std::string ,MeasurementVectorType> InputDataType;
typedef std::vector< InputDataType > MeasurementVectorContainer;
virtual void Modified()
{
m_IsUpdated = false;
}
/** Set the output filename */
itkSetStringMacro(FileName);
itkGetStringMacro(FileName);
/** Get the number of Outputs*/
itkGetMacro(NumberOfOutputs,unsigned int);
/** Method to get the MeasurementVector by name */
MeasurementVectorType GetStatisticVectorByName(const char * statisticName);
protected:
virtual void Read();
StatisticsXMLFileReader();
virtual ~StatisticsXMLFileReader() {}
void PrintSelf(std::ostream& os, itk::Indent indent) const;
private:
StatisticsXMLFileReader(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
std::string m_FileName;
MeasurementVectorContainer m_MeasurementVectorContainer;
unsigned int m_NumberOfOutputs;
bool m_IsUpdated;
}; // end of class StatisticsXMLFileReader
} // end of namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbStatisticsXMLFileReader.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 __otbStatisticsXMLFileReader_txx
#define __otbStatisticsXMLFileReader_txx
#include "otbStatisticsXMLFileReader.h"
#include "itkExceptionObject.h"
#include "itksys/SystemTools.hxx"
#include "tinyxml.h"
namespace otb {
template < class TMeasurementVector >
StatisticsXMLFileReader<TMeasurementVector>
::StatisticsXMLFileReader(): m_FileName(""),
m_NumberOfOutputs(0),
m_IsUpdated(false)
{}
template < class TMeasurementVector >
typename StatisticsXMLFileReader<TMeasurementVector>
::MeasurementVectorType
StatisticsXMLFileReader<TMeasurementVector>
::GetStatisticVectorByName(const char * statisticName)
{
// Read the xml file once
if(!m_IsUpdated)
{
this->Read();
}
// Check if the name of the Statistic is present
bool found = false;
unsigned int index = 0;
for(unsigned int idx = 0; idx < m_NumberOfOutputs; idx++)
{
if(strcmp(m_MeasurementVectorContainer[idx].first.c_str(),statisticName) == 0 )
{
found = true;
index = idx;
}
}
// if token not found throw an axception
if(!found)
itkExceptionMacro(<<"No entry corresponding to the token selected ("<<statisticName<<") in the XML file");
return m_MeasurementVectorContainer[index].second;
}
template < class TMeasurementVector >
void
StatisticsXMLFileReader<TMeasurementVector>
::Read()
{
// Check if the filename is not empty
if(m_FileName.empty())
itkExceptionMacro(<<"The XML output FileName is empty, please set the filename via the method SetFileName");
// Check that the right extension is given : expected .xml */
if (itksys::SystemTools::GetFilenameLastExtension(m_FileName) != ".xml")
{
itkExceptionMacro(<<itksys::SystemTools::GetFilenameLastExtension(m_FileName)
<<" is a wrong Extension FileName : Expected .xml");
}
// Open the xml file
TiXmlDocument doc(m_FileName.c_str());
if (!doc.LoadFile())
{
itkExceptionMacro(<<"Can't open file "<<m_FileName);
}
TiXmlHandle hDoc(&doc);
TiXmlHandle root = hDoc.FirstChildElement("FeatureStatistics");
// Iterate through the tree to get all the stats
for( TiXmlElement* currentStat = root.FirstChildElement().ToElement();
currentStat != NULL;
currentStat = currentStat->NextSiblingElement() )
{
InputDataType currentStatisticVector;
// Store the stat type name
currentStatisticVector.first = currentStat->Attribute("name");
// The size is not stored in the XML file
// Store the value in a std::vector, get the size and then
// build a measurement vector
std::vector<double> tempMeasurementVector;
for( TiXmlElement* sample = currentStat->FirstChildElement("StatisticVector");
sample != NULL;
sample = sample->NextSiblingElement() )
{
// Get the current value of the statistic vector
double value;
sample->QueryDoubleAttribute("value",&value);
// Store the value
tempMeasurementVector.push_back(value);
}
// resize the Measurement Vector
currentStatisticVector.second.SetSize(tempMeasurementVector.size());
for(unsigned int i = 0 ; i < tempMeasurementVector.size(); i++)
currentStatisticVector.second.SetElement(i,
(static_cast<InputValueType>(tempMeasurementVector[i])));
// Increment the number of output
m_MeasurementVectorContainer.push_back(currentStatisticVector);
m_NumberOfOutputs++;
}
m_IsUpdated = true;
}
template < class TMeasurementVector >
void
StatisticsXMLFileReader<TMeasurementVector>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
// Call superclass implementation
//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 __otbStatisticsXMLFileWriter_h
#define __otbStatisticsXMLFileWriter_h
#include "itkProcessObject.h"
#include <utility>
#include <string>
namespace otb {
/** \class StatisticsXMLFileWriter
* \brief Write in a xml file the values stored in a MeasurementVector set as
* input
*
* The vector can be set as input via AddInput(name,vector) where name
* is the name of the statistic, and vector the values.
* Supported vector types are those implementing the method GetElement(idx)
* and defining the type ValueType.
*
*/
template < class TMeasurementVector>
class StatisticsXMLFileWriter :
public itk::Object
{
public:
/** Standard class typedefs */
typedef StatisticsXMLFileWriter Self;
typedef itk::Object Superclass;
typedef itk::SmartPointer< Self > Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods). */
itkTypeMacro(StatisticsXMLFileWriter,itk::Object);
/** Method for creation through the object factory. */
itkNewMacro(Self);
/** InputSampleList typedefs */
typedef TMeasurementVector MeasurementVectorType;
typedef typename MeasurementVectorType::ValueType InputValueType;
/** Convenient typedef */
typedef std::pair<std::string ,MeasurementVectorType> InputDataType;
typedef std::vector< InputDataType > MeasurementVectorContainer;
/** Method to set/get the input list sample */
void AddInput(const char * name, const MeasurementVectorType& inputVector );
/** Trigger the processing */
void Update()
{
this->GenerateData();
}
/** Set the output filename */
itkSetStringMacro(FileName);
itkGetStringMacro(FileName);
protected:
virtual void GenerateData();
StatisticsXMLFileWriter();
virtual ~StatisticsXMLFileWriter() {}
void PrintSelf(std::ostream& os, itk::Indent indent) const;
private:
StatisticsXMLFileWriter(const Self&); //purposely not implemented
void operator=(const Self&); //purposely not implemented
std::string m_FileName;
MeasurementVectorContainer m_MeasurementVectorContainer;
}; // end of class StatisticsXMLFileWriter
} // end of namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbStatisticsXMLFileWriter.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 __otbStatisticsXMLFileWriter_txx
#define __otbStatisticsXMLFileWriter_txx
#include "otbStatisticsXMLFileWriter.h"
#include "itkExceptionObject.h"
#include "itksys/SystemTools.hxx"
#include "tinyxml.h"
namespace otb {
template < class TMeasurementVector >
StatisticsXMLFileWriter<TMeasurementVector>
::StatisticsXMLFileWriter(): m_FileName("")
{}
template < class TMeasurementVector >
void
StatisticsXMLFileWriter<TMeasurementVector>
::AddInput(const char * name, const MeasurementVectorType& inputVector )
{
InputDataType inputData;
inputData.first = name;
// Check if the statistic name is already added
for(unsigned int idx= 0; idx< m_MeasurementVectorContainer.size() ; idx++)
{
if(strcmp(m_MeasurementVectorContainer[idx].first.c_str(),name) == 0 )
{
itkExceptionMacro(<<"Token selected ("
<<name<<") is already added to the XML file");
}
}
inputData.second = inputVector;
m_MeasurementVectorContainer.push_back(inputData);
}
template < class TMeasurementVector >
void
StatisticsXMLFileWriter<TMeasurementVector>
::GenerateData()
{
// Check if the input are not null
if(m_MeasurementVectorContainer.size() == 0)
itkExceptionMacro(<<"At Least one input is required, please set input using the method AddInput");
// Check if the filename is not empty
if(m_FileName.empty())
itkExceptionMacro(<<"The XML output FileName is empty, please set the filename via the method SetFileName");
// Check that the right extension is given : expected .xml */
if (itksys::SystemTools::GetFilenameLastExtension(m_FileName) != ".xml")
{
itkExceptionMacro(<<itksys::SystemTools::GetFilenameLastExtension(m_FileName)
<<" is a wrong Extension FileName : Expected .xml");
}
// Write the XML file
TiXmlDocument doc;
TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );
doc.LinkEndChild( decl );
TiXmlElement * root = new TiXmlElement( "FeatureStatistics");
doc.LinkEndChild( root );
// Iterate through the input
for (unsigned int i = 0; i < m_MeasurementVectorContainer.size(); i++)
{
std::string featureName = m_MeasurementVectorContainer[i].first;
MeasurementVectorType currentMeasurementVector = m_MeasurementVectorContainer[i].second;
// The current statistic
TiXmlElement * feature = new TiXmlElement("Statistic");
feature->SetAttribute("name", featureName.c_str());
root->LinkEndChild( feature );
// Store the value for this statistic
for(unsigned int cindex = 0; cindex < currentMeasurementVector.Size();++cindex)
{
// For each value in Measurementvector
TiXmlElement * curStatisticVector = new TiXmlElement("StatisticVector");
curStatisticVector->SetDoubleAttribute("value", currentMeasurementVector.GetElement(cindex));
feature->LinkEndChild(curStatisticVector);
}
}
// Finally, write the file
doc.SaveFile( m_FileName.c_str() );
}
template < class TMeasurementVector >
void
StatisticsXMLFileWriter<TMeasurementVector>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
// Call superclass implementation
//Superclass::PrintSelf(os,indent);
}
} // End namespace otb
#endif
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