Browse Source

corrected derivation from NICE::Persistent and renamed 3D method

Sven Sickert 11 years ago
parent
commit
feea788e28

+ 2 - 3
progs/testSemanticSegmentation.cpp

@@ -16,8 +16,7 @@
 #include <vislearning/baselib/ICETools.h>
 
 #include <core/image/MultiChannelImage3DT.h>
-#include <semseg3d/semseg/SemanticSegmentation.h>
-#include <semseg3d/semseg/SemSegContextTree.h>
+#include <semseg3d/semseg/SemSegContextTree3D.h>
 
 #include <core/basics/ResourceStatistics.h>
 #include <core/image/Morph.h>
@@ -142,7 +141,7 @@ int main ( int argc, char **argv )
 
   // initialize semantic segmentation method
   SemanticSegmentation *semseg = NULL;
-  semseg = new SemSegContextTree ( &conf, &md );
+  semseg = new SemSegContextTree3D ( &conf, &md );
   
   // train semantic segmentation method
   cout << "\nTRAINING" << endl;

+ 15 - 15
semseg/SemSegContextTree.cpp → semseg/SemSegContextTree3D.cpp

@@ -1,4 +1,4 @@
-#include "SemSegContextTree.h"
+#include "SemSegContextTree3D.h"
 #include "vislearning/baselib/Globals.h"
 #include "core/basics/StringTools.h"
 
@@ -38,7 +38,7 @@ using namespace NICE;
 //###################### CONSTRUCTORS #########################//
 
 
-SemSegContextTree::SemSegContextTree () : SemanticSegmentation ()
+SemSegContextTree3D::SemSegContextTree3D () : SemanticSegmentation ()
 {
   this->lfcw                = NULL;
   this->firstiteration      = true;
@@ -73,7 +73,7 @@ SemSegContextTree::SemSegContextTree () : SemanticSegmentation ()
 }
 
 
