Commit ff573403 authored by Charles Peyrega's avatar Charles Peyrega

BUG: Correction of OTB applications to handle the same layout of the Confusion Matrix

parent a2ad53db
......@@ -46,15 +46,14 @@ public:
itkTypeMacro(ComputeConfusionMatrix, otb::Application);
typedef itk::ImageRegionConstIterator<Int32ImageType> ImageIteratorType;
typedef otb::OGRDataSourceToLabelImageFilter
<Int32ImageType> RasterizeFilterType;
typedef otb::StreamingTraits<Int32ImageType> StreamingTraitsType;
typedef itk::ImageRegionSplitter<2> SplitterType;
typedef Int32ImageType::RegionType RegionType;
typedef otb::OGRDataSourceToLabelImageFilter<Int32ImageType> RasterizeFilterType;
typedef otb::StreamingTraits<Int32ImageType> StreamingTraitsType;
typedef itk::ImageRegionSplitter<2> SplitterType;
typedef Int32ImageType::RegionType RegionType;
private:
void DoInit()
......@@ -126,37 +125,37 @@ private:
void DoExecute()
{
Int32ImageType* input = this->GetParameterImage<Int32ImageType>("in");
Int32ImageType* input = this->GetParameterImage<Int32ImageType> ("in");
std::string field;
int nodata = this->GetParameterInt("nodata");
//Init Conf Matrix
unsigned int nbClasses = this->GetParameterInt("labels");
m_Matrix.resize(nbClasses);
for(unsigned int i=0; i<nbClasses; i++ )
for (unsigned int i = 0; i < nbClasses; i++)
{
m_Matrix[i].assign(nbClasses,0);
m_Matrix[i].assign(nbClasses, 0);
}
Int32ImageType::Pointer reference;
otb::ogr::DataSource::Pointer ogrRef;
RasterizeFilterType::Pointer rasterizeReference = RasterizeFilterType::New();
if (GetParameterString("ref") == "raster")
{
reference = this->GetParameterImage<Int32ImageType>("ref.raster.in");
reference = this->GetParameterImage<Int32ImageType> ("ref.raster.in");
}
else
{
ogrRef = otb::ogr::DataSource::New(GetParameterString("ref.vector.in"), otb::ogr::DataSource::Modes::Read);
field = this->GetParameterString("ref.vector.field");
rasterizeReference->AddOGRDataSource(ogrRef);
rasterizeReference->SetOutputParametersFromImage(input);
rasterizeReference->SetBackgroundValue(nodata);
rasterizeReference->SetBurnAttribute(field.c_str());
reference = rasterizeReference->GetOutput();
reference->UpdateOutputInformation();
}
......@@ -170,63 +169,63 @@ private:
otb::SET_BUFFER_MEMORY_SIZE,
0, 1048576*GetParameterInt("ram"), 0);
RegionType streamRegion;
otbAppLogINFO("Number of stream divisions : "<<numberOfStreamDivisions);
for (unsigned int index=0; index<numberOfStreamDivisions; index++)
for (unsigned int index = 0; index < numberOfStreamDivisions; index++)
{
streamRegion = splitter->GetSplit(index, numberOfStreamDivisions, input->GetLargestPossibleRegion());
input->SetRequestedRegion(streamRegion);
input->PropagateRequestedRegion();
input->UpdateOutputData();
reference->SetRequestedRegion(streamRegion);
reference->PropagateRequestedRegion();
reference->UpdateOutputData();
ImageIteratorType itInput(input, streamRegion);
itInput.GoToBegin();
ImageIteratorType itRef(reference, streamRegion);
itRef.GoToBegin();
while (!itInput.IsAtEnd())
{
if (itRef.Get() != nodata)
{
if (itRef.Get()>0 && itRef.Get()<=static_cast<int>(nbClasses) &&
itInput.Get()>0 && itInput.Get()<=static_cast<int>(nbClasses))
if (itRef.Get() > 0 && itRef.Get() <= static_cast<int> (nbClasses)
&& itInput.Get() > 0 && itInput.Get() <= static_cast<int> (nbClasses))
{
m_Matrix[itInput.Get()-1][itRef.Get()-1] ++;
m_Matrix[itRef.Get() - 1][itInput.Get() - 1]++;
}
}
++ itInput;
++ itRef;
++itInput;
++itRef;
}
}
std::ofstream outFile;
outFile.open(this->GetParameterString("out").c_str());
outFile<<std::fixed;
outFile << std::fixed;
outFile.precision(10);
for(unsigned int j=0; j<nbClasses; j++ )
for (unsigned int i = 0; i < nbClasses; i++)
{
for(unsigned int i=0; i<nbClasses; i++ )
for (unsigned int j = 0; j < nbClasses; j++)
{
outFile << m_Matrix[i][j];
if (i<(nbClasses-1))
if (j < (nbClasses - 1))
{
outFile<<"\t";
outFile << "\t";
}
else
{
outFile<<std::endl;
outFile << std::endl;
}
}
}
outFile.close();
}
std::vector<std::vector<unsigned long> > m_Matrix;
......
......@@ -287,7 +287,7 @@ private:
os << std::endl;
}
otbAppLogINFO("Confusion matrix (columns = reference labels, rows = predicted labels):\n" << os.str());
otbAppLogINFO("Confusion matrix (rows = reference labels, columns = produced labels):\n" << os.str());
}
void DoExecute()
......
......@@ -163,6 +163,80 @@ private:
// Nothing to do here : all parameters are independent
}
std::ostringstream::__string_type LogConfusionMatrix(ConfusionMatrixCalculatorType* confMatCalc)
{
ConfusionMatrixCalculatorType::ConfusionMatrixType matrix = confMatCalc->GetConfusionMatrix();
// Compute minimal width
size_t minwidth = 0;
for (unsigned int i = 0; i < matrix.Rows(); i++)
{
for (unsigned int j = 0; j < matrix.Cols(); j++)
{
std::ostringstream os;
os << matrix(i,j);
size_t size = os.str().size();
if (size > minwidth)
{
minwidth = size;
}
}
}
typedef std::map<int, ConfusionMatrixCalculatorType::ClassLabelType> MapOfIndicesType;
MapOfIndicesType mapOfIndices = confMatCalc->GetMapOfIndices();
MapOfIndicesType::const_iterator it = mapOfIndices.begin();
MapOfIndicesType::const_iterator end = mapOfIndices.end();
for(; it != end; ++it)
{
std::ostringstream os;
os << "[" << it->second << "]";
size_t size = os.str().size();
if (size > minwidth)
{
minwidth = size;
}
}
// Generate matrix string, with 'minwidth' as size specifier
std::ostringstream os;
// Header line
for (size_t i = 0; i < minwidth; ++i)
os << " ";
os << " ";
it = mapOfIndices.begin();
end = mapOfIndices.end();
for(; it != end; ++it)
{
os << "[" << it->second << "]" << " ";
}
os << std::endl;
// Each line of confusion matrix
for (unsigned int i = 0; i < matrix.Rows(); i++)
{
ConfusionMatrixCalculatorType::ClassLabelType label = mapOfIndices[i];
os << "[" << std::setw(minwidth - 2) << label << "]" << " ";
for (unsigned int j = 0; j < matrix.Cols(); j++)
{
os << std::setw(minwidth) << matrix(i,j) << " ";
}
os << std::endl;
}
otbAppLogINFO("Confusion matrix (rows = reference labels, columns = produced labels):\n" << os.str());
return os.str();
}
void DoExecute()
{
GetLogger()->Debug("Entering DoExecute\n");
......@@ -294,7 +368,9 @@ private:
confMatCalc->Update();
otbAppLogINFO("*** SVM training performances ***\n" <<"Confusion matrix:\n" << confMatCalc->GetConfusionMatrix() << std::endl);
otbAppLogINFO("SVM training performances");
std::ostringstream::__string_type confMatString;
confMatString = LogConfusionMatrix(confMatCalc);
for (unsigned int itClasses = 0; itClasses < modelSVM->GetNumberOfClasses(); itClasses++)
{
......@@ -310,6 +386,8 @@ private:
{
std::ofstream file;
file.open(GetParameterString("out").c_str());
file << "Confusion matrix (rows = reference labels, columns = produced labels):\n" << std::endl;
file << confMatString << std::endl;
file << "Precision of the different class: " << confMatCalc->GetPrecisions() << std::endl;
file << "Recall of the different class: " << confMatCalc->GetRecalls() << std::endl;
file << "F-score of the different class: " << confMatCalc->GetFScores() << std::endl;
......
Markdown is supported
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