Johannes Ruehle 11 years ago
parent
commit
8835b2b7a1
60 changed files with 5699 additions and 1013 deletions
  1. 88 25
      features/localfeatures/GenericLFSelection.h
  2. 65 8
      features/localfeatures/GenericLocalFeatureSelection.h
  3. 191 31
      features/localfeatures/LFColorSande.cpp
  4. 74 10
      features/localfeatures/LFColorSande.h
  5. 55 1
      features/localfeatures/LFGenericLocal.cpp
  6. 50 10
      features/localfeatures/LFGenericLocal.h
  7. 36 0
      features/localfeatures/LFMikolajczyk.cpp
  8. 55 15
      features/localfeatures/LFMikolajczyk.h
  9. 108 45
      features/localfeatures/LFPatches.cpp
  10. 67 24
      features/localfeatures/LFPatches.h
  11. 216 25
      features/localfeatures/LFReadCache.cpp
  12. 89 25
      features/localfeatures/LFReadCache.h
  13. 242 27
      features/localfeatures/LFSiftPP.cpp
  14. 111 40
      features/localfeatures/LFSiftPP.h
  15. 193 19
      features/localfeatures/LFWriteCache.cpp
  16. 114 52
      features/localfeatures/LFWriteCache.h
  17. 195 29
      features/localfeatures/LFonHSG.cpp
  18. 56 5
      features/localfeatures/LFonHSG.h
  19. 59 14
      features/localfeatures/LocalFeature.h
  20. 97 18
      features/localfeatures/LocalFeatureCentrist.cpp
  21. 91 26
      features/localfeatures/LocalFeatureCentrist.h
  22. 9 2
      features/localfeatures/LocalFeatureColorWeijer.cpp
  23. 10 3
      features/localfeatures/LocalFeatureColorWeijer.h
  24. 115 5
      features/localfeatures/LocalFeatureLFInterface.cpp
  25. 75 18
      features/localfeatures/LocalFeatureLFInterface.h
  26. 107 1
      features/localfeatures/LocalFeatureOpponnentSift.cpp
  27. 89 16
      features/localfeatures/LocalFeatureOpponnentSift.h
  28. 130 14
      features/localfeatures/LocalFeatureRGBSift.cpp
  29. 85 15
      features/localfeatures/LocalFeatureRGBSift.h
  30. 61 27
      features/localfeatures/LocalFeatureRepresentation.h
  31. 189 15
      features/localfeatures/LocalFeatureSift.cpp
  32. 96 22
      features/localfeatures/LocalFeatureSift.h
  33. 134 0
      features/localfeatures/progs/computeLocalFeatures.cpp
  34. 89 0
      features/localfeatures/tests/Makefile.inc
  35. 91 0
      features/localfeatures/tests/TestGenericLFSelectionPersistent.cpp
  36. 31 0
      features/localfeatures/tests/TestGenericLFSelectionPersistent.h
  37. 91 0
      features/localfeatures/tests/TestGenericLocalFeatureSelectionPersistent.cpp
  38. 31 0
      features/localfeatures/tests/TestGenericLocalFeatureSelectionPersistent.h
  39. 93 0
      features/localfeatures/tests/TestLFonHSGPersistent.cpp
  40. 32 0
      features/localfeatures/tests/TestLFonHSGPersistent.h
  41. 28 1
      math/cluster/ClusterAlgorithm.cpp
  42. 49 8
      math/cluster/ClusterAlgorithm.h
  43. 70 6
      math/cluster/GenericClusterAlgorithmSelection.h
  44. 165 10
      math/cluster/KMeans.cpp
  45. 145 98
      math/cluster/KMeans.h
  46. 142 8
      math/cluster/KMeansHeuristic.cpp
  47. 69 7
      math/cluster/KMeansHeuristic.h
  48. 162 8
      math/cluster/KMeansMatlab.cpp
  49. 107 48
      math/cluster/KMeansMatlab.h
  50. 161 9
      math/cluster/KMedian.cpp
  51. 139 92
      math/cluster/KMedian.h
  52. 131 6
      math/cluster/RandomClustering.cpp
  53. 125 78
      math/cluster/RandomClustering.h
  54. 124 4
      math/cluster/SpectralCluster.cpp
  55. 90 42
      math/cluster/SpectralCluster.h
  56. 90 0
      math/cluster/tests/TestGenericClusterAlgorithmSelectionPersistent.cpp
  57. 31 0
      math/cluster/tests/TestGenericClusterAlgorithmSelectionPersistent.h
  58. 56 0
      math/cluster/tests/TestKMedian.cpp
  59. 4 0
      math/cluster/tests/TestKMedian.h
  60. 1 1
      progs/evaluateCompleteBoWPipeline.cpp

+ 88 - 25
features/localfeatures/GenericLFSelection.h

@@ -7,6 +7,8 @@
 #ifndef _NICE_OBJREC_LF_SELECTION_INCLUDE
 #define _NICE_OBJREC_LF_SELECTION_INCLUDE
 
+#include <core/basics/Exception.h>
+
 #include "vislearning/features/localfeatures/LocalFeatureRepresentation.h"
 #include "vislearning/features/localfeatures/LFMikolajczyk.h"
 #include "vislearning/features/localfeatures/LFPatches.h"
@@ -47,45 +49,45 @@ class GenericLFSelection
       LocalFeatureRepresentation *selectLocalFeatureRep ( const NICE::Config *conf, std::string section = "features", const UsageForTrainOrTest & useForTrainOrTest = GenericLFSelection::NOTSPECIFIED )
       {
         // return Value
-        LocalFeatureRepresentation *lfrep = NULL;
+        OBJREC::LocalFeatureRepresentation *lfrep = NULL;
       
         // string which defines the localfeature_type (for Ex. Sande, ...)
         std::string localfeature_type = conf->gS(section, "localfeature_type", "");
       
-        if ( localfeature_type == "mikolajczyk" )
+        if ( ( localfeature_type == "mikolajczyk" )|| ( localfeature_type == "LFMikolajczyk" ) )
         {
-          lfrep = new LFMikolajczyk ( conf );
+          lfrep = new OBJREC::LFMikolajczyk ( conf );
         }
-        else if ( localfeature_type == "VANDESANDE" ) //previously: "color"
+        else if ( ( localfeature_type == "VANDESANDE" ) || ( localfeature_type == "LFColorSande" ) )//previously: "color"
         {
           if ( useForTrainOrTest == TRAINING )
           {
-            lfrep = new LFColorSande ( conf, "LFColorSandeTrain" );
+            lfrep = new OBJREC::LFColorSande ( conf, "LFColorSandeTrain" );
           }
           else if ( useForTrainOrTest == TESTING )
           {
-            lfrep = new LFColorSande ( conf, "LFColorSandeTest" );
+            lfrep = new OBJREC::LFColorSande ( conf, "LFColorSandeTest" );
           }
           else //not specified whether for training or testing, so we do not care about
           {
-            lfrep = new LFColorSande ( conf );            
+            lfrep = new OBJREC::LFColorSande ( conf );            
           }          
         }
-        else if ( ( localfeature_type == "sift" ) || ( localfeature_type == "siftpp" ) ) 
+        else if ( ( localfeature_type == "sift" ) || ( localfeature_type == "siftpp" ) || ( localfeature_type == "LFSiftPP" ) ) 
         {
-                lfrep = new LFSiftPP ( conf );
+          lfrep = new OBJREC::LFSiftPP ( conf );
         }
-        else if ( ( localfeature_type == "generic_local" ) || ( localfeature_type == "generic" ) )
+        else if ( ( localfeature_type == "generic_local" ) || ( localfeature_type == "generic" ) || ( localfeature_type == "LFGenericLocal" ) )
         {
-                int numFeatures = conf->gI(section, "localfeature_count");
-          lfrep = new LFGenericLocal ( conf, numFeatures );
+          int numFeatures = conf->gI(section, "localfeature_count");
+          lfrep = new OBJREC::LFGenericLocal ( conf, numFeatures );
         }
-        else if ( ( localfeature_type == "grey" ) || ( localfeature_type == "patches" ) )
+        else if ( ( localfeature_type == "grey" ) || ( localfeature_type == "patches" ) || ( localfeature_type == "LFPatches" ) )
         {
           int numFeatures = conf->gI(section, "localfeature_count");
-          lfrep = new LFPatches ( conf, numFeatures );
+          lfrep = new OBJREC::LFPatches ( conf, numFeatures );
         } 
-        else if( localfeature_type == "onHSG" )
+        else if ( ( localfeature_type == "onHSG" ) || ( localfeature_type == "LFonHSG" ) )
         {          
           if ( useForTrainOrTest == TRAINING )
           {
@@ -121,17 +123,17 @@ class GenericLFSelection
           
           if ( useForTrainOrTest == TRAINING )
           {    
-            writeFeats = new LFWriteCache ( conf, lfrep, "cacheTrain" );
+            writeFeats = new OBJREC::LFWriteCache ( conf, lfrep, "cacheTrain" );
             lfrep = writeFeats;
           }
           else if ( useForTrainOrTest == TESTING )
           {
-            writeFeats = new LFWriteCache ( conf, lfrep, "cacheTest" );
+            writeFeats = new OBJREC::LFWriteCache ( conf, lfrep, "cacheTest" );
             lfrep = writeFeats;
           }
           else //not specified whether for training or testing, so we do not care about
           {
-            writeFeats = new LFWriteCache ( conf, lfrep );
+            writeFeats = new OBJREC::LFWriteCache ( conf, lfrep );
             lfrep = writeFeats;
           }              
 
@@ -145,37 +147,98 @@ class GenericLFSelection
           {
             if ( useForTrainOrTest == TRAINING )
             {
-              readFeats = new LFReadCache ( conf, writeFeats, numFeatures, "cacheTrain" );
+              readFeats = new OBJREC::LFReadCache ( conf, writeFeats, numFeatures, "cacheTrain" );
             }
             else if ( useForTrainOrTest == TESTING )
             {
-              readFeats = new LFReadCache ( conf, writeFeats, numFeatures, "cacheTest" );
+              readFeats = new OBJREC::LFReadCache ( conf, writeFeats, numFeatures, "cacheTest" );
             }
             else //not specified whether for training or testing, so we do not care about
             {
-              readFeats = new LFReadCache ( conf, writeFeats, numFeatures, "cache" );
+              readFeats = new OBJREC::LFReadCache ( conf, writeFeats, numFeatures, "cache" );
             }                         
           }
           else
           {
             if ( useForTrainOrTest == TRAINING )
             {
-              readFeats = new LFReadCache (conf, lfrep, numFeatures, "cacheTrain" );                        
+              readFeats = new OBJREC::LFReadCache (conf, lfrep, numFeatures, "cacheTrain" );                        
             }
             else if ( useForTrainOrTest == TESTING )
             {
-              readFeats = new LFReadCache (conf, lfrep, numFeatures, "cacheTest" );
+              readFeats = new OBJREC::LFReadCache (conf, lfrep, numFeatures, "cacheTest" );
             }
             else //not specified whether for training or testing, so we do not care about
             {
-              readFeats = new LFReadCache (conf, lfrep, numFeatures, "cache" );
+              readFeats = new OBJREC::LFReadCache (conf, lfrep, numFeatures, "cache" );
             }
           }
           lfrep = readFeats; 
         }  
           
         return lfrep;
-      }
+      };
+      
+      static
+      void restoreLocalFeatureRep ( LocalFeatureRepresentation * _lfrep, std::istream & is, int format = 0 )
+      {
+                
+        if ( is.good() )
+        {
+          if ( _lfrep != NULL )
+            delete _lfrep;
+          
+          
+          std::string className;
+          is >> className; //class name
+                    
+          if ( className == "<LFMikolajczyk>" )
+          {
+            _lfrep = new OBJREC::LFMikolajczyk();
+          }
+          else if ( className == "<LFColorSande>" )
+          {
+            _lfrep = new OBJREC::LFColorSande();            
+          }
+          else if ( className == "<LFSiftPP>" )
+          {
+            _lfrep = new OBJREC::LFSiftPP();
+          }
+          else if ( className == "<LFGenericLocal>" )
+          {
+            _lfrep = new OBJREC::LFGenericLocal();
+          }
+          else if ( className == "<LFPatches>" )
+          {
+            _lfrep = new OBJREC::LFPatches();
+          } 
+          else if ( className == "<LFonHSG>" )
+          {          
+            _lfrep = new OBJREC::LFonHSG();          
+          }
+          else
+          {
+            fthrow ( NICE::Exception, "GenericLFSelection::restoreLocalFeatureRep -- class name " << className << "unknown. Aborting." );
+          }
+          
+          //undo reading of class name
+          
+          for ( uint i = 0; i < className.size(); i++)
+          {
+            is.unget();
+          }
+          
+          //now, call the restore method of the underlying object
+          //NOTE this could be also done externally, leaving only the actual instantiation of the derived objects here
+          _lfrep->restore ( is );
+            
+        }
+        else
+        {
+          fthrow ( NICE::Exception, "GenericLFSelection::restoreLocalFeatureRep -- InStream not initialized - restoring not possible!" );
+        }      
+    };
+    
 };
 
 }

+ 65 - 8
features/localfeatures/GenericLocalFeatureSelection.h

@@ -38,7 +38,7 @@ class GenericLocalFeatureSelection
     * @param[in] string  - This string defines the value for "section" in the configfile.
     * @return LocalFeature* - The LocalFeature which contains the selected LocalFeature-Type.
     */
-    static LocalFeature *selectLocalFeature ( const NICE::Config *conf, std::string section = "Features" )
+    static OBJREC::LocalFeature *selectLocalFeature ( const NICE::Config *conf, std::string section = "Features" )
     {
       // return Value
       LocalFeature *lf = NULL;
@@ -48,23 +48,23 @@ class GenericLocalFeatureSelection
       
       // The prefix NICE_* indicates that this implementation comes from a NICE-Developer.
       // Extern implementations can be added without NICE_* in this selection-class.
-      if ( localfeature_type == "NICE_SIFT" )
+      if ( ( localfeature_type == "NICE_SIFT" ) || ( localfeature_type == "LocalFeatureSift" ) )
       {
         lf = new OBJREC::LocalFeatureSift ( conf );
       }
-      else if ( localfeature_type == "NICE_RGBSIFT" )
+      else if ( ( localfeature_type == "NICE_RGBSIFT" ) || ( localfeature_type == "LocalFeatureRGBSift" ) )
       {
         lf = new OBJREC::LocalFeatureRGBSift ( conf );
       }
-      else if ( localfeature_type == "NICE_OPPSIFT" )
+      else if ( ( localfeature_type == "NICE_OPPSIFT" ) || ( localfeature_type == "LocalFeatureOpponnentSift" ) )
       {
         lf = new OBJREC::LocalFeatureOpponnentSift ( conf );
       }
-      else if ( localfeature_type == "colornames" )
+      else if ( ( localfeature_type == "colornames" ) || ( localfeature_type == "LocalFeatureColorWeijer" ) )
       {
         lf = new OBJREC::LocalFeatureColorWeijer ( conf );
       }     
-      else if ( localfeature_type == "centrist" )
+      else if ( ( localfeature_type == "centrist" ) || ( localfeature_type == "LocalFeatureCentrist" ) )
       {
         lf = new OBJREC::LocalFeatureCentrist ( conf );
       }      
@@ -72,10 +72,67 @@ class GenericLocalFeatureSelection
 
       // no correct localfeature_type was given
       if ( lf == NULL )
-        fthrow ( NICE::Exception, "Local feature type not found: " << localfeature_type );
+        fthrow ( NICE::Exception, "Local feature type not found: " << localfeature_type << " for section " << section);
 
       return lf;
-    }
+    };
+    
+      static
+      void restoreLocalFeature ( OBJREC::LocalFeature * _lf, std::istream & is, int format = 0 )
+      {
+                
+        if ( is.good() )
+        {
+          if ( _lf != NULL )
+            delete _lf;
+          
+          
+          std::string className;
+          is >> className; //class name
+                     
+                    
+          if ( className == "<LocalFeatureSift>" )
+          {
+            _lf = new OBJREC::LocalFeatureSift();
+          }
+          else if ( className == "<LocalFeatureRGBSift>" )
+          {
+            _lf = new OBJREC::LocalFeatureRGBSift();            
+          }
+          else if ( className == "<LocalFeatureOpponnentSift>" )
+          {
+            _lf = new OBJREC::LocalFeatureOpponnentSift();
+          }
+          else if ( className == "<LocalFeatureColorWeijer>" )
+          {
+            _lf = new OBJREC::LocalFeatureColorWeijer();
+          }
+          else if ( className == "<LocalFeatureCentrist>" )
+          {
+            _lf = new OBJREC::LocalFeatureCentrist();
+          } 
+          else
+          {
+            fthrow ( NICE::Exception, "GenericLocalFeatureSelection::restoreLocalFeatureRep -- class name " << className << "unknown. Aborting." );
+          }
+          
+          //undo reading of class name
+          
+          for ( uint i = 0; i < className.size(); i++)
+          {
+            is.unget();
+          }
+          
+          //now, call the restore method of the underlying object
+          //NOTE this could be also done externally, leaving only the actual instantiation of the derived objects here
+          _lf->restore ( is );
+            
+        }
+        else
+        {
+          fthrow ( NICE::Exception, "GenericLocalFeatureSelection::restoreLocalFeatureRep -- InStream not initialized - restoring not possible!" );
+        }      
+    };    
 };
 }
 

+ 191 - 31
features/localfeatures/LFColorSande.cpp

@@ -1,41 +1,69 @@
 /**
 * @file LFColorSande.cpp
 * @brief interface to ColorSande implementation
-* @author Erik Rodner
+* @author Erik Rodner, Alexander Freytag
 * @date 11/19/2007
-
 */
+
+// STL includes
 #include <errno.h>
 #include <iostream>
+#include <sstream>
 
+// nice-core includes
+#include <core/basics/StringTools.h>
+#include <core/basics/FileMgt.h>
+// 
 #include <core/image/Convert.h>
 
-#include "core/basics/StringTools.h"
-#include "core/basics/FileMgt.h"
-#include "vislearning/baselib/Globals.h"
-
-#include "vislearning/features/localfeatures/LFColorSande.h"
+// nice-vislearning includes
+#include <vislearning/baselib/Globals.h>
+// 
+#include "LFColorSande.h"
 
 
 #define DESCSIZE_DUMMY "/home/bachi/HiWi/nice/nice/objrec-froehlichexp/progs/IMG_8762.JPG"
 
-#include <sstream>
 
-using namespace OBJREC;
 
+using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////
 
-
-LFColorSande::LFColorSande ( const Config *conf, std::string section )
+LFColorSande::LFColorSande() : LocalFeatureRepresentation () 
 {
-  std::cerr << "LF COLOR SANDE SECTION ====================== :" << section << ":"<<std::endl;
+  this->c_binaryExecutable = "";
+  this->c_params           = "--descriptor opponentsift";
+  this->scales             = "1+1.5+3.0+4.5+6";
+  this->descriptor_size    = -1;
+  this->usegrid            = false;
   
+  int gridsizeInt             = 5;
+  std::ostringstream temp;
+  temp << gridsizeInt;
+  this->gridsize = temp.str(); 
+}
+
+LFColorSande::LFColorSande ( const NICE::Config * _conf, std::string _confSection )
+{
+ 
+  this->initFromConfig( _conf );
+}
+
+LFColorSande::~LFColorSande()
+{
+}
+
+void LFColorSande::initFromConfig(const NICE::Config * _conf, const std::string & _confSection)
+{
   try
   {
     //a possible location on dbv could be: "/home/bachi/libs/van_de_sande/x86_64-linux-gcc/colorDescriptor" );
-    c_binaryExecutable = conf->gS ( section, "binaryExecutable" /*we do not add a default here, this has to adapted to your system!!!*/); 
+    this->c_binaryExecutable = _conf->gS ( _confSection, "binaryExecutable" /*we do not add a default here, this has to adapted to your system!!!*/); 
   }
   catch (NICE::Exception exception )
   {
@@ -43,43 +71,44 @@ LFColorSande::LFColorSande ( const Config *conf, std::string section )
     throw exception;
   }
 
-  c_params = conf->gS ( section, "params", "--descriptor opponentsift" );
-  scales = conf->gS ( section, "scales", "1+1.5+3.0+4.5+6" );
-  std::cerr << "scales: " << scales << std::endl;
-
-  descriptor_size = conf->gI ( section, "descriptor_size", -1 );
+  this->c_params        = _conf->gS ( _confSection, "params", "--descriptor opponentsift" );
+  this->scales          = _conf->gS ( _confSection, "scales", "1+1.5+3.0+4.5+6" );
+  this->descriptor_size = _conf->gI ( _confSection, "descriptor_size", -1 );
+  this->usegrid         = _conf->gB ( _confSection, "usegrid", false );
 
-  usegrid = conf->gB ( section, "usegrid", false );
-
-  int g = conf->gI ( section, "grid", 5 );
+  int gridsizeInt = _conf->gI ( _confSection, "grid", 5 );
   std::ostringstream temp;
-  temp << g;
-  gridsize = temp.str();
+  temp << gridsizeInt;
+  this->gridsize        = temp.str();
   
   if ( descriptor_size <= 0 )
   {
     fprintf ( stderr, "LFColorSande::LFColorSande: No descriptor size found in config -> self test\n" );
+    
     /** get feature dimension **/
     NICE::Image testimg ( DESCSIZE_DUMMY );
-    VVector features;
-    VVector positions;
-    extractFeatures ( testimg, features, positions );
+    NICE::VVector features;
+    NICE::VVector positions;
+    
+    this->extractFeatures ( testimg, features, positions );
+    
     if ( features.size() <= 0 )
       fthrow ( Exception, "No features found in " << DESCSIZE_DUMMY << " picture." );
-    descriptor_size = features[0].size();
+    this->descriptor_size = features[0].size();
 
     fprintf ( stderr, "LFColorSande::LFColorSande Self Test features:%d dimension:%d\n", ( int ) features.size(), descriptor_size );
   }
   
-  if ( descriptor_size != conf->gI ( "features", "descriptor_size", descriptor_size ) )
+  if ( descriptor_size != _conf->gI ( "features", "descriptor_size", descriptor_size ) )
   {
     cerr << "Warning: LFColorSande: descriptor sizes do not match !!!" << endl;
   }  
 }
 