-SemSegContextTree::SemSegContextTree (
+SemSegContextTree3D::SemSegContextTree3D (
     const Config *conf,
     const MultiDataset *md )
     : SemanticSegmentation ( conf, & ( md->getClassNames ( "train" ) ) )
@@ -165,14 +165,14 @@ SemSegContextTree::SemSegContextTree (
 
 //###################### DESTRUCTORS ##########################//
 
-SemSegContextTree::~SemSegContextTree()
+SemSegContextTree3D::~SemSegContextTree3D()
 {
 }
 
 
 //#################### MEMBER FUNCTIONS #######################//
 
-void SemSegContextTree::initOperations()
+void SemSegContextTree3D::initOperations()
 {
   string featsec = "Features";
 
@@ -316,7 +316,7 @@ void SemSegContextTree::initOperations()
   this->ops.push_back ( tops5 );
 }
 
-double SemSegContextTree::getBestSplit (
+double SemSegContextTree3D::getBestSplit (
     std::vector<NICE::MultiChannelImage3DT<double> > &feats,
     std::vector<NICE::MultiChannelImage3DT<unsigned short int> > &nodeIndices,
     const std::vector<NICE::MultiChannelImageT<int> > &labels,
@@ -608,7 +608,7 @@ double SemSegContextTree::getBestSplit (
   return bestig;
 }
 
-inline double SemSegContextTree::getMeanProb (
+inline double SemSegContextTree3D::getMeanProb (
     const int &x,
     const int &y,
     const int &z,
@@ -625,7 +625,7 @@ inline double SemSegContextTree::getMeanProb (
   return val / ( double ) nbTrees;
 }
 
-void SemSegContextTree::computeRayFeatImage (
+void SemSegContextTree3D::computeRayFeatImage (
     NICE::MultiChannelImage3DT<double> &feats,
     int firstChannel )
 {
@@ -707,7 +707,7 @@ void SemSegContextTree::computeRayFeatImage (
   }
 }
 
-void SemSegContextTree::updateProbabilityMaps (
+void SemSegContextTree3D::updateProbabilityMaps (
     const NICE::MultiChannelImage3DT<unsigned short int> &nodeIndices,
     NICE::MultiChannelImage3DT<double> &feats,
     int firstChannel )
@@ -760,7 +760,7 @@ inline double computeWeight ( const int &d, const int &dim )
     return 1.0 / ( pow ( 2, ( double ) ( dim - d + 1 ) ) );
 }
 
-void SemSegContextTree::train ( const MultiDataset *md )
+void SemSegContextTree3D::train ( const MultiDataset *md )
 {
   const LabeledSet trainSet = * ( *md ) ["train"];
   const LabeledSet *trainp = &trainSet;
@@ -781,7 +781,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
   }
 }
 
-void SemSegContextTree::train ( const LabeledSet * trainp )
+void SemSegContextTree3D::train ( const LabeledSet * trainp )
 {
   int shortsize = numeric_limits<short>::max();
 
@@ -1443,7 +1443,7 @@ void SemSegContextTree::train ( const LabeledSet * trainp )
 
 }
 
-void SemSegContextTree::addFeatureMaps (
+void SemSegContextTree3D::addFeatureMaps (
     NICE::MultiChannelImage3DT<double> &imgData,
     const vector<string> &filelist,
     int &amountRegions )
@@ -1646,7 +1646,7 @@ void SemSegContextTree::addFeatureMaps (
 
 }
 
-void SemSegContextTree::classify (
+void SemSegContextTree3D::classify (
     NICE::MultiChannelImage3DT<double> & imgData,
     NICE::MultiChannelImageT<double> & segresult,
     NICE::MultiChannelImage3DT<double> & probabilities,
@@ -2100,7 +2100,7 @@ void SemSegContextTree::classify (
   delete globalCategorFeat;
 }
 
-void SemSegContextTree::store ( std::ostream & os, int format ) const
+void SemSegContextTree3D::store ( std::ostream & os, int format ) const
 {
   os.precision ( numeric_limits<double>::digits10 + 1 );
   os << nbTrees << endl;
@@ -2150,7 +2150,7 @@ void SemSegContextTree::store ( std::ostream & os, int format ) const
   os << uniquenumber << endl;
 }
 
-void SemSegContextTree::restore ( std::istream & is, int format )
+void SemSegContextTree3D::restore ( std::istream & is, int format )
 {
   is >> nbTrees;
 

+ 8 - 8
semseg/SemSegContextTree.h → semseg/SemSegContextTree3D.h

@@ -1,12 +1,12 @@
 /**
-* @file SemSegContextTree.h
+* @file SemSegContextTree3D.h
 * @brief Context Trees -> Combination of decision tree and context information
-* @author Björn Fröhlich
+* @author Björn Fröhlich, Sven Sickert
 * @date 29.11.2011
 
 */
-#ifndef SemSegContextTreeINCLUDE
-#define SemSegContextTreeINCLUDE
+#ifndef SemSegContextTree3DINCLUDE
+#define SemSegContextTree3DINCLUDE
 
 // nice-core includes
 #include <core/vector/VVector.h>
@@ -30,7 +30,7 @@ namespace OBJREC
 
 /** Localization system */
 
-class SemSegContextTree : public SemanticSegmentation, public NICE::Persistent
+class SemSegContextTree3D : public SemanticSegmentation
 {
 private:
   /** Segmentation Method */
@@ -218,13 +218,13 @@ private:
 
 public:
   /** simple constructor */
-  SemSegContextTree ();
+  SemSegContextTree3D ();
 
   /** constructor */
-  SemSegContextTree ( const NICE::Config *conf, const MultiDataset *md );
+  SemSegContextTree3D ( const NICE::Config *conf, const MultiDataset *md );
 
   /** simple destructor */
-  virtual ~SemSegContextTree();
+  virtual ~SemSegContextTree3D();
 
   /**
    * classify each pixel of a single 3d image

+ 152 - 12
semseg/SemanticSegmentation.cpp

@@ -1,7 +1,7 @@
 /**
 * @file SemanticSegmentation.cpp
 * @brief abstract interface for semantic segmentation algorithms
-* @author Erik Rodner and Sven Sickert
+* @author Erik Rodner, Alexander Freytag, Sven Sickert
 * @date 03/19/2009
 
 */
@@ -17,36 +17,49 @@ using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
-SemanticSegmentation::SemanticSegmentation ()
+SemanticSegmentation::SemanticSegmentation ( )
+    : iterationCountSuffix(1)
 {
   this->classNames = NULL;
+
   this->imagetype = IMAGETYPE_GRAY;
 }
 
 SemanticSegmentation::SemanticSegmentation ( const Config *conf,
-    const ClassNames *classNames )
+                                             const ClassNames *classNames )
+    : iterationCountSuffix(1)
 {
   this->classNames = classNames;
 
-  Preprocess::Init ( conf );
+  this->initFromConfig( conf );
+}
+
+SemanticSegmentation::~SemanticSegmentation()
+{
+}
+
+void SemanticSegmentation::initFromConfig(const Config* conf, const string& s_confSection)
+{
+  std::string imagetype_s = conf->gS ( "main", "imagetype", "rgb" );
 
-  std::string imagetype_s = conf->gS ( "main", "imagetype", "gray" );
   if ( imagetype_s == "rgb" )
-    this->imagetype = IMAGETYPE_RGB;
+    imagetype = IMAGETYPE_RGB;
   else if ( imagetype_s == "gray" )
-    this->imagetype = IMAGETYPE_GRAY;
-  else
-  {
+    imagetype = IMAGETYPE_GRAY;
+  else {
     fprintf ( stderr, "SemanticSegmentation:: unknown image type option\n" );
     exit ( -1 );
   }
-}
 
-SemanticSegmentation::~SemanticSegmentation()
-{
+  // dangerous!!!
+  Preprocess::Init ( conf );
 }
 
 
+///////////////////// ///////////////////// /////////////////////
+//                      DATA CONVERSION
+///////////////////// ///////////////////// /////////////////////
+
 void SemanticSegmentation::convertLSetToSparseExamples ( Examples &examples, LabeledSetVector &lvec )
 {
 #ifdef DEBUG_PRINTS
@@ -316,3 +329,130 @@ void SemanticSegmentation::getProbabilityMap ( const NICE::MultiChannelImage3DT<
       //getchar();
     }
 }
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT /////////////////////
+
+void SemanticSegmentation::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+
+  bool b_restoreVerbose ( false );
+#ifdef B_RESTOREVERBOSE
+  b_restoreVerbose = true;
+#endif
+
+  if ( is.good() )
+  {
+    if ( b_restoreVerbose )
+      std::cerr << " restore SemanticSegmentation" << std::endl;
+
+    std::string tmp;
+    is >> tmp; //class name
+
+    if ( ! this->isStartTag( tmp, "SemanticSegmentation" ) )
+    {
+      std::cerr << " WARNING - attempt to restore SemanticSegmentation, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }
+
+    is.precision (numeric_limits<double>::digits10 + 1);
+
+    bool b_endOfBlock ( false ) ;
+
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block
+
+      if ( this->isEndTag( tmp, "SemanticSegmentation" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }
+
+      tmp = this->removeStartTag ( tmp );
+
+      if ( b_restoreVerbose )
+        std::cerr << " currently restore section " << tmp << " in SemanticSegmentation" << std::endl;
+
+      if ( tmp.compare("classNames") == 0 )
+      {
+  //dirty solution to circumvent the const-flag
+        const_cast<ClassNames*>(this->classNames)->restore ( is, format );
+
+        is >> tmp; // end of block
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("imagetype") == 0 )
+      {
+        unsigned int ui_imagetyp;
+        is >> ui_imagetyp;
+        this->imagetype = static_cast<IMAGETYP> ( ui_imagetyp );
+
+        is >> tmp; // end of block
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("iterationCountSuffix") == 0 )
+      {
+        is >> this->iterationCountSuffix;
+
+        is >> tmp; // end of block
+        tmp = this->removeEndTag ( tmp );
+      }
+      else
+      {
+      std::cerr << "WARNING -- unexpected SemanticSegmentation object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "SemanticSegmentation::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+
+
+ //TODO check whether we also have to do something linke Preprocess::Init ( conf );
+}
+
+void SemanticSegmentation::store ( std::ostream & os, int format ) const
+{
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "SemanticSegmentation" ) << std::endl;
+
+    os.precision (numeric_limits<double>::digits10 + 1);
+
+    os << this->createStartTag( "classNames" ) << std::endl;
+    this->classNames->store ( os, format );
+    os << this->createEndTag( "classNames" ) << std::endl;
+
+    //
+
+    os << this->createStartTag( "imagetype" ) << std::endl;
+    os << imagetype << std::endl;
+    os << this->createEndTag( "imagetype" ) << std::endl;
+
+    //
+
+    os << this->createStartTag( "iterationCountSuffix" ) << std::endl;
+    os << iterationCountSuffix << std::endl;
+    os << this->createEndTag( "iterationCountSuffix" ) << std::endl;
+
+    // done
+    os << this->createEndTag( "SemanticSegmentation" ) << std::endl;
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void SemanticSegmentation::clear ()
+{
+ //TODO
+}

+ 145 - 79
semseg/SemanticSegmentation.h

@@ -1,13 +1,16 @@
 /**
 * @file SemanticSegmentation.h
 * @brief abstract interface for semantic segmentation algorithms
-* @author Erik Rodner
-* @date 03/19/2009
+* @author Erik Rodner, Alexander Freytag, Sven Sickert
+* @date 03/19/2009, latest update: 14-05-2014 (dd-mm-yyyy)
 
 */
 #ifndef SEMANTICSEGMENTATIONINCLUDE
 #define SEMANTICSEGMENTATIONINCLUDE
 
+// nice-core includes
+#include <core/basics/Persistent.h>
+
 #include <vector>
 #include "core/image/MultiChannelImage3DT.h"
 #include "vislearning/cbaselib/MultiDataset.h"
@@ -20,85 +23,148 @@ namespace OBJREC
 {
 
 /** abstract interface for semantic segmentation algorithms */
-class SemanticSegmentation
+class SemanticSegmentation : public NICE::Persistent
 {
 
-protected:
-  /** accessible class names and information about
-      number of classes etc. */
-  const ClassNames *classNames;
-
-  /** enum type for imagetype */
-  enum
-  {
-    IMAGETYPE_RGB = 0,
-    IMAGETYPE_GRAY
-  };
-
-  /** whether to load images with color information */
-  int imagetype;
-
-public:
-
-  /** simple constructor */
-  SemanticSegmentation ();
-
-  /** constructor
-      @param conf global settings
-      @param classNames this ClassNames object while be stored as a attribute
-  */
-  SemanticSegmentation ( const NICE::Config *conf,
-                         const ClassNames *classNames );
-
-  /** simple destructor */
-  virtual ~SemanticSegmentation();
-
-  /** classification function (has to be overloaded by all subclasses)
-   * @param imgData image data
-   * @param segresult result of the semantic segmentation with a label for each pixel
-   * @param probabilities multi-channel image with one channel for each class and
-   *        corresponding probabilities for each pixel
-   * @param filelist filename list of images that represent slices of a stack
-   */
-  virtual void classify ( NICE::MultiChannelImage3DT<double> & imgData,
-                          NICE::MultiChannelImageT<double> & segresult,
-                          NICE::MultiChannelImage3DT<double> & probabilities,
-                          const std::vector<std::string> & filelist ) = 0;
-
-  /** training function (has to be overloaded by all subclasses)
-   * @param md the data set
-   */
-  virtual void train ( const MultiDataset * md ) = 0;
-
-  /**
-   * collect information about the depth of 3d images
-   * @param *Files a labeled set of data
-   * @param depthVec output of depth values
-   * @param run3dseg whether slice counting is necessary or not
-   */
-  void getDepthVector ( const LabeledSet *Files, std::vector<int> & depthVec, const bool run3dseg );
-
-  /**
-   * convert different datatypes
-   */
-  void convertVVectorToExamples ( NICE::VVector &feats,OBJREC::Examples &examples, std::vector<int> &label );
-  void convertExamplesToVVector ( NICE::VVector &feats,OBJREC::Examples &examples, std::vector<int> &label );
-  void convertExamplesToLSet ( OBJREC::Examples &examples, OBJREC::LabeledSetVector &lvec );
-  void convertLSetToExamples ( OBJREC::Examples &examples, OBJREC::LabeledSetVector &lvec );
-  void convertLSetToSparseExamples ( OBJREC::Examples &examples, OBJREC::LabeledSetVector &lvec );
-
-  /**
-   *load image slices into a single MCI3DT
-   */
-  void make3DImage ( const std::vector<std::string> & filelist,
-                     NICE::MultiChannelImage3DT<double> & imgData );
-
-  /**
-   * @brief show a probability map for a given class
-   * @param prob  class probabilites for each pixel
-   * @param cl    class number
-   */
-  void getProbabilityMap( const NICE::MultiChannelImage3DT<double> & prob );
+  protected:
+    /** accessible class names and information about
+        number of classes etc. */
+    const ClassNames *classNames;
+
+    /** enum type for imagetype */
+    enum IMAGETYP
+    {
+      IMAGETYPE_RGB = 0,
+      IMAGETYPE_GRAY
+    };
+
+    /** whether to load images with color information */
+    IMAGETYP imagetype;
+
+    int iterationCountSuffix;
+
+  public:
+
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////
+
+    /** default constructor */
+    SemanticSegmentation ( );
+
+    /** simple constructor
+        @param conf global settings
+        @param classNames this ClassNames object while be stored as a attribute
+    */
+    SemanticSegmentation ( const NICE::Config *conf,
+                           const ClassNames *classNames );
+
+    /** simple destructor */
+    virtual ~SemanticSegmentation();
+
+    /**
+    * @brief Setup internal variables and objects used
+    * @author Alexander Freytag
+    * @param conf Config file to specify variable settings
+    * @param s_confSection
+    */
+    void initFromConfig(const NICE::Config *conf, const std::string & s_confSection = "SemanticSegmentation");
+
+    ///////////////////// ///////////////////// /////////////////////
+    //                      SEGMENTATION STUFF
+    ///////////////////// ///////////////////// /////////////////////
+
+    /**
+     * @brief Classification function (has to be overloaded by all subclasses)
+     * @author Sven Sickert
+     * @param imgData image data
+     * @param segresult result of the semantic segmentation with a label for each pixel
+     * @param probabilities multi-channel image with one channel for each class and
+     *        corresponding probabilities for each pixel
+     * @param filelist filename list of images that represent slices of a stack
+     */
+    virtual void classify ( NICE::MultiChannelImage3DT<double> & imgData,
+                            NICE::MultiChannelImageT<double> & segresult,
+                            NICE::MultiChannelImage3DT<double> & probabilities,
+                            const std::vector<std::string> & filelist ) = 0;
+
+    /** training function (has to be overloaded by all subclasses)
+     * @param md the data set
+     */
+    virtual void train ( const MultiDataset * md ) = 0;
+
+    /**
+     * @brief Load image slices into a MultiChannelImage3DT
+     * @author Sven Sickert
+     * @param filelist filename list of images that represent slices of a stack
+     * @param imgData output
+     */
+    void make3DImage ( const std::vector<std::string> & filelist,
+                       NICE::MultiChannelImage3DT<double> & imgData );
+
+
+    ///////////////////// ///////////////////// /////////////////////
+    //                      DATA CONVERSION
+    ///////////////////// ///////////////////// /////////////////////
+
+    /**
+     * convert different datatypes
+     */
+    void convertVVectorToExamples ( NICE::VVector &feats,OBJREC::Examples &examples, std::vector<int> &label );
+    void convertExamplesToVVector ( NICE::VVector &feats,OBJREC::Examples &examples, std::vector<int> &label );
+    void convertExamplesToLSet ( OBJREC::Examples &examples, OBJREC::LabeledSetVector &lvec );
+    void convertLSetToExamples ( OBJREC::Examples &examples, OBJREC::LabeledSetVector &lvec );
+    void convertLSetToSparseExamples ( OBJREC::Examples &examples, OBJREC::LabeledSetVector &lvec );
+
+    ///////////////////// ///////////////////// /////////////////////
+    //                         GET / SET
+    ///////////////////// ///////////////////// /////////////////////
+
+    /**
+     * @brief Collect information about the depth of 3d images
+     * @author Sven Sickert
+     * @param Files a labeled set of data
+     * @param depthVec output of depth values
+     * @param run3dseg whether slice counting is necessary or not
+     */
+    void getDepthVector ( const LabeledSet *Files, std::vector<int> & depthVec, const bool run3dseg );
+
+    /**
+     * @brief Save probability maps of all classes to iamge files
+     * @author Sven Sickert
+     * @param prob class probability maps
+     */
+    void getProbabilityMap( const NICE::MultiChannelImage3DT<double> & prob );
+
+    /**
+     * @author Alexander Freytag
+     * @date 06-02-2014 ( dd-mm-yyyy )
+     */
+    void setClassNames ( const OBJREC::ClassNames * _classNames  ) ;
+
+    void setIterationCountSuffix( const int & _iterationCountSuffix);
+
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+
+    /**
+     * @brief Load active-segmentation-object from external file (stream)
+     * @author Alexander Freytag
+     */
+    virtual void restore ( std::istream & is, int format = 0 );
+
+    /**
+     * @brief Save active-segmentation-object to external file (stream)
+     * @author Alexander Freytag
+     */
+    virtual void store( std::ostream & os, int format = 0 ) const;
+
+    /**
+     * @brief Clear active-segmentation-object object
+     * @author Alexander Freytag
+     */
+    virtual void clear ();
 
 };