Skip to content
Snippets Groups Projects
Commit d39df137 authored by Ludovic Hussonnois's avatar Ludovic Hussonnois
Browse files

REFAC: Inherit ContingencyTable from itk::Object

parent 3cde2ae6
No related branches found
No related tags found
No related merge requests found
...@@ -80,6 +80,7 @@ public: ...@@ -80,6 +80,7 @@ public:
typedef ConfusionMatrixMeasurementsType::MeasurementType MeasurementType; typedef ConfusionMatrixMeasurementsType::MeasurementType MeasurementType;
typedef ContingencyTable<ClassLabelType> ContingencyTableType; typedef ContingencyTable<ClassLabelType> ContingencyTableType;
typedef ContingencyTableType::Pointer ContingencyTablePointerType;
private: private:
...@@ -207,16 +208,16 @@ private: ...@@ -207,16 +208,16 @@ private:
} }
} }
void LogContingencyTable(const ContingencyTableType& contingencyTable) void LogContingencyTable(const ContingencyTablePointerType& contingencyTable)
{ {
otbAppLogINFO("Contingency table: reference labels (rows) vs. produced labels (cols)\n" << contingencyTable); otbAppLogINFO("Contingency table: reference labels (rows) vs. produced labels (cols)\n" << (*contingencyTable.GetPointer()));
} }
void m_WriteContingencyTable(const ContingencyTableType& contingencyTable) void m_WriteContingencyTable(const ContingencyTablePointerType& contingencyTable)
{ {
std::ofstream outFile; std::ofstream outFile;
outFile.open( this->GetParameterString( "out" ).c_str() ); outFile.open( this->GetParameterString( "out" ).c_str() );
outFile << contingencyTable.to_csv(); outFile << contingencyTable->to_csv();
outFile.close(); outFile.close();
} }
...@@ -397,7 +398,7 @@ private: ...@@ -397,7 +398,7 @@ private:
calculator->Compute( itRef, itInput,sid.refhasnodata,sid.refnodata,sid.prodhasnodata,sid.prodnodata); calculator->Compute( itRef, itInput,sid.refhasnodata,sid.refnodata,sid.prodhasnodata,sid.prodnodata);
} }
ContingencyTableType contingencyTable = calculator->BuildContingencyTable(); ContingencyTablePointerType contingencyTable = calculator->BuildContingencyTable();
LogContingencyTable(contingencyTable); LogContingencyTable(contingencyTable);
m_WriteContingencyTable(contingencyTable); m_WriteContingencyTable(contingencyTable);
} }
......
...@@ -49,6 +49,9 @@ public: ...@@ -49,6 +49,9 @@ public:
typedef ConfusionMatrixCalculatorType::ConfusionMatrixType ConfusionMatrixType; typedef ConfusionMatrixCalculatorType::ConfusionMatrixType ConfusionMatrixType;
typedef ConfusionMatrixCalculatorType::MapOfIndicesType MapOfIndicesType; typedef ConfusionMatrixCalculatorType::MapOfIndicesType MapOfIndicesType;
typedef ConfusionMatrixCalculatorType::ClassLabelType ClassLabelType; typedef ConfusionMatrixCalculatorType::ClassLabelType ClassLabelType;
typedef ContingencyTable<ClassLabelType> ContingencyTableType;
typedef ContingencyTableType::Pointer ContingencyTablePointerType;
protected: protected:
void DoInit() void DoInit()
...@@ -80,14 +83,14 @@ protected: ...@@ -80,14 +83,14 @@ protected:
} }
else else
{ {
ContingencyTable<ClassLabelType> table = ComputeContingencyTable( m_PredictedList, ContingencyTablePointerType table = ComputeContingencyTable( m_PredictedList,
m_ClassificationSamplesWithLabel.labeledListSample ); m_ClassificationSamplesWithLabel.labeledListSample );
WriteContingencyTable( table ); WriteContingencyTable( table );
} }
} }
ContingencyTable<ClassLabelType> ComputeContingencyTable(const TargetListSampleType::Pointer &predictedListSample, ContingencyTablePointerType ComputeContingencyTable(const TargetListSampleType::Pointer &predictedListSample,
const TargetListSampleType::Pointer &performanceLabeledListSample) const TargetListSampleType::Pointer &performanceLabeledListSample)
{ {
typedef ContingencyTableCalculator<ClassLabelType> ContigencyTableCalcutaltorType; typedef ContingencyTableCalculator<ClassLabelType> ContigencyTableCalcutaltorType;
...@@ -103,14 +106,14 @@ protected: ...@@ -103,14 +106,14 @@ protected:
} }
void WriteContingencyTable(const ContingencyTable<ClassLabelType> & table) void WriteContingencyTable(const ContingencyTablePointerType& table)
{ {
if(IsParameterEnabled("io.confmatout")) if(IsParameterEnabled("io.confmatout"))
{ {
// Write contingency table // Write contingency table
std::ofstream outFile; std::ofstream outFile;
outFile.open( this->GetParameterString( "io.confmatout" ).c_str() ); outFile.open( this->GetParameterString( "io.confmatout" ).c_str() );
outFile << table.to_csv(); outFile << table->to_csv();
} }
} }
......
...@@ -24,24 +24,39 @@ ...@@ -24,24 +24,39 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <itkObject.h>
#include <itkObjectFactory.h>
#include <itkVariableSizeMatrix.h> #include <itkVariableSizeMatrix.h>
namespace otb namespace otb
{ {
template<class TClassLabel> template<class TClassLabel>
class ContingencyTable class ContingencyTable : public itk::Object
{ {
public: public:
/** Standard class typedefs */
typedef ContingencyTable Self;
typedef itk::Object Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Run-time type information (and related methods). */
itkTypeMacro(ContingencyTableCalculator, itk::Object);
/** Method for creation through the object factory. */
itkNewMacro(Self);
typedef itk::VariableSizeMatrix<unsigned long> MatrixType; typedef itk::VariableSizeMatrix<unsigned long> MatrixType;
typedef std::vector<TClassLabel> LabelList; typedef std::vector<TClassLabel> LabelList;
MatrixType matrix; MatrixType matrix;
ContingencyTable(LabelList referenceLabels, LabelList producedLabels) : refLabels( referenceLabels ), void SetLabels(LabelList referenceLabels, LabelList producedLabels)
prodLabels( producedLabels )
{ {
unsigned int rows = static_cast<unsigned int>(refLabels.size()); m_RefLabels = referenceLabels;
unsigned int cols = static_cast<unsigned int>(prodLabels.size()); m_ProdLabels = producedLabels;
unsigned int rows = static_cast<unsigned int>(m_RefLabels.size());
unsigned int cols = static_cast<unsigned int>(m_ProdLabels.size());
matrix.SetSize( rows, cols ); matrix.SetSize( rows, cols );
matrix.Fill( 0 ); matrix.Fill( 0 );
} }
...@@ -51,19 +66,19 @@ public: ...@@ -51,19 +66,19 @@ public:
// Retrieve the maximal width from the matrix and the labels // Retrieve the maximal width from the matrix and the labels
size_t maxWidth = 6; size_t maxWidth = 6;
for( size_t i = 0; i << contingencyTable.prodLabels.size(); ++i ) for( size_t i = 0; i << contingencyTable.m_ProdLabels.size(); ++i )
{ {
std::ostringstream oss; std::ostringstream oss;
oss << contingencyTable.prodLabels[i]; oss << contingencyTable.m_ProdLabels[i];
size_t length = oss.str().length(); size_t length = oss.str().length();
if( length > maxWidth ) if( length > maxWidth )
maxWidth = length; maxWidth = length;
} }
for( size_t i = 0; i << contingencyTable.refLabels.size(); ++i ) for( size_t i = 0; i << contingencyTable.m_RefLabels.size(); ++i )
{ {
std::ostringstream oss; std::ostringstream oss;
oss << contingencyTable.refLabels[i]; oss << contingencyTable.m_RefLabels[i];
size_t length = oss.str().length(); size_t length = oss.str().length();
if( length > maxWidth ) if( length > maxWidth )
maxWidth = length; maxWidth = length;
...@@ -85,16 +100,16 @@ public: ...@@ -85,16 +100,16 @@ public:
// Write the first line of the matrix (produced labels) // Write the first line of the matrix (produced labels)
o << std::setfill(' ') << std::setw( width ) << "labels"; o << std::setfill(' ') << std::setw( width ) << "labels";
for( size_t i = 0; i < contingencyTable.prodLabels.size(); ++i ) for( size_t i = 0; i < contingencyTable.m_ProdLabels.size(); ++i )
{ {
o << std::setfill(' ') << std::setw( width ) << contingencyTable.prodLabels[i]; o << std::setfill(' ') << std::setw( width ) << contingencyTable.m_ProdLabels[i];
} }
o << std::endl; o << std::endl;
// For each line write the reference label, then the count value // For each line write the reference label, then the count value
for( unsigned int i = 0; i < contingencyTable.matrix.Rows(); ++i ) for( unsigned int i = 0; i < contingencyTable.matrix.Rows(); ++i )
{ {
o << std::setfill(' ') << std::setw( width ) << contingencyTable.refLabels[i]; o << std::setfill(' ') << std::setw( width ) << contingencyTable.m_RefLabels[i];
for( unsigned int j = 0; j < contingencyTable.matrix.Cols(); ++j ) for( unsigned int j = 0; j < contingencyTable.matrix.Cols(); ++j )
{ {
o << std::setfill(' ') << std::setw( width ) << contingencyTable.matrix( i, j ); o << std::setfill(' ') << std::setw( width ) << contingencyTable.matrix( i, j );
...@@ -111,16 +126,16 @@ public: ...@@ -111,16 +126,16 @@ public:
std::ostringstream oss; std::ostringstream oss;
oss << "labels"; oss << "labels";
for( size_t i = 0; i < prodLabels.size(); ++i ) for( size_t i = 0; i < m_ProdLabels.size(); ++i )
{ {
oss << separator << prodLabels[i]; oss << separator << m_ProdLabels[i];
} }
oss << std::endl; oss << std::endl;
// For each line write the reference label, then the count value // For each line write the reference label, then the count value
for( unsigned int i = 0; i < matrix.Rows(); ++i ) for( unsigned int i = 0; i < matrix.Rows(); ++i )
{ {
oss << refLabels[i]; oss << m_RefLabels[i];
for( unsigned int j = 0; j < matrix.Cols(); ++j ) for( unsigned int j = 0; j < matrix.Cols(); ++j )
{ {
oss << separator << matrix( i, j ); oss << separator << matrix( i, j );
...@@ -132,9 +147,23 @@ public: ...@@ -132,9 +147,23 @@ public:
return oss.str(); return oss.str();
} }
protected:
ContingencyTable()
{
SetLabels(LabelList{}, LabelList{});
}
~ContingencyTable() ITK_OVERRIDE {}
void PrintSelf(std::ostream& os, itk::Indent itkNotUsed(indent)) const ITK_OVERRIDE
{
os << *this;
}
private: private:
LabelList refLabels; ContingencyTable(const Self &); //purposely not implemented
LabelList prodLabels; void operator=(const Self &); //purposely not implemented
LabelList m_RefLabels;
LabelList m_ProdLabels;
}; };
......
...@@ -53,7 +53,8 @@ public: ...@@ -53,7 +53,8 @@ public:
/** Method for creation through the object factory. */ /** Method for creation through the object factory. */
itkNewMacro(Self); itkNewMacro(Self);
typedef ContingencyTable<TClassLabel> ContingencyTableType; typedef ContingencyTable<TClassLabel> ContingencyTableType;
typedef typename ContingencyTableType::Pointer ContingencyTablePointerType;
typedef typename std::map<TClassLabel, unsigned long> CountMapType; typedef typename std::map<TClassLabel, unsigned long> CountMapType;
typedef typename std::map<TClassLabel, CountMapType > MapOfClassesType; typedef typename std::map<TClassLabel, CountMapType > MapOfClassesType;
...@@ -72,7 +73,7 @@ public: ...@@ -72,7 +73,7 @@ public:
itkGetConstMacro(NumberOfSamples, unsigned long); itkGetConstMacro(NumberOfSamples, unsigned long);
void Clear(); void Clear();
ContingencyTableType BuildContingencyTable(); ContingencyTablePointerType BuildContingencyTable();
protected: protected:
ContingencyTableCalculator(); ContingencyTableCalculator();
......
...@@ -83,7 +83,7 @@ ContingencyTableCalculator<TClassLabel> ...@@ -83,7 +83,7 @@ ContingencyTableCalculator<TClassLabel>
template<class TClassLabel> template<class TClassLabel>
typename ContingencyTableCalculator<TClassLabel>::ContingencyTableType typename ContingencyTableCalculator<TClassLabel>::ContingencyTablePointerType
ContingencyTableCalculator<TClassLabel> ContingencyTableCalculator<TClassLabel>
::BuildContingencyTable() ::BuildContingencyTable()
{ {
...@@ -113,11 +113,12 @@ ContingencyTableCalculator<TClassLabel> ...@@ -113,11 +113,12 @@ ContingencyTableCalculator<TClassLabel>
std::copy(refLabels.begin(), refLabels.end(), std::back_inserter(referenceLabels)); std::copy(refLabels.begin(), refLabels.end(), std::back_inserter(referenceLabels));
std::copy(prodLabels.begin(), prodLabels.end(), std::back_inserter(producedLabels)); std::copy(prodLabels.begin(), prodLabels.end(), std::back_inserter(producedLabels));
ContingencyTableType contingencyTable(referenceLabels, producedLabels); ContingencyTablePointerType contingencyTable = ContingencyTableType::New();
contingencyTable->SetLabels(referenceLabels, producedLabels);
for( unsigned int i = 0; i < rows; ++i ) for( unsigned int i = 0; i < rows; ++i )
for( unsigned int j = 0; j < cols; ++j ) for( unsigned int j = 0; j < cols; ++j )
contingencyTable.matrix(i,j) = m_LabelCount[referenceLabels[i]][producedLabels[j]]; contingencyTable->matrix(i,j) = m_LabelCount[referenceLabels[i]][producedLabels[j]];
return contingencyTable; return contingencyTable;
......
...@@ -93,7 +93,8 @@ int otbContingencyTableCalculatorCompute(int argc, char* argv[]) ...@@ -93,7 +93,8 @@ int otbContingencyTableCalculatorCompute(int argc, char* argv[])
typedef itk::FixedArray<ClassLabelType, 1> RLabelType; typedef itk::FixedArray<ClassLabelType, 1> RLabelType;
typedef itk::Statistics::ListSample<RLabelType> RListLabelType; typedef itk::Statistics::ListSample<RLabelType> RListLabelType;
typedef otb::ContingencyTableCalculator<ClassLabelType> CalculatorType; typedef otb::ContingencyTableCalculator<ClassLabelType> CalculatorType;
typedef CalculatorType::ContingencyTableType ContingencyTableType; typedef CalculatorType::ContingencyTableType ContingencyTableType;
typedef ContingencyTableType::Pointer ContingencyTablePointerType;
CalculatorType::Pointer calculator = CalculatorType::New(); CalculatorType::Pointer calculator = CalculatorType::New();
...@@ -126,7 +127,7 @@ int otbContingencyTableCalculatorCompute(int argc, char* argv[]) ...@@ -126,7 +127,7 @@ int otbContingencyTableCalculatorCompute(int argc, char* argv[])
} }
calculator->Compute( refLabels->Begin(), refLabels->End(), prodLabels->Begin(), prodLabels->End() ); calculator->Compute( refLabels->Begin(), refLabels->End(), prodLabels->Begin(), prodLabels->End() );
ContingencyTableType confmat = calculator->BuildContingencyTable(); ContingencyTablePointerType contingencyTable = calculator->BuildContingencyTable();
if( static_cast<int>(calculator->GetNumberOfRefClasses()) != nbRefClasses ) if( static_cast<int>(calculator->GetNumberOfRefClasses()) != nbRefClasses )
...@@ -148,7 +149,7 @@ int otbContingencyTableCalculatorCompute(int argc, char* argv[]) ...@@ -148,7 +149,7 @@ int otbContingencyTableCalculatorCompute(int argc, char* argv[])
} }
std::cout << "contingency table" << std::endl << confmat << std::endl; std::cout << "contingency table" << std::endl << (*contingencyTable.GetPointer()) << std::endl;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
...@@ -216,10 +217,10 @@ int otbContingencyTableCalculatorComputeWithBaseline(int itkNotUsed(argc), char* ...@@ -216,10 +217,10 @@ int otbContingencyTableCalculatorComputeWithBaseline(int itkNotUsed(argc), char*
} }
calculator->Compute( refLabels->Begin(), refLabels->End(), prodLabels->Begin(), prodLabels->End() ); calculator->Compute( refLabels->Begin(), refLabels->End(), prodLabels->Begin(), prodLabels->End() );
CalculatorType::ContingencyTableType confmat = calculator->BuildContingencyTable(); CalculatorType::ContingencyTablePointerType contingencyTable = calculator->BuildContingencyTable();
std::cout << std::endl; std::cout << std::endl;
std::cout << "contingency Table" << std::endl << confmat << std::endl; std::cout << "contingency Table" << std::endl << (*contingencyTable.GetPointer()) << std::endl;
unsigned int nbRefClasses = 5; unsigned int nbRefClasses = 5;
unsigned int nbProdClasses = 7; unsigned int nbProdClasses = 7;
......
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