소스 검색

GenericLFSelection allows for generic restoring, added UnitTest, more persistent LFReps

Alexander Freytag 11 년 전
부모
커밋
4b03a071d7

+ 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!" );
+        }      
+    };
+    
 };
 
 }

+ 35 - 3
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();
@@ -70,7 +93,16 @@ void LFGenericLocal::store ( std::ostream & os, int format ) const
 
 void LFGenericLocal::clear ()
 { 
-  fthrow ( Exception, "LFGenericLocal::clear not implemented yet." );
-  //TODO  
+  if ( this->lf != NULL )
+  {
+    delete this->lf;
+    this->lf = NULL;
+  }
+
+  if ( this->id != NULL )
+  {
+    delete this->id;
+    this->id = NULL;
+  }
 }
 

+ 24 - 9
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
-  {
+/** generic local features */
+/** @class LFGenericLocal
+* @brief Generic local features ( actually: Random Sampling of POIs followed by SIFT as descriptor)
+*/  
+class LFGenericLocal : public LocalFeatureRepresentation
+{
 
-      protected:
+  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;
 
@@ -74,7 +89,7 @@ namespace OBJREC {
      */    
     virtual void clear ();           
 
-  };
+};
 
 
 } // namespace

+ 14 - 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;

+ 30 - 15
features/localfeatures/LFMikolajczyk.h

@@ -22,26 +22,41 @@ 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

+ 88 - 47
features/localfeatures/LFPatches.cpp

@@ -23,55 +23,84 @@ 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)));
-	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;
+  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);
+  }  
+}
 
-	}
-	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;
+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 +108,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;
@@ -314,6 +352,9 @@ void LFPatches::store ( std::ostream & os, int format ) const
 
 void LFPatches::clear ()
 { 
-  fthrow ( Exception, "LFPatches::clear not implemented yet." );
-  //TODO  
+  if ( this->id != NULL )
+  {
+    delete this->id;
+    this->id = NULL;
+  }
 }

+ 36 - 18
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,47 @@ protected:
 
 	void calcDescriptors(const ImagePyramid & imp, NICE::VVector & positions,
 			NICE::VVector & features) 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();    
 
-public:
-
-	/** simple constructor */
-	LFPatches(const NICE::Config *conf, int numPatches);
+    /** simple constructor */
+    LFPatches(const NICE::Config *conf, int numPatches);
 
-	/** simple destructor */
-	virtual ~LFPatches();
+    /** simple destructor */
+    virtual ~LFPatches();
+      
+    ///////////////////// ///////////////////// /////////////////////
+    //                      FEATURE STUFF
+    ///////////////////// ///////////////////// //////////////////        
 
-	int getDescSize() const;
+    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;
+    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 visualize(NICE::Image & img, const NICE::Vector & feature) const;
 
-	void visualizeFeatures(NICE::Image & mark, const NICE::VVector & positions,
-			size_t color) 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

+ 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))
+

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

@@ -0,0 +1,84 @@
+/** 
+ * @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 ( "myLocalFeatureSelection.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 ( "myLocalFeatureSelection.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...
+  
+    
+  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