-LFColorSande::~LFColorSande()
-{
-}
+
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// ////////////////// 
 
 int LFColorSande::getDescSize () const
 {
@@ -280,3 +309,134 @@ int LFColorSande::extractFeatures ( const NICE::ColorImage & img, VVector & feat
 
   return 0;
 }
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LFColorSande::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "LFColorSande" ) )
+    {
+      std::cerr << " WARNING - attempt to restore LFColorSande, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "LFColorSande" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );     
+      
+      if ( tmp.compare("c_binaryExecutable") == 0 )
+      {
+        is >> this->c_binaryExecutable;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("c_params") == 0 )
+      {
+        is >> this->c_params;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("scales") == 0 )
+      {
+        is >> this->scales;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("descriptor_size") == 0 )
+      {
+        is >> this->descriptor_size;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("usegrid") == 0 )
+      {
+        is >> this->usegrid;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("gridsize") == 0 )
+      {
+        is >> this->gridsize;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }     
+      else
+      {
+      std::cerr << "WARNING -- unexpected LFColorSande object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "LFColorSande::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void LFColorSande::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "LFColorSande" ) << std::endl; 
+
+    
+    os << this->createStartTag( "c_binaryExecutable" ) << std::endl;
+    os << this->c_binaryExecutable << std::endl;
+    os << this->createEndTag( "c_binaryExecutable" ) << std::endl;  
+
+    os << this->createStartTag( "c_params" ) << std::endl;
+    os << this->c_params << std::endl;
+    os << this->createEndTag( "c_params" ) << std::endl;
+    
+    os << this->createStartTag( "scales" ) << std::endl;
+    os << this->scales << std::endl;
+    os << this->createEndTag( "scales" ) << std::endl;  
+
+    os << this->createStartTag( "descriptor_size" ) << std::endl;
+    os << this->descriptor_size << std::endl;
+    os << this->createEndTag( "descriptor_size" ) << std::endl; 
+    
+    os << this->createStartTag( "usegrid" ) << std::endl;
+    os << this->usegrid << std::endl;
+    os << this->createEndTag( "usegrid" ) << std::endl;
+    
+    os << this->createStartTag( "gridsize" ) << std::endl;
+    os << this->gridsize << std::endl;
+    os << this->createEndTag( "gridsize" ) << std::endl;     
+    
+    // done
+    os << this->createEndTag( "LFColorSande" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void LFColorSande::clear ()
+{
+}

+ 74 - 10
features/localfeatures/LFColorSande.h

@@ -1,19 +1,24 @@
 /**
 * @file LFColorSande.h
 * @brief interface to ColorSande implementation
-* @author Erik Rodner
+* @author Erik Rodner, Alexander Freytag
 * @date 11/19/2007
 
 */
 #ifndef LFColorSandeINCLUDE
 #define LFColorSandeINCLUDE
 
-#include "core/vector/VectorT.h"
-#include "core/vector/MatrixT.h"
-#include "core/image/ImageT.h"
+// nice-core includes
+#include <core/basics/Config.h>
+// 
+#include <core/image/ImageT.h>
+// 
+#include <core/vector/VectorT.h>
+#include <core/vector/MatrixT.h>
 
+// nice-vislearning includes
 #include "LocalFeatureRepresentation.h"
-#include "core/basics/Config.h"
+
 
 
 namespace OBJREC {
@@ -23,9 +28,19 @@ class LFColorSande : public LocalFeatureRepresentation
 {
 
   protected:
+    
+    /////////////////////////
+    /////////////////////////
+    // PROTECTED VARIABLES //
+    /////////////////////////
+    /////////////////////////    
+    
     std::string c_binaryExecutable;
+
     std::string c_params;
-    double c_minScale;
+
+    //! used scales
+    std::string scales;
 
     //! size of the descriptor
     int descriptor_size;
@@ -36,16 +51,40 @@ class LFColorSande : public LocalFeatureRepresentation
     //! size of the grid
     std::string gridsize;
 
-    //! used scales
-    std::string scales;
+
+//     double c_minScale;
 
   public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////   
+    
+    /** 
+     * @brief default constructor
+     * @date 10-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LFColorSande ( );     
 
-    /** simple constructor */
-    LFColorSande ( const NICE::Config *conf, std::string section = "LFColorSande" );
+    /** 
+     * @brief simple constructor 
+     */
+    LFColorSande ( const NICE::Config * _conf, std::string _confSection = "LFColorSande" );
 
     /** simple destructor */
     virtual ~LFColorSande();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LFColorSande");     
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////            
 
     int getDescSize () const;
 
@@ -68,6 +107,31 @@ class LFColorSande : public LocalFeatureRepresentation
      */
     int extractFeatures ( const NICE::ColorImage & img, NICE::VVector & features,
                           NICE::VVector & positions ) const;
+                          
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();                            
 
 };
 

+ 55 - 1
features/localfeatures/LFGenericLocal.cpp

@@ -19,6 +19,15 @@ using namespace std;
 using namespace NICE;
 
 
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////
+
+LFGenericLocal::LFGenericLocal()
+{
+    this->lf = NULL;
+    this->id = NULL;
+}
 
 LFGenericLocal::LFGenericLocal( const Config *conf, int numFeatures )
 {
@@ -28,9 +37,23 @@ LFGenericLocal::LFGenericLocal( const Config *conf, int numFeatures )
 
 LFGenericLocal::~LFGenericLocal()
 {
-    delete lf;
+  if ( this->lf != NULL )
+  {
+    delete this->lf;
+    this->lf = NULL;
+  }
+
+  if ( this->id != NULL )
+  {
+    delete this->id;
+    this->id = NULL;
+  }
 }
 
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 int LFGenericLocal::getDescSize () const
 {
     return lf->getDescSize();
@@ -52,3 +75,34 @@ void LFGenericLocal::visualizeFeatures ( NICE::Image & mark,
     lf->visualizeFeatures ( mark, positions, color );
 }
 
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LFGenericLocal::restore ( std::istream & is, int format )
+{ 
+  fthrow ( Exception, "LFGenericLocal::restore not implemented yet." );
+  //TODO
+}
+
+void LFGenericLocal::store ( std::ostream & os, int format ) const
+{ 
+  fthrow ( Exception, "LFGenericLocal::store not implemented yet." );
+  //TODO  
+}
+
+void LFGenericLocal::clear ()
+{ 
+  if ( this->lf != NULL )
+  {
+    delete this->lf;
+    this->lf = NULL;
+  }
+
+  if ( this->id != NULL )
+  {
+    delete this->id;
+    this->id = NULL;
+  }
+}
+

+ 50 - 10
features/localfeatures/LFGenericLocal.h

@@ -20,24 +20,39 @@
 
 namespace OBJREC {
 
-  /** generic local features */
-  /** @class LFGenericLocal
- * @brief Generic local features ( actually: Random Sampling of POIs followed by SIFT as descriptor)
- */  
-  class LFGenericLocal : public LocalFeatureRepresentation
-  {
-
-      protected:
+/** generic local features */
+/** @class LFGenericLocal
+* @brief Generic local features ( actually: Random Sampling of POIs followed by SIFT as descriptor)
+*/  
+class LFGenericLocal : public LocalFeatureRepresentation
+{
+
+  protected:
     LocalFeature *lf;
     InterestDetector *id;
 
-      public:
+  public:
+        
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////
+    
+    /** 
+     * @brief default constructor
+     * @date 10-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LFGenericLocal();        
     
     /** simple constructor */
     LFGenericLocal( const NICE::Config *conf, int numFeatures );
         
     /** simple destructor */
     virtual ~LFGenericLocal();
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////      
       
     int getDescSize () const;
 
@@ -48,8 +63,33 @@ namespace OBJREC {
     void visualizeFeatures ( NICE::Image & mark,
           const NICE::VVector & positions,
           size_t color ) const;
+          
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();           
 
-  };
+};
 
 
 } // namespace

+ 36 - 0
features/localfeatures/LFMikolajczyk.cpp

@@ -20,7 +20,17 @@ using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////
 
+LFMikolajczyk::LFMikolajczyk()
+{
+    this->c_binaryExecutable = "";
+    this->c_params = "-haraff -sift";
+    this->c_minScale = 1.0;
+    this->descriptor_size = -1;
+}
 
 LFMikolajczyk::LFMikolajczyk( const Config *conf )
 {
@@ -59,6 +69,10 @@ LFMikolajczyk::~LFMikolajczyk()
 {
 }
 
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 int LFMikolajczyk::getDescSize () const
 {
     return descriptor_size;
@@ -172,3 +186,25 @@ int LFMikolajczyk::extractFeatures ( const NICE::Image & img, VVector & features
 
     return 0;
 }
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LFMikolajczyk::restore ( std::istream & is, int format )
+{ 
+  fthrow ( Exception, "LFMikolajczyk::restore not implemented yet." );
+  //TODO  
+}
+
+void LFMikolajczyk::store ( std::ostream & os, int format ) const
+{ 
+  fthrow ( Exception, "LFMikolajczyk::store not implemented yet." );
+  //TODO  
+}
+
+void LFMikolajczyk::clear ()
+{ 
+  fthrow ( Exception, "LFMikolajczyk::clear not implemented yet." );
+  //TODO  
+}

+ 55 - 15
features/localfeatures/LFMikolajczyk.h

@@ -22,26 +22,66 @@ namespace OBJREC {
 class LFMikolajczyk : public LocalFeatureRepresentation
 {
 
-    protected:
-		std::string c_binaryExecutable;
-		std::string c_params;
-		double c_minScale;
-		
-		int descriptor_size;
+  protected:
+    std::string c_binaryExecutable;
+    std::string c_params;
+    double c_minScale;
+    
+    int descriptor_size;
 
 
-    public:
+  public:
+
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////
+    
+    /** 
+     * @brief default constructor
+     * @date 10-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LFMikolajczyk();      
+  
+    /** simple constructor */
+    LFMikolajczyk( const NICE::Config *conf );
   
-	/** simple constructor */
-	LFMikolajczyk( const NICE::Config *conf );
+    /** simple destructor */
+    virtual ~LFMikolajczyk();
+      
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////        
       
-	/** simple destructor */
-	virtual ~LFMikolajczyk();
-	
-	int getDescSize () const;
+    int getDescSize () const;
 
-	int extractFeatures ( const NICE::Image & img, NICE::VVector & features, 
-			      NICE::VVector & positions ) const;
+    int extractFeatures ( const NICE::Image & img, NICE::VVector & features, 
+                          NICE::VVector & positions ) const;
+            
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();              
      
 };
 

+ 108 - 45
features/localfeatures/LFPatches.cpp

@@ -23,55 +23,85 @@ using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
-LFPatches::LFPatches(const Config *conf, int _numPatches) :
-	numPatches(_numPatches)
+void LFPatches::setDetector ( const int & _detectormode, const NICE::Config * conf)
 {
-	xsize = conf->gI("Patches", "xsize", 11);
-	ysize = conf->gI("Patches", "ysize", 11);
-	maxLevels = conf->gI("Patches", "levels", 10);
-	scaleSpacing = conf->gD("Patches", "scale_spacing", sqrt(sqrt(2.0f)));
-	detectormode = conf->gI("Patches", "detector", 0);
-	std::string normalization_s = conf->gS("Patches", "normalization", "n01");
-
-	if (detectormode == 0)
-	{
-		std::auto_ptr<InterestDetector> id_new(new IDRandomSampling(conf,
-				numPatches));
-		id = id_new;
 
-	}
-	else if (detectormode == 1)
-	{
-		std::auto_ptr<InterestDetector> id_new(new IDKLTSampling(conf,
-				numPatches));
-		id = id_new;
-	}
-	else if (detectormode == 2)
-	{
-		std::auto_ptr<InterestDetector> id_new(new IDSIFTSampling(conf));
-		id = id_new;
-	}
-	else
-	{
-		std::auto_ptr<InterestDetector> id_new(new IDRandomSampling(conf,
-				numPatches));
-		id = id_new;
+  if ( this->id != NULL )
+  {
+    delete this->id;
+    this->id = NULL;
+  }
+  
+  if (_detectormode == 0)
+  {
+    this->id = new IDRandomSampling(conf, this->numPatches);
+  }
+  else if (_detectormode == 1)
+  {
+    this->id = new IDKLTSampling(conf, this->numPatches);    
+  }
+  else if (_detectormode == 2)
+  {
+    this->id = new IDSIFTSampling(conf);    
+  }
+  else
+  {
+    this->id = new IDRandomSampling(conf, this->numPatches);
+  }  
+}
 
-	}
+void LFPatches::setNormalization( const std::string & _normalization_s) 
+{
+  if (_normalization_s == "n01")
+          normalization = NORMALIZE_N01;
+  else if (_normalization_s == "stddev")
+          normalization = NORMALIZE_STDDEV;
+  else if (_normalization_s == "mean")
+          normalization = NORMALIZE_MEAN;
+  else if (_normalization_s == "none")
+          normalization = NORMALIZE_NONE;
+  else
+  {
+          fprintf(stderr, "LFPatches::LFPatches: unknown normalization method\n");
+          exit(-1);
+  }  
+}
+
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////
+
+LFPatches::LFPatches()
+{
+  this->numPatches  = -1;
+  this->xsize        = 11;
+  this->ysize        = 11;
+  this->maxLevels    = 10;
+  this->scaleSpacing = sqrt(sqrt(2));
+  this->detectormode = 0;  
+  this->id = NULL;
+  
+  std::string normalization_s = "n01";
+  this->setNormalization ( normalization_s );
+  
+  //TODO initialization useful here?
+  srand(time(NULL));
+}
+
+
+LFPatches::LFPatches(const Config *conf, int _numPatches) :
+	numPatches(_numPatches)
+{
+	this->xsize = conf->gI("Patches", "xsize", 11);
+	this->ysize = conf->gI("Patches", "ysize", 11);
+	this->maxLevels = conf->gI("Patches", "levels", 10);
+	this->scaleSpacing = conf->gD("Patches", "scale_spacing", sqrt(sqrt(2)));
+	this->detectormode = conf->gI("Patches", "detector", 0);
+        this->setDetector ( this->detectormode, conf );
+        
+        std::string normalization_s = conf->gS("Patches", "normalization", "n01");
+        this->setNormalization ( normalization_s );
 
-	if (normalization_s == "n01")
-		normalization = NORMALIZE_N01;
-	else if (normalization_s == "stddev")
-		normalization = NORMALIZE_STDDEV;
-	else if (normalization_s == "mean")
-		normalization = NORMALIZE_MEAN;
-	else if (normalization_s == "none")
-		normalization = NORMALIZE_NONE;
-	else
-	{
-		fprintf(stderr, "LFPatches::LFPatches: unknown normalization method\n");
-		exit(-1);
-	}
 
 	srand(time(NULL));
 
@@ -79,8 +109,17 @@ LFPatches::LFPatches(const Config *conf, int _numPatches) :
 
 LFPatches::~LFPatches()
 {
+  if ( this->id != NULL )
+  {
+    delete this->id;
+    this->id = NULL;
+  }
 }
 
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 int LFPatches::getDescSize() const
 {
 	return xsize * ysize;
@@ -296,3 +335,27 @@ void LFPatches::visualize(NICE::Image & img, const NICE::Vector & feature) const
 		}
 }
 
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LFPatches::restore ( std::istream & is, int format )
+{ 
+  fthrow ( Exception, "LFPatches::restore not implemented yet." );
+  //TODO  
+}
+
+void LFPatches::store ( std::ostream & os, int format ) const
+{ 
+  fthrow ( Exception, "LFPatches::store not implemented yet." );
+  //TODO  
+}
+
+void LFPatches::clear ()
+{ 
+  if ( this->id != NULL )
+  {
+    delete this->id;
+    this->id = NULL;
+  }
+}

+ 67 - 24
features/localfeatures/LFPatches.h

@@ -24,7 +24,7 @@ namespace OBJREC
 class LFPatches: public LocalFeatureRepresentation
 {
 
-protected:
+  protected:
 	enum
 	{
 		NORMALIZE_N01 = 0, NORMALIZE_NONE, NORMALIZE_STDDEV, NORMALIZE_MEAN
@@ -33,7 +33,7 @@ protected:
 	int xsize;
 	int ysize;
 	int normalization;
-	std::auto_ptr<InterestDetector> id;
+	InterestDetector * id;
 	int maxLevels;
 	double scaleSpacing;
 	int detectormode;
@@ -42,29 +42,72 @@ protected:
 
 	void calcDescriptors(const ImagePyramid & imp, NICE::VVector & positions,
 			NICE::VVector & features) const;
-
-public:
-
-	/** simple constructor */
-	LFPatches(const NICE::Config *conf, int numPatches);
-
-	/** simple destructor */
-	virtual ~LFPatches();
-
-	int getDescSize() const;
-
-	int extractFeatures(const NICE::Image & img, NICE::VVector & features,
-			NICE::VVector & positions) const;
-	void correctPositions(const ImagePyramid & imp, NICE::VVector & positions,
-			NICE::VVector & positions_corrected) const;
-
-	void visualize(NICE::Image & img, const NICE::Vector & feature) const;
-
-	void visualizeFeatures(NICE::Image & mark, const NICE::VVector & positions,
-			size_t color) const;
+                        
+        void setDetector ( const int & _detectormode, const NICE::Config * conf);
+        void setNormalization( const std::string & _normalization_s) ;
+
+  public:
+  
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////
+    
+    /** 
+     * @brief default constructor
+     * @date 10-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LFPatches();    
+
+    /** simple constructor */
+    LFPatches(const NICE::Config *conf, int numPatches);
+
+    /** simple destructor */
+    virtual ~LFPatches();
+      
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////        
+
+    int getDescSize() const;
+
+    int extractFeatures(const NICE::Image & img, NICE::VVector & features,
+                    NICE::VVector & positions) const;
+    void correctPositions(const ImagePyramid & imp, NICE::VVector & positions,
+                    NICE::VVector & positions_corrected) const;
+
+    void visualize(NICE::Image & img, const NICE::Vector & feature) const;
+
+    void visualizeFeatures(NICE::Image & mark, const NICE::VVector & positions,
+                    size_t color) const;
 //DIRTY for bofCreationSingleImage
-	int calcDescriptor(const ImagePyramid & imp, const NICE::Vector & position,
-				NICE::Vector & desc) const;
+    int calcDescriptor(const ImagePyramid & imp, const NICE::Vector & position,
+                            NICE::Vector & desc) const;
+        
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();          
 
 };
 

+ 216 - 25
features/localfeatures/LFReadCache.cpp

@@ -1,56 +1,120 @@
 /**
 * @file LFReadCache.cpp
 * @brief read local features from file
-* @author Erik Rodner
+* @author Erik Rodner, Alexander Freytag
 * @date 02/14/2008
-
 */
+
+// STL includes
 #include <iostream>
 #include <fstream>
 
-#include "vislearning/baselib/Globals.h"
-#include "core/basics/StringTools.h"
-#include "core/basics/FileMgt.h"
+// nice-core includes
+#include <core/basics/StringTools.h>
+#include <core/basics/FileMgt.h>
 
+// nice-vislearning includes
+#include <vislearning/baselib/Globals.h>
+// 
+#include "vislearning/features/localfeatures/GenericLFSelection.h"
 #include "vislearning/features/localfeatures/LFReadCache.h"
 
 using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
-LFReadCache::LFReadCache ( const Config *conf,
-                           const LocalFeatureRepresentation *_lfrep,
+///////////////////// ///////////////////// /////////////////////
+//                   PROTECTED METHODS
+///////////////////// ///////////////////// ////////////////
+
+void LFReadCache::setDescFormat ( const std::string & _descFormat_s )
+{
+  if ( _descFormat_s == "binary_double" )
+    this->descFormat = VVector::FILEFORMAT_BINARY_DOUBLE;
+  else if ( _descFormat_s == "binary_uchar" )
+    this->descFormat = VVector::FILEFORMAT_BINARY_CHAR;
+  else if ( _descFormat_s == "text_line" )
+    this->descFormat = VVector::FILEFORMAT_LINE;
+  else if ( ( _descFormat_s == "text_nice" ) || ( _descFormat_s == "text_ice" ) )
+    this->descFormat = VVector::FILEFORMAT_NICE;
+  else
+    fthrow ( Exception, "Format " << _descFormat_s << " is unknown." );  
+}
+
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////
+
+LFReadCache::LFReadCache ()
+{
+  this->numFeatures        = -1;
+  this->cachedir           = "";
+  this->cachemode          = Globals::getCacheMode ( "cat" );
+  std::string descFormat_s = "binary_double";
+  this->setDescFormat ( descFormat_s );
+}
+
+LFReadCache::LFReadCache ( const Config *_conf,
+                           const std::string & _confSection
+                         )
+{
+  this->initFromConfig( _conf, _confSection );  
+}
+
+LFReadCache::LFReadCache ( const Config *_conf,
+                           LocalFeatureRepresentation *_lfrep,
                            int _numFeatures,
-                           const std::string & _section ) : lfrep ( _lfrep )
+                           const std::string & _confSection ) : lfrep ( _lfrep )
 {
   //srand(time(NULL));
-  numFeatures = _numFeatures;
-  cachedir = conf->gS ( _section, "root" );
-  cachemode = Globals::getCacheMode ( conf->gS ( _section, "mode", "cat" ) );
-
-  std::string descFormat_s = conf->gS ( _section, "descriptor_format", "binary_double" );
-  if ( descFormat_s == "binary_double" )
-    descFormat = VVector::FILEFORMAT_BINARY_DOUBLE;
-  else if ( descFormat_s == "binary_uchar" )
-    descFormat = VVector::FILEFORMAT_BINARY_CHAR;
-  else if ( descFormat_s == "text_line" )
-    descFormat = VVector::FILEFORMAT_LINE;
-  else if ( ( descFormat_s == "text_nice" ) || ( descFormat_s == "text_ice" ) )
-    descFormat = VVector::FILEFORMAT_NICE;
-  else
-    fthrow ( Exception, "Format " << descFormat_s << " is unknown." );
+  this->numFeatures = _numFeatures;
+  this->cachedir = _conf->gS ( _confSection, "root" );
+  this->cachemode = Globals::getCacheMode ( _conf->gS ( _confSection, "mode", "cat" ) );
+
+  std::string descFormat_s = _conf->gS ( _confSection, "descriptor_format", "binary_double" );
+  this->setDescFormat ( descFormat_s );
 }
 
 LFReadCache::~LFReadCache()
 {
+  if ( this->lfrep != NULL )
+  {
+    delete this->lfrep;
+    this->lfrep = NULL;
+  }
+}
+
+void LFReadCache::initFromConfig(const NICE::Config* _conf, const std::string& _confSection)
+{
+  //srand(time(NULL));
+  this->numFeatures = _conf->gI ( _confSection, "numFeatures", -1 );
+  this->cachedir = _conf->gS ( _confSection, "root" );
+  this->cachemode = Globals::getCacheMode ( _conf->gS ( _confSection, "mode", "cat" ) );
+
+  std::string descFormat_s = _conf->gS ( _confSection, "descriptor_format", "binary_double" );
+  this->setDescFormat ( descFormat_s );
+  
+  if ( this->lfrep != NULL )
+  {
+    delete this->lfrep;
+    this->lfrep = NULL;
+  }  
+  this->lfrep = GenericLFSelection::selectLocalFeatureRep (  _conf, _confSection );  
 }
 
+
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// /////////////////
+
 int LFReadCache::getDescSize () const
 {
-  if ( lfrep == NULL ) {
+  if ( this->lfrep == NULL )
+  {
     fthrow ( Exception, "Unable to get descriptor size! (cache mode)" );
     return -1;
-  } else {
+  }
+  else {
     return lfrep->getDescSize();
   }
 }
@@ -83,3 +147,130 @@ void LFReadCache::visualizeFeatures ( NICE::Image & mark,
   lfrep->visualizeFeatures ( mark, positions, color );
 }
 
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LFReadCache::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "LFReadCache" ) )
+    {
+      std::cerr << " WARNING - attempt to restore LFReadCache, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "LFReadCache" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );   
+
+      
+      if ( tmp.compare("numFeatures") == 0 )
+      {
+        is >> this->numFeatures;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("lfrep") == 0 )
+      {
+        //TODO generic restore function        
+        this->lfrep->restore ( is );
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }       
+      else if ( tmp.compare("cachedir") == 0 )
+      {
+        is >> this->cachedir;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("descFormat") == 0 )
+      {
+        is >> this->descFormat;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("cachemode") == 0 )
+      {
+        is >> this->cachemode;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }   
+      else
+      {
+      std::cerr << "WARNING -- unexpected LFReadCache object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "LFReadCache::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void LFReadCache::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "LFReadCache" ) << std::endl; 
+    
+    os << this->createStartTag( "numFeatures" ) << std::endl;
+    os << this->numFeatures << std::endl;
+    os << this->createEndTag( "numFeatures" ) << std::endl;
+    
+    os << this->createStartTag( "lfrep" ) << std::endl;
+    this->lfrep->store ( os );
+    os << this->createEndTag( "lfrep" ) << std::endl;     
+
+    os << this->createStartTag( "cachedir" ) << std::endl;
+    os << this->cachedir << std::endl;
+    os << this->createEndTag( "cachedir" ) << std::endl;
+    
+    os << this->createStartTag( "descFormat" ) << std::endl;
+    os << this->descFormat << std::endl;
+    os << this->createEndTag( "descFormat" ) << std::endl;
+    
+    os << this->createStartTag( "cachemode" ) << std::endl;
+    os << this->cachemode << std::endl;
+    os << this->createEndTag( "cachemode" ) << std::endl;
+    
+    // done
+    os << this->createEndTag( "LFReadCache" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void LFReadCache::clear ()
+{
+  if ( this->lfrep != NULL )
+  {
+    delete this->lfrep;
+    this->lfrep = NULL;
+  }  
+}
+

+ 89 - 25
features/localfeatures/LFReadCache.h

@@ -19,27 +19,55 @@
 
 namespace OBJREC {
 
-  /** @class LFReadCache
-  * @brief Read local features from file
-  *
-  */   
-  class LFReadCache : public LocalFeatureRepresentation
-  {
-
-      protected:
-      int   numFeatures;
-      const LocalFeatureRepresentation *lfrep;
-      std::string cachedir;
-
-      int descFormat;
-      int cachemode;
-
-      template <class ImageClass>
-      int extractFeaturesTemplate ( const ImageClass & img, 
-            NICE::VVector & features, 
-            NICE::VVector & positions) const;
-
-      public:
+/** @class LFReadCache
+* @brief Read local features from file
+*
+*/   
+class LFReadCache : public LocalFeatureRepresentation
+{
+
+  protected:
+    
+    int   numFeatures;
+    
+    LocalFeatureRepresentation *lfrep;
+    
+    std::string cachedir;
+
+    int descFormat;
+    
+    int cachemode;
+
+    template <class ImageClass>
+    int extractFeaturesTemplate ( const ImageClass & img, 
+          NICE::VVector & features, 
+          NICE::VVector & positions) const;
+          
+    void setDescFormat ( const std::string & _descFormat_s );
+
+  public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////    
+    
+    /** 
+     * @brief default constructor
+     * @date 10-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LFReadCache ( );
+    
+    /** 
+     * @brief standard constructor 
+     * @date 10-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     * @param conf Configuration
+     * @param _section specify the block in the config object we read 
+     */
+    LFReadCache( const NICE::Config * _conf, 
+          const std::string & _confSection = "LFReadCache" /*NOTE previous default: "cache"*/          
+              );    
     
     /** standard constructor 
     * @param conf Configuration
@@ -47,14 +75,25 @@ namespace OBJREC {
     * @param _numfeatures how many features should be returned (-1 for all)
     * @param _section specify the block in the config object we read 
     */
-    LFReadCache( const NICE::Config *conf, 
-          const LocalFeatureRepresentation *lfrep,
+    LFReadCache( const NICE::Config * _conf, 
+          LocalFeatureRepresentation *lfrep,
           int _numFeatures = -1,
-          const std::string & _section = "cache"          
-               );
+          const std::string & _confSection = "LFReadCache" /*NOTE previous default: "cache"*/          
+              ); 
         
     /** simple destructor */
     virtual ~LFReadCache();
+        
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LFReadCache"); 
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////    
 
     int getDescSize () const;
 
@@ -86,6 +125,31 @@ namespace OBJREC {
     void visualizeFeatures ( NICE::Image & mark,
           const NICE::VVector & positions,
           size_t color ) const;
+          
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();           
   };
 
 } // namespace

+ 242 - 27
features/localfeatures/LFSiftPP.cpp

@@ -1,70 +1,101 @@
 /** 
 * @file LFSiftPP.cpp
 * @brief Sift++ interface
-* @author Erik Rodner
+* @author Erik Rodner, Alexander Freytag
 * @date 11/19/2007
-
 */
+
+// STL includes
 #include <iostream>
 #include <sstream>
 
+// nice-core includes
+#include <core/basics/Exception.h>
+
 // #ifdef NICE_USELIB_ICE
 //   #include <image_nonvis.h>
 // #endif
+
+// nice-vislearning includes
 #include "vislearning/features/localfeatures/LFSiftPP.h"
 
-#include "core/basics/Exception.h"
+//TODO move this to separate input or source folder
+#include "vislearning/features/localfeatures/sift.h"
 
 
 using namespace std;
-
 using namespace NICE;
+using namespace OBJREC;
 
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////
 
+LFSiftPP::LFSiftPP() : LocalFeatureRepresentation () 
+{
+    this->threshold        = 0.0;
+    this->edgeThreshold    = 10.0;
+    this->octaves          = 6;
+    this->first_octave     = -1;
+    this->levels           = 3;
+    
+    this->minScale         = 1;
+    this->maxScale         = 4;
+    this->numScales        = 10;
+    this->numAngles        = 6;
+    
+    this->descriptorAlignment = DALGIN_DETECTOR;
+    this->normalizeFeature = false;
+}
 
-#include "vislearning/features/localfeatures/sift.h"
-
-using namespace OBJREC;
+LFSiftPP::LFSiftPP( const Config * _conf )
+{
+  this->initFromConfig( _conf );
+}
 
+LFSiftPP::~LFSiftPP()
+{
+}
 
-LFSiftPP::LFSiftPP( const Config *conf )
+void LFSiftPP::initFromConfig(const NICE::Config * _conf, const std::string & _confSection)
 {
-    threshold      = conf->gD("LFSiftPP", "threshold", 0.0);
-    edgeThreshold  = conf->gD("LFSiftPP", "edge_threshold", 10.0);
-    octaves        = conf->gI("LFSiftPP", "octaves", 6);
-    first_octave   = conf->gI("LFSiftPP", "first_octave", -1);
-    levels         = conf->gI("LFSiftPP", "levels", 3);
+    this->threshold      = _conf->gD(_confSection, "threshold", 0.0);
+    this->edgeThreshold  = _conf->gD(_confSection, "edge_threshold", 10.0);
+    this->octaves        = _conf->gI(_confSection, "octaves", 6);
+    this->first_octave   = _conf->gI(_confSection, "first_octave", -1);
+    this->levels         = _conf->gI(_confSection, "levels", 3);
     
-    minScale       = conf->gD("LFSiftPP", "min_scale", 1);
-    maxScale       = conf->gD("LFSiftPP", "max_scale", 4);
-    numScales      = conf->gI("LFSiftPP", "num_scales", 10);
-    numAngles      = conf->gI("LFSiftPP", "num_angles", 6 );
+    this->minScale       = _conf->gD(_confSection, "min_scale", 1);
+    this->maxScale       = _conf->gD(_confSection, "max_scale", 4);
+    this->numScales      = _conf->gI(_confSection, "num_scales", 10);
+    this->numAngles      = _conf->gI(_confSection, "num_angles", 6 );
 
-    std::string descriptorAlignment_s = conf->gS("LFSiftPP", "descriptor_alignment", "detector" );
+    std::string descriptorAlignment_s = _conf->gS(_confSection, "descriptor_alignment", "detector" );
 
     if ( descriptorAlignment_s == "detector" )
-		descriptorAlignment = DALGIN_DETECTOR;
+                this->descriptorAlignment = DALGIN_DETECTOR;
     else if ( descriptorAlignment_s == "multiple" )
-		descriptorAlignment = DALIGN_MULTIPLE;
+                this->descriptorAlignment = DALIGN_MULTIPLE;
     else {
-		fprintf (stderr, "LFSiftPP: descriptor alignment method unknown !\n");
-		exit(-1);
+                fprintf (stderr, "LFSiftPP: descriptor alignment method unknown !\n");
+                exit(-1);
     }
 
-    normalizeFeature = conf->gB("LFSiftPP", "normalize_feature", false );
+    this->normalizeFeature = _conf->gB(_confSection, "normalize_feature", false );
 
+    //TODO check whether this os is still needed here.
     std::ostringstream os;
     os << "siftpp_" << "l" << levels << "_o" 
        << octaves << "_m" << minScale << "_t" 
        << threshold << "_e" << edgeThreshold;
 
     if ( ! normalizeFeature )
-		os << "_nd";
+                os << "_nd";  
 }
 
-LFSiftPP::~LFSiftPP()
-{
-}
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// /////////////////
 
 int LFSiftPP::getDescSize () const
 {
@@ -245,3 +276,187 @@ void LFSiftPP::visualizeFeatures ( NICE::Image & mark,
 }
 
 
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LFSiftPP::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "LFSiftPP" ) )
+    {
+      std::cerr << " WARNING - attempt to restore LFSiftPP, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "LFSiftPP" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );   
+
+      
+      if ( tmp.compare("threshold") == 0 )
+      {
+        is >> this->threshold;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("edgeThreshold") == 0 )
+      {
+        is >> this->edgeThreshold;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("octaves") == 0 )
+      {
+        is >> this->octaves;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("first_octave") == 0 )
+      {
+        is >> this->first_octave;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      } 
+      else if ( tmp.compare("levels") == 0 )
+      {
+        is >> this->levels;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("minScale") == 0 )
+      {
+        is >> this->minScale;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("maxScale") == 0 )
+      {
+        is >> this->maxScale;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("numScales") == 0 )
+      {
+        is >> this->numScales;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("numAngles") == 0 )
+      {
+        is >> this->numAngles;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("descriptorAlignment") == 0 )
+      {
+        unsigned int ui_descriptorAlignment;        
+        is >> ui_descriptorAlignment;        
+        this->descriptorAlignment = static_cast<DESCRIPTORALIGNMENT> ( ui_descriptorAlignment ) ;
+        
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      } 
+      else if ( tmp.compare("normalizeFeature") == 0 )
+      {
+        is >> this->normalizeFeature;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }       
+      else
+      {
+      std::cerr << "WARNING -- unexpected LFSiftPP object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "LFSiftPP::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void LFSiftPP::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "LFSiftPP" ) << std::endl; 
+    
+    os << this->createStartTag( "threshold" ) << std::endl;
+    os << this->threshold << std::endl;
+    os << this->createEndTag( "threshold" ) << std::endl;  
+
+    os << this->createStartTag( "edgeThreshold" ) << std::endl;
+    os << this->edgeThreshold << std::endl;
+    os << this->createEndTag( "edgeThreshold" ) << std::endl;
+    
+    os << this->createStartTag( "octaves" ) << std::endl;
+    os << this->octaves << std::endl;
+    os << this->createEndTag( "octaves" ) << std::endl;  
+
+    os << this->createStartTag( "first_octave" ) << std::endl;
+    os << this->first_octave << std::endl;
+    os << this->createEndTag( "first_octave" ) << std::endl; 
+    
+    os << this->createStartTag( "levels" ) << std::endl;
+    os << this->levels << std::endl;
+    os << this->createEndTag( "levels" ) << std::endl;    
+    
+    os << this->createStartTag( "minScale" ) << std::endl;
+    os << this->minScale << std::endl;
+    os << this->createEndTag( "minScale" ) << std::endl;  
+
+    os << this->createStartTag( "maxScale" ) << std::endl;
+    os << this->maxScale << std::endl;
+    os << this->createEndTag( "maxScale" ) << std::endl;
+    
+    os << this->createStartTag( "numScales" ) << std::endl;
+    os << this->numScales << std::endl;
+    os << this->createEndTag( "numScales" ) << std::endl;  
+
+    os << this->createStartTag( "numAngles" ) << std::endl;
+    os << this->numAngles << std::endl;
+    os << this->createEndTag( "numAngles" ) << std::endl; 
+    
+    os << this->createStartTag( "descriptorAlignment" ) << std::endl;
+    os << this->descriptorAlignment << std::endl;
+    os << this->createEndTag( "descriptorAlignment" ) << std::endl;
+    
+    os << this->createStartTag( "normalizeFeature" ) << std::endl;
+    os << this->normalizeFeature << std::endl;
+    os << this->createEndTag( "normalizeFeature" ) << std::endl; 
+    
+    
+    // done
+    os << this->createEndTag( "LFSiftPP" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void LFSiftPP::clear ()
+{
+}

+ 111 - 40
features/localfeatures/LFSiftPP.h

@@ -1,20 +1,24 @@
 /** 
 * @file LFSiftPP.h
 * @brief Sift++ interface (with detector!)
-* @author Erik Rodner
+* @author Erik Rodner, Alexander Freytag
 * @date 11/19/2007
 
 */
 #ifndef LFSIFTPPINCLUDE
 #define LFSIFTPPINCLUDE
 
-#include "core/imagedisplay/ImageDisplay.h"
+// nice-core includes
+#include <core/basics/Config.h>
+//
+#include <core/image/ImageT.h>
+// 
+#include <core/imagedisplay/ImageDisplay.h>
+// 
+#include <core/vector/VectorT.h>
+#include <core/vector/MatrixT.h>
 
-#include "core/vector/VectorT.h"
-#include "core/vector/MatrixT.h"
-#include "core/image/ImageT.h"
-
-#include "core/basics/Config.h"
+// nice-vislearning includes
 #include "LocalFeatureRepresentation.h"
 
 
@@ -24,42 +28,109 @@ namespace OBJREC {
 class LFSiftPP : public LocalFeatureRepresentation
 {
 
-    protected:
-	enum {
-	    DALGIN_DETECTOR = 0,
-	    DALIGN_MULTIPLE
-	};
-
-	int descriptorAlignment;
-	double minScale;
-	double maxScale;
-	int numScales;
-	int numAngles;
-
-	float threshold;
-	float edgeThreshold;
-	int levels;
-	int octaves;
-	int first_octave;
-	bool normalizeFeature;
-
-    public:
+  protected:
+      
+    /////////////////////////
+    /////////////////////////
+    // PROTECTED VARIABLES //
+    /////////////////////////
+    /////////////////////////         
+      enum DESCRIPTORALIGNMENT{
+          DALGIN_DETECTOR = 0,
+          DALIGN_MULTIPLE
+      };
+
+      DESCRIPTORALIGNMENT descriptorAlignment;
+      
+      double minScale;
+      
+      double maxScale;
+      
+      int numScales;
+      
+      int numAngles;
+
+      
+      float threshold;
+      
+      float edgeThreshold;
+      
+      int levels;
+      
+      int octaves;
+      
+      int first_octave;
+      
+      bool normalizeFeature;
+
+  public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////
+    
+    /** 
+     * @brief default constructor
+     * @date 10-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LFSiftPP ( );     
+
+    /** 
+     * @brief simple constructor 
+     */
+    LFSiftPP( const NICE::Config *conf );
   
-	/** simple constructor */
-	LFSiftPP( const NICE::Config *conf );
+    /** 
+     * @brief simple destructor 
+     */
+    virtual ~LFSiftPP();
+      
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LFSiftPP");       
       
-	/** simple destructor */
-	virtual ~LFSiftPP();
-	
-	int getDescSize () const;
-
-	int extractFeatures ( const NICE::Image & img, NICE::VVector & features, 
-			      NICE::VVector & positions ) const;
- 
-	void visualizeFeatures ( NICE::Image & mark,
-				 const NICE::VVector & positions,
-				 size_t color ) const;
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////       
+      
+    int getDescSize () const;
+
+    int extractFeatures ( const NICE::Image & img, NICE::VVector & features, 
+                          NICE::VVector & positions ) const;
+
+    void visualizeFeatures ( NICE::Image & mark,
+                              const NICE::VVector & positions,
+                              size_t color ) const;
+                                
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
     
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();                                 
+  
 };
 
 

+ 193 - 19
features/localfeatures/LFWriteCache.cpp

@@ -1,24 +1,29 @@
 /**
 * @file LFWriteCache.cpp
 * @brief read local features from file
-* @author Erik Rodner
+* @author Erik Rodner, Alexander Freytag
 * @date 02/14/2008
-
 */
 
 #include "core/vector/VectorT.h"
 #include "core/vector/MatrixT.h"
 #include "core/image/ImageT.h"
 
+// STL includes
 #include <iostream>
 #include <fstream>
-
+// 
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include "vislearning/baselib/Globals.h"
-#include "core/basics/StringTools.h"
+// nice-core includes
+#include <core/basics/StringTools.h>
+
+// nice-vislearning includes
+#include <vislearning/baselib/Globals.h>
 
+// 
+#include "vislearning/features/localfeatures/GenericLFSelection.h"
 #include "vislearning/features/localfeatures/LFWriteCache.h"
 
 using namespace OBJREC;
@@ -26,31 +31,84 @@ using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
+///////////////////// ///////////////////// /////////////////////
+//                   PROTECTED METHODS
+///////////////////// ///////////////////// ////////////////
 
+void LFWriteCache::setDescFormat ( const std::string & _descFormat_s )
+{
+  if ( _descFormat_s == "binary_double" )
+    this->descFormat = VVector::FILEFORMAT_BINARY_DOUBLE;
+  else if ( _descFormat_s == "binary_uchar" )
+    this->descFormat = VVector::FILEFORMAT_BINARY_CHAR;
+  else if ( _descFormat_s == "text_line" )
+    this->descFormat = VVector::FILEFORMAT_LINE;
+  else if ( ( _descFormat_s == "text_nice" ) || ( _descFormat_s == "text_ice" ) )
+    this->descFormat = VVector::FILEFORMAT_NICE;
+  else
+    fthrow ( Exception, "Format " << _descFormat_s << " is unknown." );  
+}
+
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////
+
+LFWriteCache::LFWriteCache ()
+{
+  this->cachedir           = "";
+  this->cachemode          = Globals::getCacheMode ( "cat" );
+  std::string descFormat_s = "binary_double";
+  this->setDescFormat ( descFormat_s );
+}
+
+LFWriteCache::LFWriteCache ( const Config *_conf,
+                             const std::string & _confSection
+                           )
+{
+  this->initFromConfig( _conf, _confSection );  
+}
 
 LFWriteCache::LFWriteCache ( const Config *conf,
-                             const LocalFeatureRepresentation *_lfrep,
+                             LocalFeatureRepresentation *_lfrep,
                              const std::string & _section ) : lfrep ( _lfrep )
 {
-  cachedir = conf->gS ( _section, "root" );
-  cachemode = Globals::getCacheMode ( conf->gS ( _section, "mode", "cat" ) );
+  this->cachedir = conf->gS ( _section, "root" );
+  this->cachemode = Globals::getCacheMode ( conf->gS ( _section, "mode", "cat" ) );
 
   std::string descFormat_s = conf->gS ( _section, "descriptor_format", "binary_double" );
-  if ( descFormat_s == "binary_double" )
-    descFormat = VVector::FILEFORMAT_BINARY_DOUBLE;
-  else if ( descFormat_s == "binary_uchar" )
-    descFormat = VVector::FILEFORMAT_BINARY_CHAR;
-  else if ( descFormat_s == "text_line" )
-    descFormat = VVector::FILEFORMAT_LINE;
-  else if ( descFormat_s == "text_ice" )
-    descFormat = VVector::FILEFORMAT_NICE;
-
+  this->setDescFormat ( descFormat_s );
 }
 
 LFWriteCache::~LFWriteCache()
 {
+  if ( this->lfrep != NULL )
+  {
+    delete this->lfrep;
+    this->lfrep = NULL;
+  }  
+}
+
+void LFWriteCache::initFromConfig(const NICE::Config* _conf, const std::string& _confSection)
+{
+  //srand(time(NULL));
+  this->cachedir = _conf->gS ( _confSection, "root" );
+  this->cachemode = Globals::getCacheMode ( _conf->gS ( _confSection, "mode", "cat" ) );
+
+  std::string descFormat_s = _conf->gS ( _confSection, "descriptor_format", "binary_double" );
+  this->setDescFormat ( descFormat_s );
+  
+  if ( this->lfrep != NULL )
+  {
+    delete this->lfrep;
+    this->lfrep = NULL;
+  }  
+  this->lfrep = GenericLFSelection::selectLocalFeatureRep (  _conf, _confSection );  
 }
 
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// /////////////////
+
 int LFWriteCache::getDescSize () const
 {
   return lfrep->getDescSize();
@@ -116,13 +174,129 @@ int LFWriteCache::extractFeatures ( const NICE::ColorImage & img,
 void LFWriteCache::visualize ( NICE::Image & img,
                                const NICE::Vector & feature ) const
 {
-  lfrep->visualize ( img, feature );
+  this->lfrep->visualize ( img, feature );
 }
 
 void LFWriteCache::visualizeFeatures ( NICE::Image & mark,
                                        const VVector & positions,
                                        size_t color ) const
 {
-  lfrep->visualizeFeatures ( mark, positions, color );
+  this->lfrep->visualizeFeatures ( mark, positions, color );
 }
 
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LFWriteCache::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "LFWriteCache" ) )
+    {
+      std::cerr << " WARNING - attempt to restore LFWriteCache, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "LFWriteCache" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );   
+
+      
+      if ( tmp.compare("lfrep") == 0 )
+      {
+        //TODO generic restore function        
+        this->lfrep->restore ( is );
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }       
+      else if ( tmp.compare("cachedir") == 0 )
+      {
+        is >> this->cachedir;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("descFormat") == 0 )
+      {
+        is >> this->descFormat;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("cachemode") == 0 )
+      {
+        is >> this->cachemode;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }   
+      else
+      {
+      std::cerr << "WARNING -- unexpected LFWriteCache object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "LFWriteCache::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void LFWriteCache::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "LFWriteCache" ) << std::endl; 
+    
+    os << this->createStartTag( "lfrep" ) << std::endl;
+    this->lfrep->store ( os );
+    os << this->createEndTag( "lfrep" ) << std::endl;     
+
+    os << this->createStartTag( "cachedir" ) << std::endl;
+    os << this->cachedir << std::endl;
+    os << this->createEndTag( "cachedir" ) << std::endl;
+    
+    os << this->createStartTag( "descFormat" ) << std::endl;
+    os << this->descFormat << std::endl;
+    os << this->createEndTag( "descFormat" ) << std::endl;
+    
+    os << this->createStartTag( "cachemode" ) << std::endl;
+    os << this->cachemode << std::endl;
+    os << this->createEndTag( "cachemode" ) << std::endl;
+    
+    // done
+    os << this->createEndTag( "LFWriteCache" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void LFWriteCache::clear ()
+{
+  if ( this->lfrep != NULL )
+  {
+    delete this->lfrep;
+    this->lfrep = NULL;
+  }  
+}

+ 114 - 52
features/localfeatures/LFWriteCache.h

@@ -18,64 +18,126 @@
 
 namespace OBJREC {
 
-  /** @class LFWriteCache
-  * @brief Write local features to file (whenever a descriptor is computed, it will be checked whether a corresponding file already exists. If not, we save the descriptor)
-  *
-  */  
-  class LFWriteCache : public LocalFeatureRepresentation
-  {
+/** @class LFWriteCache
+* @brief Write local features to file (whenever a descriptor is computed, it will be checked whether a corresponding file already exists. If not, we save the descriptor)
+*
+*/  
+class LFWriteCache : public LocalFeatureRepresentation
+{
 
-      protected:
-        const LocalFeatureRepresentation *lfrep;
+  protected:
+    
+    LocalFeatureRepresentation *lfrep;
 
-        std::string cachedir;
+    std::string cachedir;
 
-        int descFormat;
-        int cachemode;
+    int descFormat;
+    
+    int cachemode;
+    
+    void setDescFormat ( const std::string & _descFormat_s );    
 
 
-      public:
+  public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////
+    
+    /**     
+     * @brief default constructor
+     * @date 10-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LFWriteCache ( );
+    
+    /** 
+     * @brief standard constructor 
+     * @date 10-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     * @param conf Configuration
+     * @param _section specify the block in the config object we read 
+     */
+    LFWriteCache( const NICE::Config * _conf, 
+          const std::string & _confSection = "LFWriteCache" /*NOTE previous default: "cache"*/          
+              );       
+  
+    /** simple constructor */
+    LFWriteCache( const NICE::Config *conf, 
+        LocalFeatureRepresentation *lfrep,
+        const std::string & _section = "cache"
+                ); 
+    
+    /** simple destructor */
+    virtual ~LFWriteCache();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LFWriteCache");     
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////       
+  
+    int getDescSize () const;
+  
+    /**
+    * extract features for gray images
+    * @param img input image
+    * @param features output features
+    * @param positions position of the features
+    * @return 
+    */
+    int extractFeatures ( const NICE::Image & img, 
+          NICE::VVector & features, 
+          NICE::VVector & positions ) const;
+    
+    /**
+    * extract features for color images
+    * @param img input image
+    * @param features output features
+    * @param positions position of the features
+    * @return 
+    */
+    int extractFeatures ( const NICE::ColorImage & img, 
+          NICE::VVector & features, 
+          NICE::VVector & positions ) const;
+  
+    void visualize ( NICE::Image & img, 
+      const NICE::Vector & feature ) const;
+  
+    void visualizeFeatures ( NICE::Image & mark,
+          const NICE::VVector & positions,
+          size_t color ) const;
+              
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
     
-        /** simple constructor */
-        LFWriteCache( const NICE::Config *conf, 
-            const LocalFeatureRepresentation *lfrep,
-            const std::string & _section = "cache"
-                    ); 
-        
-        /** simple destructor */
-        virtual ~LFWriteCache();
-      
-        int getDescSize () const;
-      
-        /**
-        * extract features for gray images
-        * @param img input image
-        * @param features output features
-        * @param positions position of the features
-        * @return 
-        */
-        int extractFeatures ( const NICE::Image & img, 
-              NICE::VVector & features, 
-              NICE::VVector & positions ) const;
-        
-        /**
-        * extract features for color images
-        * @param img input image
-        * @param features output features
-        * @param positions position of the features
-        * @return 
-        */
-        int extractFeatures ( const NICE::ColorImage & img, 
-              NICE::VVector & features, 
-              NICE::VVector & positions ) const;
-      
-        void visualize ( NICE::Image & img, 
-          const NICE::Vector & feature ) const;
-      
-        void visualizeFeatures ( NICE::Image & mark,
-              const NICE::VVector & positions,
-              size_t color ) const;
-  };
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();               
+};
 
 
 } // namespace

+ 195 - 29
features/localfeatures/LFonHSG.cpp

@@ -1,7 +1,7 @@
 /**
 * @file LFonHSG.cpp
 * @brief Implementation of the LocalFeatureHSG.h. See description there.
-* @author Eric Bach
+* @author Eric Bach, Alexander Freytag
 * @date 26.10.2011
 */
 
@@ -16,30 +16,20 @@ using namespace OBJREC;
 using namespace boost;
 #endif
 
-LFonHSG::LFonHSG (const Config *conf, const string section)
-{
-  /** initialization **/
-  this->lf = NULL;
-
-  /** get parameters for the grid **/
-  this->sampleScaling = conf->gI (section, "sample_scaling", 50);
-  this->scales = conf->gS (section, "scales"        , "1");
-  // the scales are seperated by '+', like in the Van de Sande implementation
-  char separator = '+';
-
-  /** get debuginformation **/
-  this->debug = conf->gB ("debug", "show_log_HSG", false);
-
-  /** generate the descriptor-instanz **/
-  lf = GenericLocalFeatureSelection::selectLocalFeature (conf, section);
+///////////////////// ///////////////////// /////////////////////
+//                   PROTECTED METHODS
+///////////////////// ///////////////////// /////////////////
 
-  /** parse scales string **/
+void LFonHSG::convertScalesStringToScaleList ( )
+{
   if ( this->debug )
   {
     clog << "[log] LocalFeatureHSG::LocalFeatureHSG" << std::endl;
     clog << "[log] try to parse the 'scales-string': " << this->scales << " -> ";
-  }
-
+  }  
+  
+  // the scales are seperated by '+', like in the Van de Sande implementation
+  char separator = '+';
 #ifdef NICE_USELIB_BOOST
   typedef tokenizer<boost::char_separator<char> > tokenizer;
   char_separator<char> sep (&separator);
@@ -49,7 +39,7 @@ LFonHSG::LFonHSG (const Config *conf, const string section)
     if ( this->debug )
       clog << *tok_iter << " ";
     
-    scalesV.push_back(StringTools::convert<float>(*tok_iter));
+    this->scalesV.push_back(StringTools::convert<float>(*tok_iter));
   }
 #else // standard
   std::vector<std::string> temp;
@@ -59,11 +49,35 @@ LFonHSG::LFonHSG (const Config *conf, const string section)
     if ( this->debug )
       clog << *it << " ";
     
-    scalesV.push_back(StringTools::convert<float>(*it));
+    this->scalesV.push_back(StringTools::convert<float>(*it));
   }
 #endif
   if ( this->debug )
+  {
     clog << std::endl;
+  }
+}
+
+
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////
+
+LFonHSG::LFonHSG () : LocalFeatureRepresentation ()
+{
+  this->debug = false;
+
+  this->sampleScaling = 50;
+  this->scales = "1";
+  /** parse scales string **/
+  this->convertScalesStringToScaleList();
+  
+  this->lf = NULL;  
+}
+
+LFonHSG::LFonHSG ( const NICE::Config * _conf, const std::string _confSection)
+{
+  this->initFromConfig( _conf, _confSection );
 }
 
 LFonHSG::~LFonHSG()
@@ -78,6 +92,26 @@ LFonHSG::~LFonHSG()
   }
 }
 
+void OBJREC::LFonHSG::initFromConfig(const NICE::Config * _conf, const std::string & _confSection)
+{
+  this->debug         = _conf->gB (_confSection, "debug",          false);
+
+  this->sampleScaling = _conf->gI (_confSection, "sample_scaling", 50);
+  this->scales        = _conf->gS (_confSection, "scales"        , "1");
+  
+  this->lf            = NULL;
+  this->lf            = OBJREC::GenericLocalFeatureSelection::selectLocalFeature (_conf, _confSection /*TODO check whether it is useful to hand over the confSection string here*/);
+
+  /** parse scales string **/
+  this->convertScalesStringToScaleList();
+}
+
+
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// /////////////////
+
+
 int LFonHSG::getDescSize() const
 {
   return lf->getDescSize();
@@ -146,15 +180,147 @@ void LFonHSG::visualizeFeatures (NICE::Image & mark, const VVector & positions,
 }
 
 
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
 
+void LFonHSG::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+        
+    if ( ! this->isStartTag( tmp, "LFonHSG" ) )
+    {
+      std::cerr << " WARNING - attempt to restore LFonHSG, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "LFonHSG" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );   
+      
+      if ( tmp.compare("debug") == 0 )
+      {
+        is >> this->debug;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("sampleScaling") == 0 )
+      {
+        is >> this->sampleScaling;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("scales") == 0 )
+      {
+        is >> this->scales;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("scalesV") == 0 )
+      {
+        is >> tmp; //size:
+        unsigned int ui_scalesVSize;
+        is >> ui_scalesVSize;
+        this->scalesV.clear();
+        //allocate enough memory
+        this->scalesV.resize( ui_scalesVSize );
+        
+        std::vector< float >::iterator itScalesV = this->scalesV.begin();
+        for ( uint tmpIdx = 0; tmpIdx < ui_scalesVSize; tmpIdx++, itScalesV++ )
+        {
+          is >> *itScalesV;
+        }
+
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      } 
+      else if ( tmp.compare("lf") == 0 )
+      {
+        OBJREC::GenericLocalFeatureSelection::restoreLocalFeature( this->lf, is );
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }    
+      else
+      {
+      std::cerr << "WARNING -- unexpected LFonHSG object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "LFonHSG::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
 
+void LFonHSG::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "LFonHSG" ) << std::endl; 
+    
+    os << this->createStartTag( "debug" ) << std::endl;
+    os << this->debug << std::endl;
+    os << this->createEndTag( "debug" ) << std::endl;  
 
+    os << this->createStartTag( "sampleScaling" ) << std::endl;
+    os << this->sampleScaling << std::endl;
+    os << this->createEndTag( "sampleScaling" ) << std::endl;
+    
+    os << this->createStartTag( "scalesV" ) << std::endl;
+    os << "size: " << this->scalesV.size() << std::endl;
+    for ( std::vector< float >::const_iterator itScalesV = this->scalesV.begin();
+          itScalesV != this->scalesV.end();
+          itScalesV++ 
+         )
+    {
+      os << *itScalesV << " ";
+    }            
+    os << std::endl;
+    os << this->createEndTag( "scalesV" ) << std::endl;  
 
+    os << this->createStartTag( "lf" ) << std::endl;
+    if ( this->lf != NULL )
+    {
+      //TODO this might be tricky if lf was not intantiated properly.      
+      this->lf->store ( os );
+    }
+    os << this->createEndTag( "lf" ) << std::endl; 
+    
+    // done
+    os << this->createEndTag( "LFonHSG" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
 
-
-
-
-
-
-
-
+void LFonHSG::clear ()
+{
+  if ( this->lf != NULL )
+  {
+    delete this->lf;
+    this->lf = NULL;
+  }  
+}

+ 56 - 5
features/localfeatures/LFonHSG.h

@@ -43,6 +43,10 @@ class LFonHSG : public LocalFeatureRepresentation
 {
     /* private member */
   private:
+    
+    //! if true, print some log-output
+    bool debug;
+    
     /* parameter for the grid */
     //! stepwidhts of the grid
     int sampleScaling;
@@ -51,9 +55,6 @@ class LFonHSG : public LocalFeatureRepresentation
     //! vector which save the different scales
     std::vector <float> scalesV;
 
-    //! if true, print some log-output
-    bool debug;
-
     //! the descriptor instance
     OBJREC::LocalFeature* lf;    
     
@@ -67,17 +68,42 @@ class LFonHSG : public LocalFeatureRepresentation
     void getPositionsOnHSG ( const unsigned int imageWidth,
                              const unsigned int imageHeight,
                              NICE::VVector& positions ) const;
+    
+    protected:
+    void convertScalesStringToScaleList ( );
 
 
     /* public member */
   public:
     
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////    
+    
+    /** 
+     * @brief default constructor
+     * @date 10-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LFonHSG ( );     
+    
     //! simple contructor
-    LFonHSG ( const NICE::Config *conf, const std::string section = "HSG" );
+    LFonHSG ( const NICE::Config * _conf, const std::string _confSection = "LFonHSG" /*NOTE previous default: "HSG"*/);
     
     //! simple desctructor
-    ~LFonHSG();
+    virtual ~LFonHSG();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LFonHSG");     
 
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////           
+    
     //! Returns the descriptorsize
     int getDescSize() const;
 
@@ -89,6 +115,31 @@ class LFonHSG : public LocalFeatureRepresentation
 
     //! Visualisierung
     void visualizeFeatures ( NICE::Image & mark, const NICE::VVector & positions, size_t color ) const;
+    
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 10-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();     
 };
 }
 #endif

+ 59 - 14
features/localfeatures/LocalFeature.h

@@ -8,31 +8,51 @@
 #ifndef LOCALFEATUREINCLUDE
 #define LOCALFEATUREINCLUDE
 
-#include "core/vector/VectorT.h"
-#include "core/vector/MatrixT.h"
-#include "core/image/ImageT.h"
-
-#include "core/vector/VVector.h"
+// nice-core includes
+#include <core/basics/Config.h>
+#include <core/basics/Persistent.h>
+// 
+#include <core/image/ImageT.h>
+// 
+#include <core/vector/MatrixT.h>
+#include <core/vector/VectorT.h>
+#include <core/vector/VVector.h>
   
 
 namespace OBJREC {
 
-    /** @class LocalFeature
-  * @brief Abstract class for Local Features ( ONLY DESCRIPTORS, NO DETECTORS )
-  *
-  */
-  class LocalFeature
-  {
+/** @class LocalFeature
+* @brief Abstract class for Local Features ( ONLY DESCRIPTORS, NO DETECTORS )
+*
+*/
+class LocalFeature : public NICE::Persistent
+{
 
-      protected:
+  protected:
 
-      public:
+  public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////      
     
     /** simple constructor */
     LocalFeature();
         
     /** simple destructor */
     virtual ~LocalFeature();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mm-yyyy )
+     */    
+    virtual void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LocalFeature") = 0;     
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////
+    
 
     virtual int getDescSize() const = 0;
 
@@ -43,8 +63,33 @@ namespace OBJREC {
     virtual void visualizeFeatures ( NICE::Image & mark,
           const NICE::VVector & positions,
           size_t color ) const;
+          
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+
+    /**
+    * @brief Load object from external file (stream)
+    * @author Alexander Freytag
+    * @date 09-02-2014 ( dd-mm-yyyy )
+    */
+    void restore ( std::istream & is, int format = 0 ) = 0;
+
+    /**
+    * @brief Save object to external file (stream)
+    * @author Alexander Freytag
+    * @date 09-02-2014 ( dd-mm-yyyy )
+    */
+    void store ( std::ostream & os, int format = 0 ) const = 0;
+
+    /**
+    * @brief Clear object
+    * @author Alexander Freytag
+    * @date 09-02-2014 ( dd-mm-yyyy )
+    */
+    void clear () = 0;           
       
-  };
+};
 
 
 } // namespace

+ 97 - 18
features/localfeatures/LocalFeatureCentrist.cpp

@@ -176,35 +176,34 @@ void LocalFeatureCentrist::computeDesc( const NICE::ColorImage & img, NICE::VVec
 
 /* public methods*/
 
-/**
- * @brief Default constructor
- * @author Alexander Freytag
- * @date 12/06/2011
- */
-LocalFeatureCentrist::LocalFeatureCentrist()
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+LocalFeatureCentrist::LocalFeatureCentrist() : LocalFeature () 
 {
   this->i_sizeNeighborhood = 16;
 }
 
-/**
- * @brief Recommended constructor
- * @author Alexander Freytag
- * @date 12/06/2011
- */
-LocalFeatureCentrist::LocalFeatureCentrist( const Config *conf, const std::string & section )
+
+LocalFeatureCentrist::LocalFeatureCentrist( const NICE::Config * _conf )
 {
-  this->i_sizeNeighborhood = conf->gI(section, "i_sizeNeighborhood", 16);
+  this->initFromConfig( _conf );
 }
 
-/**
- * @brief Default destructor
- * @author Alexander Freytag
- * @date 12/06/2011
- */
 LocalFeatureCentrist::~LocalFeatureCentrist()
 {
 }
 
+void OBJREC::LocalFeatureCentrist::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  this->i_sizeNeighborhood = _conf->gI(_confSection, "i_sizeNeighborhood", 16);
+}
+
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 int LocalFeatureCentrist::getDescSize() const
 {
   // we have 8 neighbors, so the size is always 256 with the given implementation (without spatial levels, ...)
@@ -245,3 +244,83 @@ void LocalFeatureCentrist::visualizeFeatures ( NICE::Image & mark,
   throw NICE::Exception ( "LocalFeatureCentrist::visualizeFeatures -- currently not implemented." );
 }
 
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LocalFeatureCentrist::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "LocalFeatureCentrist" ) )
+    {
+      std::cerr << " WARNING - attempt to restore LocalFeatureCentrist, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "LocalFeatureCentrist" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );    
+      
+      if ( tmp.compare("i_sizeNeighborhood") == 0 )
+      {
+        is >> this->i_sizeNeighborhood;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else
+      {
+      std::cerr << "WARNING -- unexpected LocalFeatureCentrist object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "LocalFeatureCentrist::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void LocalFeatureCentrist::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "LocalFeatureCentrist" ) << std::endl;    
+    
+    os << this->createStartTag( "i_sizeNeighborhood" ) << std::endl;
+    os << this->i_sizeNeighborhood << std::endl;
+    os << this->createEndTag( "i_sizeNeighborhood" ) << std::endl;     
+    
+    // done
+    os << this->createEndTag( "LocalFeatureCentrist" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void LocalFeatureCentrist::clear ()
+{
+}
+

+ 91 - 26
features/localfeatures/LocalFeatureCentrist.h

@@ -8,6 +8,7 @@
 #ifndef CENTRISTINCLUDE
 #define CENTRISTINCLUDE
 
+// nice-core includes
 #include <core/basics/Config.h>
 // 
 #include <core/image/ImageT.h>
@@ -27,38 +28,102 @@ namespace OBJREC {
 class LocalFeatureCentrist : public LocalFeature
 {
 
-    protected:
-      int i_sizeNeighborhood;
+  protected:
       
-      int CensusTransform(const NICE::Image & img, const int & x, const int & y) const;
-      int CensusTransform(const NICE::ColorImage & img, const int & x, const int & y, const int & channel) const;
+    /////////////////////////
+    /////////////////////////
+    // PROTECTED VARIABLES //
+    /////////////////////////
+    /////////////////////////  
       
-      void GenerateHistForOneRect(const NICE::Image & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature) const;
-      void GenerateHistForOneRect(const NICE::ColorImage & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature) const;
+    int i_sizeNeighborhood;
       
-      void computeDesc( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors ) const;
-      void computeDesc( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors )  const;
+    /////////////////////////
+    /////////////////////////
+    //  PROTECTED METHODS  //
+    /////////////////////////
+    /////////////////////////         
+      
+    int CensusTransform(const NICE::Image & img, const int & x, const int & y) const;
+    int CensusTransform(const NICE::ColorImage & img, const int & x, const int & y, const int & channel) const;
+    
+    void GenerateHistForOneRect(const NICE::Image & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature) const;
+    void GenerateHistForOneRect(const NICE::ColorImage & img, const int & xi, const int & xa, const int & yi, const int & ya, NICE::Vector & feature) const;
+    
+    void computeDesc( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors ) const;
+    void computeDesc( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors )  const;
 
-    public:
-  
-      /** simple constructor */
-      LocalFeatureCentrist();
-      /** default constructor */
-      LocalFeatureCentrist(const NICE::Config *conf, const std::string & section="CENTRIST");
-          
-      /** simple destructor */
-      virtual ~LocalFeatureCentrist();
+  public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////     
+    
+    /** 
+     * @brief default constructor
+     * @date 09-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LocalFeatureCentrist ( );    
+    
+    /**
+     * @brief recommended constructor, calls initFromConfig
+     * @date 09-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LocalFeatureCentrist ( const NICE::Config * _conf );
 
-      /** Beware: multiply this number by the number of channels you use in your color image*/
-      virtual int getDescSize() const;
+    /**
+     * @brief simple destructor
+     */
+    virtual ~LocalFeatureCentrist();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mm-yyyy )
+     */    
+    virtual void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "CENTRIST");    
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////       
 
-      virtual int getDescriptors ( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors) const;
-      
-      virtual int getDescriptors ( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors) const;
-      
-      virtual void visualizeFeatures ( NICE::Image & mark,
-            const NICE::VVector & positions,
-            size_t color ) const;
+    /** Beware: multiply this number by the number of channels you use in your color image*/
+    virtual int getDescSize() const;
+
+    virtual int getDescriptors ( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors) const;
+    
+    virtual int getDescriptors ( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors) const;
+    
+    virtual void visualizeFeatures ( NICE::Image & mark,
+          const NICE::VVector & positions,
+          size_t color ) const;
+          
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();            
     
 };
 

+ 9 - 2
features/localfeatures/LocalFeatureColorWeijer.cpp

@@ -32,7 +32,11 @@ const int colors[11][3] =
   {255, 255,   0}, // yellow
 };
 
-OBJREC::LocalFeatureColorWeijer::LocalFeatureColorWeijer()
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+OBJREC::LocalFeatureColorWeijer::LocalFeatureColorWeijer() : LocalFeature () 
 {
   this->tfile = "";
 }
@@ -70,6 +74,10 @@ void LocalFeatureColorWeijer::initFromConfig ( const NICE::Config * _conf, const
   this->restoreLUT();  
 }
 
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 int LocalFeatureColorWeijer::getDescSize() const
 {
   return LASTCOLOR;
@@ -367,5 +375,4 @@ void LocalFeatureColorWeijer::store ( std::ostream & os, int format ) const
 
 void LocalFeatureColorWeijer::clear ()
 {
- //TODO
 }

+ 10 - 3
features/localfeatures/LocalFeatureColorWeijer.h

@@ -9,7 +9,6 @@
 
 // nice-core includes
 #include <core/basics/Config.h>
-#include <core/basics/Persistent.h>
 // 
 #include <core/image/ImageT.h>
 #include <core/image/MultiChannelImageT.h>
@@ -26,7 +25,7 @@
 namespace OBJREC {
 
 /** interface to ColorSande implementation */
-class LocalFeatureColorWeijer : public LocalFeature, public NICE::Persistent //TODO move Persistent inheritence to LocalFeature
+class LocalFeatureColorWeijer : public LocalFeature
 {
 
   protected:
@@ -55,6 +54,10 @@ class LocalFeatureColorWeijer : public LocalFeature, public NICE::Persistent //T
     
   public:
 
+
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////   
     
     /** 
      * @brief default constructor 
@@ -80,8 +83,12 @@ class LocalFeatureColorWeijer : public LocalFeature, public NICE::Persistent //T
      * @author Alexander Freytag
      * @date 06-02-2014 ( dd-mm-yyyy )
      */    
-    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LocalFeatureColorWeijer");
+    virtual void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LocalFeatureColorWeijer");
 
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////    
+    
     /**
      * get the size of the descriptor
      * @return size of descriptor

+ 115 - 5
features/localfeatures/LocalFeatureLFInterface.cpp

@@ -1,23 +1,46 @@
 #include <iostream>
-
 #include <assert.h>
 
-#include "vislearning/features/localfeatures/LocalFeatureLFInterface.h"
+#include "LocalFeatureLFInterface.h"
 
 using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
-LocalFeatureLFInterface::LocalFeatureLFInterface( const Config *conf, LocalFeatureRepresentation *_lfpres )
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+LocalFeatureLFInterface::LocalFeatureLFInterface() : LocalFeature () 
 {
-  lfpres = _lfpres;
+  this->lfpres = NULL;
+}
+
+LocalFeatureLFInterface::LocalFeatureLFInterface( const NICE::Config * _conf, LocalFeatureRepresentation *_lfpres )
+{
+  this->initFromConfig( _conf );
+
+  //TODO check for null pointers? where will deletion be performed? what about restoring those objects?  
+  this->lfpres = _lfpres;
 }
 
 LocalFeatureLFInterface::~LocalFeatureLFInterface()
 {
-  delete lfpres;
+  if ( this->lfpres != NULL )
+    delete lfpres;
+  this->lfpres = NULL;
+}
+
+void LocalFeatureLFInterface::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  //nothing to do here
+  //NOTE how to handle lfrep object? - separate set method?
 }
 
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 
 int LocalFeatureLFInterface::getDescriptors ( const NICE::Image & img, VVector & positions, VVector & descriptors ) const
 {
@@ -43,3 +66,90 @@ void LocalFeatureLFInterface::visualizeFeatures ( NICE::Image & mark,
   lfpres->visualizeFeatures(mark, positions, color);
 }
 
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LocalFeatureLFInterface::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "LocalFeatureLFInterface" ) )
+    {
+      std::cerr << " WARNING - attempt to restore LocalFeatureLFInterface, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "LocalFeatureLFInterface" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );    
+      
+      ///////////////////////////////
+      //       PARENT OBJECT       //
+      ///////////////////////////////
+      if ( tmp.compare("lfpres") == 0 )
+      {
+        // restore parent object
+        //TODO this->lfpres->restore ( is );
+      }      
+      else
+      {
+      std::cerr << "WARNING -- unexpected LocalFeatureOpponnentSift object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "LocalFeatureOpponnentSift::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void LocalFeatureLFInterface::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "LocalFeatureLFInterface" ) << std::endl;    
+        
+    ///////////////////////////////
+    //       PARENT OBJECT       //
+    ///////////////////////////////
+    os << this->createStartTag( "lfpres" ) << std::endl;
+    //TODO this->lfpres->store(os);  
+    os << this->createStartTag( "lfpres" ) << std::endl;   
+    
+    // done
+    os << this->createEndTag( "LocalFeatureLFInterface" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void LocalFeatureLFInterface::clear ()
+{
+  if ( this->lfpres != NULL )
+    delete lfpres;
+  this->lfpres = NULL;  
+}

+ 75 - 18
features/localfeatures/LocalFeatureLFInterface.h

@@ -1,18 +1,22 @@
 /** 
 * @file LocalFeatureLFInterface.h
 * @brief Interface to use a LocalFeature (Descriptor only) with routines of LocalFeatureRepresentations (Detector + Descriptor)
-* @author Björn Fröhlich
+* @author Björn Fröhlich, Alexander Freytag
 * @date 09/07/2010
 
 */
 #ifndef LocalFeatureLFInterfaceINCLUDE
 #define LocalFeatureLFInterfaceINCLUDE
 
-#include "core/vector/VectorT.h"
-#include "core/vector/MatrixT.h"
-#include "core/image/ImageT.h"
+// nice-core includes
+#include <core/basics/Config.h>
+// 
+#include <core/image/ImageT.h>
+// 
+#include <core/vector/VectorT.h>
+#include <core/vector/MatrixT.h>
 
-#include "core/basics/Config.h"
+// nice-vislearning includes
 #include "LocalFeature.h"
 #include "LocalFeatureRepresentation.h"
 
@@ -20,25 +24,53 @@
 namespace OBJREC {
 
 
-  /** @class LocalFeatureLFInterface
-  * @brief Interface to use a LocalFeature (Descriptor only) with routines of LocalFeatureRepresentations (Detector + Descriptor)
-  *
-  */  
-  class LocalFeatureLFInterface : public LocalFeature
-  {
+/** @class LocalFeatureLFInterface
+* @brief Interface to use a LocalFeature (Descriptor only) with routines of LocalFeatureRepresentations (Detector + Descriptor)
+*
+*/  
+class LocalFeatureLFInterface : public LocalFeature
+{
 
-      protected:
-      LocalFeatureRepresentation *lfpres;
+    protected:
+    LocalFeatureRepresentation *lfpres;
+
+    public:
 
-      public:
-    
-    /** simple constructor */
-      LocalFeatureLFInterface ( const NICE::Config *conf, LocalFeatureRepresentation *_lfpres );
         
-    /** simple destructor */
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////   
+    
+    /** 
+     * @brief default constructor 
+     * @author Alexander Freytag
+     * @date 06-02-2014 ( dd-mm-yyyy )
+     */
+    LocalFeatureLFInterface ( );
+    
+    /** 
+     * @brief recommended constructor, calls initFromConfig
+     * @author Alexander Freytag
+     * @date 06-02-2014 ( dd-mm-yyyy )
+     */
+    LocalFeatureLFInterface ( const NICE::Config * _conf, LocalFeatureRepresentation *_lfpres );
 
+    /** 
+     * @brief simple destructor
+     */
     virtual ~LocalFeatureLFInterface();
     
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 06-02-2014 ( dd-mm-yyyy )
+     */    
+    virtual void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LocalFeatureLFInterface");
+
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////        
+    
     /**
     * @brief returns the size of each the SIFT-Feature
     */
@@ -63,6 +95,31 @@ namespace OBJREC {
     int getDescriptors ( const NICE::ColorImage & img, NICE::VVector & positions, NICE::VVector & descriptors) const;
               
     void visualizeFeatures ( NICE::Image & mark, const NICE::VVector & positions, size_t color ) const;
+    
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();     
 
       
   };

+ 107 - 1
features/localfeatures/LocalFeatureOpponnentSift.cpp

@@ -7,14 +7,33 @@ using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
-LocalFeatureOpponnentSift::LocalFeatureOpponnentSift ( const Config *conf ) : LocalFeatureRGBSift ( conf )
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+LocalFeatureOpponnentSift::LocalFeatureOpponnentSift() : LocalFeatureRGBSift () 
+{
+}
+
+LocalFeatureOpponnentSift::LocalFeatureOpponnentSift ( const NICE::Config * _conf )
 {
+  this->initFromConfig( _conf );  
 }
 
 LocalFeatureOpponnentSift::~LocalFeatureOpponnentSift()
 {
 }
 
+void LocalFeatureOpponnentSift::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  //first of all, call method of parent object
+  LocalFeatureRGBSift::initFromConfig( _conf );
+}
+
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 int LocalFeatureOpponnentSift::getDescriptors ( const NICE::ColorImage & cimg,
     VVector & positions,
     VVector & descriptors ) const
@@ -41,3 +60,90 @@ int LocalFeatureOpponnentSift::getDescriptors ( const NICE::ColorImage & cimg,
 
   return LocalFeatureRGBSift::getDescriptors ( opimg, positions, descriptors );
 }
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LocalFeatureOpponnentSift::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "LocalFeatureOpponnentSift" ) )
+    {
+      std::cerr << " WARNING - attempt to restore LocalFeatureOpponnentSift, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "LocalFeatureOpponnentSift" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );    
+      
+      ///////////////////////////////
+      //       PARENT OBJECT       //
+      ///////////////////////////////
+      if ( tmp.compare("LocalFeatureRGBSift--Parent") == 0 )
+      {
+        // restore parent object
+        LocalFeatureRGBSift::restore(is);
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );        
+      }      
+      else
+      {
+      std::cerr << "WARNING -- unexpected LocalFeatureOpponnentSift object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "LocalFeatureOpponnentSift::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void LocalFeatureOpponnentSift::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "LocalFeatureOpponnentSift" ) << std::endl;    
+        
+    ///////////////////////////////
+    //       PARENT OBJECT       //
+    ///////////////////////////////
+    os << this->createStartTag( "LocalFeatureRGBSift--Parent" ) << std::endl;
+    LocalFeatureRGBSift::store(os);  
+    os << this->createStartTag( "LocalFeatureRGBSift--Parent" ) << std::endl;   
+    
+    // done
+    os << this->createEndTag( "LocalFeatureOpponnentSift" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void LocalFeatureOpponnentSift::clear ()
+{
+}

+ 89 - 16
features/localfeatures/LocalFeatureOpponnentSift.h

@@ -1,20 +1,27 @@
 /**
  * @file LocalFeatureOpponnentSift.h
  * @brief local feature with color sift
- * @author Björn Fröhlich
+ * @author Björn Fröhlich, Alexander Freytag
  * @date 03/08/2010
 
  */
 #ifndef LocalFeatureOpponnentSiftINCLUDE
 #define LocalFeatureOpponnentSiftINCLUDE
 
-#include "core/vector/VectorT.h"
-#include "core/vector/MatrixT.h"
-#include "core/image/ImageT.h"
-#include "core/imagedisplay/ImageDisplay.h"
+// nice-core includes
+#include <core/basics/Config.h>
+// 
+#include <core/image/ImageT.h>
+// 
+#include <core/imagedisplay/ImageDisplay.h>
+// 
+#include <core/vector/VectorT.h>
+#include <core/vector/MatrixT.h>
 
-#include "core/basics/Config.h"
-#include "vislearning/features/localfeatures/LocalFeatureRGBSift.h"
+
+
+// nice-vislearning includes
+#include "LocalFeatureRGBSift.h"
 
 
 namespace OBJREC
@@ -25,20 +32,60 @@ class LocalFeatureOpponnentSift : public LocalFeatureRGBSift
 {
 
   protected:
-    int octaves;
-    int levels;
-    bool normalizeFeature;
-    int first_octave;
-    double magnif;
+    
+    /////////////////////////
+    /////////////////////////
+    // PROTECTED VARIABLES //
+    /////////////////////////
+    /////////////////////////     
+    
+//TODO check why those member variables have been declared here originally. In the source code, they're not used at all...    
+//     int octaves;
+//     
+//     int levels;
+//     
+//     bool normalizeFeature;
+//     
+//     int first_octave;
+//     
+//     double magnif;
 
   public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////   
 
-    /** simple constructor */
-    LocalFeatureOpponnentSift ( const NICE::Config *conf );
-
-    /** simple destructor */
+    /** 
+     * @brief default constructor
+     * @date 09-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LocalFeatureOpponnentSift ( );    
+    
+    /**
+     * @brief recommended constructor, calls initFromConfig
+     * @date 09-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LocalFeatureOpponnentSift ( const NICE::Config * _conf );
 
+    /**
+     * @brief simple destructor
+     */
     virtual ~LocalFeatureOpponnentSift();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mm-yyyy )
+     */    
+    virtual void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LocalFeatureOpponnentSift");     
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////     
+
 
     /**
      * get the descriptor
@@ -48,6 +95,32 @@ class LocalFeatureOpponnentSift : public LocalFeatureRGBSift
      * @return 0
      */
     int getDescriptors ( const NICE::ColorImage & cimg, NICE::VVector & positions, NICE::VVector & descriptors ) const;
+    
+                                 
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();      
 };
 
 

+ 130 - 14
features/localfeatures/LocalFeatureRGBSift.cpp

@@ -12,20 +12,42 @@ using namespace std;
 using namespace NICE;
 
 
-LocalFeatureRGBSift::LocalFeatureRGBSift ( const Config *conf ) : LocalFeatureSift ( conf )
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+LocalFeatureRGBSift::LocalFeatureRGBSift() : LocalFeatureSift () 
+{
+  //set deletemode variable of partent object
+  this->deletemode = false;
+}
+
+LocalFeatureRGBSift::LocalFeatureRGBSift ( const NICE::Config * _conf )
 {
-  deletemode = false;
+  this->initFromConfig( _conf );  
 }
 
 LocalFeatureRGBSift::~LocalFeatureRGBSift()
 {
+}
 
+void LocalFeatureRGBSift::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  //first of all, call method of parent object
+  LocalFeatureSift::initFromConfig( _conf );
+  
+  //set deletemode variable of parent object
+  this->deletemode = false;
 }
 
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 int
 LocalFeatureRGBSift::getDescriptors ( const NICE::ColorImage & img, VVector & positions, VVector & descriptors ) const
 {
-  sortPositions ( positions );
+  this->sortPositions ( positions );
   descriptors.clear();
   for ( int i = 0; i < ( int ) positions.size(); i++ )
   {
@@ -33,13 +55,13 @@ LocalFeatureRGBSift::getDescriptors ( const NICE::ColorImage & img, VVector & po
     descriptors.push_back ( v );
   }
 
-  vector<VVector> desc ( 3 );
+  std::vector< NICE::VVector > desc ( 3 );
 
 #ifdef NICE_USELIB_OPENMP
   // check whether siftGPU should be used
   int numberOfCPU = omp_get_num_procs();
   int numberOfThreads = 0;
-  if ( isGpuUsed() )
+  if ( this->isGpuUsed() )
   {
     // in case of siftGPU it is possible to use one device
     numberOfThreads = 1;
@@ -54,30 +76,37 @@ LocalFeatureRGBSift::getDescriptors ( const NICE::ColorImage & img, VVector & po
 #endif
 
 #pragma omp parallel for num_threads(numberOfThreads)
-  for ( int i = 0; i < 3; i++ ) {
+  for ( int i = 0; i < 3; i++ )
+  {
     NICE::Image tmp ( img.width(), img.height() );
 
-    for ( int y = 0; y < img.height(); y++ ) {
-      for ( int x = 0; x < img.width(); x++ ) {
+    for ( int y = 0; y < img.height(); y++ )
+    {
+      for ( int x = 0; x < img.width(); x++ )
+      {
         tmp.setPixel ( x, y, img.getPixel ( x, y, i ) );
       }
     }
-    VVector pos = positions;
-    computeDesc ( tmp, pos, desc[i] );
+    NICE::VVector pos = positions;
+    this->computeDesc ( tmp, pos, desc[i] );
   }
 
-  for ( int i = 0; i < 3; i++ ) {
+  for ( int i = 0; i < 3; i++ )
+  {
     assert ( desc[i].size() == descriptors.size() );
 
     if ( i == 0 ) {
 #pragma omp parallel for num_threads( numberOfCPU )
-      for ( int j = 0; j < ( int ) desc[i].size(); j++ ) {
+      for ( int j = 0; j < ( int ) desc[i].size(); j++ )
+      {
         descriptors[j] = desc[i][j];
       }
     }
-    else {
+    else 
+    {
 #pragma omp parallel for num_threads( numberOfCPU )
-      for ( int j = 0; j < ( int ) desc[i].size(); j++ ) {
+      for ( int j = 0; j < ( int ) desc[i].size(); j++ )
+      {
         descriptors[j].append ( desc[i][j] );
       }
     }
@@ -85,3 +114,90 @@ LocalFeatureRGBSift::getDescriptors ( const NICE::ColorImage & img, VVector & po
 
   return positions.size();
 }
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LocalFeatureRGBSift::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "LocalFeatureRGBSift" ) )
+    {
+      std::cerr << " WARNING - attempt to restore LocalFeatureRGBSift, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "LocalFeatureRGBSift" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );    
+      
+      ///////////////////////////////
+      //       PARENT OBJECT       //
+      ///////////////////////////////
+      if ( tmp.compare("LocalFeatureSift--Parent") == 0 )
+      {
+        // restore parent object
+        LocalFeatureSift::restore(is);
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );        
+      }      
+      else
+      {
+      std::cerr << "WARNING -- unexpected LocalFeatureRGBSift object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "LocalFeatureRGBSift::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void LocalFeatureRGBSift::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "LocalFeatureRGBSift" ) << std::endl;    
+        
+    ///////////////////////////////
+    //       PARENT OBJECT       //
+    ///////////////////////////////
+    os << this->createStartTag( "LocalFeatureSift--Parent" ) << std::endl;
+    LocalFeatureSift::store(os);  
+    os << this->createStartTag( "LocalFeatureSift--Parent" ) << std::endl;   
+    
+    // done
+    os << this->createEndTag( "LocalFeatureRGBSift" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void LocalFeatureRGBSift::clear ()
+{
+}

+ 85 - 15
features/localfeatures/LocalFeatureRGBSift.h

@@ -1,19 +1,24 @@
 /**
 * @file LocalFeatureRGBSift.h
 * @brief local feature with color sift
-* @author Björn Fröhlich
+* @author Björn Fröhlich, Alexander Freytag
 * @date 03/10/2012 (Eric Bach)
 */
 
 #ifndef LocalFeatureRGBSiftINCLUDE
 #define LocalFeatureRGBSiftINCLUDE
 
-#include "core/vector/VectorT.h"
-#include "core/vector/MatrixT.h"
-#include "core/image/ImageT.h"
+// nice-core includes
+#include <core/basics/Config.h>
+// 
+#include <core/image/ImageT.h>
+// 
+#include <core/vector/VectorT.h>
+#include <core/vector/MatrixT.h>
 
-#include "core/basics/Config.h"
-#include "vislearning/features/localfeatures/LocalFeatureSift.h"
+
+// nice-vislearning includes
+#include "LocalFeatureSift.h"
 
 namespace OBJREC {
 
@@ -22,20 +27,60 @@ class LocalFeatureRGBSift : public LocalFeatureSift
 {
 
   protected:
-    int octaves;
-    int levels;
-    bool normalizeFeature;
-    int first_octave;
-    double magnif;
+    
+    /////////////////////////
+    /////////////////////////
+    // PROTECTED VARIABLES //
+    /////////////////////////
+    /////////////////////////  
+    
+    //TODO check why those member variables have been declared here originally. In the source code, they're not used at all...
+//     int octaves;
+//     
+//     int levels;
+//     
+//     bool normalizeFeature;
+//     
+//     int first_octave;
+//     
+//     double magnif;
 
   public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////   
 
-    /** simple constructor */
-    LocalFeatureRGBSift ( const NICE::Config *conf );
-
-    /** simple destructor */
+    /** 
+     * @brief default constructor
+     * @date 09-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LocalFeatureRGBSift ( );    
+    
+    /**
+     * @brief recommended constructor, calls initFromConfig
+     * @date 09-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LocalFeatureRGBSift ( const NICE::Config * _conf );
 
+    /**
+     * @brief simple destructor
+     */
     virtual ~LocalFeatureRGBSift();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mm-yyyy )
+     */    
+    virtual void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LocalFeatureRGBSift");     
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////     
+
 
     /**
      * returns the size of each the SIFT-Feature
@@ -55,6 +100,31 @@ class LocalFeatureRGBSift : public LocalFeatureSift
     virtual int getDescriptors ( const NICE::ColorImage & cimg,
                                  NICE::VVector & positions,
                                  NICE::VVector & descriptors ) const;
+                                 
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();                                   
 };
 
 

+ 61 - 27
features/localfeatures/LocalFeatureRepresentation.h

@@ -13,6 +13,7 @@
 
 // nice-core includes
 #include <core/basics/Exception.h>
+#include <core/basics/Persistent.h>
 // 
 #include <core/image/ImageT.h>
 #include <core/imagedisplay/ImageDisplay.h>
@@ -31,35 +32,68 @@ namespace OBJREC {
  * @brief Absract class for Local Feature Representations (Detector + Descriptor)
  *
  */
-class LocalFeatureRepresentation
+class LocalFeatureRepresentation : public NICE::Persistent
 {
 
-    protected:
-
-    public:
-  
-	/** simple constructor */
-	LocalFeatureRepresentation();
-      
-	/** simple destructor */
-	virtual ~LocalFeatureRepresentation();
-
-	virtual int getDescSize () const = 0;
-
-	virtual int extractFeatures ( const NICE::Image & img, 
-				      NICE::VVector & features, 
-				      NICE::VVector & positions ) const = 0;
-	
-	virtual int extractFeatures ( const NICE::ColorImage & img, 
-				      NICE::VVector & features, 
-				      NICE::VVector & positions ) const;
-
-	virtual void visualizeFeatures ( NICE::Image & mark,
-					 const NICE::VVector & positions,
-					 size_t color ) const;
-
-	virtual void visualize ( NICE::Image & img, 
-				 const NICE::Vector & feature ) const;
+  protected:
+
+  public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////         
+
+    /** simple constructor */
+    LocalFeatureRepresentation();
+    
+    /** simple destructor */
+    virtual ~LocalFeatureRepresentation();
+
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////
+
+    virtual int getDescSize () const = 0;
+
+    virtual int extractFeatures ( const NICE::Image & img,
+                                  NICE::VVector & features,
+                                  NICE::VVector & positions ) const = 0;
+
+    virtual int extractFeatures ( const NICE::ColorImage & img,
+                                  NICE::VVector & features,
+                                  NICE::VVector & positions ) const;
+
+    virtual void visualizeFeatures ( NICE::Image & mark,
+                                    const NICE::VVector & positions,
+                                    size_t color ) const;
+
+    virtual void visualize ( NICE::Image & img,
+                            const NICE::Vector & feature ) const;
+
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+
+    /**
+    * @brief Load object from external file (stream)
+    * @author Alexander Freytag
+    * @date 09-02-2014 ( dd-mm-yyyy )
+    */
+    void restore ( std::istream & is, int format = 0 ) = 0;
+
+    /**
+    * @brief Save object to external file (stream)
+    * @author Alexander Freytag
+    * @date 09-02-2014 ( dd-mm-yyyy )
+    */
+    void store ( std::ostream & os, int format = 0 ) const = 0;
+
+    /**
+    * @brief Clear object
+    * @author Alexander Freytag
+    * @date 09-02-2014 ( dd-mm-yyyy )
+    */
+    void clear () = 0;  
 
 };
 

+ 189 - 15
features/localfeatures/LocalFeatureSift.cpp

@@ -1,7 +1,7 @@
 /**
 * @file LocalFeatureSift.cpp
 * @brief local feature with sift
-* @author Erik Rodner
+* @author Erik Rodner, Alexander Freytag
 * @date 03/10/2012
 */
 #include <iostream>
@@ -14,28 +14,52 @@ using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
-LocalFeatureSift::LocalFeatureSift( const Config *conf )
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+LocalFeatureSift::LocalFeatureSift() : LocalFeature () 
+{
+  this->octaves          = 6;
+  this->levels           = 3;
+  this->first_octave     = -1;
+  this->normalizeFeature = true;
+  this->magnif           = 3;
+  this->deletemode       = true;
+  this->integerValues    = true;
+  this->usegpu           = false;
+}
+
+LocalFeatureSift::LocalFeatureSift( const NICE::Config * _conf )
+{
+  this->initFromConfig( _conf );
+}
+
+LocalFeatureSift::~LocalFeatureSift()
 {
-    this->conf = conf;
+}
 
-    octaves          = conf->gI("LFSiftPP", "octaves", 			6);
-    levels           = conf->gI("LFSiftPP", "levels", 			3);
-    first_octave     = conf->gI("LFSiftPP", "first_octave", 	-1);
-    normalizeFeature = conf->gB("LFSiftPP", "normalize_feature", true );
-    magnif 	         = conf->gD("LFSiftPP", "magnif", 			3 );
-    deletemode       = conf->gB("LFSiftPP", "deletemode", 		true );
-    integerValues    = conf->gB("LFSiftPP", "integer_values", 	true );
+void OBJREC::LocalFeatureSift::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  //NOTE previous confSection defaultet to LFSiftPP!
+  this->octaves          = _conf->gI(_confSection, "octaves",           6);
+  this->levels           = _conf->gI(_confSection, "levels",            3);
+  this->first_octave     = _conf->gI(_confSection, "first_octave",      -1);
+  this->normalizeFeature = _conf->gB(_confSection, "normalize_feature", true );
+  this->magnif           = _conf->gD(_confSection, "magnif",            3 );
+  this->deletemode       = _conf->gB(_confSection, "deletemode",        true );
+  this->integerValues    = _conf->gB(_confSection, "integer_values",    true );
 
 #ifdef NICE_USELIB_CUDASIFT
-    usegpu 	     	 = conf->gB("LFSiftPP", "use_siftgpu",		false );
+  this->usegpu           = _conf->gB(_confSection, "use_siftgpu",       false );
 #else
-	usegpu = false;
+  this->usegpu = false;
 #endif
 }
 
-LocalFeatureSift::~LocalFeatureSift()
-{
-}
+///////////////////// ///////////////////// /////////////////////
+//                      FEATURE STUFF
+///////////////////// ///////////////////// ////////////////// 
 
 void LocalFeatureSift::sortPositions(VVector & positions) const
 {
@@ -297,3 +321,153 @@ void LocalFeatureSift::withGPU(const NICE::Image& img, VVector& positions, VVect
     }
 }
 #endif
+  
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void LocalFeatureSift::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "LocalFeatureSift" ) )
+    {
+      std::cerr << " WARNING - attempt to restore LocalFeatureSift, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "LocalFeatureSift" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );    
+      
+      if ( tmp.compare("octaves") == 0 )
+      {
+        is >> this->octaves;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("levels") == 0 )
+      {
+        is >> this->levels;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("first_octave") == 0 )
+      {
+        is >> this->first_octave;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("normalizeFeature") == 0 )
+      {
+        is >> this->normalizeFeature;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("magnif") == 0 )
+      {
+        is >> this->magnif;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("deletemode") == 0 )
+      {
+        is >> this->deletemode;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("integerValues") == 0 )
+      {
+        is >> this->integerValues;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("usegpu") == 0 )
+      {
+        is >> this->usegpu;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else
+      {
+      std::cerr << "WARNING -- unexpected LocalFeatureSift object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "LocalFeatureSift::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void LocalFeatureSift::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "LocalFeatureSift" ) << std::endl;    
+    
+    os << this->createStartTag( "octaves" ) << std::endl;
+    os << this->octaves << std::endl;
+    os << this->createEndTag( "octaves" ) << std::endl;  
+
+    os << this->createStartTag( "levels" ) << std::endl;
+    os << this->levels << std::endl;
+    os << this->createEndTag( "levels" ) << std::endl;
+    
+    os << this->createStartTag( "first_octave" ) << std::endl;
+    os << this->first_octave << std::endl;
+    os << this->createEndTag( "first_octave" ) << std::endl;  
+
+    os << this->createStartTag( "normalizeFeature" ) << std::endl;
+    os << this->normalizeFeature << std::endl;
+    os << this->createEndTag( "normalizeFeature" ) << std::endl; 
+    
+    os << this->createStartTag( "magnif" ) << std::endl;
+    os << this->magnif << std::endl;
+    os << this->createEndTag( "magnif" ) << std::endl;
+    
+    os << this->createStartTag( "deletemode" ) << std::endl;
+    os << this->deletemode << std::endl;
+    os << this->createEndTag( "deletemode" ) << std::endl;  
+
+    os << this->createStartTag( "integerValues" ) << std::endl;
+    os << this->integerValues << std::endl;
+    os << this->createEndTag( "integerValues" ) << std::endl;     
+    
+    os << this->createStartTag( "usegpu" ) << std::endl;
+    os << this->usegpu << std::endl;
+    os << this->createEndTag( "usegpu" ) << std::endl;     
+    
+    // done
+    os << this->createEndTag( "LocalFeatureSift" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void LocalFeatureSift::clear ()
+{
+}

+ 96 - 22
features/localfeatures/LocalFeatureSift.h

@@ -1,7 +1,7 @@
 /**
 * @file LocalFeatureSift.h
 * @brief local feature with sift
-* @author Erik Rodner
+* @author Erik Rodner, Alexander Freytag
 * @date 03/10/2012 (Eric Bach)
 * @note some notes to the use of siftGPU (added by Eric Bach)
 *  - install cudaSift & siftGPU (see Makefile.config)
@@ -15,21 +15,27 @@
 #ifndef LOCALFEATURESIFTINCLUDE
 #define LOCALFEATURESIFTINCLUDE
 
-// NICE includes
-#include "core/vector/VectorT.h"
-#include "core/vector/MatrixT.h"
-#include "core/image/ImageT.h"
-#include "core/imagedisplay/ImageDisplay.h"
 
-#include "core/basics/Config.h"
-#include "core/basics/StringTools.h"
-#include "LocalFeature.h"
-
-// std includes
+// STL includes
 #include <iostream>
 #include <string>
 #include <stdexcept>
 
+// nice-core includes
+#include <core/basics/Config.h>
+#include <core/basics/StringTools.h>
+// 
+#include <core/image/ImageT.h>
+#include <core/imagedisplay/ImageDisplay.h>
+// 
+#include <core/vector/VectorT.h>
+#include <core/vector/MatrixT.h>
+
+// nice-vislearning includes
+#include "LocalFeature.h"
+
+
+
 // SiftGPU & GL
 #ifdef NICE_USELIB_CUDASIFT
 #include <src/SiftGPU.h>
@@ -42,23 +48,41 @@ namespace OBJREC {
 /** local feature with sift */
 class LocalFeatureSift : public LocalFeature
 {
-  private:
-    const NICE::Config* conf;
 
   protected:
+    
+    /////////////////////////
+    /////////////////////////
+    // PROTECTED VARIABLES //
+    /////////////////////////
+    /////////////////////////    
+    
     int octaves;
+    
     int levels;
+    
     bool normalizeFeature;
+    
     int first_octave;
+    
     double magnif;
+    
     bool deletemode;
+    
     bool integerValues;
 
     // for SiftGPU
     bool usegpu;
 
     float threshold;
+    
     float edgeThreshold;
+    
+    /////////////////////////
+    /////////////////////////
+    //  PROTECTED METHODS  //
+    /////////////////////////
+    /////////////////////////      
 
     void withPP ( const NICE::Image & img, NICE::VVector & positions, NICE::VVector & descriptors ) const;
 #ifdef NICE_USELIB_CUDASIFT
@@ -66,13 +90,40 @@ class LocalFeatureSift : public LocalFeature
 #endif
 
   public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////       
+
+    /** 
+     * @brief default constructor
+     * @date 09-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LocalFeatureSift ( );    
+    
+    /**
+     * @brief recommended constructor, calls initFromConfig
+     * @date 09-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    LocalFeatureSift ( const NICE::Config * _conf );
 
-    /** simple constructor */
-    LocalFeatureSift ( const NICE::Config *conf );
-
-    /** simple destructor */
-
+    /**
+     * @brief simple destructor
+     */
     virtual ~LocalFeatureSift();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LocalFeatureSift");    
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////        
 
     /**
      * returns the size of each the SIFT-Feature
@@ -117,10 +168,33 @@ class LocalFeatureSift : public LocalFeature
      */
     void sortPositions ( NICE::VVector & positions ) const;
 
-    void visualizeFeatures ( NICE::Image & mark, const NICE::VVector & positions, size_t color ) const;
-
-
-
+    virtual void visualizeFeatures ( NICE::Image & mark, const NICE::VVector & positions, size_t color ) const;
+
+
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////   
+    
+    /** 
+     * @brief Load object from external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */     
+    virtual void restore ( std::istream & is, int format = 0 );
+    
+    /** 
+     * @brief Save object to external file (stream)
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */       
+    virtual void store( std::ostream & os, int format = 0 ) const;
+    
+    /** 
+     * @brief Clear  object
+     * @author Alexander Freytag
+     * @date 09-02-2014 ( dd-mmyyyy)
+     */    
+    virtual void clear ();  
 
 };
 

+ 134 - 0
features/localfeatures/progs/computeLocalFeatures.cpp

@@ -0,0 +1,134 @@
+/**
+* @file computeLocalFeatures.cpp
+* @brief compute some features for training and testing (separate specifications possible)
+* @author Alexander Freytag
+* @date 14-06-2013
+*/
+
+//STL
+#include <iostream>
+#include <limits>
+
+//core -- basic stuff
+#include <core/basics/Config.h>
+#include <core/basics/ResourceStatistics.h>
+#include <core/basics/Timer.h>
+#include <core/image/Convert.h>
+#include <core/vector/VectorT.h>
+
+//vislearning -- basic stuff
+#include <vislearning/baselib/Globals.h>
+#include <vislearning/baselib/ICETools.h>
+#include <vislearning/cbaselib/MultiDataset.h>
+#include <vislearning/cbaselib/Example.h>
+#include <vislearning/cbaselib/ClassificationResult.h>
+#include <vislearning/cbaselib/ClassificationResults.h>
+// vislearning -- local features
+#include <vislearning/features/localfeatures/GenericLFSelection.h>
+//
+
+using namespace std;
+using namespace NICE;
+using namespace OBJREC;
+
+/**
+ a complete BoW pipeline
+ 
+ possibly, we can make use of objrec/progs/testClassifier.cpp
+*/
+int main( int argc, char **argv )
+{
+  std::set_terminate( __gnu_cxx::__verbose_terminate_handler );
+
+  NICE::Config * conf = new NICE::Config ( argc, argv );
+  
+  const std::string resultsfile = conf->gS( "main", "resultsfile", "/tmp/results.txt" );
+  
+  ResourceStatistics rs;
+  
+  // ========================================================================
+  //                            TRAINING STEP
+  // ========================================================================
+
+  MultiDataset md( conf );
+  const LabeledSet *trainFiles = md["train"];  
+   
+  //**********************************************
+  //
+  //     FEATURE EXTRACTION FOR TRAINING IMAGES
+  //
+  //**********************************************  
+  
+  std::cerr << "FEATURE EXTRACTION FOR TRAINING IMAGES" << std::endl;
+  
+  OBJREC::LocalFeatureRepresentation * featureExtractor = OBJREC::GenericLFSelection::selectLocalFeatureRep ( conf, "features", OBJREC::GenericLFSelection::TRAINING );
+  
+  
+  //TODO replace the nasty makro by a suitable for-loop to make it omp-ready (parallelization)
+  int imgCnt ( 0 );
+   
+  // the corresponding nasty makro: LOOP_ALL_S( *trainFiles )
+  for(LabeledSet::const_iterator classIt = trainFiles->begin() ; classIt != trainFiles->end() ; classIt++)
+  {
+    for ( std::vector<ImageInfo *>::const_iterator imgIt = classIt->second.begin(); 
+          imgIt != classIt->second.end(); 
+          imgIt++, imgCnt++
+        ) 
+    {
+      // the corresponding nasty makro: EACH_INFO( classno, info );
+      int classno ( classIt->first );
+      const ImageInfo imgInfo = *(*imgIt);      
+      
+      std::string filename = imgInfo.img();      
+      
+      NICE::ColorImage img( filename );
+  
+      //compute features
+      
+      //variables to store feature information
+      NICE::VVector features;
+      NICE::VVector positions;
+  
+      Globals::setCurrentImgFN ( filename );
+      featureExtractor->extractFeatures ( img, features, positions );  
+              
+    }
+  }
+  
+  
+  // ========================================================================
+  //                            TEST STEP
+  // ========================================================================
+  
+  const LabeledSet *testFiles = md["test"];
+
+  delete featureExtractor;
+  featureExtractor = OBJREC::GenericLFSelection::selectLocalFeatureRep ( conf, "features", OBJREC::GenericLFSelection::TESTING );  
+  
+  LOOP_ALL_S( *testFiles )
+  {
+      EACH_INFO( classno, info );
+      std::string filename = info.img();
+  
+      //**********************************************
+      //
+      //     FEATURE EXTRACTION FOR TEST IMAGES
+      //
+      //**********************************************  
+      
+      NICE::ColorImage img( filename );
+  
+      //compute features
+      
+      //variables to store feature information
+      NICE::VVector features;
+      NICE::VVector positions;
+  
+      Globals::setCurrentImgFN ( filename );
+      featureExtractor->extractFeatures ( img, features, positions );  
+
+  }
+
+  
+   return 0;
+}

+ 89 - 0
features/localfeatures/tests/Makefile.inc

@@ -0,0 +1,89 @@
+# BINARY-DIRECTORY-MAKEFILE
+# conventions:
+# - there are no subdirectories, they are ignored!
+# - all ".C", ".cpp" and ".c" files in the current directory are considered
+#   independent binaries, and linked as such.
+# - the binaries depend on the library of the parent directory
+# - the binary names are created with $(BINNAME), i.e. it will be more or less
+#   the name of the .o file
+# - all binaries will be added to the default build list ALL_BINARIES
+
+# --------------------------------
+# - remember the last subdirectory
+#
+# set the variable $(SUBDIR) correctly to the current subdirectory. this
+# variable can be used throughout the current makefile.inc. The many 
+# SUBDIR_before, _add, and everything are only required so that we can recover
+# the previous content of SUBDIR before exitting the makefile.inc
+
+SUBDIR_add:=$(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
+SUBDIR_before:=$(SUBDIR)
+SUBDIR:=$(strip $(SUBDIR_add))
+SUBDIR_before_$(SUBDIR):=$(SUBDIR_before)
+
+# ------------------------
+# - include subdirectories
+#
+# note the variables $(SUBDIRS_OF_$(SUBDIR)) are required later on to recover
+# the dependencies automatically. if you handle dependencies on your own, you
+# can also dump the $(SUBDIRS_OF_$(SUBDIR)) variable, and include the
+# makefile.inc of the subdirectories on your own...
+
+#SUBDIRS_OF_$(SUBDIR):=$(patsubst %/Makefile.inc,%,$(wildcard $(SUBDIR)*/Makefile.inc))
+#include $(SUBDIRS_OF_$(SUBDIR):%=%/Makefile.inc)
+
+# ----------------------------
+# - include local dependencies
+#
+# include the libdepend.inc file, which gives additional dependencies for the
+# libraries and binaries. additionally, an automatic dependency from the library
+# of the parent directory is added (commented out in the code below).
+
+-include $(SUBDIR)libdepend.inc
+
+PARENTDIR:=$(patsubst %/,%,$(dir $(patsubst %/,%,$(SUBDIR))))
+$(call PKG_DEPEND_INT,$(PARENTDIR))
+$(call PKG_DEPEND_EXT,CPPUNIT)
+
+# ---------------------------
+# - objects in this directory
+#
+# the use of the variable $(OBJS) is not mandatory. it is mandatory however
+# to update $(ALL_OBJS) in a way that it contains the path and name of
+# all objects. otherwise we can not include the appropriate .d files.
+
+OBJS:=$(patsubst %.cpp,$(OBJDIR)%.o,$(notdir $(wildcard $(SUBDIR)*.cpp))) \
+      $(patsubst %.C,$(OBJDIR)%.o,$(notdir $(wildcard $(SUBDIR)*.C))) \
+      $(shell grep -ls Q_OBJECT $(SUBDIR)*.h | sed -e's@^@/@;s@.*/@$(OBJDIR)moc_@;s@\.h$$@.o@') \
+      $(patsubst %.c,$(OBJDIR)%.o,$(notdir $(wildcard $(SUBDIR)*.c)))
+ALL_OBJS += $(OBJS)
+
+# ----------------------------
+# - binaries in this directory
+#
+# output of binaries in this directory. none of the variables has to be used.
+# but everything you add to $(ALL_LIBRARIES) and $(ALL_BINARIES) will be
+# compiled with `make all`. be sure again to add the files with full path.
+
+CHECKS:=$(BINDIR)$(call LIBNAME,$(SUBDIR))
+ALL_CHECKS+=$(CHECKS)
+
+# ---------------------
+# - binary dependencies
+#
+# there is no way of determining the binary dependencies automatically, so we
+# follow conventions. each binary depends on the corresponding .o file and
+# on the libraries specified by the INTLIBS/EXTLIBS. these dependencies can be
+# specified manually or they are automatically stored in a .bd file.
+
+$(foreach head,$(wildcard $(SUBDIR)*.h),$(eval $(shell grep -q Q_OBJECT $(head) && echo $(head) | sed -e's@^@/@;s@.*/\(.*\)\.h$$@$(BINDIR)\1:$(OBJDIR)moc_\1.o@')))
+$(eval $(foreach c,$(CHECKS),$(c):$(BUILDDIR)$(CPPUNIT_MAIN_OBJ) $(OBJS) $(call PRINT_INTLIB_DEPS,$(c),.a)))
+
+# -------------------
+# - subdir management
+#
+# as the last step, always add this line to correctly recover the subdirectory
+# of the makefile including this one!
+
+SUBDIR:=$(SUBDIR_before_$(SUBDIR))
+

+ 91 - 0
features/localfeatures/tests/TestGenericLFSelectionPersistent.cpp

@@ -0,0 +1,91 @@
+/** 
+ * @file TestGenericLFSelectionPersistent.cpp
+ * @brief CppUnit-Testcase to create a LocalFeatureRepresentation object via GenericLFSelection, to store it, and to restore it again.
+ * @author Alexander Freytag
+ * @date 10-02-2014 ( dd-mm-yyyy )
+*/
+
+#ifdef NICE_USELIB_CPPUNIT
+
+// STL includes
+
+// NICE-core includes
+
+// gp-hik-core includes
+
+#include "TestGenericLFSelectionPersistent.h"
+
+using namespace std; //C basics
+using namespace NICE;  // nice-core
+
+const bool verboseStartEnd = true;
+const bool verbose = true;
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TestGenericLFSelectionPersistent );
+
+void TestGenericLFSelectionPersistent::setUp() {
+}
+
+void TestGenericLFSelectionPersistent::tearDown() {
+}
+void TestGenericLFSelectionPersistent::testPersistentMethods()
+{
+  
+  if (verboseStartEnd)
+    std::cerr << "================== TestGenericLFSelectionPersistent::testPersistentMethods ===================== " << std::endl;  
+  
+  NICE::Config conf;
+  conf.sS( "GenericLFSelection", "localfeature_type", "sift" );
+  OBJREC::LocalFeatureRepresentation  * lfrep;  
+  
+  lfrep = OBJREC::GenericLFSelection::selectLocalFeatureRep ( &conf, "GenericLFSelection");
+  
+  // TEST STORING ABILITIES
+  if ( verbose )
+    std::cerr << " TEST STORING ABILITIES " << std::endl;
+  
+  std::string s_destination_save ( "myLFSelection.txt" );
+  
+  std::filebuf fbOut;
+  fbOut.open ( s_destination_save.c_str(), ios::out );
+  std::ostream os (&fbOut);
+  //
+  lfrep->store( os );
+  //   
+  fbOut.close();
+  
+  // TEST RESTORING ABILITIES
+  if ( verbose )
+    std::cerr << " TEST RESTORING ABILITIES " << std::endl;
+    
+  OBJREC::LocalFeatureRepresentation * lfrepRestore = NULL;  
+      
+  std::string s_destination_load ( "myLFSelection.txt" );
+  
+  std::filebuf fbIn;
+  fbIn.open ( s_destination_load.c_str(), ios::in );
+  std::istream is (&fbIn);
+  //
+  OBJREC::GenericLFSelection::restoreLocalFeatureRep ( lfrepRestore, is );
+  //   
+  fbIn.close(); 
+  
+  // currently, we have no possibility to actually verify that the restore-operation was successfull, i.e.,
+  // it returned an object identical to the stored one.
+  // However, if we reached this point, at least something went right, so we should be happy...
+  
+  // final clean up -- don't waste memory
+  if ( lf != NULL )
+    delete lf;
+    
+  if ( lfRestore != NULL )
+    delete lfRestore;  
+  
+    
+  if (verboseStartEnd)
+    std::cerr << "================== TestGenericLFSelectionPersistent::testPersistentMethods done ===================== " << std::endl;  
+  
+}
+
+#endif

+ 31 - 0
features/localfeatures/tests/TestGenericLFSelectionPersistent.h

@@ -0,0 +1,31 @@
+#ifndef _TESTGENERICLFSELECTIONPERSISTENT_H
+#define _TESTGENERICLFSELECTIONPERSISTENT_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <vislearning/features/localfeatures/GenericLFSelection.h>
+
+/**
+ * CppUnit-Testcase. 
+ * @brief CppUnit-Testcase to create a LocalFeatureRepresentation object via GenericLFSelection, to store it, and to restore it again.
+ * @author Alexander Freytag
+ * @date 10-02-2014 ( dd-mm-yyyy )
+ */
+class TestGenericLFSelectionPersistent : public CppUnit::TestFixture {
+
+    CPPUNIT_TEST_SUITE( TestGenericLFSelectionPersistent );
+	 CPPUNIT_TEST(testPersistentMethods);
+      
+    CPPUNIT_TEST_SUITE_END();
+  
+ private:
+ 
+ public:
+    void setUp();
+    void tearDown();
+
+
+    void testPersistentMethods();
+};
+
+#endif // _TESTGENERICLFSELECTIONPERSISTENT_H

+ 91 - 0
features/localfeatures/tests/TestGenericLocalFeatureSelectionPersistent.cpp

@@ -0,0 +1,91 @@
+/** 
+ * @file TestGenericLocalFeatureSelectionPersistent.cpp
+ * @brief CppUnit-Testcase to create a LocalFeatureRepresentation object via GenericLocalFeatureSelection, to store it, and to restore it again.
+ * @author Alexander Freytag
+ * @date 12-02-2014 ( dd-mm-yyyy )
+*/
+
+#ifdef NICE_USELIB_CPPUNIT
+
+// STL includes
+
+// NICE-core includes
+
+// gp-hik-core includes
+
+#include "TestGenericLocalFeatureSelectionPersistent.h"
+
+using namespace std; //C basics
+using namespace NICE;  // nice-core
+
+const bool verboseStartEnd = true;
+const bool verbose = true;
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TestGenericLocalFeatureSelectionPersistent );
+
+void TestGenericLocalFeatureSelectionPersistent::setUp() {
+}
+
+void TestGenericLocalFeatureSelectionPersistent::tearDown() {
+}
+void TestGenericLocalFeatureSelectionPersistent::testPersistentMethods()
+{
+  
+  if (verboseStartEnd)
+    std::cerr << "================== TestGenericLocalFeatureSelectionPersistent::testPersistentMethods ===================== " << std::endl;  
+  
+  NICE::Config conf;
+  conf.sS( "GenericLocalFeatureSelection", "localfeature_type", "LocalFeatureSift" );
+  OBJREC::LocalFeature  * lf;  
+  
+  lf = OBJREC::GenericLocalFeatureSelection::selectLocalFeature ( &conf, "GenericLocalFeatureSelection");
+  
+  // TEST STORING ABILITIES
+  if ( verbose )
+    std::cerr << " TEST STORING ABILITIES FOR STANDARD LOCALFEATURE" << std::endl;
+  
+  std::string s_destination_save ( "myLocalFeatureSelection.txt" );
+  
+  std::filebuf fbOut;
+  fbOut.open ( s_destination_save.c_str(), ios::out );
+  std::ostream os (&fbOut);
+  //
+  lf->store( os );
+  //   
+  fbOut.close();
+  
+  // TEST RESTORING ABILITIES
+  if ( verbose )
+    std::cerr << " TEST RESTORING ABILITIES FOR STANDARD LOCALFEATURE" << std::endl;
+    
+  OBJREC::LocalFeature * lfRestore = NULL;  
+      
+  std::string s_destination_load ( "myLocalFeatureSelection.txt" );
+  
+  std::filebuf fbIn;
+  fbIn.open ( s_destination_load.c_str(), ios::in );
+  std::istream is (&fbIn);
+  //
+  OBJREC::GenericLocalFeatureSelection::restoreLocalFeature ( lfRestore, is );
+  //   
+  fbIn.close(); 
+  
+  // currently, we have no possibility to actually verify that the restore-operation was successfull, i.e.,
+  // it returned an object identical to the stored one.
+  // However, if we reached this point, at least something went right, so we should be happy...
+  
+  // final clean up -- don't waste memory
+  if ( lf != NULL )
+    delete lf;
+    
+  if ( lfRestore != NULL )
+    delete lfRestore;  
+  
+    
+  if (verboseStartEnd)
+    std::cerr << "================== TestGenericLocalFeatureSelectionPersistent::testPersistentMethods done ===================== " << std::endl;  
+  
+}
+
+#endif

+ 31 - 0
features/localfeatures/tests/TestGenericLocalFeatureSelectionPersistent.h

@@ -0,0 +1,31 @@
+#ifndef _TESTGENERICLOCALFEATURESELECTIONPERSISTENT_H
+#define _TESTGENERICLOCALFEATURESELECTIONPERSISTENT_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <vislearning/features/localfeatures/GenericLocalFeatureSelection.h>
+
+/**
+ * CppUnit-Testcase. 
+ * @brief CppUnit-Testcase to create a LocalFeatureRepresentation object via GenericLocalFeatureSelection, to store it, and to restore it again.
+ * @author Alexander Freytag
+ * @date 12-02-2014 ( dd-mm-yyyy )
+ */
+class TestGenericLocalFeatureSelectionPersistent : public CppUnit::TestFixture {
+
+    CPPUNIT_TEST_SUITE( TestGenericLocalFeatureSelectionPersistent );
+	 CPPUNIT_TEST(testPersistentMethods);
+      
+    CPPUNIT_TEST_SUITE_END();
+  
+ private:
+ 
+ public:
+    void setUp();
+    void tearDown();
+
+
+    void testPersistentMethods();
+};
+
+#endif // _TESTGENERICLOCALFEATURESELECTIONPERSISTENT_H

+ 93 - 0
features/localfeatures/tests/TestLFonHSGPersistent.cpp

@@ -0,0 +1,93 @@
+/** 
+ * @file TestLFonHSGPersistent.cpp
+ * @brief CppUnit-Testcase to create a LFonHSG-Wrapper around an LocalFeature-object. Checks whether this is storable and restorable again.
+ * @author Alexander Freytag
+ * @date 12-02-2014 ( dd-mm-yyyy )
+*/
+
+#ifdef NICE_USELIB_CPPUNIT
+
+// STL includes
+
+// NICE-core includes
+
+// gp-hik-core includes
+
+#include "TestLFonHSGPersistent.h"
+
+using namespace std; //C basics
+using namespace NICE;  // nice-core
+
+const bool verboseStartEnd = true;
+const bool verbose = true;
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TestLFonHSGPersistent );
+
+void TestLFonHSGPersistent::setUp() {
+}
+
+void TestLFonHSGPersistent::tearDown() {
+}
+
+
+void TestLFonHSGPersistent::testPersistentMethodsForLFonHSG()
+{
+  
+  if (verboseStartEnd)
+    std::cerr << "================== TestLFonHSGPersistent::testPersistentMethodsForLFonHSG ===================== " << std::endl;  
+  
+  NICE::Config conf;
+  conf.sS( "GenericLFSelection", "localfeature_type", "LFonHSG" );
+  conf.sS( "LFonHSG", "localfeature_type", "LocalFeatureSift" );
+  OBJREC::LocalFeatureRepresentation  * lfrep;  
+  
+  lfrep = OBJREC::GenericLFSelection::selectLocalFeatureRep ( &conf, "GenericLFSelection");
+  
+  // TEST STORING ABILITIES
+  if ( verbose )
+    std::cerr << " TEST STORING ABILITIES FOR LFonHSG Wrapper" << std::endl;
+  
+  std::string s_destination_save ( "myLFonHSG.txt" );
+  
+  std::filebuf fbOut;
+  fbOut.open ( s_destination_save.c_str(), ios::out );
+  std::ostream os (&fbOut);
+  //
+  lfrep->store( os );
+  //   
+  fbOut.close();
+  
+  // TEST RESTORING ABILITIES
+  if ( verbose )
+    std::cerr << " TEST RESTORING ABILITIES FOR LFonHSG Wrapper" << std::endl;
+    
+  OBJREC::LocalFeatureRepresentation * lfrepRestore = NULL;  
+      
+  std::string s_destination_load ( "myLFonHSG.txt" );
+  
+  std::filebuf fbIn;
+  fbIn.open ( s_destination_load.c_str(), ios::in );
+  std::istream is (&fbIn);
+  //
+  OBJREC::GenericLFSelection::restoreLocalFeatureRep ( lfrepRestore, is );
+  //   
+  fbIn.close(); 
+  
+  // currently, we have no possibility to actually verify that the restore-operation was successfull, i.e.,
+  // it returned an object identical to the stored one.
+  // However, if we reached this point, at least something went right, so we should be happy...
+  
+  // final clean up -- don't waste memory
+  if ( lf != NULL )
+    delete lf;
+    
+  if ( lfRestore != NULL )
+    delete lfRestore;  
+  
+    
+  if (verboseStartEnd)
+    std::cerr << "================== TestLFonHSGPersistent::testPersistentMethodsForLFonHSG done ===================== " << std::endl;  
+  
+}
+#endif

+ 32 - 0
features/localfeatures/tests/TestLFonHSGPersistent.h

@@ -0,0 +1,32 @@
+#ifndef _TESTLFONHSGPERSISTENT_H
+#define _TESTLFONHSGPERSISTENT_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <vislearning/features/localfeatures/LFonHSG.h>
+#include <vislearning/features/localfeatures/GenericLFSelection.h>
+
+/**
+ * CppUnit-Testcase. 
+ * @brief CppUnit-Testcase to create a LFonHSG-Wrapper around an LocalFeature-object. Checks whether this is storable and restorable again.
+ * @author Alexander Freytag
+ * @date 12-02-2014 ( dd-mm-yyyy )
+ */
+class TestLFonHSGPersistent : public CppUnit::TestFixture {
+
+    CPPUNIT_TEST_SUITE( TestLFonHSGPersistent );
+         CPPUNIT_TEST(testPersistentMethodsForLFonHSG);
+      
+    CPPUNIT_TEST_SUITE_END();
+  
+ private:
+ 
+ public:
+    void setUp();
+    void tearDown();
+
+
+    void testPersistentMethodsForLFonHSG();
+};
+
+#endif // _TESTLFONHSGPERSISTENT_H

+ 28 - 1
math/cluster/ClusterAlgorithm.cpp

@@ -16,7 +16,9 @@ using namespace std;
 // old: using namespace ice;
 using namespace NICE;
 
-
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
 
 ClusterAlgorithm::ClusterAlgorithm()
 {
@@ -26,3 +28,28 @@ ClusterAlgorithm::~ClusterAlgorithm()
 {
 }
 
+void ClusterAlgorithm::initFromConfig ( const NICE::Config * _conf, const std::string & _confSection )
+{
+  //nothing to do
+}
+
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void ClusterAlgorithm::restore ( std::istream & is, int format )
+{
+  //nothing to do
+}
+
+void ClusterAlgorithm::store ( std::ostream & os, int format ) const
+{
+  //nothing to do
+}
+
+void ClusterAlgorithm::clear ()
+{
+  //nothing to do  
+}
+

+ 49 - 8
math/cluster/ClusterAlgorithm.h

@@ -1,15 +1,16 @@
 /** 
 * @file ClusterAlgorithm.h
 * @brief Interface for Cluster-Algorithms
-* @author Erik Rodner
-* @date 10/29/2007
-
+* @author Erik Rodner, Alexander Freytag
+* @date 10/29/2007 (last update on 12-02-2014 ( dd-mm-yyyy ) )
 */
 #ifndef CLUSTERALGORITHMINCLUDE
 #define CLUSTERALGORITHMINCLUDE
 
 // nice-core includes
 #include <core/basics/Exception.h>
+#include <core/basics/Persistent.h>
+#include <core/basics/Config.h>
 // 
 #include <core/vector/VectorT.h>
 #include <core/vector/MatrixT.h>
@@ -18,25 +19,65 @@
 
 namespace OBJREC {
 
-  /** Interface for Cluster-Algorithms */
-  class ClusterAlgorithm
-  {
+/** Interface for Cluster-Algorithms */
+class ClusterAlgorithm : public NICE::Persistent
+{
 
-      protected:
+  protected:
 
-      public:
+  public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////        
     
     /** simple constructor */
     ClusterAlgorithm();
         
     /** simple destructor */
     virtual ~ClusterAlgorithm();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc. -- nothing to do here
+     * @author Alexander Freytag
+     * @date 12-02-2014 ( dd-mm-yyyy )
+     */    
+    virtual void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "ClusterAlgorithm");    
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      CLUSTERING STUFF
+    ///////////////////// ///////////////////// //////////////////    
 
     virtual void cluster ( 
             const NICE::VVector & features,
             NICE::VVector & prototypes,
             std::vector<double> & weights,
             std::vector<int>    & assignment ) = 0;
+            
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+
+    /**
+    * @brief Load object from external file (stream)  -- nothing to do here
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void restore ( std::istream & is, int format = 0 );
+
+    /**
+    * @brief Save object to external file (stream)  -- nothing to do here
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void store ( std::ostream & os, int format = 0 ) const;
+
+    /**
+    * @brief Clear object  -- nothing to do here
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void clear ();             
       
   };
 

+ 70 - 6
math/cluster/GenericClusterAlgorithmSelection.h

@@ -42,7 +42,7 @@ namespace OBJREC {
         * @author Alexander Freytag
         */
         static
-        OBJREC::ClusterAlgorithm *selectClusterAlgo ( const NICE::Config *conf, std::string section = "clustering" )
+        OBJREC::ClusterAlgorithm *selectClusterAlgorithm ( const NICE::Config *conf, std::string section = "clustering" )
         {
           // return value
           OBJREC::ClusterAlgorithm *clusterAlgo = NULL;
@@ -52,19 +52,19 @@ namespace OBJREC {
           
           std::cerr << "clusterTechnique: " << clusterTechnique << std::endl;
                   
-          if ( clusterTechnique == "kmeans" )
+          if ( ( clusterTechnique == "kmeans" ) || ( clusterTechnique == "KMeans" ) )
           {
             clusterAlgo = new OBJREC::KMeans ( conf );
           }        
-          else if ( clusterTechnique == "kmeansHeuristic" )
+          else if ( ( clusterTechnique == "kmeansHeuristic" )|| ( clusterTechnique == "KMeansHeuristic" ) )
           {
             clusterAlgo = new OBJREC::KMeansHeuristic ( conf );
           }   
-          else if ( clusterTechnique == "kmeansMatlab" )
+          else if ( ( clusterTechnique == "kmeansMatlab" )|| ( clusterTechnique == "KMeansMatlab" ) )
           {
             clusterAlgo = new OBJREC::KMeansMatlab ( conf );
           }            
-          else if ( clusterTechnique == "kmedian" )
+          else if ( ( clusterTechnique == "kmedian" )|| ( clusterTechnique == "KMedian" ) )
           {
             clusterAlgo = new OBJREC::KMedian ( conf );
           }     
@@ -72,7 +72,7 @@ namespace OBJREC {
           {
             clusterAlgo = new OBJREC::GMM ( conf );
           } 
-          else if ( clusterTechnique == "spectral" )
+          else if ( ( clusterTechnique == "spectral" )|| ( clusterTechnique == "SpectralCluster" ) )
           {
             clusterAlgo = new OBJREC::SpectralCluster ( conf );
           }           
@@ -88,7 +88,71 @@ namespace OBJREC {
           }
             
           return clusterAlgo;
+        };
+        
+      static
+      void restoreClusterAlgorithm ( ClusterAlgorithm * _clusterAlgo, std::istream & is, int format = 0 )
+      {
+                
+        if ( is.good() )
+        {
+          if ( _clusterAlgo != NULL )
+            delete _clusterAlgo;
+          
+          
+          std::string className;
+          is >> className; //class name
+                              
+          if ( className == "<KMeans>" )
+          {
+            _clusterAlgo = new OBJREC::KMeans();
+          }
+          else if ( className == "<KMeansHeuristic>" )
+          {
+            _clusterAlgo = new OBJREC::KMeansHeuristic();            
+          }
+          else if ( className == "<KMeansMatlab>" )
+          {
+            _clusterAlgo = new OBJREC::KMeansMatlab();
+          }
+          else if ( className == "<KMedian>" )
+          {
+            _clusterAlgo = new OBJREC::KMedian();
+          }
+          else if ( className == "<GMM>" )
+          {
+            _clusterAlgo = new OBJREC::GMM();
+          } 
+          else if ( className == "<SpectralCluster>" )
+          {          
+            _clusterAlgo = new OBJREC::SpectralCluster();          
+          }
+          else if ( className == "<RandomClustering>" )
+          {          
+            _clusterAlgo = new OBJREC::RandomClustering();          
+          }          
+          else
+          {
+            fthrow ( NICE::Exception, "GenericClusterAlgorithmSelection::restoreClusterAlgo -- class name " << className << "unknown. Aborting." );
+          }
+          
+          //undo reading of class name
+          
+          for ( uint i = 0; i < className.size(); i++)
+          {
+            is.unget();
+          }
+          
+          //now, call the restore method of the underlying object
+          //NOTE this could be also done externally, leaving only the actual instantiation of the derived objects here
+          _clusterAlgo->restore ( is );
+            
         }
+        else
+        {
+          fthrow ( NICE::Exception, "GenericClusterAlgorithmSelection::restoreClusterAlgo -- InStream not initialized - restoring not possible!" );
+        }      
+    };        
   };
 
 }

+ 165 - 10
math/cluster/KMeans.cpp

@@ -26,30 +26,56 @@ using namespace NICE;
 
 #undef DEBUG_KMEANS
 
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+KMeans::KMeans() : ClusterAlgorithm() 
+{
+  this->noClusters       = 20;
+  this->distanceType     = "euclidean";
+  this->distancefunction = NULL;
+  this->d_minDelta       = 1e-5;
+  this->i_maxIterations  = 200;
+}
+
 KMeans::KMeans(const int & _noClusters, const std::string & _distanceType) :
         noClusters(_noClusters), distanceType(_distanceType)
 {
     //srand(time(NULL));
     this->distancefunction = GenericDistanceSelection::selectDistance(distanceType);
+    
+  this->d_minDelta       = 1e-5;
+  this->i_maxIterations  = 200;    
 }
 
-KMeans::KMeans( const NICE::Config *conf, const std::string & _section)
+KMeans::KMeans( const NICE::Config * _conf, const std::string & _confSection)
 {       
-  this->distanceType = conf->gS( _section, "distanceType", "euclidean" );
-  this->distancefunction = GenericDistanceSelection::selectDistance(distanceType);
-  
-  this->d_minDelta  = conf->gD( _section, "minDelta", 1e-5 );
-  this->i_maxIterations = conf->gI( _section, "maxIterations", 200);
-  
-  this->noClusters = conf->gI( _section, "noClusters", 20);
-  std::cerr << "KMeans::KMeans -- noClusters: " << this->noClusters << std::endl;
-  
+  this->initFromConfig( _conf, _confSection );
 }
 
 KMeans::~KMeans()
 {
+  if ( this->distancefunction != NULL )
+  {
+    delete this->distancefunction;
+    this->distancefunction = NULL ;
+  }  
+}
+
+void KMeans::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  this->noClusters       = _conf->gI( _confSection, "noClusters", 20);  
+  this->distanceType     = _conf->gS( _confSection, "distanceType", "euclidean" );
+  this->distancefunction = OBJREC::GenericDistanceSelection::selectDistance( this->distanceType );  
+  this->d_minDelta       = _conf->gD( _confSection, "minDelta", 1e-5 );
+  this->i_maxIterations  = _conf->gI( _confSection, "maxIterations", 200);
 }
 
+///////////////////// ///////////////////// /////////////////////
+//                      CLUSTERING STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 void KMeans::initial_guess(const NICE::VVector & features, NICE::VVector & prototypes)
 {
     int j = 0;
@@ -329,3 +355,132 @@ void KMeans::print_iteration(int iterations, NICE::VVector & prototypes, double
         std::cerr << "prototype = " << (*i) << std::endl;
     }
 }
+
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void KMeans::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "KMeans" ) )
+    {
+      std::cerr << " WARNING - attempt to restore KMeans, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "KMeans" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );    
+      
+      if ( tmp.compare("noClusters") == 0 )
+      {
+        is >> this->noClusters;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("distanceType") == 0 )
+      {
+        is >> this->distanceType;
+        //TODO fixme
+        this->distancefunction = OBJREC::GenericDistanceSelection::selectDistance( this->distanceType );  
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("distancefunction") == 0 )
+      {
+        //TODO is >> this->distancefunction;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("d_minDelta") == 0 )
+      {
+        is >> this->d_minDelta;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("i_maxIterations") == 0 )
+      {
+        is >> this->i_maxIterations;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else
+      {
+      std::cerr << "WARNING -- unexpected KMeans object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "KMeans::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void KMeans::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "KMeans" ) << std::endl;   
+    
+    os << this->createStartTag( "noClusters" ) << std::endl;
+    os << this->noClusters << std::endl;
+    os << this->createEndTag( "noClusters" ) << std::endl;  
+
+    os << this->createStartTag( "distanceType" ) << std::endl;
+    os << this->distanceType << std::endl;
+    os << this->createEndTag( "distanceType" ) << std::endl;
+    
+    os << this->createStartTag( "distancefunction" ) << std::endl;
+    //TODO os << this->distancefunction << std::endl;
+    os << this->createEndTag( "distancefunction" ) << std::endl;  
+
+    os << this->createStartTag( "d_minDelta" ) << std::endl;
+    os << this->d_minDelta << std::endl;
+    os << this->createEndTag( "d_minDelta" ) << std::endl; 
+    
+    os << this->createStartTag( "i_maxIterations" ) << std::endl;
+    os << this->i_maxIterations << std::endl;
+    os << this->createEndTag( "i_maxIterations" ) << std::endl;
+    
+    // done
+    os << this->createEndTag( "KMeans" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void KMeans::clear ()
+{
+  if ( this->distancefunction != NULL )
+  {
+    delete this->distancefunction;
+    this->distancefunction = NULL ;
+  }  
+}
+

+ 145 - 98
math/cluster/KMeans.h

@@ -22,108 +22,155 @@
 namespace OBJREC {
 
 /** K-Means */
-  /**
-   * @class K-Means
-   * @brief K-Means
-   * @author Erik Rodner, Alexander Freytag
-   * @date 29-10-2007 (dd-mm-yyyy)
-  */  
-  class KMeans : public ClusterAlgorithm
-  {
-
-    protected:
-          
-        /************************
-        * 
-        *   protected variables
-        * 
-        **************************/         
-          
-          //! desired number of clusters
-          int noClusters;
-          
-          //! specify which distance to use for calculating assignments
-          std::string distanceType;
-          
-          //! the actual distance metric
-          NICE::VectorDistance<double> *distancefunction;
-          
-          //! maximum difference between prototype-solutions of two iterations for convergence
-          double d_minDelta;
-          
-          //! maximum number of iterations until convergence
-          int i_maxIterations;          
-          
-        /************************
-        * 
-        *   protected methods
-        * 
-        **************************/          
-          
-        //! compute the distance between two features using the specified distance metric
-          double vectorDistance(const NICE::Vector &vector1, const NICE::Vector &vector2, uint distancetype);
-          
-        //! compute assignments of all given features wrt to the currently known prototypes (cluster centroids) == ~ E-step
-          double compute_assignments ( const NICE::VVector & features,
-                                      const NICE::VVector & prototypes,
-                                      std::vector<int> & assignment );
-
-        //! compute number of assignments for every currently found cluster
-          double compute_weights ( const NICE::VVector & features,
-                                  std::vector<double> & weights,
-                                  std::vector<int>    & assignment );
-
-        //! compute the difference between prototypes of previous iteration and those currently found
-          double compute_delta ( const NICE::VVector & oldprototypes,
-                                const NICE::VVector & prototypes );
-
-        //! compute (update) prototypes given the current assignments == ~ M-step
-          int compute_prototypes ( const NICE::VVector & features,
-                                  NICE::VVector & prototypes,
-                                  std::vector<double> & weights,
-                                  const std::vector<int>    & assignment );
-          
-        //! have an initial guess, i.e., randomly pick some features as initial cluster centroids
-          void initial_guess ( const NICE::VVector & features,
-                              NICE::VVector & prototypes );
-        //! give additional information for the current iteration
-          void print_iteration ( int iterations,
+/**
+  * @class K-Means
+  * @brief K-Means
+  * @author Erik Rodner, Alexander Freytag
+  * @date 29-10-2007 (dd-mm-yyyy)
+*/  
+class KMeans : public ClusterAlgorithm
+{
+
+  protected:
+        
+      /************************
+      * 
+      *   protected variables
+      * 
+      **************************/         
+        
+        //! desired number of clusters
+        int noClusters;
+        
+        //! specify which distance to use for calculating assignments
+        std::string distanceType;
+        
+        //! the actual distance metric
+        NICE::VectorDistance<double> *distancefunction;
+        
+        //! maximum difference between prototype-solutions of two iterations for convergence
+        double d_minDelta;
+        
+        //! maximum number of iterations until convergence
+        int i_maxIterations;          
+        
+      /************************
+      * 
+      *   protected methods
+      * 
+      **************************/          
+        
+      //! compute the distance between two features using the specified distance metric
+        double vectorDistance(const NICE::Vector &vector1, const NICE::Vector &vector2, uint distancetype);
+        
+      //! compute assignments of all given features wrt to the currently known prototypes (cluster centroids) == ~ E-step
+        double compute_assignments ( const NICE::VVector & features,
+                                    const NICE::VVector & prototypes,
+                                    std::vector<int> & assignment );
+
+      //! compute number of assignments for every currently found cluster
+        double compute_weights ( const NICE::VVector & features,
+                                std::vector<double> & weights,
+                                std::vector<int>    & assignment );
+
+      //! compute the difference between prototypes of previous iteration and those currently found
+        double compute_delta ( const NICE::VVector & oldprototypes,
+                              const NICE::VVector & prototypes );
+
+      //! compute (update) prototypes given the current assignments == ~ M-step
+        int compute_prototypes ( const NICE::VVector & features,
                                 NICE::VVector & prototypes,
-                                double delta );
-
-      public:
-
-        /**
-        * @brief simple constructor
-        * @param _noClusters the number of clusters to be computed
-        * @param _distanceMode a string specifying the distance function to be used (default: euclidean)
-        */
-        KMeans( const int & _noClusters , const std::string & _distanceMode="euclidean");
+                                std::vector<double> & weights,
+                                const std::vector<int>    & assignment );
+        
+      //! have an initial guess, i.e., randomly pick some features as initial cluster centroids
+        void initial_guess ( const NICE::VVector & features,
+                            NICE::VVector & prototypes );
+      //! give additional information for the current iteration
+        void print_iteration ( int iterations,
+                              NICE::VVector & prototypes,
+                              double delta );
+
+    public:
       
-        /**
-        * @brief standard constructor
-        * @param conf config file specifying all relevant variable settings
-        * @param _section name of the section within the configfile where the settings can be found (default: KMeans)
-        */
-        KMeans( const NICE::Config *conf, const std::string & _section = "KMeans");      
-
-        /** simple destructor */
-        virtual ~KMeans();
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// ///////////////////// 
+
+    /** 
+     * @brief default constructor
+     * @date 12-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    KMeans ( );        
+
+      /**
+      * @brief simple constructor
+      * @param _noClusters the number of clusters to be computed
+      * @param _distanceMode a string specifying the distance function to be used (default: euclidean)
+      */
+      KMeans( const int & _noClusters , const std::string & _distanceMode="euclidean");
+    
+      /**
+      * @brief standard constructor
+      * @param conf config file specifying all relevant variable settings
+      * @param _section name of the section within the configfile where the settings can be found (default: KMeans)
+      */
+      KMeans( const NICE::Config * _conf, const std::string & _confSection = "KMeans");      
+
+      /** simple destructor */
+      virtual ~KMeans();
+        
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 12-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "KMeans");     
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      CLUSTERING STUFF
+    ///////////////////// ///////////////////// //////////////////         
 
         
-          /**
-          *@brief this is the actual method that performs the clustering for a given set of features
-          *@author Erik Rodner, Alexander Freytag
-          *@date 29-10-2007 (dd-mm-yyyy)
-          *@param   features input features to be clustered
-          *@param   prototypes computed prototypes (cluster medoids) for the given samples
-          *@param   weights number of assignments for every cluster
-          *@param   assignment explicite assignments of features to computed cluster medoids
-          */            
-        void cluster ( const NICE::VVector & features,
-                      NICE::VVector & prototypes,
-                      std::vector<double> & weights,
-                      std::vector<int>    & assignment );
+        /**
+        *@brief this is the actual method that performs the clustering for a given set of features
+        *@author Erik Rodner, Alexander Freytag
+        *@date 29-10-2007 (dd-mm-yyyy)
+        *@param   features input features to be clustered
+        *@param   prototypes computed prototypes (cluster medoids) for the given samples
+        *@param   weights number of assignments for every cluster
+        *@param   assignment explicite assignments of features to computed cluster medoids
+        */            
+      void cluster ( const NICE::VVector & features,
+                    NICE::VVector & prototypes,
+                    std::vector<double> & weights,
+                    std::vector<int>    & assignment );
+      
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////      
+    
+    /**
+    * @brief Load object from external file (stream)
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void restore ( std::istream & is, int format = 0 );
+
+    /**
+    * @brief Save object to external file (stream)
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void store ( std::ostream & os, int format = 0 ) const;
+
+    /**
+    * @brief Clear object
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void clear ();          
 
   };
 

+ 142 - 8
math/cluster/KMeansHeuristic.cpp

@@ -18,25 +18,52 @@ using namespace NICE;
 
 #undef DEBUG_KMeansHeuristic
 
+
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+KMeansHeuristic::KMeansHeuristic() : ClusterAlgorithm()
+{
+  this->noClusters       = 20;
+  this->distanceType     = "euclidean";
+  this->distancefunction = NULL;
+}
+
 KMeansHeuristic::KMeansHeuristic(int _noClusters, string _distanceType) :
-	noClusters(_noClusters), distanceType(_distanceType)
+        noClusters(_noClusters), distanceType(_distanceType)
 {
   //srand(time(NULL));
-  distancefunction = GenericDistanceSelection::selectDistance(distanceType);
+  this->distancefunction = GenericDistanceSelection::selectDistance(distanceType);
 }
 
-KMeansHeuristic::KMeansHeuristic( const NICE::Config *conf, const std::string & _section)
-{       
-  this->distanceType = conf->gS( _section, "distanceType", "euclidean" );
-  this->distancefunction = GenericDistanceSelection::selectDistance(distanceType);
-  
-  this->noClusters = conf->gI( _section, "noClusters", 20);
+KMeansHeuristic::KMeansHeuristic( const NICE::Config * _conf, const std::string & _confSection)
+{  
+  this->initFromConfig( _conf, _confSection );
 }
 
+
 KMeansHeuristic::~KMeansHeuristic()
 {
+  if ( this->distancefunction != NULL )
+  {
+    delete this->distancefunction;
+    this->distancefunction = NULL ;
+  }    
+}
+
+
+void KMeansHeuristic::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  this->noClusters       = _conf->gI( _confSection, "noClusters", 20);
+  this->distanceType     = _conf->gS( _confSection, "distanceType", "euclidean" );
+  this->distancefunction = OBJREC::GenericDistanceSelection::selectDistance( this->distanceType );
 }
 
+///////////////////// ///////////////////// /////////////////////
+//                      CLUSTERING STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 void KMeansHeuristic::initial_guess(const VVector & features,
 		VVector & prototypes)
 {
@@ -321,3 +348,110 @@ void KMeansHeuristic::print_iteration(int iterations, VVector & prototypes,
 		cerr << "prototype = " << (*i) << endl;
 	}
 }
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void KMeansHeuristic::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "KMeansHeuristic" ) )
+    {
+      std::cerr << " WARNING - attempt to restore KMeansHeuristic, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "KMeansHeuristic" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );    
+      
+      if ( tmp.compare("noClusters") == 0 )
+      {
+        is >> this->noClusters;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("distanceType") == 0 )
+      {
+        is >> this->distanceType;
+        //TODO fixme
+        this->distancefunction = OBJREC::GenericDistanceSelection::selectDistance( this->distanceType );  
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("distancefunction") == 0 )
+      {
+        //TODO is >> this->distancefunction;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else
+      {
+      std::cerr << "WARNING -- unexpected KMeansHeuristic object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "KMeansHeuristic::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void KMeansHeuristic::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "KMeansHeuristic" ) << std::endl;
+    
+    os << this->createStartTag( "noClusters" ) << std::endl;
+    os << this->noClusters << std::endl;
+    os << this->createEndTag( "noClusters" ) << std::endl;  
+
+    os << this->createStartTag( "distanceType" ) << std::endl;
+    os << this->distanceType << std::endl;
+    os << this->createEndTag( "distanceType" ) << std::endl;
+    
+    os << this->createStartTag( "distancefunction" ) << std::endl;
+    //TODO os << this->distancefunction << std::endl;
+    os << this->createEndTag( "distancefunction" ) << std::endl;  
+    
+    // done
+    os << this->createEndTag( "KMeansHeuristic" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void KMeansHeuristic::clear ()
+{ 
+  if ( this->distancefunction != NULL )
+  {
+    delete this->distancefunction;
+    this->distancefunction = NULL ;
+  }    
+}

+ 69 - 7
math/cluster/KMeansHeuristic.h

@@ -1,7 +1,7 @@
 /** 
  * @file KMeansHeuristic.h
  * @brief K-Means
- * @author Erik Rodner, Michael Koch, Michael Trummer
+ * @author Erik Rodner, Michael Koch, Michael Trummer, Alexander Freytag
  * @date 02/04/2011
 
  */
@@ -10,8 +10,8 @@
 
 #include <core/basics/Config.h>
 #include <core/vector/Distance.h>
-#include "core/vector/VectorT.h"
-#include "core/vector/MatrixT.h"
+#include <core/vector/VectorT.h>
+#include <core/vector/MatrixT.h>
 
 #include "ClusterAlgorithm.h"
 
@@ -19,15 +19,29 @@
 namespace OBJREC
 {
 
-  /** K-Means (but what does Heuristic actually mean? )*/
-  class KMeansHeuristic: public ClusterAlgorithm
-  {
+/** K-Means (but what does Heuristic actually mean? )*/
+class KMeansHeuristic: public ClusterAlgorithm
+{
 
   protected:
+    
+    /************************
+    * 
+    *   protected variables
+    * 
+    **************************/         
     int noClusters;
+    
     std::string distanceType;
+    
     NICE::VectorDistance<double> *distancefunction;
     
+    /************************
+    * 
+    *   protected methods
+    * 
+    **************************/     
+    
     double compute_assignments(const NICE::VVector & features,
         const NICE::VVector & prototypes, std::vector<int> & assignment);
 
@@ -43,7 +57,19 @@ namespace OBJREC
     void print_iteration(int iterations, NICE::VVector & prototypes, double delta);
     int robust_prototypes(const NICE::VVector &features, NICE::VVector &prototypes, std::vector<
         double> & weights, const std::vector<int> & assignment);
+    
   public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// ///////////////////// 
+
+    /** 
+     * @brief default constructor
+     * @date 13-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    KMeansHeuristic ( );         
 
     /** simple constructor */
     KMeansHeuristic(int noClusters, std::string distanceMode = "euclidean");
@@ -55,12 +81,48 @@ namespace OBJREC
     * @date 14-06-2013 (dd-mm-yyyy)
     * @author Alexander Freytag
     */
-    KMeansHeuristic( const NICE::Config *conf, const std::string & _section = "KMeansHeuristic");    
+    KMeansHeuristic( const NICE::Config * _conf, const std::string & _confSection = "KMeansHeuristic");    
 
     /** simple destructor */
     virtual ~KMeansHeuristic();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 13-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "KMeansHeuristic");     
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      CLUSTERING STUFF
+    ///////////////////// ///////////////////// //////////////////       
 
     void cluster(const NICE::VVector & features, NICE::VVector & prototypes, std::vector<double> & weights, std::vector<int> & assignment);
+    
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////      
+    
+    /**
+    * @brief Load object from external file (stream)
+    * @author Alexander Freytag
+    * @date 13-02-2014 ( dd-mm-yyyy )
+    */
+    void restore ( std::istream & is, int format = 0 );
+
+    /**
+    * @brief Save object to external file (stream)
+    * @author Alexander Freytag
+    * @date 13-02-2014 ( dd-mm-yyyy )
+    */
+    void store ( std::ostream & os, int format = 0 ) const;
+
+    /**
+    * @brief Clear object
+    * @author Alexander Freytag
+    * @date 13-02-2014 ( dd-mm-yyyy )
+    */
+    void clear ();       
 
   };
 

+ 162 - 8
math/cluster/KMeansMatlab.cpp

@@ -19,17 +19,25 @@ using namespace NICE;
 
 #undef DEBUG_KMeansMatlab
 
-KMeansMatlab::KMeansMatlab( const Config *conf, const std::string & _section )
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+KMeansMatlab::KMeansMatlab() : ClusterAlgorithm()
 {
-  this->noClusters = conf->gI( _section, "noClusters", 20);
+  this->noClusters    = 20;
   
-    kmeansDir = conf->gS(_section, "source_root", "/home/rodner/osl/labor/cvs/osl/") + "/kernel/";
-    inputFN   = conf->gS(_section, "tmpInput", "/tmp/KMeansMatlab.input" );
-    outputFN   = conf->gS(_section, "tmpOutput", "/tmp/KMeansMatlab.output" );
+  this->kmeansDir     = "/home/rodner/osl/labor/cvs/osl/kernel/";
+  this->inputFN       = "/tmp/KMeansMatlab.input";
+  this->outputFN      = "/tmp/KMeansMatlab.output" ;
 
-    matlabExec = conf->gS(_section, "matlab_exec", "matlab");
-    matlabArgs = conf->gS(_section, "matlab_args", "-nosplash -nojvm -nodesktop");   
-    
+  this->matlabExec    = "matlab";
+  this->matlabArgs    = "-nosplash -nojvm -nodesktop";   
+}
+
+KMeansMatlab::KMeansMatlab( const NICE::Config * _conf, const std::string & _confSection )
+{
+  this->initFromConfig ( _conf, _confSection );   
 }
 
 KMeansMatlab::~KMeansMatlab()
@@ -38,6 +46,22 @@ KMeansMatlab::~KMeansMatlab()
     pclose (matlabPipe);
 }
 
+void KMeansMatlab::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  this->noClusters   = _conf->gI( _confSection, "noClusters", 20);
+  
+  this->kmeansDir    = _conf->gS(_confSection, "source_root", "/home/rodner/osl/labor/cvs/osl/") + "/kernel/";
+  this->inputFN      = _conf->gS(_confSection, "tmpInput", "/tmp/KMeansMatlab.input" );
+  this->outputFN     = _conf->gS(_confSection, "tmpOutput", "/tmp/KMeansMatlab.output" );
+
+  this->matlabExec   = _conf->gS(_confSection, "matlab_exec", "matlab");
+  this->matlabArgs   = _conf->gS(_confSection, "matlab_args", "-nosplash -nojvm -nodesktop"); 
+}
+
+///////////////////// ///////////////////// /////////////////////
+//                      CLUSTERING STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 
 int KMeansMatlab::compute_prototypes ( const VVector & features,
 				  VVector & prototypes,
@@ -204,3 +228,133 @@ void KMeansMatlab::cluster ( const VVector & features,
 	exit(-1);
     }
 }
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void KMeansMatlab::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "KMeansMatlab" ) )
+    {
+      std::cerr << " WARNING - attempt to restore KMeansMatlab, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "KMeansMatlab" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );   
+      
+      if ( tmp.compare("noClusters") == 0 )
+      {
+        is >> this->noClusters;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("kmeansDir") == 0 )
+      {
+        is >> this->kmeansDir;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("inputFN") == 0 )
+      {
+        is >> this->inputFN;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("outputFN") == 0 )
+      {
+        is >> this->outputFN;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("matlabExec") == 0 )
+      {
+        is >> this->matlabExec;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("matlabArgs") == 0 )
+      {
+        is >> this->matlabArgs;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else
+      {
+      std::cerr << "WARNING -- unexpected KMeansMatlab object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "KMeansMatlab::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void KMeansMatlab::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "KMeansMatlab" ) << std::endl;
+    
+    os << this->createStartTag( "noClusters" ) << std::endl;
+    os << this->noClusters << std::endl;
+    os << this->createEndTag( "noClusters" ) << std::endl;  
+
+    os << this->createStartTag( "kmeansDir" ) << std::endl;
+    os << this->kmeansDir << std::endl;
+    os << this->createEndTag( "kmeansDir" ) << std::endl;
+    
+    os << this->createStartTag( "inputFN" ) << std::endl;
+    os << this->inputFN << std::endl;
+    os << this->createEndTag( "inputFN" ) << std::endl;  
+
+    os << this->createStartTag( "outputFN" ) << std::endl;
+    os << this->outputFN << std::endl;
+    os << this->createEndTag( "outputFN" ) << std::endl;  
+
+    os << this->createStartTag( "matlabExec" ) << std::endl;
+    os << this->matlabExec << std::endl;
+    os << this->createEndTag( "matlabExec" ) << std::endl;
+    
+    os << this->createStartTag( "matlabArgs" ) << std::endl;
+    os << this->matlabArgs << std::endl;
+    os << this->createEndTag( "matlabArgs" ) << std::endl;  
+    
+    // done
+    os << this->createEndTag( "KMeansMatlab" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void KMeansMatlab::clear ()
+{ 
+}

+ 107 - 48
math/cluster/KMeansMatlab.h

@@ -17,58 +17,117 @@
 
 namespace OBJREC {
 
-  /** 
-  * @class KMeansMatlab
-  * @brief K-Means using a matlab implementation
-  * @author Erik Rodner
-  */
-
-  class KMeansMatlab : public ClusterAlgorithm
-  {
-
-      protected:
-        int noClusters;
-        // refactor-nice.pl: check this substitution
-        // old: string kmeansDir;
-        std::string kmeansDir;
-        // refactor-nice.pl: check this substitution
-        // old: string matlabExec;
-        std::string matlabExec;
-        // refactor-nice.pl: check this substitution
-        // old: string matlabArgs;
-        std::string matlabArgs;
-
-        // refactor-nice.pl: check this substitution
-        // old: string inputFN;
-        std::string inputFN;
-        // refactor-nice.pl: check this substitution
-        // old: string outputFN;
-        std::string outputFN;
-
-        FILE *matlabPipe;
-        
-        int compute_prototypes ( const NICE::VVector & features,
-                NICE::VVector & prototypes,
-                std::vector<double> & weights,
-                const std::vector<int>    & assignment );
+/** 
+* @class KMeansMatlab
+* @brief K-Means using a matlab implementation
+* @author Erik Rodner
+*/
 
+class KMeansMatlab : public ClusterAlgorithm
+{
 
-      public:
+  protected:
+    
+      /************************
+      * 
+      *   protected variables
+      * 
+      **************************/     
+      int noClusters;
+      // refactor-nice.pl: check this substitution
+      // old: string kmeansDir;
+      std::string kmeansDir;
+      // refactor-nice.pl: check this substitution
+      // old: string matlabExec;
+      std::string matlabExec;
+      // refactor-nice.pl: check this substitution
+      // old: string matlabArgs;
+      std::string matlabArgs;
+
+      // refactor-nice.pl: check this substitution
+      // old: string inputFN;
+      std::string inputFN;
+      // refactor-nice.pl: check this substitution
+      // old: string outputFN;
+      std::string outputFN;
+
+      FILE *matlabPipe;
+      
+      /************************
+      * 
+      *   protected methods
+      * 
+      **************************/        
+      
+      int compute_prototypes ( const NICE::VVector & features,
+              NICE::VVector & prototypes,
+              std::vector<double> & weights,
+              const std::vector<int>    & assignment );
+
+
+  public:
+        
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////        
+        
+    /** 
+     * @brief default constructor
+     * @date 13-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    KMeansMatlab ( );        
     
-        /** 
-        * @brief simple constructor
-        * @author Erik Rodner, Alexander Freytag
-        * Among others, you can specify for "section" the following attributes: "source_root", "tmpInput", "tmpOutput", "matlab_exec", "matlab_args"
-        */
-        KMeansMatlab( const NICE::Config *conf,  const std::string & _section = "KMeansMatlab" );
-            
-        /** simple destructor */
-        virtual ~KMeansMatlab();
+    /** 
+    * @brief simple constructor
+    * @author Erik Rodner, Alexander Freytag
+    * Among others, you can specify for "section" the following attributes: "source_root", "tmpInput", "tmpOutput", "matlab_exec", "matlab_args"
+    */
+    KMeansMatlab( const NICE::Config * _conf,  const std::string & _confSection = "KMeansMatlab" );
+        
+    /** simple destructor */
+    virtual ~KMeansMatlab();
+        
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 13-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "KMeansMatlab");         
+        
+    ///////////////////// ///////////////////// /////////////////////
+    //                      CLUSTERING STUFF
+    ///////////////////// ///////////////////// //////////////////         
           
-        void cluster ( const NICE::VVector & features,
-                NICE::VVector & prototypes,
-                std::vector<double> & weights,
-                std::vector<int>    & assignment );
+    void cluster ( const NICE::VVector & features,
+            NICE::VVector & prototypes,
+            std::vector<double> & weights,
+            std::vector<int>    & assignment );
+      
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////      
+    
+    /**
+    * @brief Load object from external file (stream)
+    * @author Alexander Freytag
+    * @date 13-02-2014 ( dd-mm-yyyy )
+    */
+    void restore ( std::istream & is, int format = 0 );
+
+    /**
+    * @brief Save object to external file (stream)
+    * @author Alexander Freytag
+    * @date 13-02-2014 ( dd-mm-yyyy )
+    */
+    void store ( std::ostream & os, int format = 0 ) const;
+
+    /**
+    * @brief Clear object
+    * @author Alexander Freytag
+    * @date 13-02-2014 ( dd-mm-yyyy )
+    */
+    void clear ();            
 
   };
 

+ 161 - 9
math/cluster/KMedian.cpp

@@ -40,32 +40,57 @@ struct CompareSecond
 #undef DEBUG_KMEDIAN_PROTOCOMP
 // #define DEBUG_KMEDIAN_PROTOCOMP
 
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+KMedian::KMedian() : ClusterAlgorithm() 
+{
+  this->noClusters       = 20;
+  this->distanceType     = "euclidean";
+  this->distancefunction = NULL;
+  this->d_minDelta       = 1e-5;
+  this->i_maxIterations  = 200;
+}
+
 
 KMedian::KMedian(const int & _noClusters, const std::string & _distanceType) :
   noClusters(_noClusters), distanceType(_distanceType)
 {
   //srand(time(NULL));
-  distancefunction = GenericDistanceSelection::selectDistance(distanceType);
+  this->distancefunction = GenericDistanceSelection::selectDistance( this->distanceType );
   
   this->d_minDelta  = 1e-5;
   this->i_maxIterations = 200;
 }
 
-KMedian::KMedian( const NICE::Config *conf, const std::string & _section)
+KMedian::KMedian( const NICE::Config * _conf, const std::string & _confSection)
 {       
-  this->distanceType = conf->gS( _section, "distanceType", "euclidean" );
-  this->distancefunction = GenericDistanceSelection::selectDistance(distanceType);
-  
-  this->d_minDelta  = conf->gD( _section, "minDelta", 1e-5 );
-  this->i_maxIterations = conf->gI( _section, "maxIterations", 200);
-  
-  this->noClusters = conf->gI( _section, "noClusters", 20);
+  this->initFromConfig( _conf, _confSection );
 }
 
 KMedian::~KMedian()
 {
+  if ( this->distancefunction != NULL )
+  {
+    delete this->distancefunction;
+    this->distancefunction = NULL ;
+  }
+}
+
+void KMedian::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  this->noClusters       = _conf->gI( _confSection, "noClusters", 20);  
+  this->distanceType     = _conf->gS( _confSection, "distanceType", "euclidean" );
+  this->distancefunction = OBJREC::GenericDistanceSelection::selectDistance( this->distanceType );  
+  this->d_minDelta       = _conf->gD( _confSection, "minDelta", 1e-5 );
+  this->i_maxIterations  = _conf->gI( _confSection, "maxIterations", 200);
 }
 
+///////////////////// ///////////////////// /////////////////////
+//                      CLUSTERING STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 void KMedian::initial_guess(const VVector & features, VVector & prototypes)
 {
   int j = 0;
@@ -428,3 +453,130 @@ void KMedian::print_iteration( int iterations, VVector & prototypes, double delt
     cerr << "prototype = " << (*i) << endl;
   }
 }
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void KMedian::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "KMedian" ) )
+    {
+      std::cerr << " WARNING - attempt to restore KMedian, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "KMedian" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );    
+      
+      if ( tmp.compare("noClusters") == 0 )
+      {
+        is >> this->noClusters;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("distanceType") == 0 )
+      {
+        is >> this->distanceType;
+        //TODO fixme
+        this->distancefunction = OBJREC::GenericDistanceSelection::selectDistance( this->distanceType );  
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("distancefunction") == 0 )
+      {
+        //TODO is >> this->distancefunction;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("d_minDelta") == 0 )
+      {
+        is >> this->d_minDelta;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("i_maxIterations") == 0 )
+      {
+        is >> this->i_maxIterations;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else
+      {
+      std::cerr << "WARNING -- unexpected KMedian object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "KMedian::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void KMedian::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "KMedian" ) << std::endl;   
+    
+    os << this->createStartTag( "noClusters" ) << std::endl;
+    os << this->noClusters << std::endl;
+    os << this->createEndTag( "noClusters" ) << std::endl;  
+
+    os << this->createStartTag( "distanceType" ) << std::endl;
+    os << this->distanceType << std::endl;
+    os << this->createEndTag( "distanceType" ) << std::endl;
+    
+    os << this->createStartTag( "distancefunction" ) << std::endl;
+    //TODO os << this->distancefunction << std::endl;
+    os << this->createEndTag( "distancefunction" ) << std::endl;  
+
+    os << this->createStartTag( "d_minDelta" ) << std::endl;
+    os << this->d_minDelta << std::endl;
+    os << this->createEndTag( "d_minDelta" ) << std::endl; 
+    
+    os << this->createStartTag( "i_maxIterations" ) << std::endl;
+    os << this->i_maxIterations << std::endl;
+    os << this->createEndTag( "i_maxIterations" ) << std::endl;
+    
+    // done
+    os << this->createEndTag( "KMedian" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void KMedian::clear ()
+{
+  if ( this->distancefunction != NULL )
+  {
+    delete this->distancefunction;
+    this->distancefunction = NULL ;
+  }  
+}

+ 139 - 92
math/cluster/KMedian.h

@@ -17,111 +17,158 @@
 
 namespace OBJREC {
 
-  /**
-   * @class KMedian
-   * @brief KMedian (aka K-medoid)
-   * @author Alexander Freytag
-   * @date 23-04-2013 (dd-mm-yyyy)
-  */    
-  class KMedian : public ClusterAlgorithm
-  {
-
-      protected:
-        
-      /************************
-       * 
-       *   protected variables
-       * 
-       **************************/ 
+/**
+  * @class KMedian
+  * @brief KMedian (aka K-medoid)
+  * @author Alexander Freytag
+  * @date 23-04-2013 (dd-mm-yyyy)
+*/    
+class KMedian : public ClusterAlgorithm
+{
+
+    protected:
       
-        //! desired number of clusters
-        int noClusters;
-        
-        //! specify which distance to use for calculating assignments
-        std::string distanceType;
-        
-        //! the actual distance metric
-        NICE::VectorDistance<double> *distancefunction;
-        
-        //! maximum difference between prototype-solutions of two iterations for convergence
-        double d_minDelta;
-        
-        //! maximum number of iterations until convergence
-        int i_maxIterations;
-        
-  
-       /************************
-       * 
-       *   protected methods
-       * 
-       **************************/  
+    /************************
+      * 
+      *   protected variables
+      * 
+      **************************/ 
+    
+      //! desired number of clusters
+      int noClusters;
+      
+      //! specify which distance to use for calculating assignments
+      std::string distanceType;
+      
+      //! the actual distance metric
+      NICE::VectorDistance<double> *distancefunction;
+      
+      //! maximum difference between prototype-solutions of two iterations for convergence
+      double d_minDelta;
+      
+      //! maximum number of iterations until convergence
+      int i_maxIterations;
       
-        //! compute the distance between two features using the specified distance metric
-        double vectorDistance(const NICE::Vector &vector1, const NICE::Vector &vector2, uint distancetype);
-        
-        //! compute assignments of all given features wrt to the currently known prototypes (cluster medoids) == ~ E-step
-        double compute_assignments ( const NICE::VVector & features,
-                  const NICE::VVector & prototypes,
-                  std::vector<int> & assignment );
 
-        //! compute number of assignments for every currently found cluster
-        double compute_weights ( const NICE::VVector & features,
-              std::vector<double> & weights,
-              std::vector<int>    & assignment );
+      /************************
+      * 
+      *   protected methods
+      * 
+      **************************/  
+    
+      //! compute the distance between two features using the specified distance metric
+      double vectorDistance(const NICE::Vector &vector1, const NICE::Vector &vector2, uint distancetype);
+      
+      //! compute assignments of all given features wrt to the currently known prototypes (cluster medoids) == ~ E-step
+      double compute_assignments ( const NICE::VVector & features,
+                const NICE::VVector & prototypes,
+                std::vector<int> & assignment );
+
+      //! compute number of assignments for every currently found cluster
+      double compute_weights ( const NICE::VVector & features,
+            std::vector<double> & weights,
+            std::vector<int>    & assignment );
 
-        //! compute the difference between prototypes of previous iteration and those currently found
-        double compute_delta ( const NICE::VVector & oldprototypes,
-                    const NICE::VVector & prototypes );
+      //! compute the difference between prototypes of previous iteration and those currently found
+      double compute_delta ( const NICE::VVector & oldprototypes,
+                  const NICE::VVector & prototypes );
+
+      //! compute (update) prototypes given the current assignments == ~ M-step
+      int compute_prototypes ( const NICE::VVector & features,
+              NICE::VVector & prototypes,
+              std::vector<double> & weights,
+              const std::vector<int>    & assignment );
 
-        //! compute (update) prototypes given the current assignments == ~ M-step
-        int compute_prototypes ( const NICE::VVector & features,
+      //! have an initial guess, i.e., randomly pick some features as initial cluster centroids
+      void initial_guess ( const NICE::VVector & features,
+              NICE::VVector & prototypes );
+      
+      //! give additional information for the current iteration
+      void print_iteration ( int iterations, 
                 NICE::VVector & prototypes,
-                std::vector<double> & weights,
-                const std::vector<int>    & assignment );
+                double delta );
 
-        //! have an initial guess, i.e., randomly pick some features as initial cluster centroids
-        void initial_guess ( const NICE::VVector & features,
-                NICE::VVector & prototypes );
+  public:
         
-        //! give additional information for the current iteration
-        void print_iteration ( int iterations, 
-                  NICE::VVector & prototypes,
-                  double delta );
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// ///////////////////// 
 
-      public:
+    /** 
+     * @brief default constructor
+     * @date 12-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    KMedian ( );    
     
-        /**
-        * @brief simple constructor
-        * @param _noClusters the number of clusters to be computed
-        * @param _distanceMode a string specifying the distance function to be used (default: euclidean)
-        */
-        KMedian( const int & _noClusters , const std::string & _distanceMode="euclidean");
-        
-        /**
-        * @brief standard constructor
-        * @param conf config file specifying all relevant variable settings
-        * @param _section name of the section within the configfile where the settings can be found (default: KMedian)
-        */
-        KMedian( const NICE::Config *conf, const std::string & _section = "KMedian");
+    /**
+    * @brief simple constructor
+    * @param _noClusters the number of clusters to be computed
+    * @param _distanceMode a string specifying the distance function to be used (default: euclidean)
+    */
+    KMedian( const int & _noClusters , const std::string & _distanceMode="euclidean");
+    
+    /**
+    * @brief standard constructor
+    * @param conf config file specifying all relevant variable settings
+    * @param _section name of the section within the configfile where the settings can be found (default: KMedian)
+    */
+    KMedian( const NICE::Config * _conf, const std::string & _confSection = "KMedian");
 
+    
         
-            
-        /** simple destructor */
-        virtual ~KMedian();
-          
-        /**
-        *@brief this is the actual method that performs the clustering for a given set of features
-        *@author Alexander Freytag
-        *@date 25-04-2013 (dd-mm-yyyy)
-        *@param   features input features to be clustered
-        *@param   prototypes computed prototypes (cluster medoids) for the given samples
-        *@param   weights number of assignments for every cluster
-        *@param   assignment explicite assignments of features to computed cluster medoids
-        */        
-        void cluster ( const NICE::VVector & features,
-                NICE::VVector & prototypes,
-                std::vector<double> & weights,
+    /** simple destructor */
+    virtual ~KMedian();
+    
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 12-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "KMedian");     
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                      CLUSTERING STUFF
+    ///////////////////// ///////////////////// //////////////////       
+      
+    /**
+    *@brief this is the actual method that performs the clustering for a given set of features
+    *@author Alexander Freytag
+    *@date 25-04-2013 (dd-mm-yyyy)
+    *@param   features input features to be clustered
+    *@param   prototypes computed prototypes (cluster medoids) for the given samples
+    *@param   weights number of assignments for every cluster
+    *@param   assignment explicite assignments of features to computed cluster medoids
+    */        
+    void cluster ( const NICE::VVector & features,
+            NICE::VVector & prototypes,
+            std::vector<double> & weights,
                 std::vector<int>    & assignment );
+    
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////      
+    
+    /**
+    * @brief Load object from external file (stream)
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void restore ( std::istream & is, int format = 0 );
+
+    /**
+    * @brief Save object to external file (stream)
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void store ( std::ostream & os, int format = 0 ) const;
+
+    /**
+    * @brief Clear object
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void clear ();       
 
   };
 

+ 131 - 6
math/cluster/RandomClustering.cpp

@@ -25,25 +25,42 @@ using namespace std;
 using namespace NICE;
 
 
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+RandomClustering::RandomClustering() : ClusterAlgorithm()
+{
+  this->noClusters       = 20;
+  this->distanceType     = "euclidean";
+  this->distancefunction = NULL;
+}
 
 RandomClustering::RandomClustering(const int & _noClusters, const std::string & _distanceType) :
   noClusters(_noClusters), distanceType(_distanceType)
 {
 }
 
-RandomClustering::RandomClustering( const NICE::Config *conf, const std::string & _section)
+RandomClustering::RandomClustering( const NICE::Config * _conf, const std::string & _confSection)
 {  
-  this->noClusters = conf->gI( _section, "noClusters", 20);
-  std::cerr << "RandomClustering::RandomClustering -- noClusters: " << this->noClusters << std::endl;
-  
-  this->distanceType = conf->gS( _section, "distanceType", "euclidean" );
-  this->distancefunction = GenericDistanceSelection::selectDistance(distanceType);  
+  this->initFromConfig ( _conf, _confSection );
 }
 
 RandomClustering::~RandomClustering()
 {
 }
 
+void RandomClustering::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  this->noClusters       = _conf->gI( _confSection, "noClusters", 20);
+  this->distanceType     = _conf->gS( _confSection, "distanceType", "euclidean" );
+  this->distancefunction = OBJREC::GenericDistanceSelection::selectDistance( this->distanceType );
+}
+
+///////////////////// ///////////////////// /////////////////////
+//                      CLUSTERING STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 int RandomClustering::compute_prototypes(const NICE::VVector & _features, NICE::VVector & _prototypes,
     std::vector<double> & _weights, const std::vector<int> & _assignment)
 {
@@ -156,3 +173,111 @@ void RandomClustering::cluster(const NICE::VVector & _features,
   //compute corresponding weights
   this->compute_weights( _features, _weights, _assignment );
 }
+
+
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void RandomClustering::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "RandomClustering" ) )
+    {
+      std::cerr << " WARNING - attempt to restore RandomClustering, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "RandomClustering" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );    
+      
+      if ( tmp.compare("noClusters") == 0 )
+      {
+        is >> this->noClusters;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else if ( tmp.compare("distanceType") == 0 )
+      {
+        is >> this->distanceType;
+        //TODO fixme
+        this->distancefunction = OBJREC::GenericDistanceSelection::selectDistance( this->distanceType );  
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("distancefunction") == 0 )
+      {
+        //TODO is >> this->distancefunction;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else
+      {
+      std::cerr << "WARNING -- unexpected RandomClustering object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "RandomClustering::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void RandomClustering::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "RandomClustering" ) << std::endl;
+    
+    os << this->createStartTag( "noClusters" ) << std::endl;
+    os << this->noClusters << std::endl;
+    os << this->createEndTag( "noClusters" ) << std::endl;  
+
+    os << this->createStartTag( "distanceType" ) << std::endl;
+    os << this->distanceType << std::endl;
+    os << this->createEndTag( "distanceType" ) << std::endl;
+    
+    os << this->createStartTag( "distancefunction" ) << std::endl;
+    //TODO os << this->distancefunction << std::endl;
+    os << this->createEndTag( "distancefunction" ) << std::endl;  
+    
+    // done
+    os << this->createEndTag( "RandomClustering" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void RandomClustering::clear ()
+{ 
+  if ( this->distancefunction != NULL )
+  {
+    delete this->distancefunction;
+    this->distancefunction = NULL ;
+  }    
+}

+ 125 - 78
math/cluster/RandomClustering.h

@@ -16,95 +16,142 @@
 
 namespace OBJREC {
 
-  /**
-   * @class RandomClustering
-   * @brief Clustering by randomly picking some samples from the set of features as representatives
-   * @author Alexander Freytag
-   * @date 03-06-2013 (dd-mm-yyyy)
-  */    
-  class RandomClustering : public ClusterAlgorithm
-  {
-
-      protected:
-        
-      /************************
-       * 
-       *   protected variables
-       * 
-       **************************/ 
+/**
+  * @class RandomClustering
+  * @brief Clustering by randomly picking some samples from the set of features as representatives
+  * @author Alexander Freytag
+  * @date 03-06-2013 (dd-mm-yyyy)
+*/    
+class RandomClustering : public ClusterAlgorithm
+{
+
+  protected:
       
-        //! desired number of clusters
-        int noClusters;
-        
-        //! specify which distance to use for calculating assignments
-        std::string distanceType;
-        
-        //! the actual distance metric
-        NICE::VectorDistance<double> *distancefunction;        
-        
-  
-       /************************
-       * 
-       *   protected methods
-       * 
-       **************************/  
+    /************************
+      * 
+      *   protected variables
+      * 
+      **************************/ 
+    
+      //! desired number of clusters
+      int noClusters;
+      
+      //! specify which distance to use for calculating assignments
+      std::string distanceType;
+      
+      //! the actual distance metric
+      NICE::VectorDistance<double> *distancefunction;        
       
-        
-        //! compute assignments of all given features wrt to the currently known prototypes (cluster medoids) == ~ E-step
-        double compute_assignments ( const NICE::VVector & features,
-                  const NICE::VVector & prototypes,
-                  std::vector<int> & assignment );
 
-        //! compute number of assignments for every currently found cluster
-        double compute_weights ( const NICE::VVector & features,
+      /************************
+      * 
+      *   protected methods
+      * 
+      **************************/  
+    
+      
+      //! compute assignments of all given features wrt to the currently known prototypes (cluster medoids) == ~ E-step
+      double compute_assignments ( const NICE::VVector & features,
+                const NICE::VVector & prototypes,
+                std::vector<int> & assignment );
+
+      //! compute number of assignments for every currently found cluster
+      double compute_weights ( const NICE::VVector & features,
+            std::vector<double> & weights,
+            std::vector<int>    & assignment );
+
+
+      //! compute (update) prototypes given the current assignments == ~ M-step
+      int compute_prototypes ( const NICE::VVector & features,
+              NICE::VVector & prototypes,
               std::vector<double> & weights,
-              std::vector<int>    & assignment );
+              const std::vector<int>    & assignment );
 
+  public:
+    
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// /////////////////////    
+    
+    /** 
+     * @brief default constructor
+     * @date 13-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    RandomClustering ( );      
 
-        //! compute (update) prototypes given the current assignments == ~ M-step
-        int compute_prototypes ( const NICE::VVector & features,
-                NICE::VVector & prototypes,
-                std::vector<double> & weights,
-                const std::vector<int>    & assignment );
+    /**
+    * @brief simple constructor
+    * @param[in] _noClasses the number of clusters to be computed
+    * @param[in] _distanceMode a string specifying the distance function to be used (default: euclidean)* 
+    * @date 03-06-2013 (dd-mm-yyyy)
+    */
+    RandomClustering( const int & _noClasses , const std::string & _distanceMode="euclidean" );
+    
+    /**
+    * @brief standard constructor
+    * @param[in] conf config file specifying all relevant variable settings
+    * @param[in] _section name of the section within the configfile where the settings can be found (default: RandomClustering)
+    * @date 03-06-2013 (dd-mm-yyyy)
+    */
+    RandomClustering( const NICE::Config * _conf, const std::string & _confSection = "RandomClustering");
 
-      public:
     
-        /**
-        * @brief simple constructor
-        * @param[in] _noClasses the number of clusters to be computed
-        * @param[in] _distanceMode a string specifying the distance function to be used (default: euclidean)* 
-        * @date 03-06-2013 (dd-mm-yyyy)
-        */
-        RandomClustering( const int & _noClasses , const std::string & _distanceMode="euclidean" );
         
-        /**
-        * @brief standard constructor
-        * @param[in] conf config file specifying all relevant variable settings
-        * @param[in] _section name of the section within the configfile where the settings can be found (default: RandomClustering)
-        * @date 03-06-2013 (dd-mm-yyyy)
-        */
-        RandomClustering( const NICE::Config *conf, const std::string & _section = "RandomClustering");
-
+    /** simple destructor */
+    virtual ~RandomClustering();
+      
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 13-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "RandomClustering");         
         
-            
-        /** simple destructor */
-        virtual ~RandomClustering();
+    ///////////////////// ///////////////////// /////////////////////
+    //                      CLUSTERING STUFF
+    ///////////////////// ///////////////////// //////////////////         
           
-        /**
-        * @brief this is the actual method that performs the clustering for a given set of features
-        * @author Alexander Freytag
-        * @date 03-06-2013 (dd-mm-yyyy)
-        * @param   features input features to be clustered
-        * @param   prototypes computed prototypes (randomly chosen) for the given samples
-        * @param   weights number of assignments for every cluster
-        * @param   assignment explicite assignments of features to computed cluster medoids
-        */        
-        void cluster ( const NICE::VVector & features,
-                NICE::VVector & prototypes,
-                std::vector<double> & weights,
-                std::vector<int>    & assignment );
-
-  };
+    /**
+    * @brief this is the actual method that performs the clustering for a given set of features
+    * @author Alexander Freytag
+    * @date 03-06-2013 (dd-mm-yyyy)
+    * @param   features input features to be clustered
+    * @param   prototypes computed prototypes (randomly chosen) for the given samples
+    * @param   weights number of assignments for every cluster
+    * @param   assignment explicite assignments of features to computed cluster medoids
+    */        
+    void cluster ( const NICE::VVector & features,
+            NICE::VVector & prototypes,
+            std::vector<double> & weights,
+            std::vector<int>    & assignment );
+        
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////      
+    
+    /**
+    * @brief Load object from external file (stream)
+    * @author Alexander Freytag
+    * @date 13-02-2014 ( dd-mm-yyyy )
+    */
+    void restore ( std::istream & is, int format = 0 );
+
+    /**
+    * @brief Save object to external file (stream)
+    * @author Alexander Freytag
+    * @date 13-02-2014 ( dd-mm-yyyy )
+    */
+    void store ( std::ostream & os, int format = 0 ) const;
+
+    /**
+    * @brief Clear object
+    * @author Alexander Freytag
+    * @date 13-02-2014 ( dd-mm-yyyy )
+    */
+    void clear ();          
+
+};
 
 
 } // namespace

+ 124 - 4
math/cluster/SpectralCluster.cpp

@@ -1,7 +1,7 @@
 /** 
 * @file SpectralCluster.cpp
 * @brief spectral clustering by kmeans-clustering of eigenvectors
-* @author Erik Rodner
+* @author Erik Rodner, Alexander Freytag
 * @date 11/13/2007
 
 */
@@ -18,21 +18,42 @@ using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
+///////////////////// ///////////////////// /////////////////////
+//                   CONSTRUCTORS / DESTRUCTORS
+///////////////////// ///////////////////// /////////////////////
+
+SpectralCluster::SpectralCluster() : ClusterAlgorithm() , kmeans()
+{
+  this->noClusters  = 20;
+  this->alpha       = 1.0;
+}
+
 SpectralCluster::SpectralCluster ( int _noClusters, double alpha ) : noClusters(_noClusters), kmeans(_noClusters)
 {
     this->alpha = alpha;
 }
 
-SpectralCluster::SpectralCluster( const NICE::Config *conf, const std::string & _section) : kmeans(conf)
+SpectralCluster::SpectralCluster( const NICE::Config * _conf, const std::string & _confSection)
 {  
-  this->noClusters = conf->gI( _section, "noClusters", 20);
-  this->alpha = conf->gD( _section, "alpha", 1.0);
+  this->initFromConfig( _conf, _confSection );
 }
 
 SpectralCluster::~SpectralCluster()
 {
 }
 
+void SpectralCluster::initFromConfig( const NICE::Config* _conf, const std::string& _confSection )
+{
+  this->noClusters = _conf->gI( _confSection, "noClusters", 20);
+  this->alpha      = _conf->gD( _confSection, "alpha", 1.0);
+  
+  this->kmeans.initFromConfig( _conf );
+}
+
+///////////////////// ///////////////////// /////////////////////
+//                      CLUSTERING STUFF
+///////////////////// ///////////////////// ////////////////// 
+
 void SpectralCluster::getSimilarityMatrix ( const VVector & features, 
                                             NICE::Matrix & laplacian,
                                             double alpha )
@@ -230,3 +251,102 @@ void SpectralCluster::cluster ( const NICE::VVector & features,
     }
 }
 
+///////////////////// INTERFACE PERSISTENT /////////////////////
+// interface specific methods for store and restore
+///////////////////// INTERFACE PERSISTENT ///////////////////// 
+
+void SpectralCluster::restore ( std::istream & is, int format )
+{
+  //delete everything we knew so far...
+  this->clear();
+  
+  
+  if ( is.good() )
+  {
+    
+    std::string tmp;
+    is >> tmp; //class name 
+    
+    if ( ! this->isStartTag( tmp, "SpectralCluster" ) )
+    {
+      std::cerr << " WARNING - attempt to restore SpectralCluster, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+      throw;
+    }   
+    
+    bool b_endOfBlock ( false ) ;
+    
+    while ( !b_endOfBlock )
+    {
+      is >> tmp; // start of block 
+      
+      if ( this->isEndTag( tmp, "SpectralCluster" ) )
+      {
+        b_endOfBlock = true;
+        continue;
+      }      
+      
+      tmp = this->removeStartTag ( tmp );    
+      
+      if ( tmp.compare("noClusters") == 0 )
+      {
+        is >> this->noClusters;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }          
+      else if ( tmp.compare("alpha") == 0 )
+      {
+        is >> this->alpha;
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }      
+      else if ( tmp.compare("kmeans") == 0 )
+      {
+        this->kmeans.restore ( is );
+        is >> tmp; // end of block 
+        tmp = this->removeEndTag ( tmp );
+      }
+      else
+      {
+      std::cerr << "WARNING -- unexpected SpectralCluster object -- " << tmp << " -- for restoration... aborting" << std::endl;
+      throw;
+      }
+    }
+  }
+  else
+  {
+    std::cerr << "SpectralCluster::restore -- InStream not initialized - restoring not possible!" << std::endl;
+    throw;
+  }
+}
+
+void SpectralCluster::store ( std::ostream & os, int format ) const
+{ 
+  if (os.good())
+  {
+    // show starting point
+    os << this->createStartTag( "SpectralCluster" ) << std::endl;
+    
+    os << this->createStartTag( "noClusters" ) << std::endl;
+    os << this->noClusters << std::endl;
+    os << this->createEndTag( "noClusters" ) << std::endl;  
+
+    os << this->createStartTag( "alpha" ) << std::endl;
+    os << this->alpha << std::endl;
+    os << this->createEndTag( "alpha" ) << std::endl;
+    
+    os << this->createStartTag( "kmeans" ) << std::endl;
+    this->kmeans.store ( os );
+    os << this->createEndTag( "kmeans" ) << std::endl; 
+    
+    // done
+    os << this->createEndTag( "SpectralCluster" ) << std::endl;    
+  }
+  else
+  {
+    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+  }
+}
+
+void SpectralCluster::clear ()
+{ 
+}

+ 90 - 42
math/cluster/SpectralCluster.h

@@ -1,7 +1,7 @@
 /** 
 * @file SpectralCluster.h
 * @brief spectral clustering by kmeans-clustering of eigenvectors
-* @author Erik Rodner
+* @author Erik Rodner, Alexander Freytag
 * @date 11/13/2007
 
 */
@@ -17,49 +17,97 @@
 
 namespace OBJREC {
 
-  /** spectral clustering by kmeans-clustering of eigenvectors */
-  class SpectralCluster : public ClusterAlgorithm
-  {
-
-      protected:
-        int noClusters;
-        double alpha;
-
-        KMeans kmeans;
-
-        enum {
-            L_UNNORMALIZED  = 0,
-            L_RW_NORMALIZED 
-        };
-
-        virtual void computeLaplacian ( const NICE::VVector & features,
-                NICE::Matrix & laplacian,
-                int method, double alpha );
-
-
-        virtual void getSimilarityMatrix ( const NICE::VVector & features, 
-                    NICE::Matrix & laplacian, double alpha );
-      public:
+/** spectral clustering by kmeans-clustering of eigenvectors */
+class SpectralCluster : public ClusterAlgorithm
+{
+
+  protected:
+      int noClusters;
+      double alpha;
+
+      KMeans kmeans;
+
+      enum {
+          L_UNNORMALIZED  = 0,
+          L_RW_NORMALIZED 
+      };
+
+      virtual void computeLaplacian ( const NICE::VVector & features,
+              NICE::Matrix & laplacian,
+              int method, double alpha );
+
+
+      virtual void getSimilarityMatrix ( const NICE::VVector & features, 
+                  NICE::Matrix & laplacian, double alpha );
+  public:
+      
+    ///////////////////// ///////////////////// /////////////////////
+    //                   CONSTRUCTORS / DESTRUCTORS
+    ///////////////////// ///////////////////// ///////////////////// 
+
+    /** 
+     * @brief default constructor
+     * @date 12-02-2014 (dd-mm-yyyy )
+     * @author Alexander Freytag
+     */
+    SpectralCluster ( );       
+  
+    /** simple constructor */
+    SpectralCluster (int _noClusters, double alpha);
+    
+    /**
+    * @brief standard constructor
+    * @param conf config file specifying all relevant variable settings
+    * @param _section name of the section within the configfile where the settings can be found (default: SpectralCluster)
+    * @date 14-06-2013 (dd-mm-yyyy)
+    * @author Alexander Freytag
+    */
+    SpectralCluster( const NICE::Config *conf, const std::string & _section = "SpectralCluster");     
+        
+    /** simple destructor */
+    virtual ~SpectralCluster();
+      
+    /** 
+     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
+     * @author Alexander Freytag
+     * @date 12-02-2014 ( dd-mm-yyyy )
+     */    
+    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "SpectralCluster");     
     
-        /** simple constructor */
-        SpectralCluster (int _noClusters, double alpha);
+    ///////////////////// ///////////////////// /////////////////////
+    //                      CLUSTERING STUFF
+    ///////////////////// ///////////////////// //////////////////       
         
-        /**
-        * @brief standard constructor
-        * @param conf config file specifying all relevant variable settings
-        * @param _section name of the section within the configfile where the settings can be found (default: SpectralCluster)
-        * @date 14-06-2013 (dd-mm-yyyy)
-        * @author Alexander Freytag
-        */
-        SpectralCluster( const NICE::Config *conf, const std::string & _section = "SpectralCluster");     
-            
-        /** simple destructor */
-        virtual ~SpectralCluster();
-          
-        void cluster ( const NICE::VVector & features,
-                NICE::VVector & prototypes,
-                std::vector<double> & weights,
-                std::vector<int>    & assignment );
+    void cluster ( const NICE::VVector & features,
+            NICE::VVector & prototypes,
+            std::vector<double> & weights,
+            std::vector<int>    & assignment );
+        
+      
+    ///////////////////// INTERFACE PERSISTENT /////////////////////
+    // interface specific methods for store and restore
+    ///////////////////// INTERFACE PERSISTENT /////////////////////      
+    
+    /**
+    * @brief Load object from external file (stream)
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void restore ( std::istream & is, int format = 0 );
+
+    /**
+    * @brief Save object to external file (stream)
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void store ( std::ostream & os, int format = 0 ) const;
+
+    /**
+    * @brief Clear object
+    * @author Alexander Freytag
+    * @date 12-02-2014 ( dd-mm-yyyy )
+    */
+    void clear ();           
 
   };
 

+ 90 - 0
math/cluster/tests/TestGenericClusterAlgorithmSelectionPersistent.cpp

@@ -0,0 +1,90 @@
+/** 
+ * @file TestGenericClusterAlgoSelectionPersistent.cpp
+ * @brief CppUnit-Testcase to create a ClusterAlgoRepresentation object via GenericClusterAlgoSelection, to store it, and to restore it again.
+ * @author Alexander Freytag
+ * @date 12-02-2014 ( dd-mm-yyyy )
+*/
+
+#ifdef NICE_USELIB_CPPUNIT
+
+// STL includes
+
+// NICE-core includes
+
+// gp-hik-core includes
+
+#include "TestGenericClusterAlgorithmSelectionPersistent.h"
+
+using namespace std; //C basics
+using namespace NICE;  // nice-core
+
+const bool verboseStartEnd = true;
+const bool verbose = true;
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( TestGenericClusterAlgoSelectionPersistent );
+
+void TestGenericClusterAlgoSelectionPersistent::setUp() {
+}
+
+void TestGenericClusterAlgoSelectionPersistent::tearDown() {
+}
+void TestGenericClusterAlgoSelectionPersistent::testPersistentMethods()
+{
+  
+  if (verboseStartEnd)
+    std::cerr << "================== TestGenericClusterAlgoSelectionPersistent::testPersistentMethods ===================== " << std::endl;  
+  
+  NICE::Config conf;
+  conf.sS( "GenericClusterAlgoSelection", "clusterTechnique", "KMeans" );
+  OBJREC::ClusterAlgorithm  * cluster;  
+  
+  cluster = OBJREC::GenericClusterAlgorithmSelection::selectClusterAlgorithm ( &conf, "GenericClusterAlgoSelection");
+  
+  // TEST STORING ABILITIES
+  if ( verbose )
+    std::cerr << " TEST STORING ABILITIES FOR STANDARD LOCALFEATURE" << std::endl;
+  
+  std::string s_destination_save ( "myClusterAlgoSelection.txt" );
+  
+  std::filebuf fbOut;
+  fbOut.open ( s_destination_save.c_str(), ios::out );
+  std::ostream os (&fbOut);
+  //
+  cluster->store( os );
+  //   
+  fbOut.close();
+  
+  // TEST RESTORING ABILITIES
+  if ( verbose )
+    std::cerr << " TEST RESTORING ABILITIES FOR STANDARD LOCALFEATURE" << std::endl;
+    
+  OBJREC::ClusterAlgorithm * clusterRestore = NULL;  
+      
+  std::string s_destination_load ( "myClusterAlgoSelection.txt" );
+  
+  std::filebuf fbIn;
+  fbIn.open ( s_destination_load.c_str(), ios::in );
+  std::istream is (&fbIn);
+  //
+  OBJREC::GenericClusterAlgorithmSelection::restoreClusterAlgorithm ( clusterRestore, is );
+  //   
+  fbIn.close(); 
+  
+  // currently, we have no possibility to actually verify that the restore-operation was successfull, i.e.,
+  // it returned an object identical to the stored one.
+  // However, if we reached this point, at least something went right, so we should be happy...
+
+  // final clean up -- don't waste memory
+  if ( cluster != NULL )
+    delete cluster;
+    
+  if ( clusterRestore != NULL )
+    delete clusterRestore;
+  
+  if (verboseStartEnd)
+    std::cerr << "================== TestGenericClusterAlgoSelectionPersistent::testPersistentMethods done ===================== " << std::endl;  
+  
+}
+
+#endif

+ 31 - 0
math/cluster/tests/TestGenericClusterAlgorithmSelectionPersistent.h

@@ -0,0 +1,31 @@
+#ifndef _TESTGENERICCLUSTERALGOSELECTIONPERSISTENT_H
+#define _TESTGENERICCLUSTERALGOSELECTIONPERSISTENT_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <vislearning/math/cluster/GenericClusterAlgorithmSelection.h>
+
+/**
+ * CppUnit-Testcase. 
+ * @brief CppUnit-Testcase to create a ClutserAlgo object via GenericClusterAlgoSelection, to store it, and to restore it again.
+ * @author Alexander Freytag
+ * @date 13-02-2014 ( dd-mm-yyyy )
+ */
+class TestGenericClusterAlgoSelectionPersistent : public CppUnit::TestFixture {
+
+    CPPUNIT_TEST_SUITE( TestGenericClusterAlgoSelectionPersistent );
+         CPPUNIT_TEST(testPersistentMethods);
+      
+    CPPUNIT_TEST_SUITE_END();
+  
+ private:
+ 
+ public:
+    void setUp();
+    void tearDown();
+
+
+    void testPersistentMethods();
+};
+
+#endif // _TESTGENERICCLUSTERALGOSELECTIONPERSISTENT_H

+ 56 - 0
math/cluster/tests/TestKMedian.cpp

@@ -86,4 +86,60 @@ void TestKMedian::testKMedianClustering()
 }
 
 
+void TestKMedian::testKMedianPersistent() 
+{
+  if (verboseStartEnd)
+    std::cerr << "================== TestKMedian::testKMedianPersistent ===================== " << std::endl;
+  
+  Config * conf = new Config;
+  std::string section ( "KMedian" );
+  conf->sS( section, "distanceType", "euclidean" );
+  conf->sI( section, "maxIterations", 200 );
+  conf->sI( section, "noClusters", 2 );
+   
+  OBJREC::KMedian kMedian;
+  kMedian.initFromConfig( conf, section );
+  
+  // TEST STORING ABILITIES
+  if ( verbose )
+    std::cerr << " TEST STORING ABILITIES FOR KMEDIAN" << std::endl;
+  
+  std::string s_destination_save ( "myKMedian.txt" );
+  
+  std::filebuf fbOut;
+  fbOut.open ( s_destination_save.c_str(), ios::out );
+  std::ostream os (&fbOut);
+  //
+  kMedian.store( os );
+  //   
+  fbOut.close();
+  
+  // TEST RESTORING ABILITIES
+  if ( verbose )
+    std::cerr << " TEST RESTORING ABILITIES FOR KMEDIAN" << std::endl;
+    
+  OBJREC::KMedian kMedianRestore;  
+      
+  std::string s_destination_load ( "myKMedian.txt" );
+  
+  std::filebuf fbIn;
+  fbIn.open ( s_destination_load.c_str(), ios::in );
+  std::istream is (&fbIn);
+  //
+  kMedianRestore.restore( is );
+  //   
+  fbIn.close(); 
+  
+  // currently, we have no possibility to actually verify that the restore-operation was successfull, i.e.,
+  // it returned an object identical to the stored one.
+  // However, if we reached this point, at least something went right, so we should be happy...  
+  
+  //don't waste memory
+  delete conf;
+  
+  if (verboseStartEnd)
+    std::cerr << "================== TestKMedian::testKMedianPersistent done ===================== " << std::endl;
+}
+
+
 #endif

+ 4 - 0
math/cluster/tests/TestKMedian.h

@@ -14,6 +14,8 @@ class TestKMedian : public CppUnit::TestFixture {
     
     CPPUNIT_TEST(testKMedianClustering);
     
+    CPPUNIT_TEST(testKMedianPersistent);
+    
     CPPUNIT_TEST_SUITE_END();
   
  private:
@@ -26,6 +28,8 @@ class TestKMedian : public CppUnit::TestFixture {
     * Constructor / Destructor testing 
     */  
     void testKMedianClustering();
+    
+    void testKMedianPersistent();
 
 };
 

+ 1 - 1
progs/evaluateCompleteBoWPipeline.cpp

@@ -151,7 +151,7 @@ int main( int argc, char **argv )
   
   std::cerr << "CODEBOOK CREATION" << std::endl;
   
-  OBJREC::ClusterAlgorithm * clusterAlgo = OBJREC::GenericClusterAlgorithmSelection::selectClusterAlgo ( conf );
+  OBJREC::ClusterAlgorithm * clusterAlgo = OBJREC::GenericClusterAlgorithmSelection::selectClusterAlgorithm ( conf );
    
   NICE::VVector prototypes;