diff --git a/Code/ObjectDetection/otbStatisticsXMLFileReader.h b/Code/ObjectDetection/otbStatisticsXMLFileReader.h new file mode 100644 index 0000000000000000000000000000000000000000..3e53fbe38ea7614c0efef22c4b64d989f5a233c6 --- /dev/null +++ b/Code/ObjectDetection/otbStatisticsXMLFileReader.h @@ -0,0 +1,99 @@ +/*========================================================================= + + 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 diff --git a/Code/ObjectDetection/otbStatisticsXMLFileReader.txx b/Code/ObjectDetection/otbStatisticsXMLFileReader.txx new file mode 100644 index 0000000000000000000000000000000000000000..002cff17d0927801ddcca629329dff4f9d86bf99 --- /dev/null +++ b/Code/ObjectDetection/otbStatisticsXMLFileReader.txx @@ -0,0 +1,147 @@ +/*========================================================================= + + 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 diff --git a/Code/ObjectDetection/otbStatisticsXMLFileWriter.h b/Code/ObjectDetection/otbStatisticsXMLFileWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..effc6a4844b10559c7f7d77faee8f0333df27f60 --- /dev/null +++ b/Code/ObjectDetection/otbStatisticsXMLFileWriter.h @@ -0,0 +1,99 @@ +/*========================================================================= + + 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 diff --git a/Code/ObjectDetection/otbStatisticsXMLFileWriter.txx b/Code/ObjectDetection/otbStatisticsXMLFileWriter.txx new file mode 100644 index 0000000000000000000000000000000000000000..8e6d1a031550d919d6e68faa2b273b6ae8151587 --- /dev/null +++ b/Code/ObjectDetection/otbStatisticsXMLFileWriter.txx @@ -0,0 +1,123 @@ +/*========================================================================= + + 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