Skip to content
Snippets Groups Projects
Commit 4149e3ca authored by Guillaume Pasero's avatar Guillaume Pasero
Browse files

ADD: HooverConfusionMatrix to compare 2 segmentations

parent b2ce0d3a
Branches
Tags
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 __otbHooverConfusionMatrix_h
#define __otbHooverConfusionMatrix_h
#include "itkLabelMapFilter.h"
#include "itkVariableSizeMatrix.h"
namespace otb
{
/** \class HooverConfusionMatrix
*
* \brief This class computes the confusion matrix from two LabelMapObject
*
* The confusion matrix stores the number of pixel inside the intersection between
* couples of region. These couples are made from a ground truth segmentation and
* a machine segmentation. The line number gives the index of the ground truth region. The
* column number gives the index of the machine segmentation region.
*/
template< class TLabelMap >
class ITK_EXPORT HooverConfusionMatrix :
public itk::LabelMapFilter< TLabelMap, TLabelMap >
{
public:
/** Standard class typedefs. */
typedef HooverConfusionMatrix Self;
typedef itk::LabelMapFilter< TLabelMap, TLabelMap > Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Standard New method. */
itkNewMacro(Self);
/** Run-time type information (and related methods). */
itkTypeMacro(HooverConfusionMatrix, LabelMapFilter);
/** Some convenient typedefs. */
typedef TLabelMap InputLabelMapType;
typedef typename InputLabelMapType::LabelObjectType LabelObjectType;
typedef typename InputLabelMapType::LabelVectorType LabelVectorType;
typedef typename LabelObjectType::LineContainerType LineContainerType;
typedef typename LabelObjectType::IndexType IndexType;
typedef typename LabelObjectType::LabelType LabelType;
typedef unsigned long CoefficientType;
typedef itk::VariableSizeMatrix<CoefficientType> MatrixType;
/** Set the ground truth label map */
void SetGroundTruthLabelMap(const InputLabelMapType *gt);
/** Set the machine segmentation label map */
void SetMachineSegmentationLabelMap(const InputLabelMapType *ms);
/** Get the ground truth label map */
const InputLabelMapType* GetGroundTruthLabelMap();
/** Get the machine segmentation label map */
const InputLabelMapType* GetMachineSegmentationLabelMap();
/** Get the output Hoover confusion matrix */
MatrixType & GetHooverConfusionMatrix()
{
return m_Matrix;
}
protected:
/** Constructor */
HooverConfusionMatrix();
~HooverConfusionMatrix() {};
/** BeforeThreadedGenerateData
* Resize the matrix
*/
virtual void BeforeThreadedGenerateData();
/** Real action of the filter : fill the line of the confusion matrix corresponding to
* the given label object
*/
virtual void ThreadedProcessLabelObject( LabelObjectType * labelObject );
private:
/** number of label objects found in the ground truth (GT) label maps */
unsigned long m_NumberOfRegionsGT;
/** number of label objects found in the machine segmentation (MS) label maps */
unsigned long m_NumberOfRegionsMS;
/** List of labels in GT label map */
LabelVectorType m_LabelsGT;
/** Hoover confusion matrix */
MatrixType m_Matrix;
};
}
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbHooverConfusionMatrix.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 __otbHooverConfusionMatrix_txx
#define __otbHooverConfusionMatrix_txx
#include "otbHooverConfusionMatrix.h"
namespace otb
{
/** Constructor */
template <class TLabelMap>
HooverConfusionMatrix<TLabelMap>
::HooverConfusionMatrix() : m_NumberOfRegionsGT(0), m_NumberOfRegionsMS(0)
{
this->SetNumberOfRequiredInputs(2);
m_Matrix.SetSize(0,0);
}
/** Set the ground truth label map */
template <class TLabelMap>
void HooverConfusionMatrix<TLabelMap>
::SetGroundTruthLabelMap(const InputLabelMapType *gt)
{
this->SetInput(0,gt);
}
/** Set the machine segmentation label map */
template <class TLabelMap>
void HooverConfusionMatrix<TLabelMap>
::SetMachineSegmentationLabelMap(const InputLabelMapType *ms)
{
this->SetInput(1,ms);
}
/** Get the ground truth label map */
template <class TLabelMap>
const TLabelMap* HooverConfusionMatrix<TLabelMap>
::GetGroundTruthLabelMap()
{
return this->GetInput(0);
}
/** Get the machine segmentation label map */
template <class TLabelMap>
const TLabelMap* HooverConfusionMatrix<TLabelMap>
::GetMachineSegmentationLabelMap()
{
return this->GetInput(1);
}
template <class TLabelMap>
void HooverConfusionMatrix<TLabelMap>
::BeforeThreadedGenerateData()
{
// first : call superclass method
Superclass::BeforeThreadedGenerateData();
// Set the matrix size
m_NumberOfRegionsGT = this->GetGroundTruthLabelMap()->GetNumberOfLabelObjects();
m_NumberOfRegionsMS = this->GetMachineSegmentationLabelMap()->GetNumberOfLabelObjects();
m_LabelsGT = this->GetGroundTruthLabelMap()->GetLabels();
m_Matrix.SetSize(m_NumberOfRegionsGT , m_NumberOfRegionsMS);
m_Matrix.Fill(0);
}
template <class TLabelMap>
void HooverConfusionMatrix<TLabelMap>
::ThreadedProcessLabelObject( LabelObjectType * labelObject )
{
typename LineContainerType::const_iterator lit;
LineContainerType & lineContainer = labelObject->GetLineContainer();
unsigned long currentRegionMS = 0;
unsigned long currentRegionGT = 0;
// find the index of the current GT region
LabelType currentLabelGT = labelObject->GetLabel();
for (unsigned long k=0;k<m_NumberOfRegionsGT;k++)
{
if (currentLabelGT == m_LabelsGT[k])
{
currentRegionGT = k;
break;
}
}
// loop over the given region
for (lit = lineContainer.begin();lit != lineContainer.end(); lit++)
{
IndexType idx = lit->GetIndex();
unsigned long length = lit->GetLength();
for (unsigned long i=0;i<length;i++)
{
// find the corresponding label in the ms label map
// if found : ++ in the cell [n,p]
for (unsigned long j = currentRegionMS;
j < (currentRegionMS + m_NumberOfRegionsMS);
j++)
{
// TODO : optimize here : call GetLabelObjet(label) would be faster
const LabelObjectType *regionMS = this->GetMachineSegmentationLabelMap()->GetNthLabelObject(j%m_NumberOfRegionsMS);
if (regionMS->HasIndex(idx))
{
currentRegionMS = j%m_NumberOfRegionsMS;
m_Matrix(currentRegionGT,currentRegionMS)++;
break;
}
}
idx[0]++;
}
}
}
}
#endif
......@@ -176,7 +176,19 @@ ADD_TEST(obTvLabelImageToLabelMapWithAdjacencyFilter ${OBIA_TESTS3}
${TEMP}/obTvLabelImageToLabelMapWithAdjacencyFilterOutput.txt
)
ADD_TEST(obTuHooverConfusionMatrixNew ${OBIA_TESTS1}
otbHooverConfusionMatrixNew)
ADD_TEST(obTvHooverConfusionMatrix ${OBIA_TESTS1}
--compare-ascii ${NOTOL}
${BASELINE_FILES}/obTvHooverConfusionMatrix.txt
${TEMP}/obTvHooverConfusionMatrix.txt
otbHooverConfusionMatrix
${INPUTDATA}/Seg1InputForRCC8Graph.tif
${INPUTDATA}/Seg2InputForRCC8Graph.tif
${TEMP}/obTvHooverConfusionMatrix.txt
)
# OBIATests2 (need PQXX)
IF(OTB_USE_PQXX)
ADD_TEST(obTuLabelMapToGISTableFilterNew ${OBIA_TESTS2}
......@@ -230,6 +242,8 @@ otbStatisticsAttributesLabelMapFilterNew.cxx
otbVectorDataToLabelMapFilter.cxx
otbVectorDataToLabelMapFilterNew.cxx
otbStreamingConnectedComponentOBIATest.cxx
otbHooverConfusionMatrixNew.cxx
otbHooverConfusionMatrix.cxx
)
IF(OTB_USE_PQXX)
......
/*=========================================================================
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.
=========================================================================*/
#include "otbHooverConfusionMatrix.h"
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "itkLabelMap.h"
#include "itkLabelObject.h"
#include "itkLabelImageToLabelMapFilter.h"
int otbHooverConfusionMatrix(int argc, char* argv[])
{
typedef itk::LabelObject<unsigned int,2> LabelObjectType;
typedef itk::LabelMap<LabelObjectType> LabelMapType;
typedef otb::HooverConfusionMatrix<LabelMapType> HooverConfusionMatrixType;
typedef otb::Image<unsigned int, 2> ImageType;
typedef itk::LabelImageToLabelMapFilter
<ImageType, LabelMapType> ImageToLabelMapFilterType;
typedef otb::ImageFileReader<ImageType> ImageReaderType;
typedef HooverConfusionMatrixType::MatrixType MatrixType;
if(argc != 4)
{
std::cerr << "Usage: " << argv[0];
std::cerr << " segmentationGT segmentationMS HooverMatrix.txt" << std::endl;
return EXIT_FAILURE;
}
ImageReaderType::Pointer gt_reader = ImageReaderType::New();
gt_reader->SetFileName(argv[1]);
ImageReaderType::Pointer ms_reader = ImageReaderType::New();
ms_reader->SetFileName(argv[2]);
ImageToLabelMapFilterType::Pointer gt_filter = ImageToLabelMapFilterType::New();
gt_filter->SetInput(gt_reader->GetOutput());
gt_filter->SetBackgroundValue(0);
ImageToLabelMapFilterType::Pointer ms_filter = ImageToLabelMapFilterType::New();
ms_filter->SetInput(ms_reader->GetOutput());
ms_filter->SetBackgroundValue(0);
HooverConfusionMatrixType::Pointer hooverFilter = HooverConfusionMatrixType::New();
hooverFilter->SetGroundTruthLabelMap(gt_filter->GetOutput());
hooverFilter->SetMachineSegmentationLabelMap(ms_filter->GetOutput());
hooverFilter->Update();
std::ofstream outputFile;
outputFile.open(argv[3]);
MatrixType &mat = hooverFilter->GetHooverConfusionMatrix();
unsigned int n = mat.Rows(), p = mat.Cols();
for (int i=0;i<n;i++)
{
for (int j=0;j<p;j++)
{
outputFile << mat(i,j);
if (j == (p-1))
{
outputFile << "\n";
}
else
{
outputFile << "\t";
}
}
}
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.
=========================================================================*/
#include "otbHooverConfusionMatrix.h"
#include "itkLabelMap.h"
#include "itkLabelObject.h"
int otbHooverConfusionMatrixNew(int argc, char* argv[])
{
typedef itk::LabelObject<unsigned int,2> LabelObjectType;
typedef itk::LabelMap<LabelObjectType> LabelMapType;
typedef otb::HooverConfusionMatrix<LabelMapType> HooverConfusionMatrixType;
// instantiation
HooverConfusionMatrixType::Pointer object = HooverConfusionMatrixType::New();
std::cout << object << std::endl;
return EXIT_SUCCESS;
}
......@@ -53,4 +53,6 @@ REGISTER_TEST(otbVectorDataToLabelMapFilterNew);
REGISTER_TEST(otbVectorDataToLabelMapFilter);
REGISTER_TEST(otbStreamingConnectedComponentSegmentationOBIAToVectorDataFilterNew);
REGISTER_TEST(otbStreamingConnectedComponentSegmentationOBIAToVectorDataFilter);
REGISTER_TEST(otbHooverConfusionMatrixNew);
REGISTER_TEST(otbHooverConfusionMatrix);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment