Example source code (DempsterShaferFusionOfClassificationMapsExample.cxx):

// The fusion filter \doxygen{otb}{DSFusionOfClassifiersImageFilter} is based on the Dempster
// Shafer (DS) fusion framework. For each pixel, it chooses the class label \emph{Ai} for which the
// belief function \emph{bel(Ai)} is maximal after the DS combination of all the available masses of
// belief of all the class labels. The masses of belief (MOBs) of all the labels present in each
// classification map are read from input *.CSV confusion matrix files.
// Moreover, the pixels into the input classification maps to be fused which are equal to the
// \emph{nodataLabel} value are ignored by the fusion process. In case of not unique class labels
// with the maximal belief function, the output pixels are set to the \emph{undecidedLabel} value.
// We start by including the appropriate header files.

#include "otbImageListToVectorImageFilter.h"
#include "otbConfusionMatrixToMassOfBelief.h"
#include "otbDSFusionOfClassifiersImageFilter.h"

#include <fstream>

#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"

// We will assume unsigned short type input labeled images. We define a type for
// confusion matrices as \doxygen{itk}{VariableSizeMatrix} which will be used to estimate the masses of belief of all the
// class labels for each input classification map. For this purpose, the
// \doxygen{otb}{ConfusionMatrixToMassOfBelief} will be used to convert each input confusion matrix
// into masses of belief for each class label.

using LabelPixelType                    = unsigned short;
using ConfusionMatrixEltType            = unsigned long;
using ConfusionMatrixType               = itk::VariableSizeMatrix<ConfusionMatrixEltType>;
using ConfusionMatrixToMassOfBeliefType = otb::ConfusionMatrixToMassOfBelief<ConfusionMatrixType, LabelPixelType>;
using MapOfClassesType                  = ConfusionMatrixToMassOfBeliefType::MapOfClassesType;

int CSVConfusionMatrixFileReader(const std::string fileName, MapOfClassesType& mapOfClassesRefClX, ConfusionMatrixType& confusionMatrixClX)
  std::ifstream inFile;;

  if (!inFile)
    std::cerr << "Confusion Matrix File opening problem with file:" << std::endl;
    std::cerr << fileName << std::endl;
    return EXIT_FAILURE;
    LabelPixelType labelRef = 0, labelProd = 0;
    std::string    currentLine, refLabelsLine, prodLabelsLine, currentValue;
    const char     endCommentChar = ':';
    const char     separatorChar  = ',';
    const char     eolChar        = '\n';
    std::getline(inFile, refLabelsLine, endCommentChar);  // Skips the comments
    std::getline(inFile, refLabelsLine, eolChar);         // Gets the first line after the comment char until the End Of Line char
    std::getline(inFile, prodLabelsLine, endCommentChar); // Skips the comments
    std::getline(inFile, prodLabelsLine, eolChar);        // Gets the second line after the comment char until the End Of Line char

    std::istringstream issRefLabelsLine(refLabelsLine);
    std::istringstream issProdLabelsLine(prodLabelsLine);

    MapOfClassesType mapOfClassesProdClX;

    int itLab = 0;
    while (issRefLabelsLine.good())
      std::getline(issRefLabelsLine, currentValue, separatorChar);
      labelRef                     = static_cast<LabelPixelType>(std::atoi(currentValue.c_str()));
      mapOfClassesRefClX[labelRef] = itLab;

    itLab = 0;
    while (issProdLabelsLine.good())
      std::getline(issProdLabelsLine, currentValue, separatorChar);
      labelProd                      = static_cast<LabelPixelType>(std::atoi(currentValue.c_str()));
      mapOfClassesProdClX[labelProd] = itLab;

    unsigned int        nbRefLabelsClk  = mapOfClassesRefClX.size();
    unsigned int        nbProdLabelsClk = mapOfClassesProdClX.size();
    ConfusionMatrixType confusionMatrixClXTemp;
    confusionMatrixClXTemp = ConfusionMatrixType(nbRefLabelsClk, nbProdLabelsClk);

    // Reading the confusion matrix confusionMatrixClXTemp from the file
    for (unsigned int itRow = 0; itRow < nbRefLabelsClk; ++itRow)
      // Gets the itRow^th line after the header lines with the labels
      std::getline(inFile, currentLine, eolChar);
      std::istringstream issCurrentLine(currentLine);
      unsigned int       itCol = 0;
      while (issCurrentLine.good())
        std::getline(issCurrentLine, currentValue, separatorChar);
        confusionMatrixClXTemp(itRow, itCol) = static_cast<ConfusionMatrixEltType>(std::atoi(currentValue.c_str()));

    MapOfClassesType::iterator itMapOfClassesRef, itMapOfClassesProd;

    // Formatting confusionMatrixClX from confusionMatrixClXTemp in order to make confusionMatrixClX a square matrix
    // from the reference labels in mapOfClassesRefClX
    int indiceLabelRef = 0, indiceLabelProd = 0;
    int indiceLabelRefTemp = 0, indiceLabelProdTemp = 0;
    // Initialization of confusionMatrixClX
    confusionMatrixClX = ConfusionMatrixType(nbRefLabelsClk, nbRefLabelsClk);
    for (itMapOfClassesRef = mapOfClassesRefClX.begin(); itMapOfClassesRef != mapOfClassesRefClX.end(); ++itMapOfClassesRef)
      // labels labelRef of mapOfClassesRefClX are already sorted
      labelRef           = itMapOfClassesRef->first;
      indiceLabelRefTemp = itMapOfClassesRef->second;

      for (itMapOfClassesProd = mapOfClassesProdClX.begin(); itMapOfClassesProd != mapOfClassesProdClX.end(); ++itMapOfClassesProd)
        // labels labelProd of mapOfClassesProdClX are already sorted
        labelProd           = itMapOfClassesProd->first;
        indiceLabelProdTemp = itMapOfClassesProd->second;

        // If labelProd is present in mapOfClassesRefClX
        if (mapOfClassesRefClX.count(labelProd) != 0)
          // Indice of labelProd in mapOfClassesRefClX; itMapOfClassesRef->second elements are already SORTED
          indiceLabelProd = mapOfClassesRefClX[labelProd];
          confusionMatrixClX(indiceLabelRef, indiceLabelProd) = confusionMatrixClXTemp(indiceLabelRefTemp, indiceLabelProdTemp);
  return EXIT_SUCCESS;

int main(int argc, char* argv[])
  // The input labeled images to be fused are expected to be scalar images.
  const unsigned int Dimension = 2;
  using LabelImageType         = otb::Image<LabelPixelType, Dimension>;
  using VectorImageType        = otb::VectorImage<LabelPixelType, Dimension>;

  LabelPixelType nodataLabel    = atoi(argv[argc - 3]);
  LabelPixelType undecidedLabel = atoi(argv[argc - 2]);
  const char*    outfname       = argv[argc - 1];

  unsigned int nbParameters         = 3;
  unsigned int nbClassificationMaps = (argc - 1 - nbParameters) / 2;

  // We declare an \doxygen{otb}{ImageListToVectorImageFilter} which will stack all the
  // input classification maps to be fused as a single VectorImage for which each
  // band is a classification map. This VectorImage will then be the input of the
  // Dempster Shafer fusion filter \doxygen{otb}{DSFusionOfClassifiersImageFilter}.
  using LabelImageListType               = otb::ImageList<LabelImageType>;
  using ImageListToVectorImageFilterType = otb::ImageListToVectorImageFilter<LabelImageListType, VectorImageType>;

  using MassOfBeliefDefinitionMethod = ConfusionMatrixToMassOfBeliefType::MassOfBeliefDefinitionMethod;

  // The Dempster Shafer fusion filter \doxygen{otb}{DSFusionOfClassifiersImageFilter} is declared.
  // Dempster Shafer
  using DSFusionOfClassifiersImageFilterType = otb::DSFusionOfClassifiersImageFilter<VectorImageType, LabelImageType>;

  using VectorOfMapOfMassesOfBeliefType = DSFusionOfClassifiersImageFilterType::VectorOfMapOfMassesOfBeliefType;

  // Both reader and writer are defined. Since the images
  // to classify can be very big, we will use a streamed writer which
  // will trigger the streaming ability of the fusion filter.
  using ReaderType = otb::ImageFileReader<LabelImageType>;
  using WriterType = otb::ImageFileWriter<LabelImageType>;

  // The image list of input classification maps is filled. Moreover, the input
  // confusion matrix files are converted into masses of belief.
  ReaderType::Pointer                        reader;
  LabelImageListType::Pointer                imageList = LabelImageListType::New();
  ConfusionMatrixToMassOfBeliefType::Pointer confusionMatrixToMassOfBeliefFilter;
  confusionMatrixToMassOfBeliefFilter = ConfusionMatrixToMassOfBeliefType::New();

  MassOfBeliefDefinitionMethod massOfBeliefDef;

  // Several parameters are available to estimate the masses of belief
  // from the confusion matrices: PRECISION, RECALL, ACCURACY and KAPPA
  massOfBeliefDef = ConfusionMatrixToMassOfBeliefType::PRECISION;

  VectorOfMapOfMassesOfBeliefType vectorOfMapOfMassesOfBelief;
  for (unsigned int itCM = 0; itCM < nbClassificationMaps; ++itCM)
    std::string fileNameClassifiedImage = argv[itCM + 1];
    std::string fileNameConfMat         = argv[itCM + 1 + nbClassificationMaps];

    reader = ReaderType::New();


    MapOfClassesType    mapOfClassesClk;
    ConfusionMatrixType confusionMatrixClk;

    // The data (class labels and confusion matrix values) are read and
    // extracted from the *.CSV file with an ad-hoc file parser
    CSVConfusionMatrixFileReader(fileNameConfMat, mapOfClassesClk, confusionMatrixClk);

    // The parameters of the ConfusionMatrixToMassOfBelief filter are set

    // Vector containing ALL the K (= nbClassificationMaps) std::map<Label, MOB>
    // of Masses of Belief

  // The image list of input classification maps is converted into a VectorImage to
  // be used as input of the \doxygen{otb}{DSFusionOfClassifiersImageFilter}.
  // Image List To VectorImage
  ImageListToVectorImageFilterType::Pointer imageListToVectorImageFilter;
  imageListToVectorImageFilter = ImageListToVectorImageFilterType::New();

  DSFusionOfClassifiersImageFilterType::Pointer dsFusionFilter;
  dsFusionFilter = DSFusionOfClassifiersImageFilterType::New();

  // The parameters of the DSFusionOfClassifiersImageFilter are set

  // Once it is plugged the pipeline triggers its execution by updating
  // the output of the writer.

  WriterType::Pointer writer = WriterType::New();
  return EXIT_SUCCESS;