Browse Source

added basics to vislearning and corrected the include paths

Alexander Luetz 13 years ago
commit
4f62dcb0ac
100 changed files with 13484 additions and 0 deletions
  1. 8 0
      Makefile
  2. 103 0
      Makefile.inc
  3. 170 0
      baselib/ColorSpace.cpp
  4. 67 0
      baselib/ColorSpace.h
  5. 115 0
      baselib/ColorSpace.tcc
  6. 76 0
      baselib/Conversions.cpp
  7. 45 0
      baselib/Conversions.h
  8. 74 0
      baselib/FastFilter.h
  9. 173 0
      baselib/FastFilter.tcc
  10. 111 0
      baselib/Globals.cpp
  11. 57 0
      baselib/Globals.h
  12. 675 0
      baselib/Gnuplot.cpp
  13. 151 0
      baselib/Gnuplot.h
  14. 287 0
      baselib/ICETools.cpp
  15. 104 0
      baselib/ICETools.h
  16. 8 0
      baselib/Makefile
  17. 103 0
      baselib/Makefile.inc
  18. 136 0
      baselib/Preprocess.cpp
  19. 61 0
      baselib/Preprocess.h
  20. 43 0
      baselib/ProgressBar.cpp
  21. 33 0
      baselib/ProgressBar.h
  22. 197 0
      baselib/ProgressBarQt.cpp
  23. 87 0
      baselib/ProgressBarQt.h
  24. 67 0
      baselib/RunningStat.cpp
  25. 44 0
      baselib/RunningStat.h
  26. 108 0
      baselib/RunningStatVector.cpp
  27. 53 0
      baselib/RunningStatVector.h
  28. 346 0
      baselib/VectorStatistics.cpp
  29. 74 0
      baselib/VectorStatistics.h
  30. 561 0
      baselib/cc.cpp
  31. 82 0
      baselib/cc.h
  32. 127 0
      baselib/cmdline.c
  33. 78 0
      baselib/cmdline.h
  34. 8 0
      baselib/doxygenDescription.h
  35. 1 0
      baselib/libdepend.inc
  36. 88 0
      baselib/progs/Makefile.inc
  37. 64 0
      baselib/progs/scaleKernelMatrix.cpp
  38. 55 0
      baselib/progs/testProgressBar.cpp
  39. 251 0
      cbaselib/BasicVectorTransformations.cpp
  40. 94 0
      cbaselib/BasicVectorTransformations.h
  41. 218 0
      cbaselib/BoundingBox.cpp
  42. 55 0
      cbaselib/BoundingBox.h
  43. 314 0
      cbaselib/CachedExample.cpp
  44. 309 0
      cbaselib/CachedExample.h
  45. 120 0
      cbaselib/CategoryInfo.cpp
  46. 48 0
      cbaselib/CategoryInfo.h
  47. 478 0
      cbaselib/ClassNames.cpp
  48. 110 0
      cbaselib/ClassNames.h
  49. 62 0
      cbaselib/ClassificationResult.cpp
  50. 88 0
      cbaselib/ClassificationResult.h
  51. 86 0
      cbaselib/ClassificationResults.cpp
  52. 57 0
      cbaselib/ClassificationResults.h
  53. 194 0
      cbaselib/Example.cpp
  54. 138 0
      cbaselib/Example.h
  55. 69 0
      cbaselib/Feature.cpp
  56. 72 0
      cbaselib/Feature.h
  57. 143 0
      cbaselib/FeaturePool.cpp
  58. 55 0
      cbaselib/FeaturePool.h
  59. 535 0
      cbaselib/ImageInfo.cpp
  60. 96 0
      cbaselib/ImageInfo.h
  61. 248 0
      cbaselib/KernelUtils.cpp
  62. 39 0
      cbaselib/KernelUtils.h
  63. 277 0
      cbaselib/LabeledFileList.cpp
  64. 64 0
      cbaselib/LabeledFileList.h
  65. 469 0
      cbaselib/LabeledSet.cpp
  66. 164 0
      cbaselib/LabeledSet.h
  67. 192 0
      cbaselib/LabeledSetSelection.h
  68. 44 0
      cbaselib/LabeledSetVectorTransform.cpp
  69. 42 0
      cbaselib/LabeledSetVectorTransform.h
  70. 330 0
      cbaselib/LocalizationAnalysis.cpp
  71. 71 0
      cbaselib/LocalizationAnalysis.h
  72. 510 0
      cbaselib/LocalizationResult.cpp
  73. 112 0
      cbaselib/LocalizationResult.h
  74. 8 0
      cbaselib/Makefile
  75. 103 0
      cbaselib/Makefile.inc
  76. 359 0
      cbaselib/MultiDataset.cpp
  77. 60 0
      cbaselib/MultiDataset.h
  78. 149 0
      cbaselib/PascalResults.cpp
  79. 46 0
      cbaselib/PascalResults.h
  80. 102 0
      cbaselib/Polygon.cpp
  81. 47 0
      cbaselib/Polygon.h
  82. 65 0
      cbaselib/VectorFeature.cpp
  83. 50 0
      cbaselib/VectorFeature.h
  84. 35 0
      cbaselib/VectorTransform.h
  85. 6 0
      cbaselib/libdepend.inc
  86. 33 0
      cbaselib/progs/ImageInfoTester.cpp
  87. 88 0
      cbaselib/progs/Makefile.inc
  88. 155 0
      cbaselib/progs/calcCurves.cpp
  89. 333 0
      cbaselib/progs/createNormTrainingSet.cpp
  90. 143 0
      cbaselib/progs/splitLabeledSetVector.cpp
  91. 52 0
      cbaselib/progs/statisticsLabeledSetVector.cpp
  92. 244 0
      cbaselib/progs/statisticsTrainingSet.cpp
  93. 79 0
      cbaselib/progs/testCachedExample.cpp
  94. 81 0
      cbaselib/progs/testLabeledSet.cpp
  95. 8 0
      classifier/Makefile
  96. 103 0
      classifier/Makefile.inc
  97. 84 0
      classifier/classifierbase/FeaturePoolClassifier.cpp
  98. 59 0
      classifier/classifierbase/FeaturePoolClassifier.h
  99. 103 0
      classifier/classifierbase/KernelClassifier.cpp
  100. 95 0
      classifier/classifierbase/KernelClassifier.h

+ 8 - 0
Makefile

@@ -0,0 +1,8 @@
+#TARGETS_FROM:=$(notdir $(patsubst %/,%,$(shell pwd)))/$(TARGETS_FROM)
+#$(info recursivly going up: $(TARGETS_FROM) ($(shell pwd)))
+
+all:
+
+%:
+	$(MAKE) TARGETS_FROM=$(notdir $(patsubst %/,%,$(shell pwd)))/$(TARGETS_FROM) -C .. $@
+

+ 103 - 0
Makefile.inc

@@ -0,0 +1,103 @@
+# LIBRARY-DIRECTORY-MAKEFILE
+# conventions:
+# - all subdirectories containing a "Makefile.inc" are considered sublibraries
+#   exception: "progs/" and "tests/" subdirectories!
+# - all ".C", ".cpp" and ".c" files in the current directory are linked to a
+#   library
+# - the library depends on all sublibraries 
+# - the library name is created with $(LIBNAME), i.e. it will be somehow
+#   related to the directory name and with the extension .a
+#   (e.g. lib1/sublib -> lib1_sublib.a)
+# - the library will be added to the default build list ALL_LIBRARIES
+
+# --------------------------------
+# - 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)
+ifeq "$(SUBDIR)" "./"
+SUBDIR:=
+endif
+
+# ------------------------
+# - 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
+#
+# you can specify libraries needed by the individual objects or by the whole
+# directory. the object specific additional libraries are only considered
+# when compiling the specific object files
+# TODO: update documentation...
+
+-include $(SUBDIR)libdepend.inc
+
+$(foreach d,$(filter-out %progs %tests,$(SUBDIRS_OF_$(SUBDIR))),$(eval $(call PKG_DEPEND_INT,$(d))))
+
+# ---------------------------
+# - 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.
+
+LIBRARY_BASENAME:=$(call LIBNAME,$(SUBDIR))
+ifneq "$(SUBDIR)" ""
+ALL_LIBRARIES+=$(LIBDIR)$(LIBRARY_BASENAME).$(LINK_FILE_EXTENSION)
+endif
+
+# ---------------------
+# - binary dependencies
+#
+# there is no way of determining the binary dependencies automatically, so we
+# follow conventions. the current library depends on all sublibraries.
+# all other dependencies have to be added manually by specifying, that the
+# current .pc file depends on some other .pc file. binaries depending on
+# libraries should exclusivelly use the .pc files as well.
+
+ifeq "$(SKIP_BUILD_$(OBJDIR))" "1"
+$(LIBDIR)$(LIBRARY_BASENAME).a:
+else
+$(LIBDIR)$(LIBRARY_BASENAME).a:$(OBJS) \
+	$(call PRINT_INTLIB_DEPS,$(PKGDIR)$(LIBRARY_BASENAME).a,.$(LINK_FILE_EXTENSION))
+endif
+
+$(PKGDIR)$(LIBRARY_BASENAME).pc: \
+	$(call PRINT_INTLIB_DEPS,$(PKGDIR)$(LIBRARY_BASENAME).pc,.pc)
+
+# -------------------
+# - 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))
+

+ 170 - 0
baselib/ColorSpace.cpp

@@ -0,0 +1,170 @@
+/** 
+ * @file ColorSpace.cpp
+ * @brief __DESC__
+ * @author Michael Koch
+ * @date 07/28/2008
+ */
+
+#include <vislearning/nice.h>
+
+#include <iostream>
+
+#include "ColorSpace.h"
+#include <math.h>
+#include "vislearning/baselib/cc.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+//bad position for this function
+void ColorSpace::ColorImagetoMultiChannelImage(const NICE::ColorImage &imgrgb,NICE::MultiChannelImageT<double> &genimg)
+{
+     genimg.reInit(imgrgb.width(),imgrgb.height(),3,true);
+     for(int y=0;y<imgrgb.height();y++)
+     {
+          for(int x=0;x<imgrgb.width();x++)
+          {
+               double r,g,b;
+               r=imgrgb.getPixelQuick(x,y,0);
+               g=imgrgb.getPixelQuick(x,y,1);
+               b=imgrgb.getPixelQuick(x,y,2);
+               genimg.set(x,y,r,0);
+               genimg.set(x,y,g,1);
+               genimg.set(x,y,b,2);
+          }
+     }
+}
+
+/*
+//TODO test it
+int checkRange(int in,int min=0,int max=255)
+{
+     int out=in;
+     
+     if(in<min)
+     {
+          out=min;
+     }
+     if(in>max)
+     {
+          out=max;
+     }
+     return out;
+}
+
+NICE::ColorImage ColorSpace::rgbtohsl(const NICE::ColorImage &imgrgb)
+{
+     NICE::ColorImage imghsl (imgrgb.width(), imgrgb.height());
+
+     for(int x=0;x<imgrgb.width();x++)
+     {
+          for(int y=0;y<imgrgb.height();y++)
+          {
+               double R,G,B,H,S,L;
+
+               R=(double)imgrgb.getPixel(x,y,0)/255.0;
+               G=(double)imgrgb.getPixel(x,y,1)/255.0;
+               B=(double)imgrgb.getPixel(x,y,2)/255.0;
+               ColorConversion::ccRGBtoHSL(R,G,B,&H,&S,&L);
+               imghsl.setPixel(x,y,0,(int)round(H*255.0));
+               imghsl.setPixel(x,y,1,(int)round(S*255.0));
+               imghsl.setPixel(x,y,2,(int)round(L*255.0));
+          }
+     }     
+     return imghsl;
+}
+
+NICE::ColorImage ColorSpace::hsltorgb(const NICE::ColorImage &imghsl)
+{
+     NICE::ColorImage imgrgb (imghsl.width(), imghsl.height());
+
+     for(int x=0;x<imghsl.width();x++)
+     {
+          for(int y=0;y<imghsl.height();y++)
+          {
+               double R,G,B,H,S,L;
+               H=(double)imghsl.getPixel(x,y,0)/255.0;
+               S=(double)imghsl.getPixel(x,y,1)/255.0;
+               L=(double)imghsl.getPixel(x,y,2)/255.0;
+             
+               ColorConversion::ccHSLtoRGB(H,S,L,&R,&G,&B);
+
+               imgrgb.setPixel(x,y,0,(int)round(R*255.0));
+
+               imgrgb.setPixel(x,y,1,(int)round(G*255.0));
+
+               imgrgb.setPixel(x,y,2,(int)round(B*255.0));
+          }
+     }     
+     return imgrgb;
+}
+        
+NICE::ColorImage ColorSpace::rgbtolab(const NICE::ColorImage &imgrgb)
+{
+     NICE::ColorImage imglab (imgrgb.width(), imgrgb.height());
+     //preprocessing RGB to XYZ
+     for(int x=0;x<imgrgb.width();x++)
+     {
+          for(int y=0;y<imgrgb.height();y++)
+          {
+               double R,G,B,X,Y,Z,L,a,b;
+               R=(double)imgrgb.getPixel(x,y,0)/255.0;
+               G=(double)imgrgb.getPixel(x,y,1)/255.0;
+               B=(double)imgrgb.getPixel(x,y,2)/255.0;
+               ColorConversion::ccRGBtoXYZ(R,G,B,&X,&Y,&Z,0);
+               ColorConversion::ccXYZtoCIE_Lab(X,Y,Z,&L,&a,&b,0);
+               imglab.setPixel(x,y,0,(int)round(L*255.0));
+               imglab.setPixel(x,y,1,(int)round(a*255.0));
+               imglab.setPixel(x,y,2,(int)round(b*255.0));
+          }
+     }     
+	 showImage ( *imglab.getChannel(0), "L" );
+     return imglab;
+}
+
+NICE::ColorImage ColorSpace::labtorgb(const NICE::ColorImage &imglab)
+{
+     NICE::ColorImage imgrgb (imglab.width(), imglab.height());
+     //preprocessing RGB to XYZ
+     for(int x=0;x<imglab.width();x++)
+     {
+          for(int y=0;y<imglab.height();y++)
+          {
+               double R,G,B,X,Y,Z,L,a,b;
+               L=(double)imglab.getPixel(x,y,0)/255.0;
+               a=(double)imglab.getPixel(x,y,1)/255.0;
+               b=(double)imglab.getPixel(x,y,2)/255.0;
+               
+               ColorConversion::ccCIE_LabtoXYZ(L,a,b,&X,&Y,&Z,0);
+               ColorConversion::ccXYZtoRGB(X,Y,Z,&R,&G,&B,0);
+               imgrgb.setPixel(x,y,0,(int)round(R*255.0));
+               imgrgb.setPixel(x,y,1,(int)round(G*255.0));
+               imgrgb.setPixel(x,y,2,(int)round(B*255.0));
+          }
+     }     
+     return imgrgb;
+}
+NICE::ColorImage ColorSpace::rgbtolms(const NICE::ColorImage &imgrgb)
+{
+     NICE::ColorImage imglms=NICE::ColorImage(imgrgb.width(),imgrgb.height());
+     //preprocessing RGB to XYZ
+     for(int x=0;x<imgrgb.width();x++)
+     {
+          for(int y=0;y<imgrgb.height();y++)
+          {
+               double R,G,B,X,Y,Z,L,M,S;
+               R=(double)imgrgb.getPixelQuick(x,y,0)/255.0;
+               G=(double)imgrgb.getPixelQuick(x,y,1)/255.0;
+               B=(double)imgrgb.getPixelQuick(x,y,2)/255.0;
+               
+               ColorConversion::ccRGBtoXYZ(R,G,B,&X,&Y,&Z,0);
+               ColorConversion::ccXYZtoLMS(X,Y,Z,&L,&M,&S);
+               imglms.setPixelQuick(x,y,0,checkRange((int)round(L*255.0)));
+               imglms.setPixelQuick(x,y,1,checkRange((int)round(M*255.0)));
+               imglms.setPixelQuick(x,y,2,checkRange((int)round(S*255.0)));
+          }
+     }     
+     return imglms;
+}*/
+

+ 67 - 0
baselib/ColorSpace.h

@@ -0,0 +1,67 @@
+/** 
+* @file ColorSpace.h
+* @brief color space conversion routines
+* @author Michael Koch
+* @date 07/28/2008
+
+*/
+#ifndef COLORSPACEINCLUDE
+#define COLORSPACEINCLUDE
+
+
+#include <vislearning/nice.h>
+
+#include "core/image/MultiChannelImageT.h"
+
+
+namespace OBJREC {
+
+/** @brief color space conversion routines */
+class ColorSpace
+{
+
+    protected:
+
+    public:
+	enum {
+	    COLORSPACE_RGB = 0,
+	    COLORSPACE_HSL,
+	    COLORSPACE_LAB,
+        COLORSPACE_LMS,
+        COLORSPACE_OPP,
+	    NUM_COLORSPACES
+	};
+//bad position choose better one
+    static void ColorImagetoMultiChannelImage(const NICE::ColorImage &imgrgb,NICE::MultiChannelImageT<double> &genimg);
+    
+#if 0	//entfernt, da Probleme mit Wertebereich, bitte GenericImage und generisches convert benutzen
+         /** convert RGB to hsl*/
+        static NICE::ColorImage rgbtohsl(const NICE::ColorImage &imgrgb);
+        /** convert hsl to RGB*/
+        static NICE::ColorImage hsltorgb(const NICE::ColorImage &imghsl);
+        
+        /** convert RGB to LAB*/
+        static NICE::ColorImage rgbtolab(const NICE::ColorImage &imgrgb);
+        
+        /** convert LAB to RGB*/
+        static NICE::ColorImage labtorgb(const NICE::ColorImage &imglab);
+        
+        /** convert RGB to LMS*/
+        
+        static NICE::ColorImage rgbtolms(const NICE::ColorImage &imgrgb);*/
+#endif
+
+	template<class SrcPixelType,class DstPixelType>
+	static void convert ( NICE::MultiChannelImageT<DstPixelType> & dst, 
+			      const NICE::MultiChannelImageT<SrcPixelType> & src,
+			      int dstColorSpace = COLORSPACE_HSL, 
+			      int srcColorSpace = COLORSPACE_RGB,
+			      double dstM = 255.0,
+			      double srcM = 255.0);
+};
+
+} // namespace
+
+#include "ColorSpace.tcc"
+
+#endif

+ 115 - 0
baselib/ColorSpace.tcc

@@ -0,0 +1,115 @@
+#include <assert.h>
+
+#include "cc.h"
+
+namespace OBJREC {
+
+template<class SrcPixelType,class DstPixelType>
+void ColorSpace::convert ( NICE::MultiChannelImageT<DstPixelType> & dst, const NICE::MultiChannelImageT<SrcPixelType> & src,
+	      int dstColorSpace, int srcColorSpace, double dstM, double srcM )
+{
+    assert ( (srcColorSpace >= 0) && (srcColorSpace < NUM_COLORSPACES) );
+    assert ( (dstColorSpace >= 0) && (dstColorSpace < NUM_COLORSPACES) );
+
+    dst.reInitFrom ( src, true );
+
+    if ( (srcColorSpace == COLORSPACE_RGB) && (dstColorSpace == COLORSPACE_HSL) )
+    {
+	 assert ( dst.numChannels == 3 );
+	 assert ( src.numChannels == 3 );
+
+	 long k = 0;
+	 for ( int y = 0 ; y < src.ysize ; y++ )
+	     for ( int x = 0 ; x < src.xsize ; x++,k++ )
+	     {
+	       double R,G,B,H,S,L;
+	       R=(double)src.data[0][k]/srcM;
+	       G=(double)src.data[1][k]/srcM;
+	       B=(double)src.data[2][k]/srcM;
+	       ColorConversion::ccRGBtoHSL(R,G,B,&H,&S,&L);
+	       dst.data[0][k] = (DstPixelType)(H*dstM);
+	       dst.data[1][k] = (DstPixelType)(S*dstM);
+	       dst.data[2][k] = (DstPixelType)(L*dstM);
+	    }
+    } 
+    else if ( (srcColorSpace == COLORSPACE_RGB) && (dstColorSpace == COLORSPACE_LAB) )
+     {
+          long k = 0;
+          for ( int y = 0 ; y < src.ysize ; y++ )
+               for ( int x = 0 ; x < src.xsize ; x++,k++ )
+          {
+               double R,G,B,X,Y,Z,L,a,b;
+               R=(double)src.data[0][k]/255.0;
+			   G=(double)src.data[1][k]/255.0;
+			   B=(double)src.data[2][k]/255.0;
+               ColorConversion::ccRGBtoXYZ(R,G,B,&X,&Y,&Z,0);
+               ColorConversion::ccXYZtoCIE_Lab(X,Y,Z,&L,&a,&b,0);
+               dst.data[0][k] = (DstPixelType)(L);
+               dst.data[1][k] = (DstPixelType)(a);
+               dst.data[2][k] = (DstPixelType)(b);
+          }
+     }
+	 else if ( (srcColorSpace == COLORSPACE_LAB) && (dstColorSpace == COLORSPACE_RGB) )
+	 {
+		 long k = 0;
+		 for ( int y = 0 ; y < src.ysize ; y++ )
+			 for ( int x = 0 ; x < src.xsize ; x++,k++ )
+		 {
+			 double R,G,B,X,Y,Z,L,a,b;
+			 L=(double)src.data[0][k];
+			 a=(double)src.data[1][k];
+			 b=(double)src.data[2][k];
+			 ColorConversion::ccCIE_LabtoXYZ(L,a,b,&X,&Y,&Z,0);
+			 ColorConversion::ccXYZtoRGB(X,Y,Z,&R,&G,&B,0);
+			 dst.data[0][k] = (DstPixelType)(R);
+			 dst.data[1][k] = (DstPixelType)(G);
+			 dst.data[2][k] = (DstPixelType)(B);
+		 }		 
+	 }
+     else if ( (srcColorSpace == COLORSPACE_RGB) && (dstColorSpace == COLORSPACE_LMS) )
+     {
+          long k = 0;
+          for ( int y = 0 ; y < src.ysize ; y++ )
+               for ( int x = 0 ; x < src.xsize ; x++,k++ )
+          {
+               double R,G,B,X,Y,Z,L,M,S;
+               R=(double)src.data[0][k]/srcM;
+               G=(double)src.data[1][k]/srcM;
+               B=(double)src.data[2][k]/srcM;
+               ColorConversion::ccRGBtoXYZ(R,G,B,&X,&Y,&Z,0);
+               ColorConversion::ccXYZtoLMS(X,Y,Z,&L,&M,&S);
+               dst.data[0][k] = (DstPixelType)(L);
+               dst.data[1][k] = (DstPixelType)(M);
+               dst.data[2][k] = (DstPixelType)(S);
+          }
+     }
+     else if ( (srcColorSpace == COLORSPACE_RGB) && (dstColorSpace == COLORSPACE_OPP) )
+{
+          long k = 0;
+          for ( int y = 0 ; y < src.ysize ; y++ )
+               for ( int x = 0 ; x < src.xsize ; x++,k++ )
+{
+               double R,G,B,X,Y,Z,L,M,S,Lum,LM,SLM;
+               R=(double)src.data[0][k]/srcM;
+               G=(double)src.data[1][k]/srcM;
+               B=(double)src.data[2][k]/srcM;
+               ColorConversion::ccRGBtoXYZ(R,G,B,&X,&Y,&Z,0);
+               ColorConversion::ccXYZtoLMS(X,Y,Z,&L,&M,&S);
+               ColorConversion::ccLMStoOPP(L,M,S,&Lum,&LM,&SLM);
+               
+               dst.data[0][k] = (DstPixelType)(Lum);
+               dst.data[1][k] = (DstPixelType)(LM);
+               dst.data[2][k] = (DstPixelType)(SLM);
+#ifdef DEBUG
+               fprintf(stderr,"R:%.4f G:%.4f B:%.4f X:%.4f Y:%.4f Z:%.4f L:%.4f M:%.4f S:%.4f Lum:%.4f LM:%.4f SLM:%.4f\n",R,G,B,X,Y,Z,L,M,S,Lum,LM,SLM);
+#endif
+}
+}
+     else {
+          fprintf (stderr, "ColorSpace::convert(): not yet implemented - SrcColorSpace %d -> DstColorSpace %d!!\n",srcColorSpace,dstColorSpace);
+	exit(-1);
+    }
+
+}
+
+}

+ 76 - 0
baselib/Conversions.cpp

@@ -0,0 +1,76 @@
+/** 
+* @file Conversions.cpp
+* @brief boring conversions
+* @author Erik Rodner
+* @date 02/19/2008
+
+*/
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+
+#include <iostream>
+#include <assert.h>
+
+#include "vislearning/baselib/Conversions.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+
+
+Conversions::Conversions()
+{
+}
+
+Conversions::~Conversions()
+{
+}
+
+vector<double> Conversions::stl_vector ( const NICE::Vector & x )
+{
+    vector<double> y;
+    for ( size_t i = 0 ; i < x.size(); i++ )
+	y.push_back(x[i]);
+    return y;
+}
+	
+void Conversions::resizeImage ( const NICE::Image & src, NICE::Image & dst, int newWidth, int newHeight )
+{
+    int nw = newWidth;
+    int nh = newHeight;
+    
+    if ( nw <= 0 ) {
+		assert ( nh > 0.0 );
+		nw = nh * src.width() / src.height();
+    }
+
+    if ( nh <= 0 ) {
+		nh = nw * src.height() / src.width();
+    }
+
+    dst.resize(nw, nh);
+    NICE::scale ( src, &dst );
+}
+
+void Conversions::resizeImage ( const NICE::ColorImage & src, NICE::ColorImage & dst, int newWidth, int newHeight )
+{
+    int nw = newWidth;
+    int nh = newHeight;
+ 
+ 	if ( nw <= 0 ) {
+		assert ( nh > 0.0 );
+		nw = nh * src.width() / src.height();
+    }
+
+    if ( nh <= 0 ) {
+		nh = nw * src.height() / src.width();
+    }
+   
+    dst.resize(nw, nh);
+    NICE::scale ( src, &dst );
+}

+ 45 - 0
baselib/Conversions.h

@@ -0,0 +1,45 @@
+/** 
+* @file Conversions.h
+* @brief boring conversions
+* @author Erik Rodner
+* @date 02/19/2008
+
+*/
+#ifndef CONVERSIONSINCLUDE
+#define CONVERSIONSINCLUDE
+
+
+#include <vislearning/nice.h>
+ 
+#include <vector>
+
+
+namespace OBJREC {
+
+/** @brief boring data conversions */
+class Conversions
+{
+
+    protected:
+
+    public:
+  
+	/** simple constructor */
+	Conversions();
+      
+	/** simple destructor */
+	virtual ~Conversions();
+
+	static std::vector<double> stl_vector ( const NICE::Vector & x );
+
+	static void resizeImage ( const NICE::Image & src, NICE::Image & dst, int newWidth, int newHeight );
+	static void resizeImage ( const NICE::ColorImage & src, NICE::ColorImage & dst, int newWidth, int newHeight );
+
+	static NICE::Image ReadImgAdv ( const std::string & filename, int normalizeWidth = -1, int normalizeHeight = -1 );
+     
+};
+
+
+} // namespace
+
+#endif

+ 74 - 0
baselib/FastFilter.h

@@ -0,0 +1,74 @@
+/** 
+* @file FastFilter.h
+* @brief standard filter functions e.g. gradient filters
+* @author Erik Rodner
+* @date 07/22/2008
+
+*/
+#ifndef FastFilterINCLUDE
+#define FastFilterINCLUDE
+
+
+namespace OBJREC {
+
+/** @brief standard filter functions e.g. gradient filters */
+class FastFilter
+{
+    public:
+
+	/** calculates gradient magnitude and gradient directions quantized in a number
+	 * of bins. 
+	 * @param pointer to the input image
+	 * @param xsize width of the image
+	 * @param ysize height of the image
+	 * @param gradient pointer to the destination memory for the gradient magnitude values
+	 * @param dir pointer to the destination memory for the gradient direction values
+	 * @param numBins number of bins used for the quantization of the gradient directions
+	 * @param usesigned if set put gradient directions alpha and - alpha in the same bin
+	 **/
+	template <class GrayValueType, class GradientMagnitudeType, class GradientDirectionType>
+	static void calcGradient ( 
+			  const GrayValueType *gray, 
+			  int xsize, int ysize,
+			  GradientMagnitudeType *gradient, 
+			  GradientDirectionType *dir, 
+			  int numBins, 
+			  bool usesigned );
+
+	/** calculates gradient magnitude and gradient directions of a color image (use
+	 * the channel with the maximum magnitude at each pixel).
+	 * The gradient direction is quantized in a number of bins. 
+	 * @param r first channel of the input image
+	 * @param g second channel of the input image
+	 * @param b third channel of the input image
+	 * @param xsize width of the image
+	 * @param ysize height of the image
+	 * @param gradient pointer to the destination memory for the gradient magnitude values
+	 * @param dir pointer to the destination memory for the gradient direction values
+	 * @param numBins number of bins used for the quantization of the gradient directions
+	 * @param usesigned if set put gradient directions alpha and - alpha in the same bin
+	 **/
+	template <class GrayValueType, class GradientMagnitudeType, class GradientDirectionType>
+	static void calcColorGradient ( 
+			  const GrayValueType *r, 
+			  const GrayValueType *g, 
+			  const GrayValueType *b, 
+			  int xsize, int ysize,
+			  GradientMagnitudeType *gradient, 
+			  GradientDirectionType *dir, 
+			  int numBins, 
+			  bool usesigned );
+
+	template <class SrcValueType, class DstValueType>
+	static void calcGradientY ( const SrcValueType *img, int xsize, int ysize, DstValueType *d );
+
+	template <class SrcValueType, class DstValueType>
+	static void calcGradientX ( const SrcValueType *img, int xsize, int ysize, DstValueType *d );
+
+};
+
+} // namespace
+
+#include "FastFilter.tcc"
+
+#endif

+ 173 - 0
baselib/FastFilter.tcc

@@ -0,0 +1,173 @@
+/** 
+* @file FastFilter.cpp
+* @brief color gradient
+* @author Erik Rodner
+* @date 07/22/2008
+
+*/
+#include <iostream>
+#include <math.h>
+
+#include "core/basics/FastMath.h"
+#include "FastFilter.h"
+
+using namespace std;
+using namespace NICE;
+using namespace OBJREC;
+
+/** global lookup tables */
+
+template <class SrcValueType, class DstValueType>
+void FastFilter::calcGradientX ( const SrcValueType *img, int xsize, int ysize, DstValueType *d )
+{
+    int k = 0;
+    for ( int y = 0 ; y < ysize ; y++ )
+    {
+	d[k] = 0.0;
+	k++;
+	for ( int x = 1 ; x < xsize-1 ; x++,k++ )
+	    d[k] = - img[k-1] + img[k+1];
+	d[k] = 0.0;
+	k++;
+    }
+}
+
+template <class SrcValueType, class DstValueType>
+void FastFilter::calcGradientY ( const SrcValueType *img, int xsize, int ysize, DstValueType *d )
+{
+    int k = xsize;
+    for ( int x = 0 ; x < xsize ; x++ )
+	d[x] = 0.0;
+    for ( int x = 0 ; x < xsize ; x++ )
+	d[x+xsize*(ysize-1)] = 0.0;
+
+    for ( int y = 1 ; y < ysize-1; y++ )
+	for ( int x = 0 ; x < xsize ; x++,k++ )
+	    d[k] = - img[k-xsize] + img[k+xsize];
+}
+
+template <class GrayValueType, class GradientMagnitudeType, class GradientDirectionType>
+void FastFilter::calcColorGradient ( 
+			  const GrayValueType *r, 
+			  const GrayValueType *g, 
+			  const GrayValueType *b, 
+			  int xsize, int ysize,
+			  GradientMagnitudeType *gradient, 
+			  GradientDirectionType *dir, 
+			  int numBins, 
+			  bool usesigned )
+{
+    double *atan2Table = FastMath::getSingleton().atan2Table;
+    double *sqrtTable = FastMath::getSingleton().sqrtTable;
+
+    double *rgx = new double[xsize*ysize];
+    calcGradientX ( r, xsize, ysize, rgx );
+    double *rgy = new double[xsize*ysize];
+    calcGradientY ( r, xsize, ysize, rgy );
+
+    double *ggx = new double[xsize*ysize];
+    calcGradientX ( g, xsize, ysize, ggx );
+    double *ggy = new double[xsize*ysize];
+    calcGradientY ( g, xsize, ysize, ggy );
+
+    double *bgx = new double[xsize*ysize];
+    calcGradientX ( b, xsize, ysize, bgx );
+    double *bgy = new double[xsize*ysize];
+    calcGradientY ( b, xsize, ysize, bgy );
+
+    double binq = usesigned ? 2*M_PI / numBins : M_PI / numBins;
+
+    int k = 0;
+    for ( int y = 0 ; y < ysize ; y++ )
+	for ( int x = 0 ; x < xsize ; x++,k++ )
+	{
+	    double rx = rgx[k];
+	    double ry = rgy[k];
+	    //GradientMagnitudeType g  = (GradientMagnitudeType)sqrt ( rx*rx + ry*ry );
+	    GradientMagnitudeType g  = (GradientMagnitudeType)sqrtTable [ (int)(rx*rx + ry*ry) ];
+	    double max = g;
+	    double mrx = rx;
+	    double mry = ry;
+
+	    rx = ggx[k];
+	    ry = ggy[k];
+	    g  = sqrt ( rx*rx + ry*ry );
+	    if ( g > max ) { max = g; mrx = rx ; mry = ry; };
+
+	    rx = bgx[k];
+	    ry = bgy[k];
+
+	    g  = sqrt ( rx*rx + ry*ry );
+	    if ( g > max ) { max = g; mrx = rx ; mry = ry; };
+
+	    gradient[k] = max;
+	    int a_index = ((int)ry+255)*(255*2+1) + ((int)rx+255);
+	    double angle = atan2Table[ a_index ];
+	    if ( usesigned ) {
+		if ( angle < 0 )
+		    angle = 2*M_PI + angle;
+	    } else {
+		if ( angle < 0 )
+		    angle = M_PI + angle;
+	    }
+
+	    GradientDirectionType bin = (GradientDirectionType)(angle / binq);
+
+	    dir[k] = bin < numBins ? bin : numBins - 1;
+	}
+
+    delete [] rgx;
+    delete [] rgy;
+    delete [] ggx;
+    delete [] ggy;
+    delete [] bgx;
+    delete [] bgy;
+}
+
+template <class GrayValueType, class GradientMagnitudeType, class GradientDirectionType>
+void FastFilter::calcGradient ( const GrayValueType *gray, 
+				  int xsize, int ysize,
+				  GradientMagnitudeType *gradient, 
+				  GradientDirectionType *dir, 
+				  int numBins, 
+				  bool usesigned )
+{
+    double *gx = new double[xsize*ysize];
+    calcGradientX ( gray, xsize, ysize, gx );
+    double *gy = new double[xsize*ysize];
+    calcGradientY ( gray, xsize, ysize, gy );
+    double *atan2Table = FastMath::getSingleton().atan2Table;
+    double *sqrtTable = FastMath::getSingleton().sqrtTable;
+
+    double binq = usesigned ? 2*M_PI / numBins : M_PI / numBins;
+
+    int k = 0;
+    for ( int y = 0 ; y < ysize ; y++ )
+	for ( int x = 0 ; x < xsize ; x++,k++ )
+	{
+	    double rx = gx[k];
+	    double ry = gy[k];
+	    //GradientMagnitudeType g  = (GradientMagnitudeType)sqrt ( rx*rx + ry*ry );
+	    GradientMagnitudeType g  = (GradientMagnitudeType)sqrtTable [ (int)(rx*rx + ry*ry) ];
+	    gradient[k] = g;
+
+	    int a_index = ((int)ry+255)*(255*2+1) + ((int)rx+255);
+	    double angle = atan2Table[ a_index ];
+
+	    if ( usesigned ) {
+		if ( angle < 0 )
+		    angle = 2*M_PI + angle;
+	    } else {
+		if ( angle < 0 )
+		    angle = M_PI + angle;
+	    }
+
+	    GradientDirectionType bin = (GradientDirectionType)(angle / binq);
+
+	    dir[k] = bin < numBins ? bin : numBins - 1;
+	}
+
+    delete [] gx;
+    delete [] gy;
+}
+

+ 111 - 0
baselib/Globals.cpp

@@ -0,0 +1,111 @@
+#include <iostream>
+
+#include "core/basics/StringTools.h"
+#include "vislearning/baselib/Globals.h"
+#include "core/basics/ossettings.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+using namespace OBJREC;
+using namespace NICE;
+using namespace std;
+
+
+
+std::string Globals::currentImgFN = "";
+
+void Globals::setCurrentImgFN ( const std::string & imgfn )
+{
+    currentImgFN = imgfn;
+}
+
+std::string Globals::getCurrentImgFN ( )
+{
+    return currentImgFN;
+}
+
+std::string Globals::getCacheFilename ( const std::string & root, int cache_mode )
+{
+    std::string filename = Globals::getCurrentImgFN();
+    vector<string> mylistdir;
+    StringTools::split ( filename, FILESEP, mylistdir );
+
+	int dirpart = 2;
+	if ( cache_mode == SORT_CATEGORIES_SECONDPART )
+	{
+		cache_mode = SORT_CATEGORIES;
+		dirpart = 3;
+	}
+
+    if ( cache_mode == SORT_CATEGORIES ) 
+    {
+      if ( mylistdir.size() < 2 )
+      {
+        cerr << "Globals::getCacheFilename: unable to parse filename " << filename << endl;
+        exit(-1);
+      }
+      std::string name = mylistdir[mylistdir.size()-1];
+      
+      vector<string> mylist;
+      StringTools::split ( name, '.', mylist );
+      
+      name = "";
+      for ( uint k = 0 ; k < mylist.size()-1 ; k++ )
+        if ( k == 0 )
+          name = name + mylist[k];
+        else 
+          name = name + "." + mylist[k];
+
+      std::string dir = root + FILESEPSTRING + mylistdir[mylistdir.size()-dirpart];
+
+      struct stat info;
+
+      if ( stat (dir.c_str(), &info ) < 0 ) {
+        if ( mkdir(dir.c_str(), 0755) < 0 )
+        {
+          cerr << "Globals::getCacheFilename: unable to create directory: " << dir << endl;
+          exit(-1);
+        }
+      }
+      
+      std::string id = dir + FILESEPSTRING + name;
+      return id;
+
+    } else if ( cache_mode == SORT_NONE ) {
+
+      vector<string> mylist;
+      std::string name = mylistdir[ mylistdir.size() - 1 ];
+
+      StringTools::split ( name, '.', mylist );
+      if ( mylist.size() != 2 )
+      {
+        cerr << "Globals::getCacheFilename: unable to parse filename " << name << endl;
+        exit(-1);
+      }
+      name = mylist[0];
+
+      std::string id = root + FILESEPSTRING + name;
+
+      return id;
+    } else {
+      fprintf (stderr, "Globals::getCacheFilename: unknown mode\n");
+    }
+
+    return "";
+}
+
+int Globals::getCacheMode ( const std::string & desc )
+{
+    if ( desc == "cat" ) {
+		return SORT_CATEGORIES;
+    } else if ( desc == "cat2" ) {
+		return SORT_CATEGORIES_SECONDPART;
+    } else if ( desc == "none" ) {
+		return SORT_NONE;
+    } else {
+		fprintf (stderr, "Globals::getCacheMode: mode unknown >%s<\n", desc.c_str() );
+		exit(-1);
+    }
+}

+ 57 - 0
baselib/Globals.h

@@ -0,0 +1,57 @@
+/** 
+* @file Globals.h
+* @brief some routines which provide access to global variables
+* @author Erik Rodner
+* @date 1/1/2008
+*/
+#ifndef GLOBALSINCLUDE
+#define GLOBALSINCLUDE
+
+#include <string>
+
+
+namespace OBJREC {
+
+/** @brief some routines which provide access to global variables */
+class Globals {
+    
+    private:
+
+    /** image filename which is currently processed */
+    static std::string currentImgFN;
+
+    public:
+
+	/** cache mode: none "none" (<root>/<imgfn>), categories "cat" (<root>/<last-dir-part>/<imgfn>),
+	    categories_secondpart "cat2" (<root>/<second-last-dir-part>/<imgfn>) */
+    enum {
+		SORT_NONE = 0,
+		SORT_CATEGORIES,
+		SORT_CATEGORIES_SECONDPART
+    };
+   
+    /** set filename of the image which is currently processed */
+    static void setCurrentImgFN ( const std::string & imgfn );
+
+    /** get filename of the image which is currently processed */
+    static std::string getCurrentImgFN ();
+
+    /** get a filename which can be used for caching
+	@param root root directory of the global cache
+	@param cache_mode mode of the caching
+	@return cache filename
+    */
+    static std::string getCacheFilename ( const std::string & root, int cache_mode );
+    
+    /** get cache mode
+	@param desc description of the cache
+	@return determined cache mode
+    */
+    static int getCacheMode ( const std::string & desc );
+
+};
+
+
+} // namespace
+
+#endif

+ 675 - 0
baselib/Gnuplot.cpp

@@ -0,0 +1,675 @@
+////////////////////////////////////////////
+//
+// A C++ interface to gnuplot. 
+//
+// This is a direct translation from the C interface
+// written by N. Devillard (which is available from
+// http://ndevilla.free.fr/gnuplot/).
+//
+// As in the C interface this uses pipes and so wont
+// run on a system that does'nt have POSIX pipe 
+// support
+//
+// Rajarshi Guha
+// <rajarshi@presidency.com>
+//
+// 07/03/03
+//
+////////////////////////////////////////////
+
+
+#include "vislearning/baselib/Gnuplot.h"
+
+using namespace OBJREC;
+#define PATH_MAXNAMESZ       4096
+
+using namespace std;
+
+/////////////////////////////
+//
+// A string tokenizer taken from
+// http://www.sunsite.ualberta.ca/Documentation/Gnu/libstdc++-2.90.8/html/21_strings/stringtok_std_h.txt
+//
+/////////////////////////////
+template<typename Container>
+void stringtok(Container &container, std::string const &in,
+		const char * const delimiters = " \t\n")
+{
+	const string::size_type len = in.length();
+	string::size_type i = 0;
+
+	while (i < len)
+	{
+		// eat leading whitespace
+		i = in.find_first_not_of(delimiters, i);
+		if (i == string::npos)
+			return; // nothing left but white space
+
+		// find the end of the token
+		string::size_type j = in.find_first_of(delimiters, i);
+
+		// push token
+		if (j == string::npos)
+		{
+			container.push_back(in.substr(i));
+			return;
+		}
+		else
+			container.push_back(in.substr(i, j - i));
+
+		// set up for next loop
+		i = j + 1;
+	}
+}
+
+//
+// Constructors
+//
+Gnuplot::Gnuplot(void)
+{
+	checkSystemVariablesOpenGnuplotCommand();
+	this->set_style("points");
+
+}
+
+Gnuplot::Gnuplot(const std::string &style)
+{
+	checkSystemVariablesOpenGnuplotCommand();
+	this->set_style(style);
+}
+
+Gnuplot::Gnuplot(const std::string &title, const std::string &style,
+		const std::string &labelx, const std::string &labely, vector<double> x,
+		vector<double> y)
+{
+	checkSystemVariablesOpenGnuplotCommand();
+
+	if (x.size() == 0 || y.size() == 0)
+		throw GnuplotException("vectors too small");
+
+	if (style == "")
+		this->set_style("lines");
+	else
+		this->set_style(style);
+
+	if (labelx == "")
+		this->set_xlabel("X");
+	else
+		this->set_xlabel(labelx);
+	if (labely == "")
+		this->set_ylabel("Y");
+	else
+		this->set_ylabel(labely);
+
+	this->plot_xy(x, y, title);
+
+	cout << "Press enter to continue" << endl;
+	while (getchar() != '\n')
+	{
+	}
+}
+
+Gnuplot::Gnuplot(const std::string &title, const std::string &style,
+		const std::string &labelx, const std::string &labely, vector<double> x)
+{
+	checkSystemVariablesOpenGnuplotCommand();
+
+	if (x.size() == 0)
+		throw GnuplotException("vector too small");
+	if (!this->gnucmd)
+		throw GnuplotException("Could'nt open connection to gnuplot");
+
+	if (style == "")
+		this->set_style("lines");
+	else
+		this->set_style(style);
+
+	if (labelx == "")
+		this->set_xlabel("X");
+	else
+		this->set_xlabel(labelx);
+	if (labely == "")
+		this->set_ylabel("Y");
+	else
+		this->set_ylabel(labely);
+
+	this->plot_x(x, title);
+
+	cout << "Press enter to continue" << endl;
+	while (getchar() != '\n')
+	{
+	}
+}
+
+void Gnuplot::checkSystemVariablesOpenGnuplotCommand()
+{
+
+	if (!this->get_program_path("gnuplot"))
+	{
+		this->valid = false;
+		throw GnuplotException("Can't find gnuplot in your PATH");
+	}
+	this->gnucmd = popen("gnuplot", "w");
+	if (!this->gnucmd)
+	{
+		this->valid = false;
+		throw GnuplotException("Could'nt open connection to gnuplot");
+	}
+	if (getenv("DISPLAY") == NULL)
+	{
+		if (this->gnucmd)
+		{
+			fprintf(stderr, "no Display found, changing to Terminal PNG\n");
+			setFileOutput("png", "gnuplot_automatic_tmp_image.png");
+		}
+	}
+	this->nplots = 0;
+	this->valid = true;
+}
+
+Gnuplot::~Gnuplot()
+{
+	if (pclose(this->gnucmd) == -1)
+		cerr << "Problem closing communication to gnuplot" << endl;
+	if ((this->to_delete).size() > 0)
+	{
+		for (vector<string>::size_type i = 0; i < this->to_delete.size(); i++)
+			remove(this->to_delete[i].c_str());
+		to_delete.clear();
+	}
+	return;
+}
+
+bool Gnuplot::is_valid(void)
+{
+	return (this->valid);
+}
+
+bool Gnuplot::get_program_path(const std::string pname)
+{
+	list<string> ls;
+	char *path;
+
+	path = getenv("PATH");
+	if (!path)
+	{
+		cerr << "Path is not set" << endl;
+		return false;
+	}
+	else
+	{
+		stringtok(ls, path, ":");
+		for (list<string>::const_iterator i = ls.begin(); i != ls.end(); ++i)
+		{
+			std::string tmp = (*i) + "/" + pname;
+			if (access(tmp.c_str(), X_OK) == 0)
+				return true;
+		}
+	}
+	return false;
+}
+
+void Gnuplot::reset_plot(void)
+{
+	if (this->to_delete.size() > 0)
+	{
+		for (vector<string>::size_type i = 0; i < this->to_delete.size(); i++)
+			remove(this->to_delete[i].c_str());
+		to_delete.clear();
+	}
+	this->nplots = 0;
+	return;
+}
+
+void Gnuplot::set_style(const std::string &stylestr)
+{
+	if (stylestr != "lines" && stylestr != "points" && stylestr
+			!= "linespoints" && stylestr != "impulses" && stylestr != "dots"
+			&& stylestr != "steps" && stylestr != "errorbars" && stylestr
+			!= "boxes" && stylestr != "boxerrorbars")
+		this->pstyle = string("points");
+	else
+		this->pstyle = stylestr;
+}
+
+void Gnuplot::cmd(const char *cmdstr, ...)
+{
+	va_list ap;
+	char local_cmd[GP_CMD_SIZE];
+
+	va_start(ap, cmdstr);
+	vsprintf(local_cmd, cmdstr, ap);
+	va_end(ap);
+	strcat(local_cmd, "\n");
+	fputs(local_cmd, this->gnucmd);
+	fflush(this->gnucmd);
+	return;
+}
+void Gnuplot::setFileOutput(const string &terminal, const string &filename)
+{
+
+	ostringstream cmdstr;
+	cmdstr << "set terminal " << terminal;
+
+	this->cmd(cmdstr.str().c_str());
+	cmdstr.str("");
+
+	cmdstr << "set output \"" << filename << "\"";
+	this->cmd(cmdstr.str().c_str());
+
+}
+void Gnuplot::set_ylabel(const std::string &label)
+{
+	std::ostringstream cmdstr;
+
+	cmdstr << "set xlabel \"" << label << "\"";
+	this->cmd(cmdstr.str().c_str());
+
+	return;
+}
+
+void Gnuplot::set_xlabel(const std::string &label)
+{
+	std::ostringstream cmdstr;
+
+	cmdstr << "set xlabel \"" << label << "\"";
+	this->cmd(cmdstr.str().c_str());
+
+	return;
+}
+
+void Gnuplot::set_zlabel(const std::string &label)
+{
+	std::ostringstream cmdstr;
+
+	cmdstr << "set zlabel \"" << label << "\"";
+	this->cmd(cmdstr.str().c_str());
+
+	return;
+}
+// set the xrange
+void Gnuplot::set_xrange(const int iFrom, const int iTo)
+{
+	std::ostringstream cmdstr;
+
+	cmdstr << "set xrange[" << iFrom << ":" << iTo << "]";
+	this->cmd(cmdstr.str().c_str());
+
+	return;
+}
+// set the yrange
+void Gnuplot::set_yrange(const int iFrom, const int iTo)
+{
+	std::ostringstream cmdstr;
+
+	cmdstr << "set yrange[" << iFrom << ":" << iTo << "]";
+	this->cmd(cmdstr.str().c_str());
+
+	return;
+}
+// set the zrange
+void Gnuplot::set_zrange(const int iFrom, const int iTo)
+{
+	std::ostringstream cmdstr;
+
+	cmdstr << "set zrange[" << iFrom << ":" << iTo << "]";
+	this->cmd(cmdstr.str().c_str());
+
+	return;
+}
+// set the palette range
+void Gnuplot::set_cbrange(const int iFrom, const int iTo)
+{
+	std::ostringstream cmdstr;
+
+	cmdstr << "set cbrange[" << iFrom << ":" << iTo << "]";
+	this->cmd(cmdstr.str().c_str());
+
+	return;
+}
+
+// 
+// Plots a linear equation (where you supply the
+// slope and intercept)
+//
+void Gnuplot::plot_slope(double a, double b, const std::string &title)
+{
+	std::ostringstream stitle;
+	std::ostringstream cmdstr;
+
+	if (title == "")
+		stitle << "no title";
+	else
+		stitle << title;
+
+	if (this->nplots > 0)
+		cmdstr << "replot " << a << " * x + " << b << " title \""
+				<< stitle.str() << "\" with " << pstyle;
+	else
+		cmdstr << "plot " << a << " * x + " << b << " title \"" << stitle.str()
+				<< "\" with " << pstyle;
+	this->cmd(cmdstr.str().c_str());
+	this->nplots++;
+	return;
+}
+
+//
+// Plot an equation which is supplied as a string
+// 
+void Gnuplot::plot_equation(const std::string &equation,
+		const std::string &title)
+{
+	std::string titlestr, plotstr;
+	std::ostringstream cmdstr;
+
+	if (title == "")
+		titlestr = "no title";
+	else
+		titlestr = title;
+
+	if (this->nplots > 0)
+		plotstr = "replot";
+	else
+		plotstr = "plot";
+
+	cmdstr << plotstr << " " << equation << " " << "title \"" << titlestr
+			<< "\" with " << this->pstyle;
+	this->cmd(cmdstr.str().c_str());
+	this->nplots++;
+
+	return;
+}
+
+void Gnuplot::plot_x(vector<double> d, const std::string &title)
+{
+	ofstream tmp;
+	std::ostringstream cmdstr;
+	char name[] = "/tmp/gnuplotiXXXXXX";
+
+	if (this->to_delete.size() == GP_MAX_TMP_FILES - 1)
+	{
+		cerr << "Maximum number of temporary files reached ("
+				<< GP_MAX_TMP_FILES << "): cannot open more files" << endl;
+		return;
+	}
+
+	//
+	//open temporary files for output
+	if (mkstemp(name) == -1)
+	{
+		cerr << "Cannot create temporary file: exiting plot" << endl;
+		return;
+	}
+	tmp.open(name);
+	if (tmp.bad())
+	{
+		cerr << "Cannot create temorary file: exiting plot" << endl;
+		return;
+	}
+
+	//
+	// Save the temporary filename
+	//
+	this->to_delete.push_back(name);
+
+	//
+	// write the data to file
+	//
+	for (vector<double>::size_type i = 0; i < d.size(); i++)
+		tmp << d[i] << endl;
+	tmp.flush();
+	tmp.close();
+
+	//
+	// command to be sent to gnuplot
+	//
+	if (this->nplots > 0)
+		cmdstr << "replot ";
+	else
+		cmdstr << "plot ";
+	if (title == "")
+		cmdstr << "\"" << name << "\" with " << this->pstyle;
+	else
+		cmdstr << "\"" << name << "\" title \"" << title << "\" with "
+				<< this->pstyle;
+
+	//
+	// Do the actual plot
+	//
+	this->cmd(cmdstr.str().c_str());
+	this->nplots++;
+
+	return;
+}
+
+void Gnuplot::plot_xy(map<double, double> xy, const std::string &title)
+{
+	vector<double> x;
+	vector<double> y;
+
+	for (map<double, double>::const_iterator i = xy.begin(); i != xy.end(); i++)
+	{
+		x.push_back(i->first);
+		y.push_back(i->second);
+	}
+	plot_xy(x, y, title);
+}
+
+void Gnuplot::plot_xy(vector<double> x, vector<double> y,
+		const std::string &title)
+{
+	ofstream tmp;
+	std::ostringstream cmdstr;
+	char name[] = "/tmp/gnuplotiXXXXXX";
+
+	// should raise an exception
+	if (x.size() != y.size())
+		return;
+
+	if ((this->to_delete).size() == GP_MAX_TMP_FILES - 1)
+	{
+		cerr << "Maximum number of temporary files reached ("
+				<< GP_MAX_TMP_FILES << "): cannot open more files" << endl;
+		return;
+	}
+
+	//
+	//open temporary files for output
+	//
+	if (mkstemp(name) == -1)
+	{
+		cerr << "Cannot create temporary file: exiting plot" << endl;
+		return;
+	}
+	tmp.open(name);
+	if (tmp.bad())
+	{
+		cerr << "Cannot create temorary file: exiting plot" << endl;
+		return;
+	}
+
+	//
+	// Save the temporary filename
+	//
+	this->to_delete.push_back(name);
+
+	//
+	// write the data to file
+	//
+	for (vector<double>::size_type i = 0; i < x.size(); i++)
+		tmp << x[i] << " " << y[i] << endl;
+	tmp.flush();
+	tmp.close();
+
+	//
+	// command to be sent to gnuplot
+	//
+	if (this->nplots > 0)
+		cmdstr << "replot ";
+	else
+		cmdstr << "plot ";
+	if (title == "")
+		cmdstr << "\"" << name << "\" with " << this->pstyle;
+	else
+		cmdstr << "\"" << name << "\" title \"" << title << "\" with "
+				<< this->pstyle;
+
+	//
+	// Do the actual plot
+	//
+	this->cmd(cmdstr.str().c_str());
+	this->nplots++;
+
+	return;
+}
+
+void Gnuplot::plot_xyz(vector<double> x, vector<double> y, vector<double> z,
+		const std::string &title)
+{
+	ofstream tmp;
+	std::ostringstream cmdstr;
+	char name[] = "/tmp/gnuplotiXXXXXX";
+
+	// should raise an exception
+	if (x.size() != y.size() || x.size() != z.size())
+	{
+		return;
+	}
+
+	if ((this->to_delete).size() == GP_MAX_TMP_FILES - 1)
+	{
+		cerr << "Maximum number of temporary files reached ("
+				<< GP_MAX_TMP_FILES << "): cannot open more files" << endl;
+		return;
+	}
+
+	//
+	//open temporary files for output
+	//
+	if (mkstemp(name) == -1)
+	{
+		cerr << "Cannot create temporary file: exiting plot" << endl;
+		return;
+	}
+	tmp.open(name);
+	if (tmp.bad())
+	{
+		cerr << "Cannot create temorary file: exiting plot" << endl;
+		return;
+	}
+
+	//
+	// Save the temporary filename
+	//
+	this->to_delete.push_back(name);
+
+	//
+	// write the data to file
+	//
+	for (unsigned int i = 0; i < x.size(); i++)
+	{
+		tmp << x[i] << " " << y[i] << " " << z[i] << endl;
+	}
+	tmp.flush();
+	tmp.close();
+
+	//
+	// command to be sent to gnuplot
+	//
+	if (this->nplots > 0)
+		cmdstr << "replot ";
+	else
+		cmdstr << "splot ";
+	if (title == "")
+		cmdstr << "\"" << name << "\" with " << this->pstyle;
+	else
+		cmdstr << "\"" << name << "\" title \"" << title << "\" with "
+				<< this->pstyle;
+
+	//
+	// Do the actual plot
+	//
+	this->cmd(cmdstr.str().c_str());
+	this->nplots++;
+
+	return;
+}
+
+/**
+ *  note that this function is not valid for versions of GNUPlot below 4.2
+ *
+ **/
+void Gnuplot::plot_image(unsigned char * ucPicBuf, int iWidth, int iHeight,
+		const std::string &title)
+{
+
+	ofstream tmp;
+	std::ostringstream cmdstr;
+	char name[] = "/tmp/gnuplotiXXXXXX";
+
+	if ((this->to_delete).size() == GP_MAX_TMP_FILES - 1)
+	{
+		cerr << "Maximum number of temporary files reached ("
+				<< GP_MAX_TMP_FILES << "): cannot open more files" << endl;
+		return;
+	}
+
+	//
+	//open temporary files for output
+	//
+	if (mkstemp(name) == -1)
+	{
+		cerr << "Cannot create temporary file: exiting plot" << endl;
+		return;
+	}
+	tmp.open(name);
+	if (tmp.bad())
+	{
+		cerr << "Cannot create temorary file: exiting plot" << endl;
+		return;
+	}
+
+	//
+	// Save the temporary filename
+	//
+	this->to_delete.push_back(name);
+
+	//
+	// write the data to file
+	//
+
+	int iIndex = 0;
+	for (int iRow = 0; iRow < iHeight; iRow++)
+	{
+		for (int iColumn = 0; iColumn < iWidth; iColumn++)
+		{
+			tmp << iColumn << " " << iRow << " "
+					<< static_cast<float> (ucPicBuf[iIndex++]) << endl;
+			;
+		}
+	}
+	tmp.flush();
+	tmp.close();
+
+	//
+	// command to be sent to gnuplot
+	//
+	if (this->nplots > 0)
+		cmdstr << "replot ";
+	else
+		cmdstr << "plot ";
+	if (title == "")
+		cmdstr << "\"" << name << "\" with " << this->pstyle;
+	else
+		cmdstr << "\"" << name << "\" title \"" << title << "\" with image  ";// << this->pstyle;
+
+	//
+	// Do the actual plot
+	//
+	this->cmd(cmdstr.str().c_str());
+	this->nplots++;
+
+	return;
+
+}
+

+ 151 - 0
baselib/Gnuplot.h

@@ -0,0 +1,151 @@
+////////////////////////////////////////////
+//
+// A C++ interface to gnuplot. 
+//
+// This is a direct translation from the C interface
+// written by N. Devillard (which is available from
+// http://ndevilla.free.fr/gnuplot/).
+//
+// As in the C interface this uses pipes and so wont
+// run on a system that does'nt have POSIX pipe 
+// support
+//
+// Rajarshi Guha
+// <rajarshi@presidency.com>
+//
+// 07/03/03
+//
+// 26/01/04 - Gnuplot::cmd() was rewritten to accept a
+// char* rather than a std::string, thus avoiding the
+// va_start warning at compile time
+// /////////////////////////////////////////
+
+#ifndef _GNUPLOT_PIPES_H_
+#define _GNUPLOT_PIPES_H_
+
+#include <stdarg.h>
+#include <unistd.h>
+
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <list>
+#include <map>
+#include <vector>
+#include <stdexcept>
+
+#define GP_MAX_TMP_FILES    64
+#define GP_TMP_NAME_SIZE    512
+#define GP_CMD_SIZE         1024
+#define GP_TITLE_SIZE       80
+
+namespace OBJREC
+{
+
+class GnuplotException: public std::runtime_error
+{
+public:
+	GnuplotException(const std::string &msg) :
+		std::runtime_error(msg)
+	{
+	}
+};
+
+class Gnuplot
+{
+private:
+	FILE *gnucmd;
+	std::string pstyle;
+	std::vector<std::string> to_delete;
+	int nplots;
+	bool get_program_path(const std::string);
+	bool valid;
+public:
+	Gnuplot();
+
+	// set a style during construction
+	Gnuplot(const std::string &);
+
+	// The equivilant of gnuplot_plot_once, the two forms
+	// allow you to plot either (x,y) pairs or just a single
+	// vector at one go
+	Gnuplot(const std::string &, // title
+			const std::string &, // style
+			const std::string &, // xlabel
+			const std::string &, // ylabel
+			std::vector<double> , std::vector<double> );
+
+	Gnuplot(const std::string &, //title
+			const std::string &, //style
+			const std::string &, //xlabel
+			const std::string &, //ylabel
+			std::vector<double> );
+
+	~Gnuplot();
+	void checkSystemVariablesOpenGnuplotCommand();
+
+	// send a command to gnuplot
+	void cmd(const char*, ...);
+
+	// set line style
+	void set_style(const std::string &);
+	// set name of eps file to plot to
+	void setFileOutput(const std::string &terminal, const std::string &filename);
+	// set y and x axis labels
+	void set_ylabel(const std::string &);
+	void set_xlabel(const std::string &);
+	void set_zlabel(const std::string &);
+
+	// set axis - ranges
+	void set_xrange(const int iFrom, const int iTo);
+	void set_yrange(const int iFrom, const int iTo);
+	void set_zrange(const int iFrom, const int iTo);
+
+	// set palette range
+	void set_cbrange(const int iFrom, const int iTo);
+
+	// plot a single vector
+	void plot_x(std::vector<double> , const std::string & // title
+			);
+
+	// plot x,y pairs
+	void plot_xy(std::vector<double> , std::vector<double> , const std::string & // title
+			);
+
+	// plot x,y pairs
+	void plot_xy ( std::map<double, double> , const std::string & // title
+			);
+
+	// plot an equation of the form: y = ax + b
+	// You supply a and b
+	void plot_slope(double, // a
+			double, // b
+			const std::string & // title
+			);
+
+	// plot an equation supplied as a string
+	void plot_equation(const std::string &, // equation
+			const std::string & // title
+			);
+
+	// if multiple plots are present it will clear the plot area
+	void reset_plot(void);
+
+	bool is_valid(void);
+
+	void plot_xyz(std::vector<double> , std::vector<double> , std::vector<double> ,
+			const std::string &);
+
+	void plot_image(unsigned char * ucPicBuf, int iWidth, int iHeight,
+			const std::string &title);
+
+};
+
+} // namespace
+
+#endif

+ 287 - 0
baselib/ICETools.cpp

@@ -0,0 +1,287 @@
+/** 
+* @file ICETools.cpp
+* @brief simple ICE GUI tools
+* @author Erik Rodner
+* @date 03/13/2008
+
+*/
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#include <core/imagedisplay/SimpleSelector.h>
+#endif
+
+#include <iostream>
+
+#include <core/image/RectT.h>
+
+#include "vislearning/baselib/ICETools.h"
+
+using namespace OBJREC;
+
+using namespace std;
+
+using namespace NICE;
+
+ICETools::ICETools()
+{
+}
+
+ICETools::~ICETools()
+{
+}
+
+void ICETools::selectRectangles ( const NICE::Image & panel, NICE::Image & overlay, vector<Vector> & x, int color )
+{
+#ifndef NOVISUAL
+    // new NICE code
+    vector<RectT<double> > rectangles;
+    NICE::selectRectangles ( panel, rectangles, "select rectangles" );
+
+    for ( vector<RectT<double> >::const_iterator i = rectangles.begin();
+	i != rectangles.end(); i++ )
+    {
+	Vector vec (4);
+	vec[0] = i->left;
+	vec[1] = i->top;
+	vec[2] = i->right();
+	vec[3] = i->bottom();
+
+	x.push_back ( vec ); 
+    }
+#else
+    fprintf (stderr, "ICETools::selectRectangles: visualization disabled !\n");
+#endif
+
+}
+
+void ICETools::selectPoints ( const NICE::Image & panel, NICE::Image & overlay, vector<Vector> & x, int color )
+{
+#ifndef NOVISUAL
+    vector<CoordT<double> > points;
+    NICE::selectPoints ( panel, points, "select points" );
+
+    for ( vector<CoordT<double> >::const_iterator i = points.begin();
+	i != points.end(); i++ )
+    {
+	Vector vec (2);
+	vec[0] = i->x;
+	vec[1] = i->y;
+
+	x.push_back ( vec ); 
+    }
+   
+    /** OLD ICE Code
+    int p[2];
+    int rc = -1;
+
+    while ( (rc = SelPoint ( DEFAULT, panel, p )) != -1 )
+    {
+        int x1, y1;
+        x1 = p[0]; y1 = p[1];
+        // refactor-nice.pl: check this substitution
+        // old: Marker ( DEFAULT, p[0], p[1], color, 5, overlay );
+        // REFACTOR-FIXME Unable to map this statement
+        // refactor-nice.pl: check this substitution
+        // old: x.push_back ( Vector(x1, y1) );
+        // REFACTOR-FIXME Unable to std::map this statement
+    }
+    */
+#else
+    fprintf (stderr, "ICETools::selectPoints: visualization disabled !\n");
+#endif
+
+}
+
+void ICETools::toColor ( double x, double & r, double & g, double & b )
+{
+    size_t seg = (size_t)(x * 6.0);
+    double y   = ( 6*x - seg );
+
+    switch ( seg ) {
+	case 0: r=0.0; g=0.0; b=y;   break; 
+	case 1: r=0.0; g=  y; b=1.0; break; 
+	case 2: r=0.0; g=1.0; b=1.0-y; break; 
+	case 3: r=  y; g=1.0; b=0.0;   break; 
+	case 4: r=1.0; g=1.0-y; b=0.0;   break; 
+	case 5: r=1.0; g=y; b=y;   break; 
+	default: r=1.0; g=1.0; b=1.0; break;
+    }
+}
+
+void ICETools::convertToRGB ( const NICE::Matrix & m, NICE::ColorImage & img )
+{
+	img.resize ( m.cols(), m.rows() );
+    double max = - numeric_limits<double>::max();
+    double min = numeric_limits<double>::max();
+    for ( size_t x = 0 ; x < (size_t)m.cols(); x++ )
+	for ( size_t y = 0 ; y < (size_t)m.rows() ; y++ )
+	{
+	    if (m(y, x) > max ) max =m(y, x);
+	    if (m(y, x) < min ) min =m(y, x);
+	}
+    
+    for ( size_t y = 0 ; y < (size_t)m.rows() ; y++ )
+	for ( size_t x = 0 ; x < (size_t)m.cols(); x++ )
+	{
+	    double val =(m(y, x) - min) / (max-min);
+	    double r,g,b;
+	    toColor(val, r, g, b);
+	    img.setPixel(x,y,0,(int)(r*255));
+	    img.setPixel(x,y,1,(int)(g*255));
+	    img.setPixel(x,y,2,(int)(b*255));
+	}
+}
+
+void ICETools::convertToRGB ( const NICE::FloatImage & m, NICE::ColorImage & img )
+{
+	img.resize ( m.width(), m.height() );
+    double max = - numeric_limits<double>::max();
+    double min = numeric_limits<double>::max();
+    for ( size_t x = 0 ; x < (size_t)m.width(); x++ )
+	for ( size_t y = 0 ; y < (size_t)m.height() ; y++ )
+	{
+	    double v = m.getPixel(x,y);
+	    if ( v > max ) max = v;
+	    if ( v < min ) min = v;
+	}
+    
+    for ( size_t y = 0 ; y < (size_t)m.height() ; y++ )
+	for ( size_t x = 0 ; x < (size_t)m.width(); x++ )
+	{
+	    double val = (m.getPixel(x,y) - min) / (max-min);
+	    double r,g,b;
+	    toColor(val, r, g, b);
+	    img.setPixel(x,y,0,(int)(r*255));
+	    img.setPixel(x,y,1,(int)(g*255));
+	    img.setPixel(x,y,2,(int)(b*255));
+	}
+}
+
+void ICETools::calcGrayImage ( const NICE::ColorImage & img, NICE::Image & imgg )
+{
+    imgg.resize(img.width(), img.height());
+    for ( int y = 0 ; y < img.height(); y++ )
+      for ( int x = 0 ; x < img.width() ; x++ )
+      {
+        unsigned char g = (unsigned char)(0.299*img.getPixel(x,y,0) + 
+          0.587*img.getPixel(x,y,1) + 0.114*img.getPixel(x,y,2));
+        imgg.setPixel(x,y,g);
+      }
+}
+
+double *ICETools::convertICE2M ( const NICE::Matrix & M )
+{
+    double *raw = new double [ M.rows() * M.cols() ];
+    long index = 0;
+    for ( uint i = 0 ; i < M.rows() ; i++ )
+      for ( uint j = 0 ; j < M.cols() ; j++, index++ )
+        raw[index] = M(i, j);
+
+    return raw;
+}
+
+void ICETools::convertM2ICE ( NICE::Matrix & M, double *raw )
+{
+    long index = 0;
+    for ( int i = 0 ; i < (int)M.rows() ; i++ )
+		for ( int j = 0 ; j < (int)M.cols() ; j++, index++ )
+	    	M(i, j) = raw[index];
+}
+
+#ifndef NOVISUAL
+int ICETools::markImage (const NICE::Image & img, NICE::Image & mark, int marksize, int color)
+{
+    fprintf (stderr, "ICETools::markImage: reimplement this function for NICE\n");
+    exit(-1);
+
+/*
+    int flags;
+    int p[2];
+    int xo = -1;
+    int yo = -1;
+    
+    while(1) {
+	// refactor-nice.pl: check this substitution
+	// old: flags = Mouse(img,p[0],p[1]);
+	// REFACTOR-FIXME Unable to map this statement
+	if ( (flags & M_LEFT_DOWN) > 0 ) {
+	    if ( (p[0] != xo) || (p[1] != yo) ) {
+		if ( marksize == 1 ) {
+		    // refactor-nice.pl: check this substitution
+		    // old: PutVal( mark, p[0], p[1], color );
+		    mark.setPixel(p[0],p[1],color);
+		} else {
+		    // refactor-nice.pl: check this substitution
+		    // old: Marker(3, p[0], p[1], color, marksize, mark);
+		    // REFACTOR-FIXME Unable to map this statement
+		}
+       
+		xo = p[0];
+		yo = p[1];
+	    }
+	}
+	if ( (flags & M_RIGHT_DOWN) > 0 ) {
+	    while ( (flags & M_RIGHT_DOWN) > 0 ) {
+		// refactor-nice.pl: check this substitution
+		// old: flags = Mouse(img,p[0],p[1]);
+		// REFACTOR-FIXME Unable to map this statement
+	    };
+	    return -1;
+	}
+    }
+*/
+
+    return 0;
+}
+
+// refactor-nice.pl: check this substitution
+// old: int ICETools::showImages ( vector<Image> & imagelist )
+int ICETools::showImages ( vector<NICE::Image> & imagelist )
+{
+#ifndef NOVISUAL
+    for ( size_t j = 0 ; j < imagelist.size() ; j++ )
+    {
+	// refactor-nice.pl: check this substitution
+	// old: Show(ON, imagelist[j]);
+	showImage(imagelist[j]);
+    }
+#endif
+
+    // assumption: same size
+    // refactor-nice.pl: check this substitution
+    // old: int xsize = imagelist[0]->xsize;
+    int xsize = imagelist[0].width();
+    // refactor-nice.pl: check this substitution
+    // old: int ysize = imagelist[0]->ysize;
+    int ysize = imagelist[0].height();
+
+    int n = imagelist.size();
+    int n1 = (int)sqrt(n);
+    int n2 = n/n1 + 1;
+
+    NICE::Image img (n1*xsize, n2*ysize);
+    img.set(0);
+    int k = 0;
+    for ( int j = 0 ; j < n2 ; j++ )
+	for ( int i = 0 ; i < n1 ; i++,k++ )
+	    if ( k >= n ) break;
+	    else {
+		for ( int y = 0 ; y < imagelist[k].height(); y++ )
+		    for ( int x = 0 ; x < imagelist[k].width(); x++ )
+		    {
+          img.setPixel( i*xsize + x, j*ysize + y,
+              imagelist[k].getPixel(x,y) );
+		    }
+	    }
+
+    img.write ("display.bmp");
+
+    getchar();
+
+    return 0;
+}
+
+#endif
+

+ 104 - 0
baselib/ICETools.h

@@ -0,0 +1,104 @@
+/** 
+* @file ICETools.h
+* @brief simple ICE GUI tools
+* @author Erik Rodner
+* @date 03/13/2008
+
+*/
+#ifndef ICETOOLSINCLUDE
+#define ICETOOLSINCLUDE
+
+
+#include <vislearning/nice.h>
+
+#include <vector>
+ 
+
+namespace OBJREC {
+
+/** @brief simple ICE tools */
+class ICETools
+{
+
+    protected:
+
+    public:
+  
+	/** simple constructor */
+	ICETools();
+      
+	/** simple destructor */
+	virtual ~ICETools();
+
+	/** select a set of rectangles (selection of top-left and bottom-right
+	    @param panel image which is displayed
+	    @param overlay overlay image which will be used to mark points
+	    @param x returned list of rectangles (top-left-x,top-left-y,width,height)
+	    @param color color which is used to mark points
+	*/
+	static void selectRectangles ( const NICE::Image & panel, NICE::Image & overlay, 
+	    std::vector<NICE::Vector> & x, int color );
+
+	/** select a set of points 
+	    @param panel image which is displayed
+	    @param overlay overlay image which will be used to mark points
+	    @param x returned list of image points
+	    @param color color which is used to mark points
+	*/
+	static void selectPoints ( const NICE::Image & panel, NICE::Image & overlay, 
+	    std::vector<NICE::Vector> & x, int color );
+
+	/** convert a double image to a pseudocolor rgb image
+	    @param m input double image
+	    @param img resulting pseudocolor rgb image
+	*/
+	static void convertToRGB ( const NICE::FloatImage & m, NICE::ColorImage & img );
+
+	/** convert a matrix to a pseudocolor rgb image
+	    @param m input double image
+	    @param img resulting pseudocolor rgb image
+	*/
+	static void convertToRGB ( const NICE::Matrix & m, NICE::ColorImage & img );
+
+	/** convert a single double value to a pseudocolor
+	    @param x input double value
+	    @param r resulting red value
+	    @param g resulting green value
+	    @param b resulting blue value
+	*/
+	static void toColor ( double x, double & r, double & g, double & b );
+
+	/** calc grayscale image from a rgb image
+	    @param img color image
+	    @param imgg resulting grayscale image
+	*/
+	static void calcGrayImage ( const NICE::ColorImage & img, NICE::Image & imgg );
+
+	/** convert a c buffer to a matrix
+	    @param M resulting matrix
+	    @param raw input c buffer
+	*/
+	static void convertM2ICE ( NICE::Matrix & M, double *raw );
+
+	/** convert a matrix to a c buffer
+	    @param M input matrix
+	    @return resulting c buffer
+	*/
+	static double *convertICE2M ( const NICE::Matrix & M );
+
+	/** show a collection of images 
+	    @param imagelist collection of images
+	    @return ...
+	*/
+	static int showImages ( std::vector<NICE::Image> & imagelist );
+
+#ifndef NOVISUAL
+	static int markImage (const NICE::Image & img, NICE::Image & mark, int marksize, int maxColor);
+#endif
+     
+};
+
+
+} // namespace
+
+#endif

+ 8 - 0
baselib/Makefile

@@ -0,0 +1,8 @@
+#TARGETS_FROM:=$(notdir $(patsubst %/,%,$(shell pwd)))/$(TARGETS_FROM)
+#$(info recursivly going up: $(TARGETS_FROM) ($(shell pwd)))
+
+all:
+
+%:
+	$(MAKE) TARGETS_FROM=$(notdir $(patsubst %/,%,$(shell pwd)))/$(TARGETS_FROM) -C .. $@
+

+ 103 - 0
baselib/Makefile.inc

@@ -0,0 +1,103 @@
+# LIBRARY-DIRECTORY-MAKEFILE
+# conventions:
+# - all subdirectories containing a "Makefile.inc" are considered sublibraries
+#   exception: "progs/" and "tests/" subdirectories!
+# - all ".C", ".cpp" and ".c" files in the current directory are linked to a
+#   library
+# - the library depends on all sublibraries 
+# - the library name is created with $(LIBNAME), i.e. it will be somehow
+#   related to the directory name and with the extension .a
+#   (e.g. lib1/sublib -> lib1_sublib.a)
+# - the library will be added to the default build list ALL_LIBRARIES
+
+# --------------------------------
+# - 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)
+ifeq "$(SUBDIR)" "./"
+SUBDIR:=
+endif
+
+# ------------------------
+# - 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
+#
+# you can specify libraries needed by the individual objects or by the whole
+# directory. the object specific additional libraries are only considered
+# when compiling the specific object files
+# TODO: update documentation...
+
+-include $(SUBDIR)libdepend.inc
+
+$(foreach d,$(filter-out %progs %tests,$(SUBDIRS_OF_$(SUBDIR))),$(eval $(call PKG_DEPEND_INT,$(d))))
+
+# ---------------------------
+# - 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.
+
+LIBRARY_BASENAME:=$(call LIBNAME,$(SUBDIR))
+ifneq "$(SUBDIR)" ""
+ALL_LIBRARIES+=$(LIBDIR)$(LIBRARY_BASENAME).$(LINK_FILE_EXTENSION)
+endif
+
+# ---------------------
+# - binary dependencies
+#
+# there is no way of determining the binary dependencies automatically, so we
+# follow conventions. the current library depends on all sublibraries.
+# all other dependencies have to be added manually by specifying, that the
+# current .pc file depends on some other .pc file. binaries depending on
+# libraries should exclusivelly use the .pc files as well.
+
+ifeq "$(SKIP_BUILD_$(OBJDIR))" "1"
+$(LIBDIR)$(LIBRARY_BASENAME).a:
+else
+$(LIBDIR)$(LIBRARY_BASENAME).a:$(OBJS) \
+	$(call PRINT_INTLIB_DEPS,$(PKGDIR)$(LIBRARY_BASENAME).a,.$(LINK_FILE_EXTENSION))
+endif
+
+$(PKGDIR)$(LIBRARY_BASENAME).pc: \
+	$(call PRINT_INTLIB_DEPS,$(PKGDIR)$(LIBRARY_BASENAME).pc,.pc)
+
+# -------------------
+# - 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))
+

+ 136 - 0
baselib/Preprocess.cpp

@@ -0,0 +1,136 @@
+/** 
+* @file Preprocess.cpp
+* @brief simple preprocessing operations
+* @author Erik Rodner
+* @date 02/20/2008
+
+*/
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+
+#include <iostream>
+
+#include "vislearning/baselib/Preprocess.h"
+#include "vislearning/baselib/Conversions.h"
+#include "core/basics/StringTools.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+int    Preprocess::normalizeWidth 	   = -1;
+int    Preprocess::normalizeHeight 	   = -1;
+bool   Preprocess::init			   = false;
+std::string Preprocess::substituteFilenameRegex = "";
+std::string Preprocess::substituteFilenameSubs  = "";
+bool   Preprocess::disableReadImg          = false;
+bool   Preprocess::disableReadImgHeader    = false;
+
+void Preprocess::Init ( const Config *conf )
+{
+    init = true;
+    normalizeWidth = conf->gI("preprocess", "normalize_width", -1 );
+    normalizeHeight = conf->gI("preprocess", "normalize_height", -1 );
+    substituteFilenameRegex = conf->gS("preprocess", "substitute_filename_regex", "");
+    substituteFilenameSubs = conf->gS("preprocess", "substitute_filename_subs", "");
+    disableReadImg = conf->gB("preprocess", "disable_readimg", false);
+    disableReadImgHeader = conf->gB("preprocess", "disable_readimg_header", false);
+}
+
+void Preprocess::getImageSize ( const std::string & filename, int & xsize, int & ysize )
+{
+    ImageFile file ( filename );
+    xsize = file.width();
+    ysize = file.height();
+
+    if ( normalizeWidth > 0 ) xsize = normalizeWidth;
+    if ( normalizeHeight > 0 ) ysize = normalizeHeight;
+}
+
+NICE::Image Preprocess::ReadImgAdv ( const std::string & filename )
+{
+    std::string realfilename = filename;
+
+    if ( substituteFilenameRegex.size() > 0 ) {
+		fprintf (stderr, "%s -> ", realfilename.c_str() );
+		StringTools::regexSubstitute ( realfilename, substituteFilenameRegex, substituteFilenameSubs );+
+		fprintf (stderr, "%s\n", realfilename.c_str() );
+    }
+
+    if ( disableReadImg ) {
+	int xsize,ysize; // refactor: ,maxval;
+	if ( ! disableReadImgHeader ) {
+	    try {
+		ImageFile file ( filename );
+		xsize = file.width();
+		ysize = file.height();
+	    } catch ( ImageException & ) {
+		xsize = 10;
+		ysize = 10;
+	    }
+	} else {
+	    xsize = 10;
+	    ysize = 10;
+	}
+	fprintf (stderr, "Preprocess: read image disabled (xsize=%d,ysize=%d) !\n", xsize, ysize);
+
+		return Image(xsize,ysize);
+    }
+
+
+    NICE::Image img;
+
+    try {
+		img.read ( realfilename );
+    }
+    catch(ImageException &)
+    {
+		fprintf (stderr, "Failed to open image file: %s\n", realfilename.c_str() );
+		exit(-1);
+    }
+
+    if ( ( (normalizeWidth > 0) && (normalizeWidth != img.width()) ) ||
+	 ( (normalizeHeight >0) && (normalizeHeight != img.height()) ) )
+    {
+		NICE::Image img_s;
+		Conversions::resizeImage ( img, img_s, normalizeWidth, normalizeHeight );
+		return img_s;
+    } else {
+		return img;
+    }
+}
+
+NICE::ColorImage Preprocess::ReadImgAdvRGB ( const std::string & filename )
+{
+    std::string realfilename = filename;
+
+    if ( substituteFilenameRegex.size() > 0 ) {
+		fprintf (stderr, "%s -> ", realfilename.c_str() );
+		StringTools::regexSubstitute ( realfilename, substituteFilenameRegex, substituteFilenameSubs );
+		fprintf (stderr, "%s\n", realfilename.c_str() );
+    }
+
+    NICE::ColorImage img;
+
+    try {
+		img.read (realfilename);
+    } catch ( ImageException & ) {
+		fprintf (stderr, "Failed to open image file: %s\n", realfilename.c_str() );
+		exit(-1);
+    }
+
+    if ( ( (normalizeWidth > 0) && (normalizeWidth != img.width()) ) ||
+	 ( (normalizeHeight > 0) && (normalizeHeight != img.height()) ) )
+    {
+		NICE::ColorImage img_s;
+		cerr << "resizing image to: " << normalizeWidth << " " << normalizeHeight << endl;
+		Conversions::resizeImage ( img, img_s, normalizeWidth, normalizeHeight );
+		return img_s;
+    } else {
+		return img;
+    }
+}

+ 61 - 0
baselib/Preprocess.h

@@ -0,0 +1,61 @@
+/** 
+* @file Preprocess.h
+* @brief simple preprocessing operations
+* @author Erik Rodner
+* @date 02/20/2008
+
+*/
+#ifndef PREPROCESSINCLUDE
+#define PREPROCESSINCLUDE
+
+
+
+#include "core/basics/Config.h"
+#include "core/image/ImageT.h"
+
+
+namespace OBJREC {
+
+/** @brief simple preprocessing operations */
+class Preprocess
+{
+
+    protected:
+	static int normalizeWidth;
+	static int normalizeHeight;
+	static bool init;
+	static std::string substituteFilenameRegex;
+	static std::string substituteFilenameSubs;
+	static bool disableReadImg;
+	static bool disableReadImgHeader;
+
+    public:
+	
+	/** init preprocessing routines */
+	static void Init ( const NICE::Config *conf );
+
+	/** read an image and apply preprocessing 
+	    @param filename input filename
+	    @return resulting grayscale image
+	*/
+	static NICE::Image ReadImgAdv ( const std::string & filename  );
+	
+	/** read a color image and apply preprocessing 
+	    @param filename input filename
+	    @return resulting color image
+	*/
+	static NICE::ColorImage ReadImgAdvRGB ( const std::string & filename );
+
+	/** get the size of an image 
+	    @param filename filename of the image
+	    @param xsize resulting width of the image
+	    @param ysize resulting height of the image
+	*/
+	static void getImageSize ( const std::string & filename, int & xsize, int & ysize );
+	
+};
+
+
+} // namespace
+
+#endif

+ 43 - 0
baselib/ProgressBar.cpp

@@ -0,0 +1,43 @@
+/** 
+ * @file ProgressBar.cpp
+ * @brief Show a Progress-Bar with time estimation - threaded
+ * @author Michael Koch
+ * @date 25/03/2010
+
+ */
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#include <core/imagedisplay/QtFramework.h>
+#endif
+
+#include <iostream>
+#include <sys/time.h>
+
+#include "vislearning/baselib/ProgressBar.h"
+
+
+using namespace OBJREC;
+
+using namespace std;
+
+using namespace NICE;
+
+ProgressBar::ProgressBar( std::string a ) : ProgressBarQt(a, true)
+{
+    start();
+}
+ProgressBar::~ProgressBar()
+{
+	terminate();
+	wait();
+}
+void ProgressBar::run()
+{
+ if(working)
+ {
+	 sleep(1);
+ }
+}
+

+ 33 - 0
baselib/ProgressBar.h

@@ -0,0 +1,33 @@
+/** 
+ * @file ProgressBar.h
+ * @brief Show a Progress-Bar with time estimation - threaded
+ * @author Michael Koch
+ * @date 25/03/2010
+
+ */
+#ifndef ProgressBarINCLUDE
+#define ProgressBarINCLUDE
+
+#include <qthread.h>
+#include <iostream>
+#include <string>
+
+#include "vislearning/baselib/ProgressBarQt.h"
+
+namespace OBJREC
+{
+/** @brief show a Progress-Bar with time estimation */
+class ProgressBar: public QThread, public ProgressBarQt
+{
+public:
+	ProgressBar(std::string a = "ProgressBar");
+	/** simple destructor */
+	virtual ~ProgressBar();
+	virtual void run();
+private:
+
+};
+
+}
+
+#endif

+ 197 - 0
baselib/ProgressBarQt.cpp

@@ -0,0 +1,197 @@
+/** 
+ * @file ProgressBarQt.cpp
+ * @brief Show a Progress-Bar with time estimation
+ * @author Michael Koch
+ * @date 25/03/2010
+
+ */
+//#ifdef NOVISUAL
+//#include <vislearning/nice_nonvis.h>
+//#else
+#include <vislearning/nice.h>
+#include <core/imagedisplay/QtFramework.h>
+//#endif
+
+#include <iostream>
+#include <sys/time.h>
+
+#include "vislearning/baselib/ProgressBarQt.h"
+
+
+using namespace OBJREC;
+
+using namespace std;
+
+using namespace NICE;
+
+ProgressBarQt::ProgressBarQt(const std::string & _name, bool _useGraphics)
+	: useGraphics (_useGraphics)
+{
+	name = _name;
+	step = 0;
+
+	display_on = false;
+	working = true;
+	if (graphicIsAvailable())
+	{
+		if (qApp == NULL)
+		{
+			QtFramework::instance();
+		}
+
+		dialogwindow = new QWidget;
+
+		progressdialog = new QProgressDialog("Process at work ...", "Cancel",
+				0, 100);
+		layout = new QGridLayout(dialogwindow, 1, 1);
+		layout->addWidget(progressdialog, 0, 0);
+		dialogwindow->setLayout(layout);
+	}
+	reset(_name);
+}
+
+ProgressBarQt::~ProgressBarQt()
+{
+}
+
+void ProgressBarQt::timediff2str(char *text, long time)
+{
+	int seconds;
+	int minutes;
+	int hours;
+	int milliseconds;
+
+	milliseconds = time % 100;
+	time /= 100;
+	seconds = time % 60;
+	time /= 60;
+	minutes = time % 60;
+	time /= 60;
+	hours = time;
+
+	if (hours != 0)
+	{
+		sprintf(text, "%dh %dm %d.%d s", hours, minutes, seconds, milliseconds);
+	}
+	else if (minutes != 0)
+	{
+		sprintf(text, "%dm %d.%d s", minutes, seconds, milliseconds);
+	}
+	else
+	{
+		sprintf(text, "%d.%d s", seconds, milliseconds);
+	}
+}
+
+void ProgressBarQt::displayTimeStat(int posy, char *text, long time)
+{
+	// Text (char *str,int x0,int y0,int val,int exp,Image img);
+	char disptext[200];
+	char timetext[200];
+
+	timediff2str(timetext, time);
+	sprintf(disptext, "%s %s", text, timetext);
+
+}
+
+double ProgressBarQt::getCurrentTime()
+{
+	struct timeval curtime;
+
+	gettimeofday(&curtime, NULL);
+
+	return curtime.tv_sec * 100.0 + curtime.tv_usec / 10000.0;
+}
+
+void ProgressBarQt::show()
+{
+	if (!display_on)
+	{
+		display_on = true;
+	}
+	if (graphicIsAvailable())
+	{
+		if (qApp == NULL)
+		{
+			QtFramework::instance();
+		}
+		dialogwindow->show();
+	}
+}
+
+void ProgressBarQt::hide()
+{
+
+	if (display_on)
+	{
+		//		Show ( OFF, display, name );
+		display_on = false;
+	}
+	if (graphicIsAvailable())
+	{
+		dialogwindow->hide();
+	}
+}
+
+void ProgressBarQt::stop()
+{
+
+	working = false;
+}
+
+void ProgressBarQt::reset(const std::string & _name)
+{
+	name = _name;
+	step = 0;
+	elapsed_time = 0;
+	avg_time_step = 0;
+	start_time = getCurrentTime();
+}
+
+void ProgressBarQt::update(int count)
+{
+	step++;
+
+	double progress = step / (double) count;
+
+	elapsed_time = getCurrentTime() - start_time;
+	avg_time_step = elapsed_time / step;
+	estimated_time = (count - step) * avg_time_step;
+
+	size_t mod;
+	if (avg_time_step > 50.0)
+		mod = 1;
+	else
+		mod = (size_t) (50.0 / avg_time_step) + 1;
+
+	if ((mod <= 1) || (step % mod == 0))
+	{
+		char percent_text[10];
+		sprintf(percent_text, "%4.2f %%", step * 100.0 / count);
+
+		displayTimeStat(0, "Elapsed Time : ", (long int) elapsed_time);
+		displayTimeStat(1, "Estimated Time : ", (long int) estimated_time);
+		displayTimeStat(2, "Avg. Time per step : ", (long int) avg_time_step);
+
+		char eltime[200];
+		char estime[200];
+		char avgtime[200];
+		timediff2str(eltime, (long int) elapsed_time);
+		timediff2str(estime, (long int) estimated_time);
+		timediff2str(avgtime, (long int) avg_time_step);
+		fprintf(
+				stderr,
+				"[PROGRESS] %s %s (elapsed time %s, estimated time %s, avg %s), \n",
+				name.c_str(), percent_text, eltime, estime, avgtime);
+		//set progress value.
+		if (graphicIsAvailable())
+		{
+			progressdialog->setValue(progress * 100);
+		}
+	}
+}
+
+bool ProgressBarQt::graphicIsAvailable()
+{
+	return (useGraphics && (getenv("DISPLAY") != NULL));
+}

+ 87 - 0
baselib/ProgressBarQt.h

@@ -0,0 +1,87 @@
+/** 
+ * @file ProgressBarQt.h
+ * @brief Show a Progress-Bar with time estimation
+ * @author Michael Koch
+ * @date 25/03/2010
+
+ */
+#ifndef ProgressBarQtINCLUDE
+#define ProgressBarQtINCLUDE
+
+#include <qprogressdialog.h>
+#include <qwidget.h>
+#include <qlayout.h>
+
+#include "core/image/ImageT.h"
+
+namespace OBJREC {
+
+/** @brief show a Progress-Bar with time estimation */
+class ProgressBarQt
+{
+
+protected:
+
+	QGridLayout* layout;
+	QWidget* dialogwindow;
+	QProgressDialog* progressdialog;
+
+
+	NICE::Image display;
+	bool display_on;
+	bool working;
+	double start_time;
+	double avg_time_step;
+	double elapsed_time;
+	double estimated_time;
+
+	int step;
+
+	int bar_width;
+	int bar_height;
+	int bar_top;
+	int bar_borderx;
+
+	int text_top;
+	int text_height;
+
+	std::string name;
+
+	bool useGraphics;
+
+	void timediff2str(char *text, long time);
+	void displayTimeStat(int posy, char *text, long time);
+	double getCurrentTime();
+	bool graphicIsAvailable();
+
+public:
+
+	/** constructor 
+	 @param name name of the operation
+	 */
+	ProgressBarQt(const std::string & name, bool useGraphics = true);
+
+	/** simple destructor */
+	virtual ~ProgressBarQt();
+
+	/** reset the progress bar and the corresponding
+	 name of the operation */
+
+	void reset(const std::string & name);
+
+	/** show the progress bar */
+	void show();
+	/** hide the progress bar */
+	void hide();
+
+	void stop();
+
+	/** update the progress bar
+	 @param count number of total steps of this operation
+	 */
+	void update(int count);
+
+};
+} // namespace
+
+#endif

+ 67 - 0
baselib/RunningStat.cpp

@@ -0,0 +1,67 @@
+/** 
+ * @file RunningStat.cpp
+ * @brief B. P. Welford Computation of Mean and Variance download at: http://www.johndcook.com/standard_deviation.html
+ * @author Michael Koch
+ * @date 18/02/2009
+ */
+
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+
+#include "vislearning/baselib/RunningStat.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+void RunningStat::Clear()
+{
+     m_n = 0;
+}
+
+void RunningStat::Push(double x)
+{
+     m_n++;
+
+            // See Knuth TAOCP vol 2, 3rd edition, page 232
+     if (m_n == 1)
+     {
+          m_oldM = m_newM = x;
+          m_oldS = 0.0;
+     }
+     else
+     {
+          m_newM = m_oldM + (x - m_oldM)/m_n;
+          m_newS = m_oldS + (x - m_oldM)*(x - m_newM);
+    
+                // set up for next iteration
+          m_oldM = m_newM; 
+          m_oldS = m_newS;
+     }
+}
+
+size_t RunningStat::NumDataValues() const
+{
+     return m_n;
+}
+
+double RunningStat::Mean() const
+{
+     return (m_n > 0) ? m_newM : 0.0;
+}
+
+double RunningStat::Variance() const
+{
+     return ( (m_n > 1) ? m_newS/(m_n - 1) : 0.0 );
+}
+
+double RunningStat::StandardDeviation() const
+{
+     return sqrt( Variance() );
+}
+
+
+

+ 44 - 0
baselib/RunningStat.h

@@ -0,0 +1,44 @@
+/** 
+ * @file RunningStat.h
+ * @brief B. P. Welford Computation of Mean and Variance download at: http://www.johndcook.com/standard_deviation.html
+ * @author Michael Koch
+ * @date 18/02/2009
+ */
+#ifndef RunningStatINCLUDE
+#define RunningStatINCLUDE
+
+namespace OBJREC {
+
+/** @brief online statistics */
+class RunningStat
+{
+     public:
+          RunningStat() : m_n(0) {}
+
+	  /** clear the current statistics */
+          void Clear();
+          
+	  /** add a new data element */
+          void Push(double x);
+          
+	  /** get number of data elements */
+          size_t NumDataValues() const;
+
+	  /** get mean value */
+          double Mean() const;
+          
+	  /** get variance */
+	  double Variance() const;
+          
+	  /** get standard deviation */
+          double StandardDeviation() const;
+         
+
+     private:
+          size_t m_n;
+          double m_oldM, m_newM, m_oldS, m_newS;
+};
+
+}
+#endif
+

+ 108 - 0
baselib/RunningStatVector.cpp

@@ -0,0 +1,108 @@
+/**
+ * @file RunningStatVector.cpp
+ * @brief B. P. Welford Computation of Mean and Variance download at: http://www.johndcook.com/standard_deviation.html
+ * @author Michael Koch
+ * @date 19/01/2010
+ */
+
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+
+#include "vislearning/baselib/RunningStatVector.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+void RunningStatVector::Clear()
+{
+	m_n = 0;
+	for (size_t k = 0; k < datavector.size(); k++)
+	{
+		if (datavector[k] != NULL)
+		{
+			delete datavector[k];
+		}
+	}
+	datavector.clear();
+}
+
+RunningStatVector::~RunningStatVector()
+{
+	Clear();
+}
+
+void RunningStatVector::Push(NICE::Vector x)
+{
+	m_n++;
+
+	// See Knuth TAOCP vol 2, 3rd edition, page 232
+	if ((size_t) x.size() != this->size)
+	{
+		if (m_n == 1)
+		{
+			this->size = x.size();
+		}
+		else
+		{
+			fthrow(Exception,"RunningStatVector::Push(): this->size != x.size()\n");
+		}
+	}
+	else
+	{
+		for (size_t k = 0; k < x.size(); k++)
+		{
+			if (m_n == 1)
+			{
+				RunningStat * rs = new RunningStat();
+				datavector.push_back(rs);
+			}
+			datavector[k]->Push(x[k]);
+		}
+	}
+
+}
+
+size_t RunningStatVector::NumDataValues() const
+{
+return m_n;
+}
+
+size_t RunningStatVector::Size() const
+{
+return size;
+}
+
+NICE::Vector RunningStatVector::Mean() const
+{
+NICE::Vector mean(datavector.size(), 0.0);
+for (size_t k = 0; k < datavector.size(); k++)
+{
+	mean[k] = datavector[k]->Mean();
+}
+return mean;
+}
+
+NICE::Vector RunningStatVector::Variance() const
+{
+NICE::Vector variance(datavector.size(), 0.0);
+for (size_t k = 0; k < datavector.size(); k++)
+{
+	variance[k] = datavector[k]->Variance();
+}
+return variance;
+}
+
+NICE::Vector RunningStatVector::StandardDeviation() const
+{
+NICE::Vector std(Variance());
+for (size_t k = 0; k < std.size(); k++)
+{
+	std[k] = sqrt(std[k]);
+}
+return std;
+}
+

+ 53 - 0
baselib/RunningStatVector.h

@@ -0,0 +1,53 @@
+/**
+ * @file RunningStatVector.h
+ * @brief B. P. Welford Computation of Mean and Variance download at: http://www.johndcook.com/standard_deviation.html
+ * @author Michael Koch
+ * @date 19/01/2010
+ */
+#ifndef RunningStatVectorINCLUDE
+#define RunningStatVectorINCLUDE
+
+#include "vislearning/baselib/RunningStat.h"
+#include <core/vector/VectorT.h>
+namespace OBJREC
+{
+
+/** @brief online statistics */
+class RunningStatVector
+{
+public:
+	RunningStatVector(size_t n=0) :
+		m_n(0),size(n)
+	{
+	}
+	~RunningStatVector();
+
+	/** clear the current statistics */
+	void Clear();
+
+	/** add a new data element */
+	void Push(NICE::Vector x);
+
+	/** get number of data elements */
+	size_t NumDataValues() const;
+	/** get vector size */
+	size_t Size() const;
+
+	/** get mean value */
+	NICE::Vector Mean() const;
+
+	/** get variance */
+	NICE::Vector Variance() const;
+
+	/** get standard deviation */
+	NICE::Vector StandardDeviation() const;
+
+private:
+	size_t m_n;
+	size_t size;
+	std::vector<RunningStat *> datavector;
+};
+
+}
+#endif
+

+ 346 - 0
baselib/VectorStatistics.cpp

@@ -0,0 +1,346 @@
+/** 
+ * @file VectorStatistics.cpp
+ * @brief B. P. Welford Computation of Mean and Variance download at: http://www.johndcook.com/standard_deviation.html
+ * @author Michael Koch
+ * @date 18/02/2009
+ */
+
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+
+#include "vislearning/baselib/RunningStat.h"
+#include "vislearning/baselib/VectorStatistics.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+//non-static
+
+VectorStatistics::VectorStatistics(const NICE::Vector &data, bool compute)
+{
+	datavector = data;
+	initVariables();
+	if (compute)
+	{
+		calculateStatistics();
+	}
+}
+
+VectorStatistics::~VectorStatistics()
+{
+}
+
+void VectorStatistics::calculateStatistics()
+{
+	setMean();
+	setMedian();
+	setVariance();
+	setSkewness();
+	setKurtosis();
+	setEntropy();
+	setNormalizedEntropy();
+}
+
+void VectorStatistics::setData(const NICE::Vector &data)
+{
+	datavector = data;
+	initVariables();
+}
+void VectorStatistics::initVariables()
+{
+	mean = 0.0;
+	med = 0.0;
+	var = 0.0;
+	skew = 0.0;
+	kurt = 0.0;
+	entropy=0.0;
+	meancalculated = false;
+	mediancalculated = false;
+	varcalculated = false;
+	stdcalculated = false;
+	skewcalculated = false;
+	kurtcalculated = false;
+	entropycalculated = false;
+	normalizedentropy = false;
+}
+void VectorStatistics::setMean()
+{
+	if (!meancalculated)
+	{
+		mean = computeMean(datavector);
+		meancalculated = true;
+	}
+}
+void VectorStatistics::setMedian()
+{
+	if (!mediancalculated)
+	{
+		med = computeMedian(datavector);
+		mediancalculated = true;
+	}
+}
+void VectorStatistics::setVariance()
+{
+	if (!varcalculated)
+	{
+		var = computeVariance(datavector);
+		varcalculated = true;
+	}
+}
+void VectorStatistics::setSkewness()
+{
+	if (!skewcalculated)
+	{
+		skew = computeSkew(datavector);
+		skewcalculated = true;
+	}
+}
+void VectorStatistics::setKurtosis()
+{
+	if (!kurtcalculated)
+	{
+		kurt = computeKurtosis(datavector);
+		kurtcalculated = true;
+	}
+}
+
+void VectorStatistics::setEntropy()
+{
+	if (!entropycalculated)
+	{
+		entropy = computeEntropy(datavector);
+		entropycalculated = true;
+	}
+}
+
+void VectorStatistics::setNormalizedEntropy()
+{
+	if (!normalizedentropycalculated)
+	{
+		normalizedentropy = computeNormalizedEntropy(datavector);
+		normalizedentropycalculated = true;
+	}
+}
+
+double VectorStatistics::getMean()
+{
+	if (meancalculated)
+	{
+		return mean;
+	}
+	else
+	{
+		setMean();
+		return mean;
+	}
+}
+double VectorStatistics::getMedian()
+{
+	if (mediancalculated)
+	{
+		return med;
+	}
+	else
+	{
+		setMedian();
+		return med;
+	}
+}
+double VectorStatistics::getVariance()
+{
+	if (varcalculated)
+	{
+		return var;
+	}
+	else
+	{
+		setVariance();
+		return var;
+	}
+}
+double VectorStatistics::getStandardDeviation()
+{
+	if (varcalculated)
+	{
+		return sqrt(var);
+	}
+	else
+	{
+		setVariance();
+		return sqrt(var);
+	}
+}
+double VectorStatistics::getSkewness()
+{
+	if (skewcalculated)
+	{
+		return skew;
+	}
+	else
+	{
+		setSkewness();
+		return skew;
+	}
+}
+double VectorStatistics::getKurtosis()
+{
+	if (kurtcalculated)
+	{
+		return kurt;
+	}
+	else
+	{
+		setKurtosis();
+		return kurt;
+	}
+}
+double VectorStatistics::getEntropy()
+{
+	if (entropycalculated)
+	{
+		return entropy;
+	}
+	else
+	{
+		setEntropy();
+		return entropy;
+	}
+}
+
+double VectorStatistics::getNormalizedEntropy()
+{
+	if (normalizedentropycalculated)
+	{
+		return normalizedentropy;
+	}
+	else
+	{
+		setNormalizedEntropy();
+		return normalizedentropy;
+	}
+}
+
+//static
+double VectorStatistics::computeMedian(const NICE::Vector &data)
+{
+	if (data.size() > 0)
+	{
+		NICE::Vector data_tmp(data);
+		data_tmp.sortAscend();
+		return data_tmp[data.size() / 2];
+	}
+	else
+	{
+		fprintf(stderr, "VectorStatistics: median - size of data is 0!\n");
+		return 0.0;
+	}
+}
+double VectorStatistics::computeNormalizedEntropy(const NICE::Vector &data)
+{
+	double entropy = computeEntropy(data);
+	if (data.size()>1)
+	{
+	  double max_entropy = -log(1.0 / (double) data.size());
+	  entropy/=max_entropy;
+	}
+	return entropy;
+}
+double VectorStatistics::computeEntropy(const NICE::Vector &data)
+{
+	double entropy = 0.0;
+	double sum = 0.0;
+	for (size_t i = 0; i < data.size(); i++)
+	{
+		double val = data[i];
+		if (val <= 0.0)
+			continue;
+		entropy -= val * log(val);
+		sum += val;
+	}
+	if (fabs(sum) > 1e-6)
+	{
+		entropy /= sum;
+		entropy += log(sum);
+	}
+	else
+	{
+		fprintf(stderr,
+				"VectorStatistics: entropy - sum of values is numerically small\n");
+	}
+	return entropy;
+}
+
+double VectorStatistics::computeSkew(const NICE::Vector &data)
+{
+
+	double skew = 0.0;
+
+	double meanvalue = computeMean(data);
+	double var = computeVariance(data);
+	if (data.size() > 0 && var>1e-8)
+	{
+		for (size_t i = 0; i < data.size(); ++i)
+		{
+
+			skew += (data[i] - meanvalue) * (data[i] - meanvalue) * (data[i]
+					- meanvalue);
+
+		}
+
+		skew *= sqrt(double(data.size())) / pow(var * double(data.size()), 1.5);
+	}
+	return skew;
+}
+double VectorStatistics::computeKurtosis(const NICE::Vector &data)
+{
+
+	double kurt = 0.0;
+
+	double meanvalue = computeMean(data);
+	double var = computeVariance(data);
+	if (data.size() > 0 && var>1e-8)
+	{
+		for (size_t i = 0; i < data.size(); i++)
+		{
+			kurt += pow((data[i] - meanvalue), 4.0);
+		}
+
+		kurt /= double(data.size()) * pow(var, 2.0);
+
+		kurt -= 3.0;
+	}
+	return kurt;
+}
+
+double VectorStatistics::computeMean(const NICE::Vector &data)
+{
+	RunningStat rs;
+	for (size_t i = 0; i < data.size(); i++)
+	{
+		rs.Push(data[i]);
+	}
+	return rs.Mean();
+}
+double VectorStatistics::computeVariance(const NICE::Vector &data)
+{
+	RunningStat rs;
+	for (size_t i = 0; i < data.size(); i++)
+	{
+		rs.Push(data[i]);
+	}
+	return rs.Variance();
+}
+double VectorStatistics::computeStandardDeviation(const NICE::Vector &data)
+{
+	RunningStat rs;
+	for (size_t i = 0; i < data.size(); i++)
+	{
+		rs.Push(data[i]);
+	}
+	return rs.StandardDeviation();
+}
+

+ 74 - 0
baselib/VectorStatistics.h

@@ -0,0 +1,74 @@
+/** 
+ * @file VectorStatistics.h
+ * @brief B. P. Welford Computation of Mean and Variance download at: http://www.johndcook.com/standard_deviation.html
+ * @author Michael Koch
+ * @date 18/02/2009
+ */
+#ifndef VectorStatisticsINCLUDE
+#define VectorStatisticsINCLUDE
+
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+namespace OBJREC
+{
+
+/** @brief online statistics */
+class VectorStatistics
+{
+public:
+
+	VectorStatistics(const NICE::Vector &data,bool compute=true);
+
+	~VectorStatistics();
+
+	void calculateStatistics();
+	void initVariables();
+	void setData(const NICE::Vector &data);
+
+	void setMean();
+	void setMedian();
+	void setVariance();
+	void setSkewness();
+	void setKurtosis();
+	void setEntropy();
+	void setNormalizedEntropy();
+	
+
+	double getMean();
+	double getMedian();
+	double getVariance();
+	double getStandardDeviation();
+	double getSkewness();
+	double getKurtosis();
+	double getEntropy();
+	double getNormalizedEntropy();
+	
+
+
+	static double computeEntropy(const NICE::Vector &data);
+	static double computeNormalizedEntropy(const NICE::Vector &data);
+	static double computeMean(const NICE::Vector &data);
+	static double computeMedian(const NICE::Vector &data);
+	static double computeVariance(const NICE::Vector &data);
+	static double computeStandardDeviation(const NICE::Vector &data);
+	static double computeSkew(const NICE::Vector &data);
+	static double computeKurtosis(const NICE::Vector &data);
+private:
+
+	NICE::Vector datavector;
+	double mean, med;
+	double var, skew, kurt;
+	double entropy,normalizedentropy;
+	bool meancalculated, mediancalculated, varcalculated, stdcalculated,
+			skewcalculated, kurtcalculated,entropycalculated,normalizedentropycalculated;
+
+private:
+
+};
+
+}
+#endif
+

+ 561 - 0
baselib/cc.cpp

@@ -0,0 +1,561 @@
+
+#include<assert.h>
+#include<math.h>
+
+#include"cc.h"
+
+using namespace OBJREC;
+using namespace std;
+  
+  /*
+          *	Tristimulus reference values
+  */
+const double _ccTristimulusValues[ccNTristimulus][3] = 
+{
+     /* 2 degrees */
+  /*ccTA_2*/{109.850, 100.000, 35.585},
+  /*ccTC_2*/{98.074,  100.000, 118.232},
+  /* D50 */ {96.422,  100.000, 82.521},
+  /* D55 */ {95.682,  100.000, 92.149},
+  /* D65 */ {95.047,  100.000, 108.883},
+  /* D75 */ {94.972,  100.000, 122.638},
+  /* F2 */  {99.187,  100.000, 67.395},
+  /* F7 */  {95.044,  100.000, 108.755},
+  /* F11 */ {100.966, 100.000, 64.370},
+
+            /* 10 degrees */
+  /* A */   {111.144, 100.000, 35.200},
+  /* C */   {97.285,  100.000, 116.145},
+  /* D50 */ {96.720,  100.000, 81.427},
+  /* D55 */ {95.799,  100.000, 90.926},
+  /* D65 */ {94.811,  100.000, 107.304},
+  /* D75 */ {94.416,  100.000, 120.641},
+  /* F2 */  {103.280, 100.000, 69.026},
+  /* F7 */  {95.792,  100.000, 107.687},
+  /* F11 */ {103.866, 100.000, 65.627}
+};
+
+
+
+
+double ColorConversion::ccmin(double val1, double val2, double val3)
+{
+  if (val1 < val2)
+  {
+    if(val1 < val3) return val1;
+    else return val3;
+  }
+  else if (val2 < val3)
+    return val2;
+  return val3;
+}
+
+double ColorConversion::ccmax(double val1, double val2, double val3)
+{
+  if (val1 > val2)
+  {
+    if(val1 > val3) return val1;
+    else return val3;
+  }
+  else if (val2 > val3)
+    return val2;
+  return val3;
+}
+
+ double ColorConversion::Hue_2_RGB( double v1, double v2, double vH )
+{
+   if ( vH < 0 ) vH += 1;
+   if ( vH > 1 ) vH -= 1;
+   if ( ( 6 * vH ) < 1 ) return ( v1 + ( v2 - v1 ) * 6 * vH );
+   if ( ( 2 * vH ) < 1 ) return ( v2 );
+   if ( ( 3 * vH ) < 2 ) return ( v1 + ( v2 - v1 ) * ( ( 2./3 ) - vH ) * 6 );
+   return ( v1 );
+}
+
+ double ColorConversion::degree_2_radian(double val)
+{
+  return (val*M_PI)/180;
+}
+
+//RGB values = From 0 to 1
+ int ColorConversion::ccRGBtoHSL(double r, double g, double b, double* h, double* s, double* l)
+{
+  double vmin, vmax, delta;
+  double dr,dg,db;
+
+  vmin = ccmin( r, g, b );                // Min. value of RGB
+  vmax = ccmax( r, g, b );                // Max. value of RGB
+  delta = vmax - vmin;                    // Delta RGB value
+
+  *l = ( vmax + vmin ) / 2;
+
+  if ( delta == 0 )                     // This is a gray, no chroma...
+  {
+     *h = 0;                            // HSL results = From 0 to 1
+     *s = 0;
+  }
+  else                                  // Chromatic data...
+  {
+     if ( *l < 0.5 ) *s = delta / ( vmax + vmin );
+     else            *s = delta / ( 2 - vmax - vmin );
+
+     dr = ( ( ( vmax - r ) / 6 ) + ( delta / 2 ) ) / delta;
+     dg = ( ( ( vmax - g ) / 6 ) + ( delta / 2 ) ) / delta;
+     db = ( ( ( vmax - b ) / 6 ) + ( delta / 2 ) ) / delta;
+
+     if      ( r == vmax ) *h = db - dg;
+     else if ( g == vmax ) *h = ( 1./3 ) + dr - db;
+     else if ( b == vmax ) *h = ( 2./3 ) + dg - dr;
+
+     if ( *h < 0 ) *h += 1;
+     if ( *h > 1 ) *h -= 1;
+  }
+
+  return 1;
+}
+
+ int ColorConversion::ccHSLtoRGB(double h, double s, double l, double* r, double* g, double* b)
+{
+  double v1, v2;
+
+  if ( s == 0 )                       // HSL values = From 0 to 1
+  {
+     *r = l * 255;                     // RGB results = From 0 to 255
+     *g = l * 255;
+     *b = l * 255;
+  }
+  else
+  {
+     if ( l < 0.5 ) 
+       v2 = l * ( 1 + s );
+     else           
+       v2 = ( l + s ) - ( s * l );
+
+     v1 = 2 * l - v2;
+
+     *r = 255 * Hue_2_RGB( v1, v2, h + ( 1./3 ) );
+     *g = 255 * Hue_2_RGB( v1, v2, h );
+     *b = 255 * Hue_2_RGB( v1, v2, h - ( 1./3 ) );
+  } 
+
+  return 1;
+
+}
+
+
+// RGB values = From 0 to 1
+ int ColorConversion::ccfRGBtoCMY(double r, double g, double b, double* c, double* m, double* y)
+{
+  assert(c && m && y);
+  *c = 1 - r;
+  *m = 1 - g;
+  *y = 1 - b;
+
+  return 1;
+}
+
+// RGB values = From 0 to 255
+ int ColorConversion::cciRGBtoCMY(int r, int g, int b, double* c, double* m, double* y)
+{
+  assert(c && m && y);
+  assert(r >= 0 && r < 256);
+  assert(g >= 0 && g < 256);
+  assert(b >= 0 && b < 256);
+
+  *c = 1 - ( (double)r / 255 );
+  *m = 1 - ( (double)g / 255 );
+  *y = 1 - ( (double)b / 255 );
+
+  return 1;
+}
+
+// CMY values = From 0 to 255
+ int ColorConversion::ccCMYtofRGB(double c, double m, double y, double* r, double* g, double* b)
+{
+  assert(r && g && b);
+  assert(c >= 0 && c <= 1);
+  assert(m >= 0 && m <= 1);
+  assert(y >= 0 && y <= 1);
+
+  *r = ( 1 - c );
+  *g = ( 1 - m );
+  *b = ( 1 - y );
+
+  return 1;
+
+}
+// CMY values = From 0 to 1
+ int ColorConversion::ccCMYtoiRGB(double c, double m, double y, int* r, int* g, int* b)
+{
+  assert(r && g && b);
+  assert(c >= 0 && c <= 1);
+  assert(m >= 0 && m <= 1);
+  assert(y >= 0 && y <= 1);
+
+  *r = (int)( 1 - c ) * 255;
+  *g = (int)( 1 - m ) * 255;
+  *b = (int)( 1 - y ) * 255;
+
+  return 1;
+}
+
+
+// CMY values = From 0 to 1
+ int ColorConversion::ccCMYtoCMYK(double c, double m, double y, double* C, double* M, double* Y, double* K)
+{
+  double var_K = 1;
+
+  assert(C && M && Y && K);
+  assert(c >= 0 && c <= 1);
+  assert(m >= 0 && m <= 1);
+  assert(y >= 0 && y <= 1);
+
+  if ( c < var_K )
+    var_K = c;
+  if ( m < var_K )
+    var_K = m;
+  if ( y < var_K )
+    var_K = y;
+
+  *C = ( c - var_K ) / ( 1 - var_K );
+  *M = ( m - var_K ) / ( 1 - var_K );
+  *Y = ( y - var_K ) / ( 1 - var_K );
+  *K = var_K;
+
+  return 1;
+}
+
+// CMYK values = From 0 to 1
+ int ColorConversion::ccCMYKtoCMY(double c, double m, double y, double k, double* C, double* M, double* Y)
+{
+  assert(C && M && Y);
+  assert(c >= 0 && c <= 1);
+  assert(m >= 0 && m <= 1);
+  assert(y >= 0 && y <= 1);
+  assert(k >= 0 && k <= 1);
+
+  *C = ( c * ( 1 - k ) + k );
+  *M = ( m * ( 1 - k ) + k );
+  *Y = ( y * ( 1 - k ) + k );
+ 
+  return 1;
+}
+
+ int ColorConversion::ccRGBtoHSV(double r, double g, double b, double* h, double* s, double* v)
+{
+  double var_Min;
+  double var_Max;
+  double del_Max;
+
+  var_Min  = ccmin( r, g, b );    //Min. value of RGB
+  var_Max  = ccmax( r, g, g );    //Max. value of RGB
+  del_Max = var_Max - var_Min;    //Delta RGB value 
+
+  *v = var_Max;
+
+  if ( del_Max == 0 )                      // This is a gray, no chroma...
+  {
+     *h = 0;                               // HSV results = From 0 to 1
+     *s = 0;
+  }
+  else                                     // Chromatic data...
+  {
+     double del_R = ( ( ( var_Max - r ) / 6 ) + ( del_Max / 2 ) ) / del_Max;
+     double del_G = ( ( ( var_Max - g ) / 6 ) + ( del_Max / 2 ) ) / del_Max;
+     double del_B = ( ( ( var_Max - b ) / 6 ) + ( del_Max / 2 ) ) / del_Max;
+
+     *s = del_Max / var_Max;
+
+
+     if      ( r == var_Max ) *h = del_B - del_G;
+     else if ( g == var_Max ) *h = ( 1./3 ) + del_R - del_B;
+     else if ( g == var_Max ) *h = ( 2./3 ) + del_G - del_R;
+
+     if ( *h < 0 ) ; *h += 1;
+     if ( *h > 1 ) ; *h -= 1;
+  }
+
+  return 1;
+}
+
+ int ColorConversion::ccHSVtoRGB(double h, double s, double v, double* r, double* g, double* b)
+{
+  if ( s == 0 )                       // HSV values = From 0 to 1
+  {
+     *r = v;
+     *g = v;
+     *b = v;
+  }
+  else
+  {
+     double var_h = h * 6;
+     double var_i = floor( var_h );
+     double var_1 = v * ( 1 - s );
+     double var_2 = v * ( 1 - s * ( var_h - var_i ) );
+     double var_3 = v * ( 1 - s * ( 1 - ( var_h - var_i ) ) );
+
+     if      ( var_i == 0 ) { *r = v     ; *g = var_3 ; *b = var_1; }
+     else if ( var_i == 1 ) { *r = var_2 ; *g = v     ; *b = var_1; }
+     else if ( var_i == 2 ) { *r = var_1 ; *g = v     ; *b = var_3; }
+     else if ( var_i == 3 ) { *r = var_1 ; *g = var_2 ; *b = v;     }
+     else if ( var_i == 4 ) { *r = var_3 ; *g = var_1 ; *b = v;     }
+     else                   { *r = v     ; *g = var_1 ; *b = var_2; }
+
+  }
+
+  return 1;
+}
+
+ int ColorConversion::ccXYZtoHunterLab(double x, double y, double z, double* L, double* a, double* b)
+{
+  *L = 10 * sqrt( y );
+  *a = 17.5 * ( ( ( 1.02 * x ) - y ) / sqrt( y ) );
+  *b = 7 * ( ( y - ( 0.847 * z ) ) / sqrt( y ) );
+
+  return 1;
+}
+
+ int ccHunterLabtoXYZ(double L, double a, double b, double* x, double* y, double* z)
+{
+  double var_Y = L / 10;
+  double var_X = a / 17.5 * L / 10;
+  double var_Z = b / 7 * L / 10;
+
+  *y = pow(var_Y,2);
+  *x = ( var_X + *y ) / 1.02;
+  *z = -( var_Z - *y ) / 0.847;
+
+  return 1;
+}
+
+ int ColorConversion::ccXYZtoYxy(double x, double y, double z, double* rY, double* rx, double* ry)
+{
+  *rY = y;
+  *rx = x / ( x + y + z );
+  *ry = y / ( x + y + z );
+
+  return 1;
+}
+
+int ColorConversion::ccXYZtoLMS(double x, double y, double z, double* l, double* m, double* s)
+{
+     *l=0.7328*x+0.4296*y-0.1624*z;
+     *m=-0.7036*x+1.6975*y+0.0061*z;
+     *s=0.0030*x+0.0136*y+0.9834*z;
+     return 1;
+}
+int ColorConversion::ccLMStoOPP(double l, double m, double s, double* lum, double* lm, double* slm)
+{
+     *lum=l+m;
+     if (fabs(*lum)>1.0e-8)
+     {
+          *lm=(l-m)/ *lum;
+     }
+     else
+     {
+          *lm=l-m; //linear model
+     }     
+     if(fabs(s+ *lum)>1.0e-8)
+     {
+          
+          *slm=(s- *lum)/(s+ *lum);
+     }
+     else
+     {
+          *slm=2*s- *lum;//linear model
+     }
+     return 1;
+}
+ int ColorConversion::ccYxytoXYZ(double Y, double x, double y, double* rx, double* ry, double* rz)
+{
+  //Y = From 0 to 100
+  //x = From 0 to 1
+  //y = From 0 to 1
+
+  *rx = x * ( Y / y );
+  *ry = Y;
+  *rz = ( 1 - x - y ) * ( Y / y );
+
+  return 1;
+}
+
+ int ColorConversion::ccFixRGB(double* r, double* g, double* b)
+{
+    double min,max;
+    int mod=0;
+    min=(*r>*g)?*g:*r;
+    min=(min>*b)?*b:min;
+    if (min<0) {*r+=-min; *g+=-min; *b+=-min; mod=1;}
+    max=(*r>*g)?*r:*g;
+    max=(max>*b)?max:*b;
+    if (max>1){*r/=max; *g/=max; *b/=max; mod=1;}
+    return mod;
+}
+
+//r,g,b from 0 to 1
+ int ColorConversion::ccXYZtoRGB(double x, double y, double z, double* r, double* g, double* b, char ObsIll)
+{
+	
+  double ref_X = 100.0;//_ccTristimulusValues[ObsIll][ccX];
+  double ref_Y = 100.0;//_ccTristimulusValues[ObsIll][ccY];
+  double ref_Z = 100.0;//_ccTristimulusValues[ObsIll][ccZ];
+
+  double var_X = x / ref_X;        //X = From 0 to ref_X
+  double var_Y = y / ref_Y;        //Y = From 0 to ref_Y
+  double var_Z = z / ref_Z;        //Z = From 0 to ref_Y
+  
+  double var_R = var_X *  3.2406 + var_Y * -1.5372 + var_Z * -0.4986;
+  double var_G = var_X * -0.9689 + var_Y *  1.8758 + var_Z *  0.0415;
+  double var_B = var_X *  0.0557 + var_Y * -0.2040 + var_Z *  1.0570;
+
+  if ( var_R > 0.0031308 ) var_R = 1.055 * ( pow(var_R,( 1 / 2.4 )) ) - 0.055;
+  else                     var_R = 12.92 * var_R;
+  if ( var_G > 0.0031308 ) var_G = 1.055 * ( pow(var_G,( 1 / 2.4 )) ) - 0.055;
+  else                     var_G = 12.92 * var_G;
+  if ( var_B > 0.0031308 ) var_B = 1.055 * ( pow(var_B,( 1 / 2.4 )) ) - 0.055;
+  else                     var_B = 12.92 * var_B;
+
+  *r = var_R;
+  *g = var_G;
+  *b = var_B;
+
+  return 1;
+}
+
+ int ColorConversion::ccRGBtoXYZ(double r, double g, double b, double* x, double* y, double* z, char ObsIll)
+{
+  double var_R = r;        //R = From 0 to 1
+  double var_G = g;        //G = From 0 to 1
+  double var_B = b;        //B = From 0 to 1
+
+  if ( var_R > 0.04045 ) var_R = pow(( ( var_R + 0.055 ) / 1.055 ),2.4);
+  else                   var_R = var_R / 12.92;
+  if ( var_G > 0.04045 ) var_G = pow(( ( var_G + 0.055 ) / 1.055 ),2.4);
+  else                   var_G = var_G / 12.92;
+  if ( var_B > 0.04045 ) var_B = pow(( ( var_B + 0.055 ) / 1.055 ),2.4);
+  else                   var_B = var_B / 12.92;
+
+  var_R = var_R * 100;
+  var_G = var_G * 100;
+  var_B = var_B * 100;
+
+  *x = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805;
+  *y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722;
+  *z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505;
+  
+  return 1;
+}
+
+ int ColorConversion::ccXYZtoCIE_Lab(double x, double y, double z, double* L, double* a, double* b, char ObsIll)
+{
+  double var_X = x/_ccTristimulusValues[ObsIll][ccX];
+  double var_Y = y/_ccTristimulusValues[ObsIll][ccY];
+  double var_Z = z/_ccTristimulusValues[ObsIll][ccZ];
+
+  if ( var_X > 0.008856 ) var_X = pow(var_X,( 1./3 ));
+  else                    var_X = ( 7.787 * var_X ) + ( 16./ 116 );
+  if ( var_Y > 0.008856 ) var_Y = pow(var_Y,( 1./3 ));
+  else                    var_Y = ( 7.787 * var_Y ) + ( 16./ 116 );
+  if ( var_Z > 0.008856 ) var_Z = pow(var_Z,( 1./3 ));
+  else                    var_Z = ( 7.787 * var_Z ) + ( 16./ 116 );
+
+  *L = ( 116 * var_Y ) - 16;
+  *a = 500 * ( var_X - var_Y );
+  *b = 200 * ( var_Y - var_Z );
+
+  return 1;
+}
+
+ int ColorConversion::ccCIE_LabtoXYZ(double L, double a, double b, double* x, double* y, double* z, char ObsIll)
+{
+  double var_Y = ( L + 16 ) / 116;
+  double var_X = a / 500 + var_Y;
+  double var_Z = var_Y - b / 200;
+
+  if ( pow(var_Y,3) > 0.008856 ) var_Y = pow(var_Y,3);
+  else                      var_Y = ( var_Y - 16./ 116 ) / 7.787;
+  if ( pow(var_X,3) > 0.008856 ) var_X = pow(var_X,3);
+  else                      var_X = ( var_X - 16./ 116 ) / 7.787;
+  if ( pow(var_Z,3) > 0.008856 ) var_Z = pow(var_Z,3);
+  else                      var_Z = ( var_Z - 16./ 116 ) / 7.787;
+
+  *x = _ccTristimulusValues[ObsIll][ccX] * var_X;
+  *y = _ccTristimulusValues[ObsIll][ccY] * var_Y;
+  *z = _ccTristimulusValues[ObsIll][ccZ] * var_Z;
+
+  return 1;
+}
+
+ int ColorConversion::ccCIE_LabtoCIE_LCH(double L, double a, double b, double* rL, double* rC, double* rH)
+{
+  double var_H = atan2( b, a );  //Quadrant by signs
+
+  if ( var_H > 0 ) var_H = ( var_H / M_PI ) * 180;
+  else             var_H = 360 - ( (int)var_H / M_PI ) * 180;
+
+  *rL = L;
+  *rC = sqrt( pow(a,2) + pow(b,2) );
+  *rH = var_H;
+
+  return 1;
+}
+
+ int ColorConversion::ccCIE_LCHtoCIE_Lab(double L, double C, double H, double* rL, double* ra, double* rb)
+{
+  //CIE-H = From 0 to 360
+
+  *rL = L;
+  *ra = cos( degree_2_radian(H) ) * C;
+  *rb = sin( degree_2_radian(H) ) * C;
+
+  return 1;
+}
+
+ int ColorConversion::ccXYZtoCIE_Luv(double x, double y, double z, double* L, double* u, double* v, char ObsIll)
+{
+  double ref_X = _ccTristimulusValues[ObsIll][ccX];
+  double ref_Y = _ccTristimulusValues[ObsIll][ccY];
+  double ref_Z = _ccTristimulusValues[ObsIll][ccZ];
+  
+  double ref_U = ( 4 * ref_X ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) );
+  double ref_V = ( 9 * ref_Y ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) );
+
+  double var_U = ( 4 * x ) / ( x + ( 15 * y ) + ( 3 * z ) );
+  double var_V = ( 9 * y ) / ( x + ( 15 * y ) + ( 3 * z ) );
+  double var_Y = y / 100;
+
+  
+  if ( var_Y > 0.008856 ) var_Y = pow(var_Y,( 1./3 ));
+  else                    var_Y = ( 7.787 * var_Y ) + ( 16./ 116 );
+
+
+  *L = ( 116 * var_Y ) - 16;
+  *u = 13 * *L * ( var_U - ref_U );
+  *v = 13 * *L * ( var_V - ref_V );
+
+  return 1;
+}
+
+ int ColorConversion::ccCIE_LuvtoXYZ(double L, double u, double v, double* x, double* y, double* z, char ObsIll)
+{
+  double ref_X = _ccTristimulusValues[ObsIll][ccX];
+  double ref_Y = _ccTristimulusValues[ObsIll][ccY];
+  double ref_Z = _ccTristimulusValues[ObsIll][ccZ];
+
+  double ref_U = ( 4 * ref_X ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) );
+  double ref_V = ( 9 * ref_Y ) / ( ref_X + ( 15 * ref_Y ) + ( 3 * ref_Z ) );
+
+  double var_U = u / ( 13 * L ) + ref_U;
+  double var_V = v / ( 13 * L ) + ref_V;
+
+  double var_Y = ( L + 16 ) / 116;
+  
+  if ( pow(var_Y,3) > 0.008856 ) var_Y = pow(var_Y,3);
+  else                      var_Y = ( var_Y - 16./ 116 ) / 7.787;
+
+  (*y) = var_Y * 100;
+  (*x) =  - ( 9 * *y * var_U ) / ( ( var_U - 4 ) * var_V  - var_U * var_V );
+  (*z) = ( 9 * *y - ( 15 * var_V * *y ) - ( var_V * *x ) ) / ( 3 * var_V );
+
+  return 1;
+}

+ 82 - 0
baselib/cc.h

@@ -0,0 +1,82 @@
+#ifndef _CC_H_
+#define _CC_H_
+
+enum {
+  ccTA_2, ccTC_2, D50_2, D55_2, D65_2, D75_2, F2_2, F7_2, F11_2,
+  ccTA_10, ccTC_10, D50_10, D55_10, D65_10, D75_10, F2_10, F7_10, F11_10,
+  ccNTristimulus
+};
+
+enum { ccX, ccY, ccZ};
+
+/*
+ *	Function Headers
+ */
+
+namespace OBJREC {
+
+class ColorConversion
+{
+     private:
+          static double ccmin(double val1, double val2, double val3);
+          static double ccmax(double val1, double val2, double val3);
+          static double Hue_2_RGB( double v1, double v2, double vH );
+          static double degree_2_radian(double val);
+        
+     public:
+          
+static int ccXYZtoRGB(double x, double y, double z, double* r, double* g, double* b, char ObsIll); //
+
+static int ccRGBtoXYZ(double r, double g, double b, double* x, double* y, double* z, char ObsIll); //
+
+static int ccXYZtoYxy(double x, double y, double z, double* rY, double* rx, double* ry);//
+
+static int ccXYZtoLMS(double x, double y, double z, double* l, double* m, double* s);//
+
+static int ccLMStoOPP(double l, double m, double s, double* lum, double* lm, double* slm);//
+
+static int ccYxytoXYZ(double Y, double x, double y, double* rx, double* ry, double* rz);//
+
+static int ccXYZtoHunterLab(double x, double y, double z, double* L, double* a, double* b); //
+
+static int ccHunterLabtoXYZ(double L, double a, double b, double* x, double* y, double* z); //
+
+static int ccXYZtoCIE_Lab(double x, double y, double z, double* L, double* a, double* b, char ObsIll); //
+
+static int ccCIE_LabtoXYZ(double L, double a, double b, double* x, double* y, double* z, char ObsIll); //
+
+static int ccCIE_LabtoCIE_LCH(double L, double a, double b, double* rL, double* rC, double* rH);
+
+static int ccCIE_LCHtoCIE_Lab(double L, double C, double H, double* rL, double* ra, double* rb);
+
+static int ccXYZtoCIE_Luv(double x, double y, double z, double* L, double* u, double* v, char ObsIll);
+
+static int ccCIE_LuvtoXYZ(double L, double u, double v, double* x, double* y, double* z, char ObsIll);
+
+static int ccRGBtoHSL(double L, double a, double b, double* h, double* s, double* l); //
+
+static int ccHSLtoRGB(double h, double s, double l, double* r, double* g, double* b); //
+
+static int ccRGBtoHSV(double r, double g, double b, double* h, double* s, double* v); //
+
+static int ccHSVtoRGB(double h, double s, double v, double* r, double* g, double* b); //
+
+static int ccfRGBtoCMY(double r, double g, double b, double* c, double* m, double* y); //
+
+static int cciRGBtoCMY(int r, int g, int b, double* c, double* m, double* y); //
+
+static int ccCMYtofRGB(double c, double m, double y, double* r, double* g, double* b); //
+
+static int ccCMYtoiRGB(double c, double m, double y, int* r, int* g, int* b); //
+
+static int ccCMYtoCMYK(double c, double m, double y, double* C, double* M, double* Y, double* K); //
+
+static int ccCMYKtoCMY(double c, double m, double y, double k, double* C, double* M, double* Y); //
+
+static int ccFixRGB(double* r, double* g, double* b);
+
+};
+
+} // namespace
+
+#endif

+ 127 - 0
baselib/cmdline.c

@@ -0,0 +1,127 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "cmdline.h"
+
+#define MAX_LENGTH_PER_PARAMETER_FORMAT 128
+#define MAX_PARAMETERS_PER_OPTION 8
+
+static int parse_option_parameters(const char **params, const char *format, void *storage)
+{
+	int error = 0;
+	int fmt_pos=0;
+	int pa_num=0;
+	//fprintf (stderr, "parse_option_parameters !\n");
+	while (1) {
+		char s[MAX_LENGTH_PER_PARAMETER_FORMAT];
+		int s_pos=0;
+		while (format[fmt_pos] == ' ') fmt_pos++;
+		while ((format[fmt_pos] != ' ') &&
+		       (format[fmt_pos] != 0))
+			s[s_pos++] = format[fmt_pos++];
+		if (s_pos==0) break; /* end of format string */
+		s[s_pos++] = 0;
+		if (params[pa_num]==NULL) {error++;break;}
+		//fprintf (stderr, "option parameter tag %s value %s\n", s, params[pa_num]);
+		if (storage!=NULL) sscanf(params[pa_num], s, &(((int*)storage)[pa_num]));
+		pa_num++;
+	}
+	if (error!=0) return -error;
+	return pa_num;
+}
+
+
+/* return 1 if help mode was active
+   return negative number if an error occured
+   return 0 if everything went fine */
+int parse_arguments(int argc, const char **argv, const struct CmdLineOption *options, char **moreParameters, const char *helpText)
+{
+	int error = 0, helpmode = 0;
+	int opt, arg;
+	int numMoreParameters = 0;
+	if (options==NULL) return -1;
+
+	for (opt=0; options[opt].name != NULL; opt++) {
+		if (options[opt].storage != NULL) {
+			if (options[opt].parameters==NULL) *(int*)options[opt].storage = 0;
+			else if (options[opt].default_value != NULL) {
+				const char *defaults = options[opt].default_value;
+				const char *default_argv[MAX_PARAMETERS_PER_OPTION];
+				int arg = 0, pos = 0;
+				while (1) {
+					int len = 0;
+					while (defaults[pos] == ' ') pos++;
+					default_argv[arg] = &(defaults[pos]);
+					while ((defaults[pos] != ' ')&&
+					       (defaults[pos] != 0)) {pos++;len++;}
+					if (len==0) {
+						default_argv[arg] = NULL;
+						break;
+					}
+					arg++;
+				}
+				parse_option_parameters(default_argv, options[opt].parameters, options[opt].storage);
+			}
+			
+		}
+	}
+
+	for (arg=1; arg<argc; arg++) {
+		const struct CmdLineOption *foundOption = NULL;
+		int minuses = 0;
+		while ((argv[arg][minuses]=='-')&&(minuses<2)) minuses++;
+
+		if (minuses > 0) {
+			if ((!strcmp("help", &(argv[arg][minuses])))||
+			    (!strcmp("h", &argv[arg][minuses]))) {
+				helpmode = 1;
+				break;
+			}
+			for (opt=0; options[opt].name != NULL; opt++) {
+				if (!strcmp(options[opt].name, &(argv[arg][minuses]))) {
+					foundOption = &(options[opt]);
+					break;
+				}
+			}
+		}
+
+		if (foundOption!=NULL) {
+			//fprintf(stderr, "option %s was recognized\n",  (argv[arg]));
+			if (foundOption->parameters!=NULL) {
+				int ret = parse_option_parameters(&(argv[arg+1]), foundOption->parameters, foundOption->storage);
+				if (ret<0) { fprintf (stderr, "cmdline: error reading this option!\n"); error++; break; }
+				arg+=ret;
+			} else { /* there are no parameters */
+				if (foundOption->storage!=NULL) *(int*)(foundOption->storage) = 1;
+			}
+		} else { /* option not recognized */
+			if (moreParameters) {
+				moreParameters[numMoreParameters++] = (char*)argv[arg];
+			}
+			/* else fprintf(stderr, "option %s not recognized\n",  (argv[arg]));*/
+		}
+	}
+	moreParameters[numMoreParameters] = NULL;
+
+	if (helpmode)
+		return print_help ( options, helpText );
+	return -error;
+}
+
+int print_help ( const struct CmdLineOption *options, const char *helpText )
+{
+       if(helpText!=NULL) fprintf(stdout, "%s\n",helpText);
+       fprintf(stdout, "Options:\n");
+       int opt;
+       for (opt=0; options[opt].name != NULL; opt++) {
+		if (options[opt].description!=NULL) {
+			fprintf(stdout, "  -%-20s%s", options[opt].name, options[opt].description);
+			if (options[opt].default_value!=NULL)
+				fprintf(stdout, " (dflt: %s)",options[opt].default_value);
+			fprintf(stdout, "\n");
+		}
+	}
+	return 1;
+}
+

+ 78 - 0
baselib/cmdline.h

@@ -0,0 +1,78 @@
+/**
+* @file cmdline.h
+* @author Olaf Kähler
+*/
+
+#ifndef _CMDLINE_H_
+#define _CMDLINE_H_
+
+#warning "CmdLine is deprecated ! Please use baselib/Config"
+
+#ifdef __cplusplus
+#define DEFAULT_ARGUMENT_VALUE(x) = (x)
+
+extern "C" {
+
+#else
+#define DEFAULT_ARGUMENT_VALUE(x)
+#endif
+
+/** This struct describes a singe command line parameter, with help message,
+    default values and so on...
+*/
+struct CmdLineOption {
+	/** The word required on the command line, e.g. "verbose" or "seq"
+	    NULL means end of a list of parameters
+	*/
+	const char *name;
+
+	/** Description of the parameter in the help message
+	    NULL means, option is not shown in help
+	*/
+	const char *description;
+
+	/** Default value, e.g. "~/.config" or "0 0 1"
+	   NULL means no default will be set
+	*/
+	const char *default_value;
+
+	/** scanf-like parameters of the option, e.g. "%s" or "%i %i %i"
+	    NULL means no parameters follow
+	*/
+	const char *parameters;
+
+	/** Storage place for parameters. If there are no parameters, storage
+	    will be set to 1 if the option was found, 0 otherwise
+	    NULL means, nothing is to be stored
+	*/
+	void *storage;
+};
+
+
+/** Function to parse the commandline using the structure defined above
+	@param argc Number of commandline arguments
+	@param argv argv as it is passed to main()
+	@param options Array of structures of the options to search for
+	@param moreParameters all parameters not recognized are stored here in order of appearance
+	@param helpText Text printed in case "help" or "h" is found
+
+	@return 1 if help mode was active
+	@return negative number if an error occured
+	@return 0 if everything went fine
+*/
+int parse_arguments(int argc, const char **argv,
+		const struct CmdLineOption *options,
+		char **moreParameters DEFAULT_ARGUMENT_VALUE(0),
+		const char *helpText DEFAULT_ARGUMENT_VALUE(0));
+
+/** Function to print help text using the structure defined above */
+int print_help ( const struct CmdLineOption *options, const char *helpText DEFAULT_ARGUMENT_VALUE(0) );
+
+#ifdef __cplusplus
+} /* extern C */
+#endif
+
+#undef DEFAULT_ARGUMENT_VALUE
+
+#endif
+

+ 8 - 0
baselib/doxygenDescription.h

@@ -0,0 +1,8 @@
+/**
+ * @brief Machine learning and computer vision tools for object recognition approaches.
+ *
+ * @author Erik Rodner, Michael Koch, Björn Fröhlich, Michael Kemmler
+ *
+ */
+namespace OBJREC {
+}

+ 1 - 0
baselib/libdepend.inc

@@ -0,0 +1 @@
+$(call PKG_DEPEND_INT,core)

+ 88 - 0
baselib/progs/Makefile.inc

@@ -0,0 +1,88 @@
+# 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))))
+$(eval $(call PKG_DEPEND_INT,$(PARENTDIR)))
+
+# ---------------------------
+# - 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.
+
+BINARIES:=$(patsubst %.o,$(BINDIR)%,$(filter-out moc_%,$(notdir $(OBJS))))
+ALL_BINARIES+=$(BINARIES)
+
+# ---------------------
+# - 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@')))
+-include $(OBJS:%.o=%.bd)
+
+# -------------------
+# - 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))
+

+ 64 - 0
baselib/progs/scaleKernelMatrix.cpp

@@ -0,0 +1,64 @@
+/** 
+* @file scaleKernelMatrix.cpp
+* @brief scale a kernel matrix
+* @author Erik Rodner
+* @date 12/21/2009
+
+*/
+#include "core/basics/Config.h"
+#include "core/vector/MatrixT.h"
+
+using namespace std;
+using namespace NICE;
+
+
+/** 
+    
+    scale a kernel matrix 
+    
+*/
+int main (int argc, char **argv)
+{   
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+
+    Config conf ( argc, argv );
+    
+	string kernel_in = conf.gS("main", "kernel_in");    
+	string kernel_out = conf.gS("main", "kernel_out");
+    
+    Vector labels;
+	Matrix kernelMatrix;
+
+	ifstream ifs ( kernel_in.c_str(), ios::in );
+	if ( ! ifs.good() )
+		fthrow(Exception, "Unable to read kernel matrix from " << kernel_in );
+
+	ifs >> kernelMatrix;
+	ifs >> labels;
+
+	ifs.close();
+
+	if ( kernelMatrix.cols() != kernelMatrix.rows() )
+	{
+		fthrow(Exception, "Kernel matrix is not quadratic!");
+	}
+	Matrix kernelMatrixScaled ( kernelMatrix.cols(), kernelMatrix.rows() );
+    
+	for ( uint i = 0 ; i < kernelMatrix.cols(); i++ )
+		for ( uint j = 0 ; j < kernelMatrix.rows(); j++ )
+		{
+			double K_ii = kernelMatrix(i,i);
+			double K_jj = kernelMatrix(j,j);
+			kernelMatrixScaled(i,j) = kernelMatrix(i,j) / sqrt(K_ii * K_jj);
+		}
+
+	ofstream ofs ( kernel_out.c_str(), ios::out );
+	if ( ! ofs.good() )
+		fthrow(Exception, "Unable to write kernel matrix to " << kernel_out );
+
+	ofs << kernelMatrixScaled;
+	ofs << labels;
+	ofs.close();
+    
+    return 0;
+}

+ 55 - 0
baselib/progs/testProgressBar.cpp

@@ -0,0 +1,55 @@
+/**\example testProgressBar.cpp
+ * @file testProgressBar.cpp
+ * @brief FourierLibrary Testsystem
+ * @author Michael Koch
+ * @date 05/28/2008
+
+ */
+
+// #define DEBUG
+// #undef DEBUG
+
+
+#include "core/basics/Config.h"
+
+#include "core/basics/StringTools.h"
+// #include "features/simplefeatures/FourierLibrary.h"
+#include "vislearning/baselib/ProgressBar.h"
+
+#include <iostream>
+#include <fstream>
+
+using namespace NICE;
+using namespace OBJREC;
+
+using namespace std;
+
+/**
+
+ ProgressBarQtThread Testsystem
+
+ */
+
+//main
+
+int main(int argc, char **argv)
+{
+	std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+	Config mainconf(argc, argv);
+
+	OBJREC::ProgressBar P;
+	for (int i = 0; i < 10; i++)
+	{
+		P.update(10);
+		sleep(3);
+		cerr << i << endl;
+		if (i > 2)
+		{
+			P.show();
+		}
+	}
+	P.hide();
+	//	P.wait();
+
+	return 0;
+}

+ 251 - 0
cbaselib/BasicVectorTransformations.cpp

@@ -0,0 +1,251 @@
+#include <list>
+
+#include "vislearning/cbaselib/BasicVectorTransformations.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+		/** ========= DO NOTHING =========== */
+
+		NICE::Vector IdentityTransform::transform( const NICE::Vector& vec)
+		{
+			return vec;
+		};
+
+		NICE::Vector IdentityTransform::transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params)
+		{
+			return vec;
+		}
+
+		/** ========= UNIT LENGTH NORMALIZATION OF A VECTOR =========== */
+
+		NICE::Vector UnitLengthTransform::transform( const NICE::Vector& vec)
+		{
+			NICE::Vector new_vec(vec);
+			new_vec.normalizeL2();
+			return new_vec;
+		};
+
+		NICE::Vector UnitLengthTransform::transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params)
+		{
+			//fprintf(stderr,"\nWARNING: NO PARAMETER IS NEEDED FOR UNIT LENGTH NORMALIZATION!\n");
+			return transform(vec);
+		}
+
+		/** ========= ADD A CONSTANT TO THE VECTOR =========== */
+
+		NICE::Vector ConstantShiftingTransform::transform( const NICE::Vector& vec)
+		{
+			fprintf(stderr,"\n\nERROR: ONE PARAMETER IS NEEDED FOR CONSTANT SHIFTING TRANSFORM!\n\n");
+			exit(-1);
+		};
+
+		NICE::Vector ConstantShiftingTransform::transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params)
+		{
+			if(params.size()<1 || params[0].size()<1){
+				fprintf(stderr,"\n\nERROR: ONE PARAMETER IS NEEDED FOR CONSTANT SHIFTING TRANSFORM!\n\n");
+				exit(-1);
+			}else{
+				NICE::Vector new_vec(vec);
+				new_vec+=params[0][0];
+				return new_vec;
+			}
+		}
+
+		/** ========= CONSTANT SCALING OF A VECTOR =========== */
+
+		NICE::Vector ConstantScalingTransform::transform( const NICE::Vector& vec)
+		{
+			fprintf(stderr,"\n\nERROR: ONE PARAMETER IS NEEDED FOR CONSTANT SCALING TRANSFORM!\n\n");
+			exit(-1);
+		};
+
+		NICE::Vector ConstantScalingTransform::transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params)
+		{
+			if(params.size()<1 || params[0].size()<1){
+				fprintf(stderr,"\n\nERROR: ONE PARAMETER IS NEEDED FOR CONSTANT SCALING TRANSFORM!\n\n");
+				exit(-1);
+			}else{
+				NICE::Vector new_vec(vec);
+				new_vec*=params[0][0];
+				return new_vec;
+			}
+		}
+
+
+		/** ========= ELEMENTWISE ADDITION OF VECTORS =========== */
+
+		NICE::Vector VectorShiftingTransform::transform( const NICE::Vector& vec)
+		{
+			fprintf(stderr,"\n\nERROR: ONE PARAMETER VECTOR IS NEEDED FOR VECTOR SHIFTING TRANSFORM!\n\n");
+			exit(-1);
+		};
+
+		NICE::Vector VectorShiftingTransform::transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params)
+		{
+			if(params.size()<1 || params[0].size()!=vec.size() ){
+				fprintf(stderr,"\n\nERROR: ONE PARAMETER VECTOR WITH APPROPRIATE DIMENSION IS NEEDED FOR VECTOR SHIFTING TRANSFORM!\n\n");
+				exit(-1);
+			}else{
+				NICE::Vector new_vec(vec);
+				new_vec+=params[0];
+				return new_vec;
+			}
+		}
+
+		/** ========= ELEMENTWISE MULTIPLICATION OF VECTORS =========== */
+
+		NICE::Vector VectorScalingTransform::transform( const NICE::Vector& vec)
+		{
+			fprintf(stderr,"\n\nERROR: ONE PARAMETER VECTOR IS NEEDED FOR VECTOR SCALING TRANSFORM!\n\n");
+			exit(-1);
+		};
+
+		NICE::Vector VectorScalingTransform::transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params)
+		{
+			if(params.size()<1 || params[0].size()!=vec.size() ){
+				fprintf(stderr,"\n\nERROR: ONE PARAMETER VECTOR WITH APPROPRIATE DIMENSION IS NEEDED FOR VECTOR SCALING TRANSFORM!\n\n");
+				exit(-1);
+			}else{
+				NICE::Vector new_vec(vec);
+				new_vec*=params[0];
+				return new_vec;
+			}
+		}
+
+
+		/** ========= Running Median OF VECTOR =========== */
+		NICE::Vector RunningMedianTransform::transform( const NICE::Vector& vec)
+		{
+			std::vector<NICE::Vector> param_vec;
+			NICE::Vector param(1);
+			param[0]=3;
+			param_vec.push_back(param);
+			return RunningMedianTransform::transform(vec,param_vec);
+		};
+
+		NICE::Vector RunningMedianTransform::transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params)
+		{
+			if(params.size()<1 || params[0].size()<1 || params[0][0]<1 || params[0][0]>=vec.size()){
+				fprintf(stderr,"\n\nERROR: ONE POSITIVE 1 < PARAMETER < SIZE MUST BE PROVIDED AS MEDIAN WIDTH!\n\n");
+				exit(-1);
+			}else{
+				std::list<double> auxlist;
+				std::list<double> worklist;
+				std::list<double>::iterator it;
+				NICE::Vector median(vec.size());
+
+				int vecsize=(int)vec.size();
+				int size = (int) params[0][0];
+				int klow= (size%2!=0 ? -(size-1)/2 : -size/2);
+				int kup= (size%2!=0 ? (size-1)/2 : size/2-1);
+				int mid= (size%2!=0 ? (size-1)/2 : size/2-1);
+				//set up initial list, only k<0 case should occur
+				for(int k=klow;k<kup+1;k++) {
+					auxlist.push_back( (k<0 || k>=vecsize)? 0.0 : vec[k] );
+				}
+				worklist=auxlist;
+				worklist.sort();
+
+				if(size%2 != 0){ //real median
+					int k=0;
+					for (it=worklist.begin(); it!=worklist.end(); ++it){
+						if(k >= mid){
+							median[0]=*it;
+							break;
+						}
+						k++;
+					}
+					//for all other inices >0
+					for(int i=1;i<vecsize;i++){
+						auxlist.pop_front();
+						//only i+kup>=vecsize should occur
+						auxlist.push_back( (i+kup>=vecsize || i+kup<0)? 0.0 : vec[i+kup] );
+						worklist=auxlist;
+						worklist.sort();
+						k=0;
+						for (it=worklist.begin(); it!=worklist.end(); ++it){
+							if(k >= mid){
+								median[i]=*it;
+								break;
+							}
+							k++;
+						}					
+					}
+				}else{ //midpoint between two centerd points
+					int k=0;
+					double m1,m2;
+					for (it=worklist.begin(); it!=worklist.end(); ++it){
+						if(k == mid){
+							m1=*it;it++;m2=*it;
+							median[0]=0.5*(m1+m2);
+							break;
+						}
+						k++;
+					}
+					//for all other inices >0
+					for(int i=1;i<vecsize;i++){
+						auxlist.pop_front();
+						//only i+kup>=vecsize should occur
+						auxlist.push_back( (i+kup>=vecsize || i+kup<0)? 0.0 : vec[i+kup] );
+						worklist=auxlist;
+						worklist.sort();
+						k=0;
+						for (it=worklist.begin(); it!=worklist.end(); ++it){
+							if(k == mid){
+								m1=*it;++it;m2=*it;
+								median[i]=0.5*(m1+m2);
+								break;
+							}
+							k++;
+						}					
+					}
+				}
+				return median;
+			}
+		}
+
+
+		/** ========= Running Mean OF VECTOR =========== */
+
+		NICE::Vector RunningMeanTransform::transform( const NICE::Vector& vec)
+		{
+			std::vector<NICE::Vector> param_vec;
+			NICE::Vector param(1);
+			param[0]=3;
+			param_vec.push_back(param);
+			return RunningMeanTransform::transform(vec,param_vec);
+		};
+
+		//for mirroring
+		uint RunningMeanTransform::get_index( int index, int vec_size)
+		{
+			if(index<0) return (-index-1);
+			if(index>=vec_size) return (2*vec_size-index-1);
+			return index;
+		}
+
+		NICE::Vector RunningMeanTransform::transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params)
+		{
+			if(params.size()<1 || params[0].size()<1 || params[0][0]<1 || params[0][0]>=vec.size()){
+				fprintf(stderr,"\n\nERROR: ONE POSITIVE 1 < PARAMETER < SIZE MUST BE PROVIDED AS MEAN WIDTH!\n\n");
+				exit(-1);
+			}else{
+				uint vecsize=vec.size();
+				int size = (int) params[0][0];
+				int klow= (size%2!=0 ? -(size-1)/2 : -size/2);
+				int kup= (size%2!=0 ? (size-1)/2 : size/2-1);
+				//augment vector with mirroring elements at the boundary
+				NICE::Vector mean( vec.size() );
+				double mean_i=0;
+				for(int k=klow;k<kup+1;k++) {mean_i+=vec[get_index(k,vecsize)];}
+				mean[0]=mean_i/size;
+				for(int i=1;i<(int)vec.size();i++){
+					mean_i+=vec[get_index(i+kup,vecsize)]-vec[get_index(i+klow,vecsize)];
+					mean[i]=mean_i/size;
+				}
+				return mean;
+			}
+		}
+

+ 94 - 0
cbaselib/BasicVectorTransformations.h

@@ -0,0 +1,94 @@
+/** 
+* @file LabeledSet.h
+* @brief Transformation of vectors
+* @author MiKe
+* @date 20.01.2010
+
+*/
+#ifndef BASICVECTORTRANSFORMATIONSINCLUDE
+#define BASICVECTORTRANSFORMATIONSINCLUDE
+
+#include <vislearning/nice_nonvis.h>
+#include "core/vector/VVector.h"
+#include <vector>
+#include "vislearning/cbaselib/VectorTransform.h"
+
+namespace OBJREC {
+
+   ///do nothing
+   class IdentityTransform : public VectorTransform{
+	public:
+		IdentityTransform (){};
+		~IdentityTransform (){};
+		NICE::Vector transform( const NICE::Vector& vec);
+		NICE::Vector transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params);
+    };
+
+   ///vec = vec/||vec||_2, where vec~vector
+   class UnitLengthTransform : public VectorTransform{
+	public:
+		UnitLengthTransform(){};
+		~UnitLengthTransform(){};
+		NICE::Vector transform( const NICE::Vector& vec);
+		NICE::Vector transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params);
+    };
+
+   ///vec = vec + params[0][0], where vec~vector, params[0][0]~scalar
+   class ConstantShiftingTransform : public VectorTransform{
+	public:
+		ConstantShiftingTransform(){};
+		~ConstantShiftingTransform(){};
+		NICE::Vector transform( const NICE::Vector& vec);
+		NICE::Vector transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params);
+    };
+
+   ///vec = vec * params[0][0], where vec~vector, params[0][0]~scalar
+   class ConstantScalingTransform : public VectorTransform{
+	public:
+		ConstantScalingTransform(){};
+		~ConstantScalingTransform(){};
+		NICE::Vector transform( const NICE::Vector& vec);
+		NICE::Vector transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params);
+    };
+
+   ///vec = vec .+ params[0], where vec~vector, params[0]~vector (dimensionwise addition, vectors must have same length)
+   class VectorShiftingTransform : public VectorTransform{
+	public:
+		VectorShiftingTransform(){};
+		~VectorShiftingTransform(){};
+		NICE::Vector transform( const NICE::Vector& vec);
+		NICE::Vector transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params);
+    };
+
+   ///vec = vec .* params[0], where vec~vector, params[0]~vector (dimensionwise scaling, vectors must have same length)
+   class VectorScalingTransform  : public VectorTransform{
+	public:
+		VectorScalingTransform(){};
+		~VectorScalingTransform(){};
+		NICE::Vector transform( const NICE::Vector& vec);
+		NICE::Vector transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params);
+    };   
+
+   /// Running Median wrt vec of width params[0][0] (if not specified, default width=3), vec filled with zeros at boundaries
+   class RunningMedianTransform : public VectorTransform{
+	public:
+		RunningMedianTransform(){};
+		~RunningMedianTransform(){};
+		NICE::Vector transform( const NICE::Vector& vec);
+		NICE::Vector transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params);
+    };
+   /// Running Mean wrt vec of width params[0][0] (if not specified, default width=3), vec mirrored at boundaries
+   class RunningMeanTransform : public VectorTransform{
+	private:
+		uint get_index( int index, int vec_size);
+	public:
+		RunningMeanTransform(){};
+		~RunningMeanTransform(){};
+		NICE::Vector transform( const NICE::Vector& vec);
+		NICE::Vector transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params);
+    };
+
+
+} // namespace
+
+#endif

+ 218 - 0
cbaselib/BoundingBox.cpp

@@ -0,0 +1,218 @@
+/*!
+ * \file BoundingBox.cpp
+ * \brief
+ * \author Gapchich Vladislav
+ * \date 23/10/11
+ */
+
+#include "vislearning/cbaselib/BoundingBox.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+//! A constructor
+BoundingBox::BoundingBox()
+{
+	top_left_.x = -1;
+	top_left_.y = -1;
+	bottom_right_.x = -1;
+	bottom_right_.y = -1;
+	id_ = -1;
+}
+
+// A copy-constructor
+BoundingBox::BoundingBox(const BoundingBox &copy)
+{
+	top_left_ = copy.topLeft();
+	bottom_right_ = copy.bottomRight();
+	id_ = copy.id();
+}
+
+//! A desctructor
+BoundingBox::BoundingBox::~BoundingBox()
+{
+	
+}
+
+//! Sets top left coordinate of the bounding box
+/*!
+ * /param[in] aTopLeft should not contain negative data 
+ */
+void 
+BoundingBox::setTopLeft(const CoordT< int > &aTopLeft)
+{
+	if (aTopLeft.x < 0 || aTopLeft.y < 0) {
+		return;
+		/* NOTREACHED */
+	}
+	
+	top_left_ = aTopLeft;
+}
+
+//! overloaded
+/*!
+ * \see setTopLeft(const CoordT< int > &aTopLeft)
+ */
+void 
+BoundingBox::setTopLeft(const int &x, const int &y)
+{
+	if (x < 0 || y < 0) {
+		return;
+		/* NOTREACHED */
+	}
+	
+	CoordT< int > topLeft(x, y);
+	top_left_ = topLeft;
+}
+
+//! Sets bottom right coordinate of the bounding box
+/*!
+ * /param[in] aBottomRight should not contain negative data 
+ */
+void 
+BoundingBox::setBottomRight(const CoordT< int > &aBottomRight)
+{
+	if (aBottomRight.x < 0 || aBottomRight.y < 0) {
+		return;
+		/* NOTREACHED */
+	}
+	
+	bottom_right_ = aBottomRight;	
+}
+
+//! overloaded
+/*!
+ * \see setBottomRight(const CoordT< int > &aBottomRight)
+ */
+void 
+BoundingBox::setBottomRight(const int &x, const int &y)
+{
+	if (x < 0 || y < 0) {
+		return;
+		/* NOTREACHED */
+	}
+	
+	CoordT< int > bottomRight(x, y);
+	bottom_right_ = bottomRight;
+}
+
+//!
+void
+BoundingBox::setWidth(const int &aWidth)
+{
+	if (aWidth < 0) {
+		return;
+		/* NOTREACHED */
+	}
+	
+	bottom_right_.x = top_left_.x + aWidth;
+}
+
+//!
+void
+BoundingBox::setHeight(const int &aHeight)
+{
+	if (aHeight < 0) {
+		return;
+		/* NOTREACHED */
+	}
+	
+	bottom_right_.y = top_left_.y + aHeight;
+}
+
+//! Sets a category ID(label ID) for the bounding box 
+/*!
+ * /param[in] anID should not be less than zero 
+ */
+void 
+BoundingBox::setID(const int &anID)
+{
+	if (anID < 0) {
+		return;
+		/* NOTREACHED */
+	}
+}
+
+//! returns top left coordinate of the bounding box
+CoordT< int > 
+BoundingBox::topLeft() const
+{
+	return top_left_;
+}
+
+//! returns bottom right coordinate of the bounding box
+CoordT< int > 
+BoundingBox::bottomRight() const
+{
+	return bottom_right_;
+}
+
+//!
+int
+BoundingBox::width()
+{
+	if (top_left_.x < bottom_right_.x)
+		return bottom_right_.x - top_left_.x;
+	else
+		return -1;
+}
+
+//!
+int
+BoundingBox::height()
+{
+	if (top_left_.y < bottom_right_.y)
+		return bottom_right_.y - top_left_.y;
+	else
+		return -1;
+}
+
+//! returns a category ID of the bounding box
+int 
+BoundingBox::id() const
+{ 
+	return id_;
+}
+
+//! Checks whether bounding box is valid or not
+/*!
+ * Member checks if top left and bottom right coordinates are really 
+ * so, if category id and coordinates are positive
+ * 
+ * returns true on success.
+ */
+bool 
+BoundingBox::isValid() const
+{
+	if (id_ < 0 || 
+		top_left_.x < 0 ||
+		top_left_.y < 0 ||
+		bottom_right_.x < 0 ||
+		bottom_right_.y < 0 ||
+		bottom_right_.y <= top_left_.y ||
+		top_left_.x <= bottom_right_.x)
+	{
+		return false;
+		/* NOTREACHED */
+	}
+	
+	return true;
+}
+
+//! swaps top left and bottom right coordinates if they are mixed
+void
+BoundingBox::validate()
+{
+	if (bottom_right_.y < top_left_.y ||
+		top_left_.x < bottom_right_.x)
+	{
+		CoordT< int > buffer = top_left_;
+		top_left_ = bottom_right_;
+		bottom_right_ = buffer;
+	}
+}
+
+/*
+ * 
+ */

+ 55 - 0
cbaselib/BoundingBox.h

@@ -0,0 +1,55 @@
+/*!
+ * \file BoundingBox.h
+ * \brief
+ * \author Gapchich Vladislav
+ * \date 23/10/11
+ */
+
+#ifndef __BOUNDINGBOX_H__
+#define __BOUNDINGBOX_H__
+
+#include "core/image/CoordT.h"
+
+using namespace NICE;
+
+namespace OBJREC {
+
+//! \brief Contains category ID, top left and bottom right points of the bounding
+//!  box rectangle. 
+class BoundingBox
+{
+public:
+	BoundingBox();
+	BoundingBox(const BoundingBox &copy);
+	~BoundingBox();
+	
+	void setTopLeft(const CoordT< int > &aTopLeft);
+	void setTopLeft(const int &x, const int &y);
+	void setBottomRight(const CoordT< int > &aBottomRight);
+	void setBottomRight(const int &x, const int &y);
+	void setWidth(const int &aWidth);
+	void setHeight(const int &aHeight);
+	void setID(const int &anID);
+	
+	CoordT< int > topLeft() const;
+	CoordT< int > bottomRight() const;
+	int width();
+	int height();
+	int id() const;
+	
+	bool isValid() const;
+	void validate();
+	
+private:
+	CoordT< int > top_left_;
+	CoordT< int > bottom_right_;
+	int id_;
+};
+
+} //namespace
+
+#endif /* __BOUNDINGBOX_H__ */
+
+/*
+ * 
+ */

+ 314 - 0
cbaselib/CachedExample.cpp

@@ -0,0 +1,314 @@
+/** 
+* @file CachedExample.cpp
+* @brief data caching
+* @author Erik Rodner
+* @date 04/21/2008
+
+*/
+#include <iostream>
+
+#include "vislearning/cbaselib/CachedExample.h"
+#include "vislearning/baselib/Conversions.h"
+#include "vislearning/baselib/ProgressBar.h"
+
+#include "vislearning/image/GenericImageTools.h"
+#include "vislearning/baselib/Preprocess.h"
+#include "vislearning/baselib/ICETools.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+
+void CachedExample::init ()
+{
+    dchannels = new MultiChannelImageT<double> [D_NUMCHANNELS];
+    ichannels = new MultiChannelImageT<int> [I_NUMCHANNELS];
+    lchannels = new MultiChannelImageT<long> [L_NUMCHANNELS];
+
+    svmap = new SparseVector *[SVNUMCHANNELS];
+    svmap_xsize = new int [SVNUMCHANNELS];
+    svmap_ysize = new int [SVNUMCHANNELS];
+    for ( uint k = 0 ; k < SVNUMCHANNELS ; k++ )
+    {
+	svmap[k] = NULL;
+	svmap_xsize[k] = 0;
+	svmap_ysize[k] = 0;
+    }
+}
+
+CachedExample::CachedExample( const std::string & _imgfn,
+			      int _newWidth,
+			      int _newHeight )
+{
+    imgfn = _imgfn;
+    newWidth = _newWidth;
+    newHeight = _newHeight;
+    Preprocess::getImageSize ( _imgfn, oxsize, oysize );
+    init();
+    hasColorInformation = true;
+}
+
+CachedExample::CachedExample( const NICE::Image & _img )
+{
+    imgfn = "";
+    newWidth = -1;
+    newHeight = -1;
+    init();
+
+    oxsize = _img.width();
+    oysize = _img.height();
+    int *gray = new int [ oxsize*oysize ];
+    int k = 0;
+    for ( int y = 0 ; y < oysize ; y++ )
+	for ( int x = 0 ; x < oxsize ; x++,k++ )
+	    gray[k] = _img.getPixel(x,y);
+
+    ichannels[I_GRAYVALUES].reInit ( oxsize, oysize, 1, false );
+    ichannels[I_GRAYVALUES].setImage ( gray, oxsize, oysize, 0 );
+
+    hasColorInformation = false;
+}
+
+CachedExample::CachedExample( const NICE::ColorImage & img, bool disableGrayConversion )
+{
+    imgfn = "";
+    oxsize = img.width();
+    oysize = img.height();
+    newWidth = -1;
+    newHeight = -1;
+    init();
+
+    if ( ! disableGrayConversion )
+    {
+	// refactor-nice.pl: check this substitution
+	// old: Image imggray;
+	NICE::Image imggray;
+	ICETools::calcGrayImage ( img, imggray );
+
+	ichannels[I_GRAYVALUES].reInit ( oxsize, oysize, 1, true );
+	int *gray = ichannels[I_GRAYVALUES].data[0];
+	int k = 0;
+	for ( int y = 0 ; y < oysize ; y++ )
+	    for ( int x = 0 ; x < oxsize ; x++,k++ )
+		// refactor-nice.pl: check this substitution
+		// old: gray[k] = GetVal(imggray,x,y);
+		gray[k] = imggray.getPixel(x,y);
+    }
+
+    ichannels[I_COLOR].reInit ( oxsize, oysize, 3, true );
+
+    long int k = 0;
+    for ( int y = 0 ; y < oysize ; y++ )
+	for ( int x = 0 ; x < oxsize ; x++,k++ )
+	{
+	    // refactor-nice.pl: check this substitution
+	    // old: ichannels[I_COLOR].data[0][k] = GetVal(img.RedImage(), x, y);
+	    ichannels[I_COLOR].data[0][k] = img.getPixel(x,y,0);
+	    // refactor-nice.pl: check this substitution
+	    // old: ichannels[I_COLOR].data[1][k] = GetVal(img.GreenImage(), x, y);
+	    ichannels[I_COLOR].data[1][k] = img.getPixel(x,y,1);
+	    // refactor-nice.pl: check this substitution
+	    // old: ichannels[I_COLOR].data[2][k] = GetVal(img.BlueImage(), x, y);
+	    ichannels[I_COLOR].data[2][k] = img.getPixel(x,y,2);
+	}
+
+    hasColorInformation = true;
+}
+	
+CachedExample::~CachedExample()
+{
+    delete [] dchannels;
+    delete [] ichannels;
+    delete [] lchannels;
+
+    for ( uint k = 0 ; k < SVNUMCHANNELS ; k++ )
+	if ( svmap[k] != NULL )
+	    delete [] (svmap[k]);
+
+    delete [] svmap;
+    delete [] svmap_xsize;
+    delete [] svmap_ysize;
+
+    // remove all temporary files
+    for ( map<int, string>::const_iterator j = dtemps.begin();
+					   j != dtemps.end();
+					   j++ )
+    {
+	//fprintf (stderr, "CachedExample: removing temp file %s\n", j->second.c_str() );
+	FileMgt::deleteTempFile ( j->second );
+    }
+    
+    for ( map<int, string>::const_iterator j = itemps.begin();
+					   j != itemps.end();
+					   j++ )
+    {
+	//fprintf (stderr, "CachedExample: removing temp file %s\n", j->second.c_str() );
+	FileMgt::deleteTempFile ( j->second );
+    }
+
+    for ( map<int, string>::const_iterator j = ltemps.begin();
+					   j != ltemps.end();
+					   j++ )
+    {
+	//fprintf (stderr, "CachedExample: removing temp file %s\n", j->second.c_str() );
+	FileMgt::deleteTempFile ( j->second );
+    }
+
+}
+
+void CachedExample::readImageData ()
+{
+    if ( imgfn == "" ) return;
+
+    NICE::Image orig = Preprocess::ReadImgAdv(imgfn);
+    NICE::Image imggray;
+
+    if ( newWidth > 0 )
+	Conversions::resizeImage ( orig, imggray, newWidth, newHeight );
+    else
+	imggray = orig;
+
+    oxsize = imggray.width();
+    oysize = imggray.height();
+
+    ichannels[I_GRAYVALUES].reInit ( oxsize, oysize, 1, true );
+    int *gray = ichannels[I_GRAYVALUES].data[0];
+    int k = 0;
+    for ( int y = 0 ; y < oysize ; y++ )
+	for ( int x = 0 ; x < oxsize ; x++,k++ )
+	    gray[k] = imggray.getPixel(x,y);
+}
+
+void CachedExample::readImageDataRGB ()
+{
+    if ( imgfn == "" ) return;
+
+    NICE::ColorImage img;
+    try {
+	img = Preprocess::ReadImgAdvRGB(imgfn);
+    } catch ( NICE::ImageException & ) {
+	fprintf (stderr, "error reading rgb image %s\n", imgfn.c_str());
+	hasColorInformation = false;
+	return;
+    }
+
+    oxsize = img.width();
+    oysize = img.height();
+
+    hasColorInformation = true;
+    
+    ichannels[I_COLOR].reInit ( oxsize, oysize, 3, true );
+
+    long k = 0;
+    for ( int y = 0 ; y < oysize ; y++ )
+	for ( int x = 0 ; x < oxsize ; x++,k++ )
+	{
+	    ichannels[I_COLOR].data[0][k] = img.getPixel(x,y,0);
+	    ichannels[I_COLOR].data[1][k] = img.getPixel(x,y,1);
+	    ichannels[I_COLOR].data[2][k] = img.getPixel(x,y,2);
+	}
+}
+
+void CachedExample::calcIntegralImage ()
+{
+    if (ichannels[I_GRAYVALUES].xsize == 0)
+    {
+	readImageData ();
+	if ( ichannels[I_GRAYVALUES].xsize == 0 )
+	{
+	    fprintf (stderr, "CachedExample::getChannel: unable to recover data channel\n");
+	    exit(-1);
+	}
+    }
+
+    lchannels[L_INTEGRALIMAGE].reInit ( ichannels[I_GRAYVALUES].xsize,
+					ichannels[I_GRAYVALUES].ysize,
+					1, true );
+    
+		GenericImageTools::calcIntegralImage ( 
+		lchannels[L_INTEGRALIMAGE].data[0], 
+		ichannels[I_GRAYVALUES].data[0], 
+		ichannels[I_GRAYVALUES].xsize, 
+		ichannels[I_GRAYVALUES].ysize );
+
+}
+
+void CachedExample::buildIntegralSV ( int svchannel, 
+				      SparseVector *_map, 
+				      int xsize_s, int ysize_s )
+{
+    SparseVector *map = _map;
+    svmap[svchannel] = _map;
+    svmap_xsize[svchannel] = xsize_s;
+    svmap_ysize[svchannel] = ysize_s;
+
+    int k = xsize_s;
+    for ( int y = 1 ; y < ysize_s; y++, k+=xsize_s )
+	map[k].add ( (map[k-xsize_s]) );
+
+    k = 1;
+    for ( int x = 1 ; x < xsize_s; x++, k++ )
+	map[k].add ( (map[k-1]) );
+
+    k = xsize_s + 1;
+
+    for ( int y = 1 ; y < ysize_s ; y++,k++ )
+    {
+	for ( int x = 1 ; x < xsize_s ; x++,k++ )
+	{
+	    map[k].add ( (map[k-1]) );
+	    map[k].add ( (map[k-xsize_s]) );
+	    map[k].add ( (map[k-xsize_s-1]), -1.0 );
+	}
+    }
+}
+
+void CachedExample::setSVMap ( int svchannel, 
+			      SparseVector *_map, 
+			      int xsize_s, int ysize_s )
+{
+    svmap[svchannel] = _map;
+    svmap_xsize[svchannel] = xsize_s;
+    svmap_ysize[svchannel] = ysize_s;
+}
+
+SparseVector *CachedExample::getSVMap ( int svchannel,
+				        int & _xsize, int & _ysize,
+				        int & _tm_xsize, int & _tm_ysize ) const
+{
+    _xsize = oxsize;
+    _ysize = oysize;
+    _tm_xsize = svmap_xsize[svchannel];
+    _tm_ysize = svmap_ysize[svchannel];
+    assert ( svmap[svchannel] != NULL );
+    return svmap[svchannel];
+}
+
+bool CachedExample::colorInformationAvailable() const
+{
+    if ( hasColorInformation ) return true;
+    else {
+	if ( imgfn.size() == 0 ) return false;
+
+	int tmp_xsize, tmp_ysize, tmp_maxval, tmp_nr;
+	// refactor: InfImgFile ( imgfn, tmp_xsize, tmp_ysize, tmp_maxval, tmp_nr );
+	ImageFile imgf ( imgfn );
+	const ImageFile::Header & imgfheader = imgf.getHeader();
+	tmp_xsize = imgfheader.width;
+	tmp_ysize = imgfheader.height;
+	tmp_maxval = 255;
+	tmp_nr = imgfheader.channel;
+
+	if ( tmp_nr > 1 ) return true;
+	else return false;
+    }
+}
+
+void CachedExample::dropPreCached()
+{
+    dropImages<double> ( dchannels, dtemps, D_NUMCHANNELS );
+    dropImages<int> ( ichannels, itemps, I_NUMCHANNELS );
+    dropImages<long> ( lchannels, ltemps, L_NUMCHANNELS );
+}

+ 309 - 0
cbaselib/CachedExample.h

@@ -0,0 +1,309 @@
+/** 
+* @file CachedExample.h
+* @brief data caching of several feature images and many more
+* @author Erik Rodner
+* @date 04/21/2008
+
+*/
+#ifndef CACHEDEXAMPLEINCLUDE
+#define CACHEDEXAMPLEINCLUDE
+
+#include <assert.h>
+#include <map>
+
+#include "core/vector/SparseVector.h"
+#include "core/image/MultiChannelImageT.h"
+#include "core/basics/FileMgt.h"
+
+using namespace NICE;
+
+namespace OBJREC {
+
+/** data caching of several feature images and many more,
+    can be used in conjunction with Example 
+    to share image data between different sliding windows within
+    an image
+    @see Example */
+class CachedExample
+{
+
+    protected:
+	/** resize image to this fixed width */
+	int newWidth;
+	/** resize image to this fixed height */
+	int newHeight;
+
+	/** original image width */
+	int oxsize;
+	/** original image height */
+	int oysize;
+
+	/** filename of image */
+	std::string imgfn;
+
+	/** array of double images */
+	MultiChannelImageT<double> *dchannels;
+
+	/** array of integer images */
+	MultiChannelImageT<int> *ichannels;
+
+	/** array of histogram images */
+	MultiChannelImageT<long> *lchannels;
+
+	/** maps for temporary files */
+	std::map<int, std::string> dtemps;
+	std::map<int, std::string> itemps;
+	std::map<int, std::string> ltemps;
+
+	/** read standard image data from file */
+	void readImageData ();
+	
+	/** read rgb image data from file */
+	void readImageDataRGB ();
+
+	/** calc grayvalue integral image */
+	void calcIntegralImage ();
+
+	/** array of histogram images */
+	SparseVector **svmap;
+	
+	/** sizes of histogram images */
+	int *svmap_xsize;
+	int *svmap_ysize;
+
+	bool hasColorInformation;
+
+    public:
+
+	/** whether one can obtain color information */
+	bool colorInformationAvailable() const;
+
+  	enum {
+	    L_INTEGRALIMAGE = 0,
+	    L_NUMCHANNELS
+	};
+
+	/** integer channel types */
+	enum {
+	    I_GRAYVALUES = 0,
+	    I_COLOR,
+	    I_EDGES,
+	    I_NUMCHANNELS
+	};
+
+	/** double value channels */
+	enum {
+	    D_EOH = 0,
+	    D_INTEGRALPRIOR,
+	    D_INTEGRALEOH,
+	    D_INTEGRALCOLOR,
+	    D_NUMCHANNELS
+	};
+
+	
+	/** sparse histogram channel types */
+	enum {
+	    SVTEXTON = 0,
+	    SVNUMCHANNELS
+	};
+
+	/** default init method */
+	void init ();
+
+	/** simple constructor 
+	    @param imgfn image filename
+	    @param newWidth resize raw image to this width
+	    @param newHeight resize raw image to this height
+	*/
+	CachedExample( const std::string & imgfn, int newWidth = -1, 
+					     int newHeight = -1 );
+	
+	/** constructor (disabled buffering)
+	    @param img gray-value image
+	*/
+	CachedExample( const NICE::Image & img );
+      
+	/** constructor (disabled buffering)
+	    @param img rgb image
+	    @param disableGrayConversion whether to provide gray values or not
+	*/
+	CachedExample( const NICE::ColorImage & img, bool disableGrayConversion = false );
+
+	/** simple destructor */
+	virtual ~CachedExample();
+
+	/**
+	 * get the NICE::Image Filename
+	 * @return NICE::Image Filename
+	 */
+	inline std::string getFilename();
+	
+	
+	/** get double image channel 
+	    @param channel channel type (choose from enum type)
+	    @param[out] xsize width of image
+	    @param[out] ysize height of image
+	    @return buffer to image data
+	*/
+	inline MultiChannelImageT<double> & getDChannel ( int channel ); 
+
+	/** get integer image channel 
+	    @param channel channel type (choose from enum type)
+	    @param[out] xsize width of image
+	    @param[out] ysize height of image
+	    @return buffer to image data
+	*/
+	inline MultiChannelImageT<int> & getIChannel ( int channel ); 
+
+	/** get long image channel 
+	    @param channel channel type (choose from enum type)
+	    @param[out] xsize width of image
+	    @param[out] ysize height of image
+	    @return buffer to image data
+	*/
+	inline MultiChannelImageT<long> & getLChannel ( int channel ); 
+
+	/** get histogram image
+	    @param svchannel channel type (choose from histogram channel enum)
+	    @param[out] xsize width of raw image
+	    @param[out] ysize height of raw image
+	    @param[out] tm_xsize width of histogram channel buffer
+	    @param[out] tm_ysize height of histogram channel buffer
+	    @remark buffer will be not copied !!
+	    @return pointer to histogram channel buffer
+	*/
+	SparseVector *getSVMap ( int svchannel, int & xsize, int & ysize, int & tm_xsize, int & tm_ysize ) const;
+
+	/** assign histogram channel buffer and compute integral image
+	    @param svchannel 
+	    @param _map pointer to histogram channel buffer
+	    @param xsize_s width of histogram channel buffer
+	    @param ysize_s height of histogram channel buffer
+	    @remark buffer will be not copied !!
+	*/
+	void buildIntegralSV ( int svchannel, SparseVector *_map, int xsize_s, int ysize_s );
+	
+    	/** assign histogram channel buffer
+	    @param svchannel 
+	    @param _map pointer to histogram channel buffer
+	    @param xsize_s width of histogram channel buffer
+	    @param ysize_s height of histogram channel buffer
+	    @remark buffer will be not copied !!
+	*/
+	void setSVMap ( int svchannel, SparseVector *_map, int xsize_s, int ysize_s );
+
+	/** get image sizes */
+	void getImageSize ( int & xsize, int & ysize ) const { xsize = oxsize; ysize = oysize; };
+
+	/** drop precached data: 
+		(1) this is only possible if an image filename is given 
+		(2) only data channels are deleted that can be reproduced by CachedExample itself
+	*/
+	void dropPreCached();
+
+	template<class ImgPixelValue>
+	void dropImages ( MultiChannelImageT<ImgPixelValue> *images, 
+			  std::map<int, std::string> & temps, 
+			  int numImages ); 
+};
+
+
+/********************** INLINE FUNCTIONS *****************************/
+inline MultiChannelImageT<double> & CachedExample::getDChannel ( int channel )
+{
+    assert ( (channel >= 0) && (channel < D_NUMCHANNELS) ); 
+
+    if ( dchannels[channel].data == NULL ) {
+	std::map<int, std::string>::const_iterator j = dtemps.find(channel);
+	if ( j == dtemps.end() ) {
+	    //fprintf (stderr, "MultiChannelImageT: unable to recover data channel %s (double %d)!\n", 
+	    //	imgfn.c_str(), channel);
+	} else {
+	    //fprintf (stderr, "MultiChannelImageT: restoring data from %s ", j->second.c_str() );
+	    dchannels[channel].restore ( j->second );
+	    //fprintf (stderr, "(%d x %d)\n", dchannels[channel].xsize, dchannels[channel].ysize );
+	}
+    }
+
+    return dchannels[channel];
+}
+
+inline std::string CachedExample::getFilename()
+{
+	return imgfn;
+}
+
+inline MultiChannelImageT<int> & CachedExample::getIChannel ( int channel )
+{
+    assert ( (channel >= 0) && (channel < I_NUMCHANNELS) ); 
+
+    if ( (ichannels[channel].data == NULL) )
+    {
+	if ( (imgfn != "") && (channel == I_GRAYVALUES) ) 
+	{
+	    readImageData();
+	} else if ( (imgfn != "") && (channel == I_COLOR) ) {
+	    readImageDataRGB();
+	    assert ( hasColorInformation );
+	} else {
+	    std::map<int, std::string>::const_iterator j = itemps.find(channel);
+	    if ( j == itemps.end() ) {
+		//fprintf (stderr, "MultiChannelImageT: unable to recover data channel (int %d)!\n", channel);
+		//exit(-1);
+	    } else {
+		//fprintf (stderr, "MultiChannelImageT: restoring data from %s\n", j->second.c_str() );
+		ichannels[channel].restore ( j->second );
+	    }
+	}
+    }
+
+    return ichannels[channel];
+}
+
+inline MultiChannelImageT<long> & CachedExample::getLChannel ( int channel )
+{
+    assert ( (channel >= 0) && (channel < L_NUMCHANNELS) ); 
+
+    if ( lchannels[channel].data == NULL ) {
+	std::map<int, std::string>::const_iterator j = ltemps.find(channel);
+	if ( j == ltemps.end() ) {
+
+	    if ( channel == L_INTEGRALIMAGE ) {
+		calcIntegralImage();
+	    } else {
+		//fprintf (stderr, "MultiChannelImageT: unable to recover data channel (long %d)!\n", channel);
+		//exit(-1);
+	    }
+	} else {
+	    //fprintf (stderr, "MultiChannelImageT: restoring data from %s\n", j->second.c_str() );
+	    lchannels[channel].restore ( j->second );
+	}
+    }
+
+    return lchannels[channel];
+}
+
+template<class ImgPixelValue>
+void CachedExample::dropImages ( MultiChannelImageT<ImgPixelValue> *images, std::map<int, std::string> & temps, int numImages )
+{
+    for ( int i = 0 ; i < numImages; i++ )
+    {
+	std::map<int, std::string>::iterator j = temps.find(i);
+	if ( j == temps.end() )
+	{
+	    std::string tempfilename = FileMgt::createTempFile("tmp/cachedexample_%s");
+	    //fprintf (stderr, "CachedExample: dumping channel %d/%d to %s (%d x %d)\n", i, numImages, tempfilename.c_str(),
+	    //	images[i].xsize, images[i].ysize );
+	    images[i].store ( tempfilename );
+	    temps[i] = tempfilename;
+	}
+	images[i].freeData();
+    }
+
+}
+
+
+
+} // namespace
+
+#endif

+ 120 - 0
cbaselib/CategoryInfo.cpp

@@ -0,0 +1,120 @@
+/*!
+ * \file CategoryInfo.cpp
+ * \brief
+ * \author Gapchich Vladislav
+ * \date 23/10/11
+ */
+
+#include "vislearning/cbaselib/CategoryInfo.h"
+
+using namespace OBJREC;
+using namespace std;
+
+//! A constructor
+CategoryInfo::CategoryInfo()
+{
+	category_name_.clear();
+	id_ = -1;
+	color_ = 0;
+	is_main_ = 0;
+}
+
+//! A copy-constructur
+CategoryInfo::CategoryInfo(const CategoryInfo &copy)
+{
+	category_name_ = copy.categoryName();
+	color_ = copy.color();
+	id_ = copy.id();
+	is_main_ = copy.isMain();
+}
+
+//! A desctructor
+CategoryInfo::~CategoryInfo()
+{
+	
+}
+
+//! Sets category name(label)
+/*!
+ * \param[in] aCategoryName should not be empty otherwise member does nothing. 
+ */
+void 
+CategoryInfo::setCategoryName(const std::string &aCategoryName)
+{
+	if (aCategoryName.empty()) {
+		return;
+		/* NOTREACHED */
+	}
+	
+	category_name_ = aCategoryName;
+}
+
+//! Sets category ID(label ID)
+/*!
+ * \param[in] anID should not be negative otherwise id_ becomes -1
+ */
+void 
+CategoryInfo::setID(const int &anID)
+{
+	if (anID < 0) {
+		id_ = -1;
+		return;
+		/* NOTREACHED */
+	}
+	
+	id_ = anID;
+}
+
+//! Sets the color of a category
+/*!
+ * \param[in] aColor is unsigned in which can be translated into ARGB
+ * like 0xAARRBBGG
+ */
+void 
+CategoryInfo::setColor(const unsigned int &aColor)
+{
+	color_ = aColor;
+}
+
+//! Sets category priority
+/*!
+ * \param[in] aMain is a flag indicating whether current label is main or not
+ */
+void 
+CategoryInfo::setMain(bool aMain)
+{
+	is_main_ = aMain;
+}
+
+//! returns category name(label name)
+std::string
+CategoryInfo::categoryName() const
+{
+	return category_name_;
+}
+
+//!  returns category ID(label ID)
+int 
+CategoryInfo::id() const
+{
+	return id_;
+}
+
+//! \brief returns unsigned int indicating category color which can 
+//! be translated into ARGB like 0xAARRBBGG
+unsigned int 
+CategoryInfo::color() const
+{
+	return color_;
+}
+
+//! returns is_main_ flag
+bool 
+CategoryInfo::isMain() const
+{
+	return is_main_;
+}
+
+/*
+ * 
+ */

+ 48 - 0
cbaselib/CategoryInfo.h

@@ -0,0 +1,48 @@
+/*!
+ * \file CategoryInfo.h
+ * \brief
+ * \author Gapchich Vladislav
+ * \date 23/10/11
+ */
+
+#ifndef __CATEGORYINFO_H__
+#define __CATEGORYINFO_H__
+
+#include <iostream>
+#include <string>
+
+namespace OBJREC {
+
+//! \brief Contains category name, it's color, id, flag
+//!  indicating if it's main or not and methods for working with them
+class CategoryInfo
+{
+public:
+	CategoryInfo();
+	CategoryInfo(const CategoryInfo &copy);
+	~CategoryInfo();
+	
+	std::string categoryName() const;
+	int id() const;
+	unsigned int color() const;
+	bool isMain() const;
+
+	void setCategoryName(const std::string &aCategoryName);
+	void setID(const int &anID);
+	void setColor(const unsigned int &aColor);
+	void setMain(bool aMain = true);
+	
+private:
+	std::string category_name_;
+	int id_;
+	unsigned int color_;
+	bool is_main_;
+};
+
+} //namespace
+
+#endif /* __CATEGORYINFO_H__ */
+
+/*
+ * 
+ */

+ 478 - 0
cbaselib/ClassNames.cpp

@@ -0,0 +1,478 @@
+/** 
+* @file ClassNames.cpp
+* @brief simple interface for class name confusion
+* @author Erik Rodner
+* @date 02/08/2008
+
+*/
+#include <vislearning/nice_nonvis.h>
+
+#include <iostream>
+#include <algorithm>
+#include <string>
+#include <functional>
+#include <assert.h>
+
+#include "vislearning/cbaselib/ClassNames.h"
+#include "core/basics/StringTools.h"
+#include "vislearning/baselib/ICETools.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+
+ClassNames::ClassNames()
+{
+	maxClassNo = 0;
+}
+
+ClassNames::ClassNames ( const ClassNames & cn, 
+			 const std::string & classselection )
+{
+	std::set<int> selection;
+	cn.getSelection ( classselection, selection );
+	maxClassNo = 0;
+
+	store ( cerr );
+
+	for ( map<string, string>::const_iterator i  = cn.tbl_code_text.begin();
+						  i != cn.tbl_code_text.end();
+						  i++ )
+	{
+		const std::string & classname = i->second;
+		std::string code = i->first;
+
+		if ( cn.tbl_code_classno.find(code) == cn.tbl_code_classno.end() )
+		{
+			fprintf (stderr, "class %s excluded in base classnames\n", code.c_str() );
+			continue;
+		}
+
+		int classno = cn.classno(code);
+		if ( selection.find(classno) != selection.end() )
+		{
+			addClass( classno, code, classname );
+			if ( classno > maxClassNo ) maxClassNo = classno;
+#ifdef DEBUG_ClassNames
+			fprintf (stderr, "class %s (%d) inherited\n", code.c_str(), classno );
+#endif
+		} else {
+#ifdef DEBUG_ClassNames
+			fprintf (stderr, "class %s (%d) excluded in selection\n", code.c_str(), classno );
+#endif
+		}
+	}
+}
+
+ClassNames::ClassNames ( const ClassNames & cn )
+	: tbl_code_text(cn.tbl_code_text), tbl_text_code(cn.tbl_text_code),
+	  tbl_classno_code(cn.tbl_classno_code), tbl_code_classno(cn.tbl_code_classno),
+	  tbl_color_classno(tbl_color_classno), tbl_classno_color(cn.tbl_classno_color), maxClassNo(cn.maxClassNo)
+{
+}
+
+ClassNames::~ClassNames()
+{
+}
+	
+
+int ClassNames::classnoFromText ( std::string text ) const
+{
+	map<string, string>::const_iterator j = tbl_text_code.find(text);
+	if ( j == tbl_text_code.end() ) return -1;
+
+	map<string, int>::const_iterator jj = tbl_code_classno.find(j->second);
+	if ( jj == tbl_code_classno.end() ) return -1;
+
+	return jj->second;
+}
+
+void ClassNames::getSelection ( const std::string & classselection,
+				std::set<int> & classnos ) const
+{
+	if ( classselection.size() <= 0 ) return;
+
+	std::vector<string> classlist;
+	StringTools::split ( classselection, ',', classlist );
+
+	if ( classlist.size() <= 0 )
+	{
+	fprintf (stderr, "FATAL ERROR: wrong format for classselection\n");
+	exit(-1);
+	} else if ( classlist[0] == "*" )
+	{
+	map<string, bool> forbidden_classes;
+	for ( size_t k = 1 ; k < classlist.size() ; k++ )
+		if ( classlist[k].substr(0,1) == "-" )
+		{
+			std::string f_class = classlist[k].substr(1);
+#if defined DEBUG_ClassNames
+			fprintf (stderr, "ClassNames: class %s excluded !\n", f_class.c_str() );
+#endif
+			forbidden_classes[ f_class ] = true;
+		} else {
+			fprintf (stderr, "FATAL ERROR: wrong format for classselection: *,-class0,class1,...\n");
+			exit(-1);
+		}
+   
+	for ( map<int, string>::const_iterator i  = tbl_classno_code.begin();
+						  i != tbl_classno_code.end();
+						  i++ )
+	{
+		int myclassno = i->first;
+		const std::string & classname = text(myclassno);
+		if ( forbidden_classes.find(classname) != forbidden_classes.end() )
+		continue;
+		
+		classnos.insert ( myclassno );
+	}
+	} else {
+		for ( vector<string>::const_iterator i  = classlist.begin();
+							i != classlist.end();
+							i++ )
+		{
+			const std::string & classname = *i;
+			map<string, string>::const_iterator j = tbl_text_code.find(classname);
+	
+			if ( j == tbl_text_code.end() )
+			{
+				fprintf (stderr, "ClassNames: FATAL ERROR This is not a selection of a subset: %s [%s]\n",
+					classname.c_str(), classselection.c_str());
+				exit(-1);
+			}
+	
+			const std::string & code = j->second;
+			int myclassno = classno (code);
+	
+			if ( myclassno < 0 ) {
+				fprintf (stderr, "ClassNames: FATAL ERROR This is not a selection of a subset\n");
+				exit(-1);
+			}
+			classnos.insert ( myclassno );
+		}
+	}
+
+}
+
+std::string ClassNames::text ( int classno ) const
+{  
+	map<string, string>::const_iterator i = 
+		tbl_code_text.find ( code(classno) );
+
+	if ( i == tbl_code_text.end() )
+	{
+		fprintf (stderr, "ClassNames: no name found for classno %d\n", classno );
+		return "unknown";
+	} else {
+		return i->second;
+	}
+
+}
+
+std::string ClassNames::code ( int classno ) const
+{
+	map<int, string>::const_iterator i = 
+		tbl_classno_code.find ( classno );
+
+	if ( i == tbl_classno_code.end() )
+	{
+		fprintf (stderr, "ClassNames: no code found for classno %d\n", classno );
+		return "unknown";
+	} else {
+		return i->second;
+	}
+
+}
+
+int ClassNames::classno ( std::string code ) const
+{
+	map<string, int>::const_iterator i = 
+		tbl_code_classno.find ( code );
+
+	if ( i == tbl_code_classno.end() )
+	{
+		fthrow(Exception, "no classno found for code <" << code << ">" );
+	} else {
+		return i->second;
+	}
+}
+
+int ClassNames::numClasses () const
+{
+	return tbl_classno_code.size();
+}
+
+
+void ClassNames::addClass ( int classno, const std::string & code, 
+	const std::string & text )
+{
+	tbl_classno_code[classno] = code;
+	tbl_text_code[text]	   = code;
+	tbl_code_text[code]	   = text;
+	tbl_code_classno[code]	= classno;
+
+	if ( classno > maxClassNo ) maxClassNo = classno;
+}
+	
+bool ClassNames::existsClassno ( int classno ) const
+{
+	return (tbl_classno_code.find(classno) != tbl_classno_code.end());
+}
+
+// refactor-nice.pl: check this substitution
+// old: bool ClassNames::existsClassCode ( const string & classcode ) const
+bool ClassNames::existsClassCode ( const std::string & classcode ) const
+{
+	return (tbl_code_classno.find(classcode) != tbl_code_classno.end());
+}
+
+bool ClassNames::readFromConfig ( const Config & datasetconf, 
+			// refactor-nice.pl: check this substitution
+			// old: const string & classselection )
+			const std::string & classselection )
+{
+
+	datasetconf.getAllS ( "classnames", tbl_code_text );
+
+	if ( tbl_code_text.size() <= 0 ) {
+		fprintf (stderr, "ClassNames: no classnames specified\n");
+		return false;
+	}
+
+	// reverse map and lower case
+	for ( map<string, string>::const_iterator i  = tbl_code_text.begin();
+									   i != tbl_code_text.end(); i++ )
+		tbl_text_code [ i->second ] = i->first;	
+
+#if defined DEBUG_ClassNames
+	cerr << "ClassNames::read: selection = " << classselection << endl;
+#endif
+
+	std::vector<string> classlist;
+	StringTools::split ( classselection, ',', classlist );
+
+	if ( classlist.size() <= 0 )
+	{
+	fprintf (stderr, "FATAL ERROR: wrong format for classselection\n");
+	exit(-1);
+	} else if ( classlist[0] == "*" )
+	{
+	map<string, bool> forbidden_classes;
+	for ( size_t k = 1 ; k < classlist.size() ; k++ )
+		if ( classlist[k].substr(0,1) == "-" )
+		{
+		// refactor-nice.pl: check this substitution
+		// old: string f_class = classlist[k].substr(1);
+		std::string f_class = classlist[k].substr(1);
+#if defined DEBUG_ClassNames
+		fprintf (stderr, "ClassNames: class %s excluded !\n", f_class.c_str() );
+#endif
+		forbidden_classes[ f_class ] = true;
+		} else {
+		fprintf (stderr, "FATAL ERROR: wrong format for classselection: *,-class0,class1,...\n");
+		exit(-1);
+		}
+
+	int classno_seq = 0;
+	for ( map<string, string>::const_iterator i  = tbl_code_text.begin();
+						  i != tbl_code_text.end();
+						  i++,classno_seq++ )
+	{
+		const std::string & classname = i->second;
+		if ( forbidden_classes.find(classname) != forbidden_classes.end() )
+			continue;
+
+		// refactor-nice.pl: check this substitution
+		// old: string code = tbl_text_code [ i->second ];
+		std::string code = tbl_text_code [ i->second ];
+		int classno;
+		classno = classno_seq;
+		tbl_classno_code[classno] = code;
+		tbl_code_classno[code] = classno;
+		if ( classno > maxClassNo ) maxClassNo = classno;
+
+#if defined DEBUG_ClassNames
+		fprintf (stderr, "classno %d class code %s class text %s\n", classno, code.c_str(), classname.c_str() );
+#endif
+	}
+	} else {
+
+#if defined DEBUG_ClassNames
+	cerr << "list : " << classlist.size() << endl;
+#endif
+	for ( size_t classno_seq = 0 ; classno_seq < classlist.size() ; classno_seq++ )
+	{
+		std::string classname = classlist[classno_seq];
+
+		if ( tbl_text_code.find ( classname ) != tbl_text_code.end() )
+		{
+			std::string code = tbl_text_code [ classname ];
+			int classno;
+			classno = classno_seq;
+			tbl_classno_code[classno] = code;
+			tbl_code_classno[code] = classno;
+			if ( classno > maxClassNo ) maxClassNo = classno;
+
+#if defined DEBUG_ClassNames
+			fprintf (stderr, "classno %d class code %s class text %s\n", (int)classno, code.c_str(), classname.c_str() );
+#endif
+		} else {
+			fprintf (stderr, "ClassNames::ClassNames: FATAL ERROR class >%s< not found in data set\n", classname.c_str() );
+			exit(-1);
+		}
+	}
+	}
+
+	/****** after all, try to read color coding *******/
+	map<string, string> list;
+	datasetconf.getAllS ( "colors", list );
+
+	if ( list.size() > 0 ) {
+		for ( map<string,string>::const_iterator i = list.begin();
+			i != list.end();
+			i++ )
+		{
+			std::string value = i->second;
+			std::string classname = i->first;
+			int _classno = classno(classname);
+			vector<string> submatches;
+			if ( StringTools::regexMatch ( value, "^ *([[:digit:]]+) *: *([[:digit:]]+) *: *([[:digit:]]+) *$", submatches ) 
+				&& ( submatches.size() == 4 ) )
+			{
+				int r = StringTools::convert<int> ( submatches[1] );
+				int g = StringTools::convert<int> ( submatches[2] );
+				int b = StringTools::convert<int> ( submatches[3] );
+				long index = 256*(256*r + g) + b;
+				tbl_color_classno[index] = _classno;
+				tbl_classno_color[_classno] = index;
+			} else {
+				fprintf (stderr, "LabeledFileList: parse error colors >%s<\n", value.c_str() );
+				exit(-1);
+			}
+		}
+	}
+
+	return true;
+}
+	
+int ClassNames::getMaxClassno () const
+{
+	return maxClassNo;
+}
+	
+void ClassNames::getRGBColor ( int classno, int & r, int & g, int & b ) const
+{
+	map<int, long>::const_iterator i = tbl_classno_color.find(classno);
+
+	if ( i == tbl_classno_color.end() )
+	{
+		fprintf (stderr, "ClassNames: no color setting found for class %d\n", classno );
+		getchar();
+		double x = classno / (double)numClasses();
+		double rd, gd, bd;
+		ICETools::toColor ( x, rd, gd, bd );
+		r = (int)(255*rd);
+		g = (int)(255*gd);
+		b = (int)(255*bd);
+	} else {
+		long color = i->second;
+		b = color % 256;
+		color /= 256;
+		g = color % 256;
+		color /= 256;
+		r = color % 256;
+	}
+}
+
+void ClassNames::getClassnoFromColor ( int & classno, int r, int g, int b ) const
+{
+	long color = 256*(256*r+g) + b;
+	map<long, int>::const_iterator i = tbl_color_classno.find(color);
+
+	if ( i == tbl_color_classno.end() )
+	{
+		classno = -1;
+	} else {
+		classno = i->second;
+	}
+}
+
+void ClassNames::labelToRGB ( const NICE::Image & img, NICE::ColorImage & rgb ) const
+{
+	int red, green, blue;
+
+	rgb.resize(img.width(), img.height());
+
+	for ( int y = 0 ; y < img.height(); y++ )
+	for ( int x = 0 ; x < img.width(); x++ )
+	{
+		int label = img.getPixel(x,y);
+		getRGBColor ( label, red, green, blue );
+		rgb.setPixel(x,y,0,red);
+		rgb.setPixel(x,y,1,green);
+		rgb.setPixel(x,y,2,blue);
+	}
+
+}
+
+int ClassNames::getBackgroundClass () const
+{
+	if ( existsClassCode ("various" ) )
+		return classno("various");
+	else if ( existsClassCode ("background" ) )
+		return classno("background");
+	else if ( existsClassCode ("clutter" ) )
+		return classno("clutter");
+	else
+		return 0;
+}
+
+void ClassNames::restore (istream & is, int format)
+{
+	maxClassNo = -1;
+	while ( ! is.eof() )
+	{
+		std::string mytext;
+		std::string mycode;
+		int myclassno;
+
+		if ( !(is >> mytext) ) break;
+		if ( !(is >> mycode) ) break;
+		if ( !(is >> myclassno) ) break;
+
+		tbl_code_text.insert ( pair<string, string> ( mycode, mytext ) );
+		tbl_text_code.insert ( pair<string, string> ( mytext, mycode ) );
+		tbl_classno_code.insert ( pair<int, string> ( myclassno, mycode ) );
+		tbl_code_classno.insert ( pair<string, int> ( mycode, myclassno ) );
+
+		if ( myclassno > maxClassNo ) maxClassNo = myclassno;
+	}
+}
+
+void ClassNames::store (ostream & os, int format) const
+{
+	assert ( tbl_classno_code.size() == tbl_code_classno.size() );
+	for ( map<int, string>::const_iterator i  = tbl_classno_code.begin() ;
+						  i != tbl_classno_code.end();
+						  i++ )
+	{
+		int myclassno = i->first;
+		std::string mycode = i->second;
+		std::string mytext = text(myclassno);
+
+		os << mytext << "\t" << mycode << "\t" << myclassno << endl;
+	}	
+}
+
+void ClassNames::clear ()
+{
+	tbl_code_text.clear();
+	tbl_text_code.clear();
+	tbl_classno_code.clear();
+	tbl_code_classno.clear();
+	tbl_color_classno.clear();
+	tbl_classno_color.clear();
+}
+

+ 110 - 0
cbaselib/ClassNames.h

@@ -0,0 +1,110 @@
+/** 
+* @file ClassNames.h
+* @brief simple interface for class name confusion
+* @author Erik Rodner
+* @date 02/08/2008
+
+*/
+#ifndef CLASSNAMESINCLUDE
+#define CLASSNAMESINCLUDE
+
+#include <vislearning/nice_nonvis.h>
+ 
+#include <string>
+#include <map>
+
+#include "core/basics/Config.h"
+#include "core/basics/Persistent.h"
+
+
+namespace OBJREC {
+
+/** simple interface for class name confusion */
+class ClassNames : public NICE::Persistent
+{
+
+    protected:
+
+		std::map<std::string, std::string> tbl_code_text;
+		std::map<std::string, std::string> tbl_text_code;
+		std::map<int, std::string> tbl_classno_code;
+		std::map<std::string, int> tbl_code_classno;
+		std::map<long, int> tbl_color_classno;
+		std::map<int, long> tbl_classno_color;
+
+		int maxClassNo;
+
+    public:
+  
+	/** simple constructor */
+	ClassNames();
+    
+	/** copy constructor */
+	ClassNames ( const ClassNames & cn );
+  
+	/** create sub selection */
+	ClassNames ( const ClassNames & cn, 
+		     const std::string & classselection );
+
+	/** simple destructor */
+	virtual ~ClassNames();
+    
+	/** get the readable class number of a class number */
+	std::string text ( int classno ) const;
+
+	/** get the class code (e.g. ascii code) of a class number */
+	std::string code ( int classno ) const;
+
+	/** get the class number corresponding to the code */
+	int classno ( std::string code ) const;
+	
+	/** get the class number corresponding to the name */
+	int classnoFromText ( std::string text ) const;
+
+	/** number of classes */
+	int numClasses () const;
+	void getSelection ( const std::string & classselection,
+			    std::set<int> & classnos ) const;
+
+	/** add new class information 
+	 * @param classno class number
+	 * @param code class code (such as ascii number or just the name)
+	 * @param text class name as readable ascii representation
+	 */
+	void addClass ( int classno, const std::string & code, 
+	    const std::string & text );
+
+	bool readFromConfig ( const NICE::Config & datasetconf, 
+		    const std::string & classselection );
+
+	/** is there any class with this class number */
+	bool existsClassno ( int classno ) const;
+	/** is there any class with this class code */
+	bool existsClassCode ( const std::string & classcode ) const;
+
+	int getMaxClassno () const;
+
+	void getRGBColor ( int classno, int & r, int & g, int & b ) const;
+	
+	void getClassnoFromColor ( int & classno, int r, int g, int b ) const;
+
+	/** colorize a labeled image using color information given in the class 
+	 *  information file */
+	void labelToRGB ( const NICE::Image & img, NICE::ColorImage & rgb ) const;
+
+	int getBackgroundClass () const;
+
+	/** restore classnames in the format <classtext> <classcode> <classno> */ 
+	void restore (std::istream & is, int format = 0);
+
+	/** store classnames in the format <classtext> <classcode> <classno> */ 
+	void store (std::ostream & os, int format = 0) const;
+
+	/** clear class information */
+    void clear ();
+};
+
+
+} // namespace
+
+#endif

+ 62 - 0
cbaselib/ClassificationResult.cpp

@@ -0,0 +1,62 @@
+/** 
+* @file ClassificationResult.cpp
+* @brief classification result, what else?
+* @author Erik Rodner
+* @date 02/13/2008
+
+*/
+#include <vislearning/nice_nonvis.h>
+
+#include <iostream>
+
+#include "vislearning/cbaselib/ClassificationResult.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+
+
+ClassificationResult::ClassificationResult( int _rejection_status, int maxClassNo ) : scores(maxClassNo+1)
+{
+    rejection_status = _rejection_status;
+    classno = -1;
+    classno_groundtruth = -1;
+    classname = "rejected";
+	uncertainty = 0.0;
+}
+
+ClassificationResult::ClassificationResult( int _classno, double _score, int maxClassNo ) : scores(maxClassNo+1)
+{
+    rejection_status = REJECTION_NONE;
+    classno = _classno;
+    scores[classno] = _score;
+    classname = "unknown";
+    classno_groundtruth = -1;
+	uncertainty = 0.0;
+}
+
+ClassificationResult::ClassificationResult( int _classno, const FullVector & _scores )
+{
+    rejection_status = REJECTION_NONE;
+    classno = _classno;
+    scores = _scores;
+    classname = "unknown";
+    classno_groundtruth = -1;
+	uncertainty = 0.0;
+}
+
+ClassificationResult::~ClassificationResult()
+{
+}
+
+double ClassificationResult::confidence () const
+{
+    return scores.get(classno);
+}
+	
+bool ClassificationResult::ok () const
+{
+    return ( rejection_status == REJECTION_NONE );
+}

+ 88 - 0
cbaselib/ClassificationResult.h

@@ -0,0 +1,88 @@
+/** 
+* @file ClassificationResult.h
+* @brief classification result data (probabilities, most probable class, rejection status, ...) 
+* @author Erik Rodner
+* @date 02/13/2008
+
+*/
+#ifndef CLASSIFICATIONRESULTINCLUDE
+#define CLASSIFICATIONRESULTINCLUDE
+
+#include <vislearning/nice_nonvis.h>
+
+#include <string>
+#include <map>
+#include "core/vector/SparseVector.h"
+#include "vislearning/math/mathbase/FullVector.h"
+  
+
+namespace OBJREC {
+
+/** @brief classification result data (probabilities, most probable class, rejection status, ...) */
+class ClassificationResult
+{
+
+    public:
+
+	/** rejection types */
+	enum {
+	    REJECTION_FEATURE = 0,
+	    REJECTION_CLASSIFIER,
+	    REJECTION_MISC,
+	    REJECTION_NONE,
+	    REJECTION_UNINTIALIZED
+	};
+
+	/** rejection status (selected from enum) */
+	int rejection_status;
+
+	/** std::vector consisting of scores for each class 
+	    @remark no guaranteed probabilities
+	    low scores means low probability for this class
+	*/
+	FullVector scores;
+
+	/** most important part: class number of classification result,
+	    most probable class */
+	int classno;
+
+	/** evil workaround: ground truth class number (useful within ClassificationResults)
+	    @see testClassification.cpp
+	    @see ClassificationResults
+	*/
+	int classno_groundtruth;
+
+	/** text representation of the most probable class 
+	    @remark has to be set manually !! */
+	std::string classname;
+ 
+ 	/** uncertainty of the estimate, only available for GP classifiers */
+	double uncertainty;
+ 
+	/** simple constructor, create rejected result */
+	ClassificationResult( int rejection_status = REJECTION_UNINTIALIZED, int maxClassNo = 0 );
+      
+	/** result of classification only consists of the most probable
+	    class @p classno and a score of this assigment */
+	ClassificationResult( int classno, double score, int maxClassNo );
+	
+	/** result of classification consists of most probable class @p classno
+	    and a score for each of the other classes */
+	ClassificationResult( int classno, const FullVector & scores );
+
+	/** simple destructor */
+	virtual ~ClassificationResult();
+
+	/** was it rejected ? */
+	bool ok () const;
+
+	/** probability of predicted class */
+	double confidence () const;
+
+     
+};
+
+
+} // namespace
+
+#endif

+ 86 - 0
cbaselib/ClassificationResults.cpp

@@ -0,0 +1,86 @@
+/** 
+* @file ClassificationResults.cpp
+// refactor-nice.pl: check this substitution
+// old: * @brief vector of ClassificationResult
+* @brief std::vector of ClassificationResult
+* @author Erik Rodner
+* @date 02/13/2008
+
+*/
+#include <vislearning/nice_nonvis.h>
+
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+
+#include "vislearning/cbaselib/ClassificationResults.h"
+#include "vislearning/cbaselib/LocalizationAnalysis.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+
+
+ClassificationResults::ClassificationResults()
+{
+}
+
+ClassificationResults::~ClassificationResults()
+{
+}
+
+void ClassificationResults::writeWEKA ( const std::string & filename, int classno ) const
+{
+    ofstream ofs ( filename.c_str(), ios::out );
+    int instno = 0;
+    for ( const_iterator i = begin(); i != end() ; i++, instno++ )
+    {
+		const ClassificationResult & r = *i;
+		double confidence = r.scores.get(classno);
+
+		ofs << instno << ", " << r.classno_groundtruth << ", " <<setiosflags(ios::fixed)<< setprecision(20)<<confidence << ", " << r.classno << endl;
+    }
+    ofs.close();
+}
+
+double ClassificationResults::getBinaryClassPerformance ( int type ) const
+{
+	LocalizationAnalysis la;
+	vector< pair<double, int> > resultsFlat;
+	uint countPositives = 0;
+	uint countNegatives = 0;
+	for ( const_iterator i = begin(); i != end(); i++ )
+	{
+		const ClassificationResult & r = *i;
+		double confidence = r.scores.get(1);
+		uint classno_groundtruth = r.classno_groundtruth;
+
+		resultsFlat.push_back ( pair<double, int> ( confidence, classno_groundtruth ) );
+
+		if ( classno_groundtruth == 1 )
+			countPositives++;
+		if ( classno_groundtruth == 0 )
+			countNegatives++;
+	}
+
+	if ( countPositives <= 0 )
+		fthrow(Exception, "No positive ground truth examples");
+	if ( countNegatives <= 0 )
+		fthrow(Exception, "No negative ground truth examples");
+
+	vector<double> thresholds, x, y;
+
+	if ( type == PERF_AUC )  
+		la.calcROCCurve ( resultsFlat, countPositives, countNegatives, thresholds, x, y );
+	else
+		la.calcRecallPrecisionCurve ( resultsFlat, countPositives, thresholds, x, y );
+
+	if ( type == PERF_AUC )
+		return la.calcAreaUnderROC ( x, y );
+	else if ( type == PERF_AVG_PRECISION_11_POINT )
+		return la.calcAveragePrecision ( x, y );
+	else
+		return la.calcAveragePrecisionPrecise ( x, y );
+}

+ 57 - 0
cbaselib/ClassificationResults.h

@@ -0,0 +1,57 @@
+/** 
+* @file ClassificationResults.h
+// refactor-nice.pl: check this substitution
+// old: * @brief vector of ClassificationResult's
+* @brief std::vector of ClassificationResult's
+* @author Erik Rodner
+* @date 02/13/2008
+
+*/
+#ifndef CLASSIFICATIONRESULTSINCLUDE
+#define CLASSIFICATIONRESULTSINCLUDE
+
+#include <vislearning/nice_nonvis.h>
+
+#include <vector>
+#include "ClassificationResult.h"
+
+namespace OBJREC {
+
+/** vector of ClassificationResult's
+    @see ClassificationResult */
+class ClassificationResults : public std::vector<ClassificationResult>
+{
+	public:
+		enum {
+			PERF_AVG_PRECISION_11_POINT = 0,
+			PERF_AUC = 1,
+			PERF_AVG_PRECISION
+		};
+
+    protected:
+		
+
+    public:
+  
+	/** simple constructor */
+	ClassificationResults();
+      
+	/** simple destructor */
+	virtual ~ClassificationResults();
+   
+	/** write BINARY classification results in WEKA format
+	    suitable for drawing ROC curves 
+	    @param filename write results to filename
+	    @param classno class number of object class within the binary classification setting
+	*/
+	void writeWEKA ( const std::string & filename, int classno ) const;
+
+	/** please choose the type from the public enum,
+	 *  this only works for binary classification problems */
+	double getBinaryClassPerformance ( int type = PERF_AUC ) const;
+};
+
+
+} // namespace
+
+#endif

+ 194 - 0
cbaselib/Example.cpp

@@ -0,0 +1,194 @@
+#include "Example.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+Example::Example()
+{
+	weight = 0.0;
+	height = 0;
+	width = 0;
+	x = 0;
+	y = 0;
+	vec = NULL;
+	svec = NULL;
+	position = 0;
+}
+
+Example::~Example ()
+{
+}
+
+Example::Example ( CachedExample *_ce )
+{
+    _ce->getImageSize ( width, height );
+
+    if ( width % 2 == 0 )
+	width--;
+
+    if ( height % 2 == 0 )
+	height--;
+
+    x = width/2;
+    y = height/2;
+
+    ce = _ce; 
+    vec = NULL;
+    svec = NULL;
+    weight = 1.0;
+	position = 0;
+}
+
+Example::Example ( CachedExample *_ce, 
+						   int _x,
+						   int _y,
+						   double _weight )
+{
+    ce = _ce;
+    x  = _x;
+    y  = _y;
+    width = 0;
+    height = 0;
+    vec = NULL;
+    svec = NULL;
+    weight = _weight;
+	position = 0;
+}
+
+Example::Example ( CachedExample *_ce, 
+						   int _x,
+						   int _y,
+						   int _width,
+						   int _height,
+						   double _weight )
+{
+    ce = _ce;
+    x  = _x;
+    y  = _y;
+    width = _width;
+    height = _height;
+    assert ( (width > 0) && (height > 0) );
+
+    vec = NULL;
+    svec = NULL;
+    weight = _weight;
+	position = 0;
+}
+
+Example::Example ( NICE::Vector *_vec, 
+						   double _weight )
+{
+    x = y = 0;
+    width = height = 0;
+    ce = NULL;
+    vec = _vec;
+    svec = NULL;
+    weight = _weight;
+	position = 0;
+}
+
+void Example::clean ()
+{
+	if ( ce != NULL )
+	{
+		delete ce;
+		ce =  NULL;
+	}
+
+	if ( vec != NULL )
+	{
+		delete vec;
+		vec = NULL;
+	}
+    
+	if ( svec != NULL )
+	{
+		delete svec;
+		svec = NULL;
+	}
+}
+
+
+Example::Example ( const Example &ex)
+{
+	copy(ex);
+}
+
+void Example::copy ( const Example &ex)
+{
+	vec = ex.vec;
+	svec = ex.svec;
+	weight = ex.weight;
+	position = ex.position;
+	width = ex.width;
+	height = ex.height;
+	x = ex.x;
+	y = ex.y;
+	ce = ex.ce;
+	scale = ex.scale;
+}
+
+void Example::restore (istream & is, int format)
+{
+	is >> weight;
+	is >> x;
+	is >> y;
+	is >> width;
+	is >> height;
+	is >> position;
+	int tmp;
+	is >> tmp;
+
+	if(tmp == 1)
+	{
+		svec = new SparseVector();
+		svec->restore(is);
+	}
+	else
+		svec = NULL;
+	is >> tmp;
+	if(tmp >= 0 )
+	{
+		vec = new Vector(tmp);
+		for(int i = 0; i < tmp; i++)
+		{
+			is >> vec[i];
+		}
+	}
+	else
+		vec = NULL;
+}
+
+void Example::store (ostream & os, int format) const
+{
+	os << weight << " " <<  x << " " << y << " " << width << " " << height << " " << position << endl;
+	if(svec == NULL)
+		os << 0 << endl;
+	else
+	{
+		os << 1 << endl;
+		svec->store(os);
+	}
+	
+	if(vec == NULL)
+		os << -1 << endl;
+	else
+	{
+		os << vec->size() << endl;
+		for(int i = 0; i < (int)vec->size(); i++)
+		{
+			os << vec[i] << " ";
+		}
+	}
+}
+
+void Examples::clean ()
+{
+	for ( iterator i = begin(); i != end(); i++ )
+	{
+		Example & example = i->second;
+		example.clean();
+	}
+	clear();
+}

+ 138 - 0
cbaselib/Example.h

@@ -0,0 +1,138 @@
+#ifndef EXAMPLEINCLUDE
+#define EXAMPLEINCLUDE
+
+/** 
+* @file Example.h
+* @brief data caching of several feature images and many more
+* @author Erik Rodner
+* @date 04/21/2008
+*/
+
+#include "CachedExample.h"
+
+namespace OBJREC {
+
+/** Cached example with window information */
+class Example
+{
+    public:
+	/** weight of example */
+	double weight;
+
+	/** complete image example */
+	CachedExample *ce;
+
+	/** x position of window */
+	long long int x;
+	/** y position of window */
+	long long int y;
+
+	/** width of window */
+	int width;
+	/** height of window */
+	int height;
+	
+	//! if some examples are related, they have the same position
+	int position;
+	
+	//! scale of the feature
+	double scale;
+	
+	/** evil workaround: store simple vector example */
+	NICE::Vector *vec;
+	
+	/** evil workaround: store sparse vector example */
+	NICE::SparseVector *svec;
+
+	/** simple constructor, initialize everything with 0
+	 */
+	Example();
+
+	/** constructor using a window covering the whole image
+	    @param ce associated image data
+	*/
+	Example ( CachedExample *_ce );
+
+	/** constructor 
+	    @param ce associated image data
+	    @param x x position of window
+	    @param y y position of window
+	    @param weight weight of example
+	*/
+	Example ( CachedExample *ce, int x, int y, double weight = 1.0 );
+	
+	/** constructor 
+	    @param ce associated image data
+	    @param x x position of window
+	    @param y y position of window
+	    @param weight weight of example
+	*/
+	Example ( CachedExample *ce, int x, int y, int width, int height, double weight = 1.0 );
+
+	/** evil workaround: simple constructors for std::vector examples 
+	    @param vec simple feature vector
+	    @param weight optional weight
+	*/
+	Example ( NICE::Vector *vec, double weight = 1.0 );
+
+	/**
+	 * copy constructor
+	 * @param ex input Example
+	 */
+	Example ( const Example &ex);
+	
+	/**
+	 * copies the values of ex in this example
+	 * @param ex input Example
+	 */
+	void copy ( const Example &ex);
+	
+	/** destructor */
+	~Example ();
+
+	/** delete all data associated with this example
+	    (sparse vector, vector, cached example, etc.) */
+	void clean ();
+	
+	/**
+	 * load from file (warning: no cachedexamples supported yet
+	 * @param is file
+	 * @param format 
+	 */
+	void restore (std::istream & is, int format = 0);
+	
+	
+	/**
+	 * write to file (warning: no cachedexamples supported yet
+	 * @param is file
+	 * @param format 
+	 */
+	void store (std::ostream & os, int format = 0) const;
+};
+
+/** labeled pair of Example 
+    @see Example */
+class Examples : public std::vector< std::pair<int, Example> >
+{
+    public:
+		std::string filename;
+
+    inline int getMaxClassNo () const 
+    {
+		int maxClassno = -1;
+		for ( const_iterator i = begin(); i != end(); i++ )
+			if ( i->first > maxClassno )
+			maxClassno = i->first;
+		
+		return maxClassno;
+    }
+
+	/** delete all data associated with all examples
+	    (sparse vector, vector, cached example, etc.) */
+	void clean ();
+};
+
+
+} // namespace
+
+#endif

+ 69 - 0
cbaselib/Feature.cpp

@@ -0,0 +1,69 @@
+/** 
+* @file Feature.cpp
+* @brief abstraction of a feature
+* @author Erik Rodner
+* @date 04/21/2008
+
+*/
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+
+#include <iostream>
+
+#include "Feature.h"
+#include "FeaturePool.h"
+
+using namespace OBJREC;
+
+using namespace std;
+// refactor-nice.pl: check this substitution
+// old: using namespace ice;
+using namespace NICE;
+
+
+
+Feature::Feature()
+{
+}
+
+Feature::~Feature()
+{
+}
+
+void Feature::calcFeatureValues ( const Examples & examples,
+				    vector<int> & examples_selection,
+				    FeatureValues & values ) const
+{
+    for ( vector<int>::const_iterator si = examples_selection.begin();
+				   si != examples_selection.end();
+				   si++ )
+    {
+	int index = *si;
+	const pair<int, Example> & p = examples[index];
+	int classno = p.first;
+	const Example & ce = p.second;
+	double value = val ( &ce );
+	values.insert ( quadruplet<double, int, int,double> ( value, classno, index, ce.weight ) );
+    }
+}
+
+void Feature::calcFeatureValues ( const Examples & examples,
+				    vector<int> & examples_selection,
+				    FeatureValuesUnsorted & values ) const
+{
+    for ( vector<int>::const_iterator si = examples_selection.begin();
+				   si != examples_selection.end();
+				   si++ )
+    {
+	int index = *si;
+	const pair<int, Example> & p = examples[index];
+	int classno = p.first;
+	const Example & ce = p.second;
+	double value = val ( &ce );
+	values.push_back ( quadruplet<double, int, int, double> ( value, classno, index, ce.weight ) );
+    }
+}
+

+ 72 - 0
cbaselib/Feature.h

@@ -0,0 +1,72 @@
+/** 
+* @file Feature.h
+* @brief abstraction of a feature
+* @author Erik Rodner
+* @date 04/21/2008
+
+*/
+#ifndef FEATUREINCLUDE
+#define FEATUREINCLUDE
+
+#include <set>
+#include <map>
+
+#include "vislearning/cbaselib/CachedExample.h"
+#include "vislearning/cbaselib/Example.h"
+#include "core/basics/Persistent.h"
+#include "core/basics/triplet.h"
+#include "core/basics/quadruplet.h"
+
+//#include "FeaturePool.h"
+
+namespace OBJREC {
+
+class FeaturePool;
+
+#define ROADWORKS { fprintf(stderr, "not yet implemented !\n"); exit(-1); }
+
+/* stores a sorted set of feature values: value classno index weight **/
+class FeatureValues : public std::set< NICE::quadruplet<double, int, int, double> > {};
+class FeatureStorage : public std::map< int, FeatureValues > {};
+
+/* stores an unsorted set of feature values: value classno index weight **/
+class FeatureValuesUnsorted : public std::vector< NICE::quadruplet<double, int, int, double > > {};
+class FeatureStorageUnsorted : public std::map< int, FeatureValuesUnsorted > {};
+
+
+/** abstraction of a feature */
+class Feature : public NICE::Persistent
+{
+
+    protected:
+
+    public:
+  
+	/** simple constructor */
+	Feature();
+      
+	/** simple destructor */
+	virtual ~Feature();
+
+	virtual double val( const Example *example ) const = 0;
+
+	virtual Feature *clone() const = 0;
+
+	virtual void explode ( FeaturePool & featurePool, bool variableWindow = true ) const = 0;
+
+	virtual void calcFeatureValues ( const Examples & examples,
+				    std::vector<int> & examples_selection,
+				    FeatureValuesUnsorted & values ) const;
+    
+        virtual void calcFeatureValues ( const Examples & examples,
+				    std::vector<int> & examples_selection,
+				    FeatureValues & values ) const;
+
+};
+
+
+} // namespace
+
+#undef ROADWORKS
+
+#endif

+ 143 - 0
cbaselib/FeaturePool.cpp

@@ -0,0 +1,143 @@
+/**
+* @file FeaturePool.cpp
+* @brief collection of features
+* @author Erik Rodner
+* @date 04/21/2008
+
+*/
+#include <iostream>
+#include <stdlib.h>
+
+#include "FeaturePool.h"
+#include "VectorFeature.h"
+
+using namespace OBJREC;
+
+using namespace std;
+
+using namespace NICE;
+
+FeaturePool::FeaturePool()
+{
+	conf = NULL;
+	//srand48(time(NULL));
+}
+
+FeaturePool::FeaturePool(const Config *conf)
+{
+	this->conf = conf;
+}
+
+FeaturePool::~FeaturePool()
+{
+}
+
+Feature *FeaturePool::getRandomFeature() const
+{
+	assert(size() == cumsum.size());
+	assert(! empty());
+	double sum = cumsum[ cumsum.size() - 1 ];
+	double pos = drand48() * sum;
+
+	vector<double>::const_iterator j = lower_bound(cumsum.begin(), cumsum.end(), pos);
+	uint index = distance(cumsum.begin(), j);
+
+	const_iterator i = begin() + index;
+
+	return i->second;
+}
+
+void FeaturePool::initRandomFeatureSelection()
+{
+	double sum = 0.0;
+
+    cumsum.clear();
+    cumsum.reserve( size() );
+    for ( vector< pair<double, Feature *> >::const_iterator i = begin();
+						      i != end();
+						      i++ )
+    {
+		sum += i->first;
+		cumsum.push_back ( sum );	
+    }
+}
+
+void FeaturePool::addFeature(Feature *f, double probability)
+{
+	assert(finite(probability));
+	assert(probability > 10e-12);
+	push_back(pair<double, Feature *> (probability, f));
+}
+
+void FeaturePool::destroy()
+{
+	for (vector< pair<double, Feature *> >::iterator i = begin();
+						i != end();
+						i++)
+	{
+		assert(i->second != NULL);
+		delete i->second;
+	}
+
+	vector<pair<double, Feature *> >::clear();
+}
+
+void FeaturePool::restore(istream & is, int format)
+{
+	vector<pair<int, double> > tmpPool;
+	clear();
+
+	fprintf(stderr, "FeaturePool::restore: reading plain vector features!\n");
+    while ( !is.eof() )
+    {
+		double weight = 1.0;
+		if ( !(is >> weight) ) break;
+
+		std::string feature_tag;
+		if ( !(is >> feature_tag) ) break;
+		if ( feature_tag != "VECTORFEATURE" ) {
+			fthrow(Exception, "FeaturePool::restore: if you want to read features other than VectorFeature, use createFeatures::...");
+		}
+		int feature_index;
+		if ( !(is >> feature_index) ) break;
+
+		tmpPool.push_back ( pair<int, double> ( feature_index, weight ) );
+    }
+	
+	for ( vector<pair<int, double> >::const_iterator i = tmpPool.begin();
+		i != tmpPool.end(); i++ )
+	{
+		int feature_index = i->first;
+		double weight = i->second;
+		Feature *f = new VectorFeature ( tmpPool.size(), feature_index );
+		push_back ( pair<double, Feature *> ( weight, f ) );
+	}
+
+}
+
+void FeaturePool::store(ostream & os, int format) const
+{
+    for ( const_iterator i = begin(); i != end(); i++ )
+    {
+		const Feature *f = i->second;
+		os << i->first << " ";
+		f->store ( os, format );
+		os << endl;
+    }
+}
+
+void FeaturePool::clear()
+{
+	destroy();
+}
+
+void FeaturePool::calcFeatureVector ( const Example & pe, NICE::Vector & x ) const
+{
+    x.resize ( size() );
+    int index = 0;
+    for ( const_iterator i = begin(); i != end(); i++, index++ )
+    {
+		const Feature *f = i->second;
+		x[index] = f->val ( &pe );
+    }
+}

+ 55 - 0
cbaselib/FeaturePool.h

@@ -0,0 +1,55 @@
+/** 
+* @file FeaturePool.h
+* @brief collection of features
+* @author Erik Rodner
+* @date 04/21/2008
+
+*/
+#ifndef FEATUREPOOLINCLUDE
+#define FEATUREPOOLINCLUDE
+
+#include "Feature.h"
+#include "core/basics/Persistent.h"
+#include "core/basics/Config.h"
+#include "vislearning/cbaselib/CachedExample.h"
+
+
+namespace OBJREC {
+
+/** collection of features */
+class FeaturePool : public std::vector< std::pair<double, Feature *> >, public NICE::Persistent
+{
+    protected:
+	std::vector<double> cumsum;
+	const NICE::Config *conf;
+
+    public:
+	
+	/** simple constructor */
+	FeaturePool();
+      
+	/** constructor uses config */
+	FeaturePool( const NICE::Config *conf );
+
+	/** simple destructor */
+	virtual ~FeaturePool();
+
+	Feature *getRandomFeature () const;
+
+	void initRandomFeatureSelection ();
+
+	void addFeature ( Feature *f, double probability = 1.0 );
+
+	void calcFeatureVector ( const Example & pe, NICE::Vector & x ) const;
+
+	void destroy ();
+     
+	virtual void restore (std::istream & is, int format = 0);
+	virtual void store (std::ostream & os, int format = 0) const;
+	virtual void clear ();
+};
+
+
+} // namespace
+
+#endif

+ 535 - 0
cbaselib/ImageInfo.cpp

@@ -0,0 +1,535 @@
+/** 
+* @file ImageInfo.cpp
+* @brief localization info + image filename + ?
+* @author Erik Rodner
+* @date 04/16/2008
+
+*/
+#include <vislearning/nice_nonvis.h>
+
+#include <iostream>
+
+#include "vislearning/cbaselib/ImageInfo.h"
+
+/* Qt */
+#ifdef NICE_USELIB_QT4_XML
+
+#include <QFile>
+#include <QString>
+#include <QByteArray>
+#include <QDomDocument>
+#include <QDomNode>
+#include <QDomElement>
+#include <QPoint>
+
+#endif //NICE_USELIB_QT4_XML
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+ImageInfo::~ImageInfo()
+{
+    //if ( lr != NULL )
+	//delete lr;
+}
+
+//! A member loading labeled image from formatted xml file.
+/*!
+ * \param[in] filename a std::string containing a path to the file
+ * we need to load data from
+ *
+ * \see loadLegendFromNode(QDomElement *)
+ * \see BBoxFromData(QString *aBBoxData, int *ID)
+ * \see polyFromData(QString *aPolyData, int *labelID)
+ */
+bool
+ImageInfo::loadImageInfo(const string &aFilename)
+{
+	#ifdef NICE_USELIB_QT4_XML
+
+	QString filename(aFilename.data());
+	QDomDocument doc("Image Labeler");
+	QFile file(filename);
+	if (!file.open(QIODevice::ReadOnly)) {
+		cout << "loadImageInfo:Can not open such file\n";
+		return false;
+		/* NOTREACHED */
+	}
+
+	QString errMsg;
+	if (!doc.setContent(&file, &errMsg)) {
+		QByteArray array = errMsg.toAscii();
+		cout << array.data();
+		//showWarning(errMsg);
+		file.close();
+		return false;
+		/* NOTREACHED */
+	}
+
+	file.close();
+
+	/* getting all info */
+	QDomElement elements = doc.documentElement();
+	QDomNode rootNode = elements.firstChild();
+	QString string_buffer;
+	int width = -1;
+	int height = -1;
+
+//	cout << "\nlet the parsing begin!\n";
+	while(!rootNode.isNull()) {
+		QDomElement element = rootNode.toElement();
+		if(!element.isNull()) {
+			/* path to the image */
+			if (element.tagName() == "image") {
+				string_buffer = element.text();
+				if (string_buffer.isEmpty()) {
+					cout << "loadImageInfo:The file with data"
+							" doesn't contain path to the image\n";
+					return false;
+					/* NOTREACHED */
+				}
+
+				QByteArray array = string_buffer.toAscii();
+				image_path_ = string(array.data());
+			}
+			/* path to the segmented image */
+			if (element.tagName() == "segmented") {
+				string_buffer = element.text();
+				if (string_buffer.isEmpty()) {
+					continue;
+				}
+				QByteArray array = string_buffer.toAscii();
+				segmented_image_path_ = string(array.data());
+			}
+			/* image description */
+			else if (element.tagName() == "description") {
+				string_buffer = element.text();
+				if (string_buffer.isEmpty()) {
+					continue;
+				}
+				QByteArray array = string_buffer.toAscii();
+				image_description_ = string(array.data());
+			}
+			/* tags */
+			else if (element.tagName() == "tags") {
+				string_buffer = element.text();
+				if (string_buffer.isEmpty()) {
+					rootNode = rootNode.nextSibling();
+					cout << "tags are empty\n";
+					continue;
+				}
+				QByteArray array = string_buffer.toAscii();
+				//TODO: make parsing into the string list 
+				tags_ = string(array.data());
+			}
+			/* legend */
+			else if (element.tagName() == "legend") {
+				loadLegendFromElement(&element);
+			}
+			/* objects */
+			else if (element.tagName() == "objects") {
+				QDomNode subNode = element.firstChild();
+				QDomElement subElement;
+
+				while(!subNode.isNull()) {
+					subElement = subNode.toElement();
+
+					if (subElement.isNull() || subElement.text().isEmpty()) {
+						subNode = subNode.nextSibling();
+						continue;
+					}
+
+					string_buffer = subElement.attribute("id");
+					bool ok = 1;
+					int id = string_buffer.toInt(&ok, 10);
+
+					if (!ok) {
+						cout << "loadImageInfo: "
+								"poly id format is corrupted\n";
+						subNode = subNode.nextSibling();
+						continue;
+					}
+
+					string_buffer = subElement.text();
+
+					if (subElement.tagName() == "bbox") {
+						BoundingBox bbox = BBoxFromData(&string_buffer);
+						bbox.setID(id);
+						bboxes_.push_back(bbox);
+					}
+					if (subElement.tagName() == "poly") {
+						Polygon poly = polyFromData(&string_buffer);
+						poly.setID(id);
+						polys_.push_back(poly);
+					}
+
+					subNode = subNode.nextSibling();
+				}
+			}
+			/* image size */
+			else if (element.tagName() == "image_size") {
+				string_buffer = element.text();
+				if (string_buffer.isEmpty()) {
+					cout << "loadImageInfo: "
+							"image size format is corrupted\n";
+					return false;
+					/* NOTREACHED */
+				}
+
+				QString buffer;
+				int size = string_buffer.size();
+				bool ok = 0;
+				for (int i = 0; i < size; i++) {
+					/* ";" is a separator */
+					if (';' != string_buffer.at(i))
+						continue;
+
+					buffer = string_buffer.mid(0, i);
+
+					width = buffer.toInt(&ok, 10);
+					if (!ok) {
+						cout <<
+							"loadImageInfo: "
+							"image size format is corrupted\n";
+						return false;
+						/* NOTREACHED */
+					}
+
+					buffer = string_buffer.mid(i + 1, size - (i + 1));
+
+					height = buffer.toInt(&ok, 10);
+
+					if (!ok) {
+						cout <<
+							"loadImageInfo: "
+							"image size format is corrupted";
+						return false;
+						/* NOTREACHED */
+					}
+					break;
+				}
+			}
+			else if (element.tagName() == "pure_data") {
+				string_buffer = element.text();
+				labeled_image_ = imageTFromData(width, height, &string_buffer);
+			}
+		}
+		rootNode = rootNode.nextSibling();
+	}
+
+	#endif //NICE_USELIB_QT4_XML
+
+	return true;
+}
+
+#ifdef NICE_USELIB_QT4_XML
+
+//! A member loading legend from xml node
+/*!
+ * \param[in] anElement a pointer to the object containing all the legend
+ */
+void
+ImageInfo::loadLegendFromElement(QDomElement *anElement)
+{
+	if (!anElement) {
+		return;
+		/* NOTREACHED */
+	}
+	QDomNode subNode = anElement->firstChild();
+	QDomElement subElement;
+
+	while(!subNode.isNull()) {
+		subElement = subNode.toElement();
+
+		if (!subElement.isNull() && !subElement.text().isEmpty())
+			loadCategoryInfo(&subElement);
+
+		subNode = subNode.nextSibling();
+	}
+}
+
+//! Loads one category info(label) from xml QDomElement
+/*!
+ * \param[in] anElement an object containing category info data
+ */
+bool
+ImageInfo::loadCategoryInfo(QDomElement *anElement)
+{
+	QString string_buffer;
+	int id = -1;
+	bool isMain;
+	uint color = 0xff000000;
+	/* id attribute */
+	string_buffer = anElement->attribute("id");
+	bool ok = 0;
+	id = string_buffer.toInt(&ok, 10);
+
+	if (!ok) {
+		cout <<
+			"loadCategoryInfo: "
+			"label id format is corrupted\n";
+		return false;
+		/* NOTREACHED */
+	}
+
+	/* isMain attribute */
+	string_buffer = anElement->attribute("isMain");
+	isMain = string_buffer.toInt(&ok, 2);
+
+	if (!ok) {
+		cout <<
+			"loadCategoryInfo: "
+			"label isMain flag format is corrupted\n";
+		return false;
+		/* NOTREACHED */
+	}
+
+	/* color attribute */
+	string_buffer = anElement->attribute("color");
+	color = string_buffer.toUInt(&ok, 16);
+
+	if (!ok) {
+		cout <<
+			"loadCategoryInfo: "
+			"label color format is corrupted\n";
+		return false;
+		/* NOTREACHED */
+	}
+
+	/* converting label name from QString to std::string*/
+	string_buffer = anElement->text();
+	QByteArray array = string_buffer.toAscii();
+	std::string labelName(array.data());
+
+	CategoryInfo label;
+	label.setID(id);
+	label.setCategoryName(labelName);
+	label.setColor(color);
+	labels_.push_back(label);
+}
+
+//! A protected member parsing string data and returning a BoundingBox from it
+/*!
+ * format is x;y;w;h where w - width and h - height
+ */
+BoundingBox
+ImageInfo::BBoxFromData(
+	QString *aBBoxData
+)
+{
+	BoundingBox bbox;
+	QString buffer;
+	int startPos = 0;
+	bool ok = 1;
+
+	int counter = 0;
+	for (int i = 0; i < aBBoxData->size(); i++) {
+		if (';' != aBBoxData->at(i))
+			continue;
+
+		buffer = aBBoxData->mid(startPos, i - startPos);
+
+		int bboxData = buffer.toInt(&ok, 10);
+		if (!ok) {
+			cout <<
+				"BBoxFromData: "
+				"bbox format is corrupted\n";
+			break;
+		}
+
+		if (!counter) {
+			bbox.setTopLeft(bboxData, 0);
+			counter++;
+		}
+		else if (1 == counter) {
+			int x = bbox.topLeft().x;
+			bbox.setTopLeft(x, bboxData);
+			counter++;
+		}
+		else if (2 == counter) {
+			bbox.setWidth(bboxData);
+			counter++;
+		}
+		else if (3 == counter) {
+			bbox.setHeight(bboxData);
+			counter++;
+		}
+
+		startPos = i + 1;
+	}
+
+	if (!bbox.isValid() || !ok) {
+		cout <<
+			"BBoxFromData: "
+			"bbox format is corrupted\n";
+		bbox.setTopLeft(0, 0);
+		bbox.setBottomRight(0, 0);
+	}
+
+	return bbox;
+}
+
+//! A protected member parsing string data and returning a Polygon from it
+/*!
+ * format is x0;y0;x1;y1;...
+ */
+Polygon
+ImageInfo::polyFromData(
+	QString *aPolyData
+)
+{
+	Polygon poly;
+	QPoint point;
+	QString buffer;
+	int startPos = 0;
+	bool ok = 1;
+	/* indicates whether coordinate x or y */
+	bool evenFlag = 0;
+
+	for (int i = 0; i < aPolyData->size(); i++) {
+		/* ";" is a separator */
+		if (';' != aPolyData->at(i))
+			continue;
+
+		buffer = aPolyData->mid(startPos, i - startPos);
+
+		int polyCoor = buffer.toInt(&ok, 10);
+		if (!ok) {
+			cout <<
+				"polyFromData: "
+				"poly format is corrupted\n";
+			break;
+		}
+
+		if (!evenFlag) {
+			point.setX(polyCoor);
+			evenFlag = 1;
+		}
+		else {
+			point.setY(polyCoor);
+			poly.push(point.x(), point.y());
+			evenFlag = 0;
+		}
+		startPos = i + 1;
+	}
+
+	/* last coordinate was Xi what means an error or
+	   last converting from string was not successful */
+	if (evenFlag || !ok) {
+		cout <<
+			"polyFromData: "
+			"poly format is corrupted\n";
+		//poly.clear();
+	}
+
+	return poly;
+}
+
+//!
+ImageT< unsigned int >
+ImageInfo::imageTFromData(
+	const int &aWidth,
+	const int &aHeight,
+	QString *aPureData
+)
+{
+	int startPos = 0;
+	QString buffer = 0;
+	ImageT< unsigned int > image(aWidth, aHeight);
+	int y = 0;
+	int x = 0;
+	bool ok = 0;
+	for (int i = 0; i < aPureData->size(); i++) {
+		if ('\n' == aPureData->at(i)) {
+			y++;
+			x = 0;
+			startPos = i + 1;
+			continue;
+		}
+		/* ";" is a separator */
+		if (';' != aPureData->at(i))
+			continue;
+
+		buffer = aPureData->mid(startPos, i - startPos);
+
+		int pixel = buffer.toInt(&ok, 10);
+		if (!ok) {
+			cout <<
+				"imageTFromData: "
+				"pure data format is corrupted\n";
+			image = 0;
+			return image;
+			/* NOTREACHED */
+		}
+		image.setPixel(x, y, pixel);
+		x++;
+
+		startPos = i + 1;
+	}
+
+	return image;
+}
+
+#endif //NICE_USELIB_QT4_XML
+
+//! returns pointer to labels_ list
+const std::list< CategoryInfo > *
+ImageInfo::labels() const
+{
+	return &labels_;
+}
+
+//! returns pointer to bboxes_ list
+const std::list< BoundingBox > *
+ImageInfo::bboxes() const
+{
+	return &bboxes_;
+}
+
+//! returns pointer to polys_ list
+const std::list< Polygon > *
+ImageInfo::polys() const
+{
+	return &polys_;
+}
+
+//! returns ImageT object labeled_image_
+ImageT< unsigned int >
+ImageInfo::labeledImage() const
+{
+	return labeled_image_;
+}
+
+//! returns tags
+std::string
+ImageInfo::tags() const
+{
+	return tags_;
+}
+
+//! returns path to the original image
+std::string
+ImageInfo::imagePath() const
+{
+	return image_path_;
+}
+
+//! returns string with the image description
+std::string
+ImageInfo::imageDescription() const
+{
+	return image_description_;
+}
+
+//! returns path to the image segmented by ImageLabeler tool
+std::string
+ImageInfo::segmentedImagePath() const
+{
+	return segmented_image_path_;
+}
+
+/*
+ * 
+ */

+ 96 - 0
cbaselib/ImageInfo.h

@@ -0,0 +1,96 @@
+/** 
+* @file ImageInfo.h
+* @brief localization info + image filename + ?
+* @author Erik Rodner
+* @date 04/16/2008
+*/
+#ifndef IMAGEINFOINCLUDE
+#define IMAGEINFOINCLUDE
+
+#include <vislearning/nice_nonvis.h>
+ 
+#include "vislearning/cbaselib/Polygon.h"
+#include "vislearning/cbaselib/BoundingBox.h"
+#include "vislearning/cbaselib/CategoryInfo.h"
+
+#include "LocalizationResult.h"
+#include <assert.h>
+
+#ifdef NICE_USELIB_QT4_XML
+
+class QString;
+class QDomElement;
+
+#endif //NICE_USELIB_QT4_XML
+
+namespace OBJREC {
+
+/** localization info + image filename + ? */
+class ImageInfo
+{
+
+    protected:
+	std::string imagefn;
+	LocalizationResult *lr;
+	bool localization_info;
+
+	#ifdef NICE_USELIB_QT4_XML
+	
+	Polygon	polyFromData(QString *aPolyData);
+	BoundingBox BBoxFromData(QString *aBBoxData);
+	void loadLegendFromElement(QDomElement *anElement);
+	bool loadCategoryInfo(QDomElement *anElement);
+	ImageT< unsigned int >	imageTFromData(
+		const int &aWidth,
+		const int &aHeight,
+		QString *aPureData
+	);
+
+	#endif //NICE_USELIB_QT4_XML
+
+    public:
+  
+	/** simple constructor */
+	ImageInfo( const std::string & _imagefn, LocalizationResult *_lr ) : 
+	    imagefn(_imagefn), lr(_lr), localization_info(true) {};
+	
+	ImageInfo() {};
+      
+	ImageInfo( const std::string & _imagefn ) : 
+	    imagefn(_imagefn), lr(NULL), localization_info(false) {};
+
+	/** simple destructor */
+	virtual ~ImageInfo();
+
+	const std::string & img () const { return imagefn; };
+	const LocalizationResult *localization () const { assert(localization_info); return lr; };
+	bool hasLocalizationInfo () const { return localization_info; };
+	
+	bool loadImageInfo(const std::string &aFilename);
+	
+	const std::list< CategoryInfo > * labels() const;
+	const std::list< BoundingBox > * bboxes() const;
+	const std::list< Polygon > * polys() const;
+	ImageT< unsigned int > labeledImage() const;
+	std::string tags() const;
+	std::string imagePath() const;
+	std::string imageDescription() const;
+	std::string segmentedImagePath() const;
+
+    private:
+	std::list< CategoryInfo > labels_;
+	std::list< BoundingBox > bboxes_;
+	std::list< Polygon > polys_;
+	ImageT< unsigned int > labeled_image_;
+	//std::list< std::string > tags_;
+	std::string tags_;
+	std::string image_path_;
+	std::string image_description_;
+	std::string segmented_image_path_;
+	
+};
+
+
+} // namespace
+
+#endif

+ 248 - 0
cbaselib/KernelUtils.cpp

@@ -0,0 +1,248 @@
+/** 
+* @file KernelUtils.cpp
+* @brief some utilities to select kernel sub matrices etc.
+* @author Erik Rodner
+* @date 03/01/2010
+
+*/
+#include <iostream>
+#include <set>
+
+#include "KernelUtils.h"
+#include "core/basics/StringTools.h"
+
+using namespace std;
+using namespace NICE;
+using namespace OBJREC;
+
+
+void KernelUtils::selectExamples ( const Config *conf, const Vector & labels,
+	vector<int> & trainSelection, vector<int> & testSelection )
+{
+	string selectionType = conf->gS("main", "selection_type");
+	map<int, int> trainExamplesCount;
+	map<int, int> testExamplesCount;
+
+	if ( selectionType == "seq" ) {
+		int trainExamples = conf->gI("main", "selection_examples" );
+		if ( ((int)labels.size() < trainExamples) || (trainExamples <= 0) )
+			fthrow(Exception, "Unable to select " << trainExamples << " from " << labels.size() << ".");
+		for ( uint i = 0 ; i < (uint)trainExamples; i++ )
+		{
+			int classno = (int)labels[i];
+			trainSelection.push_back( i );
+			trainExamplesCount[classno] ++;
+		}
+		
+		for ( uint i = (uint)trainExamples ; i < labels.size(); i++ )
+		{
+			int classno = (int)labels[i];
+			testSelection.push_back( i );
+			testExamplesCount[classno] ++;
+		}
+
+		
+	} else if ( selectionType == "seq_class" ) 
+	{
+		int trainExamplesForEachClassSingle = conf->gI("main", "selection_examples_class", -1 );
+
+		Vector trainExamplesForEachClass;
+		if ( trainExamplesForEachClassSingle <=0 ) {
+			string trainExamplesForEachClass_s = conf->gS("main", "selection_examples_class" );
+			StringTools::splitVector ( trainExamplesForEachClass_s, ',', trainExamplesForEachClass );
+		}
+
+		for ( uint i = 0 ; i < labels.size() ; i++ )
+		{
+			int classno = (int)labels[i];
+			if ( (trainExamplesForEachClassSingle <= 0) && (classno >= (int)trainExamplesForEachClass.size()) )
+				fthrow(Exception, "-selection_examples_class <n0>,<n1>,..." << endl << "Missing data in selection_examples_class!" );
+
+			int limit = trainExamplesForEachClassSingle;
+			if ( limit <= 0 )
+				limit = trainExamplesForEachClass[classno];
+			if ( trainExamplesCount[classno] < limit )
+			{
+				trainSelection.push_back ( i );
+				trainExamplesCount[classno] ++;
+			} else {
+				testSelection.push_back ( i );
+				testExamplesCount[classno] ++;
+			}
+		}
+	} else if ( selectionType == "random_class_doaa" ) 
+	{
+		if ( labels.size() != 224*5 )
+			fthrow(Exception, "This selection only works with the Jena-Range-02 database!\n");
+		int k = conf->gI("main", "selection_instances", 3 );
+
+		map<int, set<int> > trainInstances;
+		// loop through all classes
+		for ( int i = 0 ; i < 5 ; i++ ) 
+		{
+			trainInstances.insert ( pair<int, set<int> > ( i, set<int> () ) );
+			for ( int j = 0 ; j < k ; j++ )
+			{
+				int inst;
+				do {
+					inst = randInt ( 6 ) + 1;
+				} while ( trainInstances[i].find(inst) != trainInstances[i].end() );
+				trainInstances[i].insert ( inst );
+			}
+		}
+
+		for ( uint i = 0 ; i < labels.size() ; i++ )
+		{
+			int classno = (int)labels[i];
+			int instance = (i % 224) / 32;
+
+			if ( instance == 0 )
+				continue;
+//			cerr << i << " " << "inst " << instance << " " << trainInstances[classno].size() << endl;
+
+			if ( trainInstances[classno].find(instance) != trainInstances[classno].end() ) {
+				trainSelection.push_back ( i );
+				trainExamplesCount[classno] ++;
+			} else {
+				testSelection.push_back ( i );
+				testExamplesCount[classno] ++;
+			}
+		}
+
+		for ( int i = 0 ; i < 5 ; i++ ) 
+			if ( trainExamplesCount[i] != k*32 ) {
+				fthrow(Exception, "Something is wrong here: training examples of class " << i << " = " << trainExamplesCount[i] << " != " << k*32 );
+			}
+	} else if ( selectionType == "seq_class_doaa" ) 
+	{
+		int trainExamplesForEachClassSingle = 100;
+		int testExamplesForEachClassSingle = 60;
+
+		for ( uint i = 0 ; i < labels.size() ; i++ )
+		{
+			int classno = (int)labels[i];
+
+			if ( trainExamplesCount[classno] < trainExamplesForEachClassSingle )
+			{
+				trainSelection.push_back ( i );
+				trainExamplesCount[classno] ++;
+			} else if ( testExamplesCount[classno] < testExamplesForEachClassSingle )  {
+				testSelection.push_back ( i );
+				testExamplesCount[classno] ++;
+			}
+		}
+
+	} else if ( selectionType == "random_class" ) 
+	{
+		int trainExamplesForEachClassSingle = conf->gI("main", "selection_examples_class", -1 );
+
+		Vector trainExamplesForEachClass;
+		if ( trainExamplesForEachClassSingle <=0 ) {
+			string trainExamplesForEachClass_s = conf->gS("main", "selection_examples_class" );
+			StringTools::splitVector ( trainExamplesForEachClass_s, ',', trainExamplesForEachClass );
+		}
+
+		map<uint, uint> counts;
+		for ( uint i = 0 ; i < labels.size(); i++ )
+		{
+			uint classno = (uint)labels[i];
+			map<uint, uint>::iterator i = counts.find( classno );
+			if ( i == counts.end() )
+				counts.insert ( pair<uint, uint> ( classno, 1 ) );
+			else
+				i->second += 1;
+		}
+
+		set<int> memory;
+		for ( map<uint, uint>::const_iterator k = counts.begin(); k != counts.end(); k++ )
+		{
+			uint count = k->second;
+			uint classno = k->first;
+			if ( (trainExamplesForEachClassSingle <= 0) && (classno >= trainExamplesForEachClass.size()) )
+				fthrow(Exception, "-selection_examples_class <n0>,<n1>,..." << endl << "Missing data in selection_examples_class!" );
+
+			int limit = trainExamplesForEachClassSingle;
+			if ( limit <= 0 )
+				limit = trainExamplesForEachClass[classno];
+			if ( limit > (int)count )
+			{
+				cerr << "Class " << classno << " has not enough examples, we will use all of them (" << count << ") !" << endl;
+				limit = count;
+			}
+
+			for ( int j = 0 ; j < limit ; j++ )
+			{
+				int k;
+				// inefficient random selection 
+				do {
+					k = rand() % labels.size();
+				} while ( (memory.find(k) != memory.end()) || ((uint)labels[k] != classno) );
+
+				memory.insert(k);
+				trainSelection.push_back ( k );	
+			}
+
+			cerr << classno << " -> " << limit << endl;
+		}
+
+		// put the remainder to the test sets
+		for ( uint i = 0 ; i < labels.size(); i++ )
+		{
+			if ( memory.find(i) == memory.end() ) {
+				testSelection.push_back ( i );
+			}
+		}
+
+	} else {
+		fthrow(Exception, "Selection type " << selectionType << " is unknown." );
+	}
+
+
+	cerr << "Learning" << endl;
+	for ( map<int, int>::const_iterator j = trainExamplesCount.begin();
+		j != trainExamplesCount.end(); j++ )
+		cerr << "class " << j->first << ": " << j->second << endl;
+		
+	cerr << "Testing" << endl;
+	for ( map<int, int>::const_iterator j = testExamplesCount.begin();
+		j != testExamplesCount.end(); j++ )
+		cerr << "class " << j->first << ": " << j->second << endl;
+}
+		
+void KernelUtils::getKernelMatrix ( const vector<int> & trainSelection, 
+	const Matrix & kernelMatrix, const Vector & labels, 
+	Matrix & kernelMatrixTrain, Vector & labelsTrain )
+{
+	kernelMatrixTrain.resize ( trainSelection.size(), trainSelection.size() );
+	labelsTrain.resize ( trainSelection.size() );
+
+	int ik = 0;
+	for ( vector<int>::const_iterator i = trainSelection.begin(); 
+		i != trainSelection.end(); i++,ik++ )
+	{
+		int index_i = *i;
+		labelsTrain[ik] = labels[index_i];
+
+		int jk = 0;
+		for ( vector<int>::const_iterator j = trainSelection.begin(); 
+			j != trainSelection.end(); j++,jk++ )
+		{
+			int index_j = *j;
+			kernelMatrixTrain(ik,jk) = kernelMatrix(index_i,index_j);
+		}
+	}
+}
+			
+void KernelUtils::getKernelVector ( const vector<int> & trainSelection, 
+	const Matrix & kernelMatrix, uint index, Vector & kernelVector )
+{
+	kernelVector.resize ( trainSelection.size() );
+	int ik = 0;
+	for ( vector<int>::const_iterator i = trainSelection.begin();
+		i != trainSelection.end(); i++,ik++ )
+	{
+		int index_i = *i;
+		kernelVector(ik) = kernelMatrix(index_i,index);
+	}
+}
+

+ 39 - 0
cbaselib/KernelUtils.h

@@ -0,0 +1,39 @@
+/** 
+* @file KernelUtils.h
+* @author Erik Rodner
+* @date 03/01/2010
+
+*/
+#ifndef _NICE_OBJREC_KERNELUTILSINCLUDE
+#define _NICE_OBJREC_KERNELUTILSINCLUDE
+
+#include <vector>
+
+#include "core/vector/MatrixT.h"
+#include "core/basics/Config.h"
+
+namespace OBJREC {
+  
+/** @class KernelUtils
+ * some utilities to select kernel sub matrices etc. 
+ *
+ * @author Erik Rodner
+ */
+class KernelUtils
+{
+    public:
+  		static void selectExamples ( const NICE::Config *conf, const NICE::Vector & labels,
+			std::vector<int> & trainSelection, std::vector<int> & testSelection );
+
+ 		static void getKernelMatrix ( const std::vector<int> & trainSelection, 
+			const NICE::Matrix & kernelMatrix, const NICE::Vector & labels, 
+			NICE::Matrix & kernelMatrixTrain, NICE::Vector & labelsTrain );
+    
+		static void getKernelVector ( const std::vector<int> & trainSelection, 
+			const NICE::Matrix & kernelMatrix, uint index, NICE::Vector & kernelVector );
+
+};
+
+}
+
+#endif

+ 277 - 0
cbaselib/LabeledFileList.cpp

@@ -0,0 +1,277 @@
+/** 
+* @file LabeledFileList.cpp
+* @brief reads images from directory
+* @author Erik Rodner
+* @date 17.09.2007
+
+*/
+#include <vislearning/nice_nonvis.h>
+
+#include <iostream>
+#include <sstream>
+
+#include "core/basics/StringTools.h"
+#include "core/basics/FileMgt.h"
+
+#include "vislearning/cbaselib/LabeledFileList.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+LabeledFileList::LabeledFileList() 
+{
+    debug_dataset = false;
+}
+
+LabeledFileList::~LabeledFileList()
+{
+}
+
+
+LocalizationResult *LabeledFileList::getLocalizationInfo ( const ClassNames & classnames,
+					    int classno,
+					    const std::string & file,
+					    const Config & conf ) const
+{
+    /*
+    localization_pattern = image
+    localization_subst   = mask
+    localization_format  = image
+    */
+    std::string format = conf.gS("main", "localization_format", "unknown");
+    if ( format == "unknown" )
+	return NULL;
+
+    std::string pattern = conf.gS("main", "localization_pattern" );
+    std::string subst   = conf.gS("main", "localization_subst" );
+
+    std::string lfile = file;
+    if ( ! StringTools::regexSubstitute ( lfile, pattern, subst ) )
+    {
+	fprintf (stderr, "Unable to substitute using pattern #%s# and string #%s#\n",
+	    pattern.c_str(), lfile.c_str() );
+	exit(-1);
+    }
+
+    if ( ! FileMgt::fileExists(lfile) ) return NULL;
+    if ( debug_dataset )
+    {
+	fprintf (stderr, "LabeledFileList: reading localization information %s\n", lfile.c_str() );
+    }
+
+    LocalizationResult *lr = NULL;
+
+    if ( format == "image" )
+    {
+		NICE::Image mask;
+		try {
+			mask.read(lfile);
+		} catch (ImageException &) {
+			fprintf (stderr, "WARNING: unable to open file %s (no localization info provided)\n",
+			lfile.c_str() );
+			return NULL;
+		}
+		
+		lr = new LocalizationResult ( &classnames, mask, classno );
+
+    } else if ( format == "imagergb" ) {
+		NICE::ColorImage mask;
+		try {
+			mask.read( lfile );
+		} catch (ImageException &e) {
+			fprintf (stderr, "WARNING: unable to open file %s (no localization info provided)\n",
+			lfile.c_str() );
+			fprintf (stderr, "Error: %s\n", e.what() );
+			return NULL;
+		}
+		lr = new LocalizationResult ( &classnames, mask );
+
+    } else if ( format == "polygon" ) {
+		lr = new LocalizationResult ( &classnames );
+
+		lr->read ( lfile, LocalizationResult::FILEFORMAT_POLYGON );
+
+		if ( debug_dataset )
+		   fprintf (stderr, "LabeledFileList: object localization %d\n", (int)lr->size() );
+		} else {
+			fthrow(Exception, "Localization format not yet supported !!\n");
+		}
+   
+	if ( debug_dataset )
+	    if ( lr != NULL )
+			fprintf (stderr, "%s (%d objects)\n", lfile.c_str(), (int)lr->size() );
+
+    return lr;
+}
+
+void LabeledFileList::getFromPattern (
+    const std::string & dir,
+    const Config & datasetconf,
+    const ClassNames & classnames, 
+    LabeledSet & ls,
+    bool localizationInfoDisabled ) const
+{
+    std::string filemask;
+    
+    if ( dir.substr(dir.length()-1,1) != "/" )
+		filemask = dir + "/" + datasetconf.gS("main", "pattern");
+    else
+		filemask = dir + datasetconf.gS("main", "pattern");
+
+    std::vector<string> files;
+
+    int classnameField = datasetconf.gI("main", "classname_field", 1);
+    std::string fixedClassname = datasetconf.gS("main", "fixed_classname", "");
+    
+    files.clear();
+    FileMgt::DirectoryRecursive ( files, dir );
+    fprintf (stderr, "LabeledFileList: Files: %d\n", (int)files.size());
+
+    sort ( files.begin(), files.end() );
+
+    for ( vector<string>::const_iterator i  = files.begin();
+					 i != files.end(); 
+					 i++ ) 
+    {
+		vector<string> submatches;
+		// refactor-nice.pl: check this substitution
+		// old: const string & file = *i;
+		const std::string & file = *i;
+		if ( debug_dataset ) 
+			fprintf (stderr, "LabeledFileList: next file: %s\n", file.c_str() );
+
+		bool match = StringTools::regexMatch ( file, filemask, submatches );
+
+		if ( (fixedClassname == "") && ((int)submatches.size() <= classnameField) ) match = false;
+
+		if ( ! match  )
+		{
+			if ( debug_dataset )
+			fprintf (stderr, "LabeledFileList: WARNING: %s does not match filemask: %s!!\n", file.c_str(), filemask.c_str() );
+		} else {
+			std::string classcode = ( fixedClassname == "" ) ? submatches[classnameField] : fixedClassname;
+
+			if ( classnames.existsClassCode(classcode) ) {
+				int classno = classnames.classno(classcode);
+				LocalizationResult *lr  = NULL;
+				
+				if ( ! localizationInfoDisabled )
+					lr = getLocalizationInfo ( 
+					classnames, classno, file, datasetconf);
+
+				if ( debug_dataset )
+					fprintf (stderr, "LabeledFileList: LabeledSet: add %s (%d)\n", file.c_str(), classno );
+				if ( lr == NULL ) 
+				{
+					ls.add ( classno, new ImageInfo(file) );
+				} else {
+					ls.add ( classno, new ImageInfo(file, lr) );
+					if ( debug_dataset )
+					fprintf (stderr, "LabeledFileList: LocalizationResult added!\n");
+
+				}
+			} else {
+				if ( debug_dataset )
+				{
+					for ( vector<string>::iterator i = submatches.begin();
+								   i != submatches.end();
+								   i++ )
+					{
+						fprintf (stderr, "LabeledFileList: submatch: %s\n", i->c_str() );
+					}
+					fprintf (stderr, "LabeledFileList: WARNING: code %s ignored !\n", classcode.c_str() );
+				}
+			}
+		}
+		if ( debug_dataset )
+			fprintf (stderr, "LabeledFileList: filename processed\n");
+	}
+
+    cerr << "directory " << dir << " loaded..." << endl;
+    ls.printInformation();
+
+}
+
+void LabeledFileList::getFromList (
+    const std::string & filelist,
+    const Config & datasetconf,
+    const ClassNames & classnames, 
+    LabeledSet & ls,
+    bool localizationInfoDisabled) const
+{
+	if ( debug_dataset ) 
+		fprintf (stderr, "Reading file list: %s\n", filelist.c_str() );
+
+    ifstream ifs ( filelist.c_str(), ios::in );
+	if ( ! ifs.good() ) 
+		fthrow(IOException, "File list " << filelist << " not found !");
+    
+    std::string fixedClassname = datasetconf.gS("main", "fixed_classname", "");
+
+    while ( ! ifs.eof() )
+    {
+		std::string classcode;
+		std::string file;
+
+		if ( fixedClassname == "" ) {
+			if ( ! (ifs >> classcode) ) break;
+		} else {
+			classcode = fixedClassname;
+		}
+
+		if ( ! (ifs >> file) ) break;
+
+		if ( classnames.existsClassCode(classcode) ) {
+			int classno = classnames.classno(classcode);
+			
+			LocalizationResult *lr  = NULL;
+			
+			if ( ! localizationInfoDisabled )
+				lr = getLocalizationInfo ( classnames, classno, file, datasetconf);
+
+			if ( debug_dataset )
+				cerr << "Adding file " << file << " with classno " << classno << endl;
+
+			if ( lr == NULL ) 
+				ls.add ( classno, new ImageInfo(file) );
+			else
+				ls.add ( classno, new ImageInfo(file, lr) );
+		} else {
+			if ( debug_dataset )
+				fprintf (stderr, "WARNING: code %s ignored !\n", classcode.c_str() );
+		}
+
+    }
+
+	if ( debug_dataset )
+	    ls.printInformation();
+}
+
+
+void LabeledFileList::get ( 
+    const std::string & dir,
+    const Config & datasetconf,
+    const ClassNames & classnames, 
+    LabeledSet & ls, 
+    bool localizationInfoDisabled,
+    bool debugDataset ) 
+{
+    std::string pattern = datasetconf.gS("main", "pattern", "");
+    std::string filelist = datasetconf.gS("main", "filelist", "");
+    this->debug_dataset = debugDataset;
+
+    if ( pattern.size() > 0 ) 
+		getFromPattern ( dir, datasetconf, classnames, ls, localizationInfoDisabled );
+    else if ( filelist.size() > 0 ) {
+
+		std::string cfilelist = datasetconf.gS("main", "filelist");
+		std::string filelist = ( cfilelist.substr(0,1) == "/" ) ? cfilelist : dir + "/" + cfilelist;
+
+		getFromList ( filelist, datasetconf, classnames, ls, localizationInfoDisabled );
+    } else {
+		fprintf (stderr, "LabeledFileList: Unable to obtain labeled file list\n");
+		exit(-1);
+    }
+}

+ 64 - 0
cbaselib/LabeledFileList.h

@@ -0,0 +1,64 @@
+/** 
+* @file LabeledFileList.h
+* @brief reads images from directory
+* @author Erik Rodner
+* @date 17.09.2007
+*/
+#ifndef LabeledFileListINCLUDE
+#define LabeledFileListINCLUDE
+
+#include <string>
+
+#include "core/basics/Config.h"
+#include "vislearning/baselib/ProgressBar.h"
+
+#include "ClassNames.h"
+#include "LocalizationResult.h"
+#include "LabeledSet.h"
+
+namespace OBJREC {
+
+/** reads images from directory */
+class LabeledFileList
+{
+    private:
+	bool debug_dataset;
+
+    public:
+  
+	/** simple constructor */
+	LabeledFileList(); 
+      
+	/** simple destructor */
+	virtual ~LabeledFileList();
+ 
+	LocalizationResult *getLocalizationInfo ( const ClassNames & classnames,
+					    int classno,
+					    const std::string & file,
+					    const NICE::Config & conf ) const;
+
+	void get ( const std::string & dir,
+		   const NICE::Config & datasetconf,
+		   const ClassNames & classnames, 
+		   LabeledSet & ls,
+		   bool localizationInfoDisabled = false,
+		   bool debugDataset = false );
+		   
+	void getFromPattern ( const std::string & dir,
+		   const NICE::Config & datasetconf,
+		   const ClassNames & classnames, 
+		   LabeledSet & ls,
+		   bool localizationInfoDisabled = false ) const;
+
+	void getFromList ( const std::string & filelist,
+		   const NICE::Config & datasetconf,
+		   const ClassNames & classnames, 
+		   LabeledSet & ls,
+		   bool localizationInfoDisabled = false ) const;
+
+};
+
+
+} // namespace
+
+#endif

+ 469 - 0
cbaselib/LabeledSet.cpp

@@ -0,0 +1,469 @@
+/** 
+* @file LabeledSet.cpp
+* @brief Labeled set of vectors
+* @author Erik Rodner
+* @date 07.09.2007
+
+*/
+#ifndef LABELEDSETTCCINCLUDE
+#define LABELEDSETTCCINCLUDE
+
+#include <vislearning/nice_nonvis.h>
+
+#include <iostream>
+
+#include "vislearning/cbaselib/LabeledSet.h"
+#include "core/basics/StringTools.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+
+LabeledSet::LabeledSet ( bool _selection ) : selection(_selection)
+{
+}
+	
+LabeledSet::~LabeledSet ()
+{
+    //This is a big problem when using selections
+    //clear();
+    //fprintf (stderr, "LabeledSet: destructor (FIXME: memory leak)\n");
+}
+
+int LabeledSet::count ( int classno ) const
+{
+    const_iterator i = find(classno);
+    return ( i == end() ) ? 0 : i->second.size();
+}
+
+int LabeledSet::count () const
+{
+    int mycount = 0;
+    for ( const_iterator i = begin() ; i != end() ; i++ )
+    {
+		mycount += i->second.size();
+    }
+    return mycount;
+}
+
+void LabeledSet::clear ()
+{
+    if ( !selection ) 
+    {
+		for ( Permutation::const_iterator i  = insertOrder.begin(); 
+						  i != insertOrder.end();
+						  i++ )
+		{
+			const ImageInfo *s = i->second;
+			delete s;
+		}
+    }
+    
+    std::map< int, vector<ImageInfo *> >::clear();
+}
+
+void LabeledSet::add ( int classno, ImageInfo *x )
+{
+    if ( selection ) {
+		fprintf (stderr, "Operation not available for selections !\n");
+		exit(-1);
+    }
+
+    iterator i = find(classno);
+    if ( i == end() ) {
+		operator[](classno) = vector<ImageInfo *>();
+		i = find(classno);
+    }
+    i->second.push_back ( x ); 
+    insertOrder.push_back ( ElementPointer ( classno, x ) );
+}
+	
+void LabeledSet::getPermutation ( Permutation & permutation ) const
+{
+    permutation = Permutation ( insertOrder );
+}
+
+void LabeledSet::add_reference ( int classno, ImageInfo *pointer )
+{
+    iterator i = find(classno);
+    if ( i == end() ) {
+		operator[](classno) = vector<ImageInfo *>();
+		i = find(classno);
+    }
+    i->second.push_back ( pointer ); 
+    insertOrder.push_back ( ElementPointer ( classno, pointer ) );
+}
+
+void LabeledSet::getClasses ( std::vector<int> & classes ) const
+{
+    for ( const_iterator i = begin(); i != end(); i++ )
+		classes.push_back ( i->first );
+}
+
+void LabeledSet::printInformation () const
+{
+    for ( const_iterator i = begin(); i != end(); i++ )
+    {
+	cerr << "class " << i->first << ": " << i->second.size() << endl;
+    }
+}
+
+
+/************************************
+    LabeledSetVector
+*************************************/
+
+
+LabeledSetVector::LabeledSetVector (bool _selection) : selection(_selection)
+{}
+	
+LabeledSetVector::~LabeledSetVector ()
+{
+    // FIXME: THIS is a big problem with selections !!!
+    //clear();
+}
+
+int LabeledSetVector::dimension () const
+{
+    if ( insertOrder.size() <= 0 ) return -1;
+    return (*(begin()->second.begin()))->size();
+    //insertOrder[0].second->size();
+}
+
+void LabeledSetVector::restore (istream & is, int format)
+{
+    if ( format == FILEFORMAT_RAW )
+		restoreRAW ( is );
+    else
+		restoreASCII ( is, format );
+}
+
+void LabeledSetVector::restoreASCII (istream & is, int format)
+{
+    const int bufsize = 1024*1024;
+    char *buf = new char[bufsize];
+    std::string buf_s;
+
+    vector<string> elements;
+    vector<string> pair;
+
+	// maximal dimension of all feature vectors;
+	int dataset_dimension = -numeric_limits<int>::max();
+
+    while (! is.eof())
+    {
+		elements.clear();
+		int classno;
+		
+		if ( ! (is >> classno) ) {
+			break;
+		}
+
+		is.get ( buf, bufsize );
+		buf_s = buf;
+
+		if ( buf_s.size() <= 0 ) 
+			break;
+
+		StringTools::split ( buf_s, ' ', elements );
+
+		if ( elements.size() <= 1 )
+			break;
+		
+		int dimension = - numeric_limits<int>::max();
+		if ( format == FILEFORMAT_INDEX_SPARSE_ONE ) 
+		{
+			// in this format we have to determine the maximum index
+			for ( vector<string>::const_iterator i  = elements.begin()+1; 
+							 i != elements.end();
+							 i++ ) 
+			{
+				pair.clear();
+				StringTools::split ( *i, ':', pair );
+				if ( pair.size() != 2 ) continue;
+
+				int index = atoi(pair[0].c_str());
+				
+				if ( index > dimension )
+					dimension = index;
+			}
+
+			if ( dimension > dataset_dimension )
+				dataset_dimension = dimension;
+
+			
+		} else {
+			// skip first element because of white space
+			dimension = elements.size()-1;
+		}
+
+
+		NICE::Vector vec ( dimension, 0.0 );
+		size_t l = 0;
+
+		// skip first element because of white space
+		for ( vector<string>::const_iterator i  = elements.begin()+1; 
+							 i != elements.end();
+							 i++, l++ )
+		{
+			if ( format == FILEFORMAT_INDEX ) 
+			{
+				pair.clear();
+				StringTools::split ( *i, ':', pair );
+				if ( pair.size() == 2 ) {
+					double val = atof ( pair[1].c_str() );
+					vec[l] = val;
+				}
+			} else if ( format == FILEFORMAT_INDEX_SPARSE_ONE ) 
+			{
+				pair.clear();
+				StringTools::split ( *i, ':', pair );
+				if ( pair.size() == 2 ) {
+					double val = atof ( pair[1].c_str() );
+					int index = atoi ( pair[0].c_str() ) - 1;
+					vec[index] = val;
+				}
+			} else {
+				vec[l] = atof( i->c_str() );
+			}
+		}
+		add( classno, vec );
+    }
+    delete [] buf;
+
+	if ( format == FILEFORMAT_INDEX_SPARSE_ONE ) {
+		// we have to resize all feature vectors of the dataset to dataset_dimension
+		for ( LabeledSetVector::iterator iLOOP_ALL = begin() ; iLOOP_ALL != end() ; iLOOP_ALL++)
+			for ( vector<NICE::Vector *>::iterator jLOOP_ALL = iLOOP_ALL->second.begin(); 
+									 jLOOP_ALL != iLOOP_ALL->second.end(); 
+									 jLOOP_ALL++ )
+			{
+				NICE::Vector *x = (*jLOOP_ALL);
+
+				uint old_dimension = x->size();
+
+				// resize the vector to the dataset dimension
+				x->resize(dataset_dimension);
+				
+				// set all elements to zero, which are new after the resize operation
+				for ( uint k = old_dimension; k < x->size(); k++ )
+					(*x)[k] = 0.0;
+			}
+	}
+}
+
+void LabeledSetVector::store (ostream & os, int format) const
+{
+    for ( Permutation::const_iterator i  = insertOrder.begin();
+				      i != insertOrder.end();
+				      i++ )
+    {
+		int classno = i->first;
+		const NICE::Vector & x = *(i->second);
+		
+		storeElement ( os, classno, x, format );
+    }
+}
+
+void LabeledSetVector::storeElement ( ostream & os, int classno, const NICE::Vector & x, int format )
+{
+    if ( format != FILEFORMAT_RAW ) {
+		os << classno << " ";
+		for ( size_t k = 0 ; k < x.size() ; k++ )
+		{
+			if ( format == FILEFORMAT_INDEX )
+				os << k+1 << ":" << x[k];
+			else if ( format == FILEFORMAT_NOINDEX )  
+				os << x[k];
+			else if ( format == FILEFORMAT_INDEX_SPARSE_ONE )  {
+				if ( x[k] != 0.0 ) 
+					os << k+1 << ":" << x[k];
+			}
+
+			if ( k != x.size() )
+				os << " ";
+		}
+		os << endl;
+	} else {
+		const double *data = x.getDataPointer();
+		int dimension = x.size();
+
+		os.write ( (char *)&classno, sizeof(int) );
+		os.write ( (char *)&dimension, sizeof(int) );
+		os.write ( (char *)data, sizeof(double)*dimension );
+    }
+}
+
+void LabeledSetVector::restoreRAW (istream & is)
+{
+    while (! is.eof())
+    {
+		int classno;
+		int dimension;
+
+		is.read ( (char *)&classno, sizeof(int) );
+		if ( is.gcount() != sizeof(int) )
+			return;
+
+		is.read ( (char *)&dimension, sizeof(int) );
+		if ( is.gcount() != sizeof(int) )
+			return;
+
+		NICE::Vector vec;
+
+		try {
+			vec.resize(dimension);
+		} catch ( std::bad_alloc ) {
+			fthrow(IOException, "Unable to allocate a vector with size " << dimension << "." << endl 
+					<< "(debug: class " << classno << " ; " << "sizeof(int) = " << 8*sizeof(int) << " Bit ; " << endl
+					<< "elements read = " << count() << " )" << endl );
+		}
+		double *data = vec.getDataPointer();
+
+		is.read ( (char *)data, sizeof(double)*dimension );
+		if ( (int)is.gcount() != (int)sizeof(double)*dimension )
+			return;
+
+		for ( int k = 0 ; k < dimension ; k++ )
+			if ( isnan(data[k]) ) {
+				cerr << "WARNING: nan's found !!" << endl;
+				data[k] = 0.0;
+			}
+		
+		add( classno, vec );
+    }
+}
+
+LabeledSetVector::ElementPointer LabeledSetVector::pickRandomSample () const
+{
+    if ( insertOrder.size() <= 0 ) {
+		fprintf (stderr, "LabeledSet::pickRandomSample: failure !\n");
+		exit(-1);
+    }
+    
+    int selection = rand() % insertOrder.size();
+    return insertOrder[selection];
+}
+
+int LabeledSetVector::count ( int classno ) const
+{
+    const_iterator i = find(classno);
+    return ( i == end() ) ? 0 : i->second.size();
+}
+
+int LabeledSetVector::count () const
+{
+    int mycount = 0;
+    for ( const_iterator i = begin() ; i != end() ; i++ )
+		mycount += i->second.size();
+    return mycount;
+}
+
+int LabeledSetVector::pickRandomSample ( int classno, ElementPointer & i ) const
+{
+    const_iterator j = find(classno);
+    if ( j == end() ) return -1;
+
+    const vector<Vector *> & l = j->second;
+    int num = rand() % l.size();
+
+    i.first = classno;
+    i.second = l[num];
+
+    return classno;
+}
+
+void LabeledSetVector::clear ()
+{
+    if ( ! selection ) {
+		for ( Permutation::const_iterator i  = insertOrder.begin(); 
+						  i != insertOrder.end();
+						  i++ )
+		{
+			const NICE::Vector *s = i->second;
+			delete s;
+		}
+		insertOrder.clear();
+    }
+
+    std::map< int, vector<Vector *> >::clear();
+}
+
+void LabeledSetVector::add ( int classno, const NICE::Vector & x )
+{
+    if ( selection ) {
+		fprintf (stderr, "Add operation not available for selections !\n");
+		exit(-1);
+    }
+
+    iterator i = find(classno);
+    if ( i == end() ) {
+		operator[](classno) = vector<Vector *>();
+		i = find(classno);
+    }
+    NICE::Vector *xp = new Vector(x);
+
+    i->second.push_back ( xp ); 
+    insertOrder.push_back ( ElementPointer ( classno, xp ) );
+}
+    
+void LabeledSetVector::getPermutation ( Permutation & permutation ) const
+{
+    permutation = Permutation ( insertOrder );
+}
+
+void LabeledSetVector::add_reference ( int classno, NICE::Vector *pointer )
+{
+    iterator i = find(classno);
+    if ( i == end() ) {
+		operator[](classno) = vector<Vector *>();
+		i = find(classno);
+    }
+    i->second.push_back ( pointer ); 
+    insertOrder.push_back ( ElementPointer ( classno, pointer ) );
+}
+	
+void LabeledSetVector::getClasses ( std::vector<int> & classes ) const
+{
+    for ( const_iterator i = begin(); i != end(); i++ )
+	classes.push_back ( i->first );
+}
+	
+void LabeledSetVector::printInformation () const
+{
+    for ( const_iterator i = begin(); i != end(); i++ )
+    {
+		cerr << "class " << i->first << ": " << i->second.size() << endl;
+    }
+}
+	
+int LabeledSetVector::getMaxClassno() const
+{
+    int maxclassno = 0;
+
+    for ( const_iterator i = begin(); i != end(); i++ )
+		if ( i->first > maxclassno ) 
+			maxclassno = i->first;
+
+    return maxclassno;
+}
+
+void LabeledSetVector::getFlatRepresentation ( VVector & vecSet, NICE::Vector & vecSetLabels ) const
+{
+	int k = 0;
+	vecSetLabels.resize(count());
+	for ( LabeledSetVector::const_iterator iLOOP_ALL = begin() ; iLOOP_ALL != end() ; iLOOP_ALL++)
+		for ( vector<NICE::Vector *>::const_iterator jLOOP_ALL = iLOOP_ALL->second.begin(); 
+								 jLOOP_ALL != iLOOP_ALL->second.end(); 
+								 jLOOP_ALL++,k++ )
+		{
+			const NICE::Vector & (x) = *(*jLOOP_ALL);
+			vecSet.push_back ( x );
+			vecSetLabels[k] = iLOOP_ALL->first;
+		}
+
+}
+
+#endif

+ 164 - 0
cbaselib/LabeledSet.h

@@ -0,0 +1,164 @@
+/** 
+* @file LabeledSet.h
+* @brief Labeled set of vectors
+* @author Erik Rodner
+* @date 07.09.2007
+
+*/
+#ifndef LABELEDSETINCLUDE
+#define LABELEDSETINCLUDE
+
+#include <vector>
+#include <map>
+
+#include "core/basics/Persistent.h"
+#include "core/vector/VVector.h"
+
+#include "LabeledSetSelection.h"
+#include "ImageInfo.h"
+
+#define LOOP_ALL(ls) for(LabeledSetVector::const_iterator iLOOP_ALL = (ls).begin() ; iLOOP_ALL != (ls).end() ; iLOOP_ALL++) \
+				    for ( std::vector<NICE::Vector *>::const_iterator jLOOP_ALL = iLOOP_ALL->second.begin(); \
+									 jLOOP_ALL != iLOOP_ALL->second.end(); \
+									 jLOOP_ALL++ )
+#define EACH(classno,x) int (classno) = iLOOP_ALL->first; \
+			const NICE::Vector & (x) = *(*jLOOP_ALL);
+	
+#define LOOP_ALL_NONCONST(ls) for(LabeledSetVector::iterator iLOOP_ALL = (ls).begin() ; iLOOP_ALL != (ls).end() ; iLOOP_ALL++) \
+				    for ( std::vector<NICE::Vector *>::iterator jLOOP_ALL = iLOOP_ALL->second.begin(); \
+									 jLOOP_ALL != iLOOP_ALL->second.end(); \
+									 jLOOP_ALL++ )
+#define EACH_NONCONST(classno,x) int (classno) = iLOOP_ALL->first; \
+			NICE::Vector & (x) = *(*jLOOP_ALL);
+				
+#define LOOP_ALL_S(ls) for(LabeledSet::const_iterator iLOOP_ALL = (ls).begin() ; iLOOP_ALL != (ls).end() ; iLOOP_ALL++) \
+				    for ( std::vector<ImageInfo *>::const_iterator jLOOP_ALL = iLOOP_ALL->second.begin(); \
+									 jLOOP_ALL != iLOOP_ALL->second.end(); \
+									 jLOOP_ALL++ )
+#define EACH_S(classno,x) int (classno) = iLOOP_ALL->first; \
+			const std::string & (x) = (*jLOOP_ALL)->img();
+
+#define EACH_INFO(classno,x) int (classno) = iLOOP_ALL->first; \
+			const ImageInfo & (x) = *(*jLOOP_ALL);
+
+
+namespace OBJREC {
+
+class LabeledSet : 
+	public std::map< int, std::vector<ImageInfo *> >
+{
+    public:
+	typedef std::vector<std::string *> ElementIterator;
+	typedef std::pair<size_t, const ImageInfo *> ElementPointer;
+	typedef std::vector< ElementPointer > Permutation;
+
+    private:
+	bool selection;
+
+	Permutation insertOrder;
+
+    public:
+
+	void add_reference ( int classno, ImageInfo *pointer );
+
+	LabeledSet ( bool selection = false );
+	~LabeledSet ();
+
+	int numClasses () const
+	{   return size();   }
+
+	int count ( int classno ) const;
+	int count () const;
+	
+	void clear ();
+
+	void add ( int classno, ImageInfo *x );
+
+	void getPermutation ( Permutation & permutation ) const; 
+	void getClasses ( std::vector<int> & classes ) const; 
+
+	void printInformation () const;
+
+	friend class LabeledSetSelection<LabeledSet>;
+};
+
+
+/** simple labeled set of vectors as a specialization of std::map<> */
+class LabeledSetVector : 
+	public std::map< int, std::vector<NICE::Vector *> >, 
+	public NICE::Persistent
+{
+    public:
+	typedef std::vector<NICE::Vector *> ElementIterator;
+	typedef std::pair<int, const NICE::Vector *> ElementPointer;
+	typedef std::vector< ElementPointer > Permutation;	
+
+	enum {
+	    FILEFORMAT_INDEX = 0,
+	    FILEFORMAT_NOINDEX = 1,
+	    FILEFORMAT_RAW = 2,
+	    FILEFORMAT_INDEX_SPARSE_ONE = 3
+	};
+    
+    private:
+	bool selection;
+
+	Permutation insertOrder;
+
+    public:
+
+	LabeledSetVector ( bool selection = false );
+	~LabeledSetVector ();
+
+	void add_reference ( int classno, NICE::Vector *pointer );
+
+	int dimension () const;
+
+	int numClasses () const
+	{   return size();   }
+
+	void restore (std::istream & is, int format = FILEFORMAT_INDEX);
+	void restoreRAW ( std::istream & is );
+	void restoreASCII (std::istream & is, int format = FILEFORMAT_INDEX);
+	void store (std::ostream & os, int format = FILEFORMAT_INDEX) const;
+	static void storeElement ( std::ostream & os, int classno, const NICE::Vector & x, int format = FILEFORMAT_INDEX );
+
+	ElementPointer pickRandomSample () const;
+
+	int count ( int classno ) const;
+	int count () const;
+	
+	int pickRandomSample ( int classno, ElementPointer & i ) const;
+
+	void clear ();
+
+	/** most important function: add a labeled vector */
+	void add ( int classno, const NICE::Vector & x );
+
+	void getPermutation ( Permutation & permutation ) const; 
+	void getClasses ( std::vector<int> & classes ) const; 
+	
+	void printInformation () const;
+
+	void setSelection ( bool _selection = true ) { selection = _selection; };
+
+	/**
+	 * returns the highest class number (not the number of classes!)
+	 */
+	int getMaxClassno() const;
+
+	/**
+	 * converts LabeledSetVector to a NICE::VVector Set (containing data) and a Labelvector (containing labels for each Data)
+	 * @param vecSet dataset (output)
+	 * @param vecSetLabels labels (output)
+	 */
+	void getFlatRepresentation ( NICE::VVector & vecSet, NICE::Vector & vecSetLabels ) const;
+	
+	friend class LabeledSetSelection<LabeledSetVector>;
+};
+
+
+
+} // namespace
+
+#endif

+ 192 - 0
cbaselib/LabeledSetSelection.h

@@ -0,0 +1,192 @@
+/** 
+* @file LabeledSetSelection.h
+* @brief Select a subset of a LabeledSet
+* @author Erik Rodner
+* @date 02/08/2008
+
+*/
+#ifndef LABELEDSETSELECTIONINCLUDE
+#define LABELEDSETSELECTIONINCLUDE
+
+#include <vislearning/nice_nonvis.h>
+
+#include <set>
+#include <map>
+  
+namespace OBJREC {
+
+/** Select a subset of a LabeledSet */
+template <class F>
+class LabeledSetSelection
+{
+
+    protected:
+
+    public:
+  
+	static void selectRandom ( const std::map<int,int> & fixedPositiveExamples, const F & base, F & positive, F & negative )
+	{
+	    F & base_nonconst = const_cast< F & >(base);
+	    //srand(time(NULL));
+
+	    for ( std::map<int,int>::const_iterator i = fixedPositiveExamples.begin(); 
+				    i != fixedPositiveExamples.end() ; 
+				    i++ )
+	    {
+			int classno = i->first;
+			int fixedPositiveExamples = i->second;
+
+			std::set<int> memory;
+
+			int count = base_nonconst[classno].size();
+			if ( (count < fixedPositiveExamples) ) {
+				fthrow ( Exception, "LabeledSetSelection::selectRandom: unable to select " << fixedPositiveExamples 
+					<< " of " << count << " examples" );
+			}
+
+			for ( int j = 0 ; j < fixedPositiveExamples ; j++ )
+			{
+				int k;
+				do {
+				k = rand() % count;
+				} while ( memory.find(k) != memory.end() );
+
+				memory.insert(k);
+				positive.add_reference ( classno, base_nonconst[classno][k]);
+			}
+
+			for ( int k = 0 ; k < count ; k++ )
+				if ( memory.find(k) == memory.end() )
+				negative.add_reference ( classno, base_nonconst[classno][k]);
+	    }
+	}
+
+	static void selectRandomMax ( const std::map<int,int> & fixedPositiveExamples, const F & base, F & positive, F & negative )
+	{
+	    F & base_nonconst = const_cast< F & >(base);
+	    //srand(time(NULL));
+
+	    for ( std::map<int,int>::const_iterator i = fixedPositiveExamples.begin(); 
+				    i != fixedPositiveExamples.end() ; 
+				    i++ )
+	    {
+			int classno = i->first;
+			int fixedPositiveExamples = i->second;
+
+			std::set<int> memory;
+
+			int count = base_nonconst[classno].size();
+
+			int m = fixedPositiveExamples < count ? fixedPositiveExamples : count;
+			for ( int j = 0 ; j < m ; j++ )
+			{
+				int k;
+				do {
+					k = rand() % count;
+				} while ( memory.find(k) != memory.end() );
+
+				memory.insert(k);
+				positive.add_reference ( classno, base_nonconst[classno][k]);
+			}
+
+			for ( int k = 0 ; k < count ; k++ )
+				if ( memory.find(k) == memory.end() )
+					negative.add_reference ( classno, base_nonconst[classno][k]);
+	    }
+	}
+
+	static void selectSequentialStep ( const std::map<int, int> & fixedPositiveExamples, const F & base, F & positive, F & negative )
+	{
+	    F & base_nonconst = const_cast< F & >(base);
+
+	    for ( std::map<int,int>::const_iterator i = fixedPositiveExamples.begin(); 
+				    i != fixedPositiveExamples.end() ; 
+				    i++ )
+	    {
+			int classno = i->first;
+			int fixedPositiveExamples = i->second;
+			int count = base_nonconst[classno].size();
+			int step = fixedPositiveExamples ? (count / fixedPositiveExamples) : 0;
+
+			if ( count < fixedPositiveExamples ) {
+				fthrow ( Exception, "LabeledSetSelection::selectSequentialStep: unable to select " << fixedPositiveExamples 
+						<< " of " << count << " examples (classno " << classno << ")" );
+		}
+
+
+		int k = 0;
+		for ( int j = 0 ; j < count ; j++ )
+		{
+		    if ( (step == 0) || (k >= fixedPositiveExamples) || (j % step != 0) ) 
+				negative.add_reference ( classno, base_nonconst[classno][j] );
+		    else {
+				k++;
+				positive.add_reference ( classno, base_nonconst[classno][j] );
+		    }
+		}
+	    }
+	};
+
+
+	static void selectSequential ( const std::map<int, int> & fixedPositiveExamples, const F & base, F & positive, F & negative )
+	{
+	    F & base_nonconst = const_cast< F & >(base);
+
+	    for ( std::map<int,int>::const_iterator i = fixedPositiveExamples.begin(); 
+				    i != fixedPositiveExamples.end() ; 
+				    i++ )
+	    {
+			int classno = i->first;
+			int fixedPositiveExamples = i->second;
+			int count = base_nonconst[classno].size();
+
+			if ( count < fixedPositiveExamples ) {
+				fthrow ( Exception, "LabeledSetSelection::selectSequential: unable to select " << fixedPositiveExamples 
+					<< " of " << count << " examples" );
+			}
+
+			for ( int j = 0 ; j < fixedPositiveExamples ; j++ )
+				positive.add_reference ( classno, base_nonconst[classno][j] );
+			
+			for ( int j = fixedPositiveExamples ; j < count ; j++ )
+				negative.add_reference ( classno, base_nonconst[classno][j] );
+	    }
+
+	};
+
+	static void selectClasses ( const std::set<int> & classnos, const F & base, F & positive, F & negative )
+	{
+	    F & base_nonconst = const_cast< F & >(base);
+
+	    std::vector<int> classes;
+	    base.getClasses(classes);
+
+	    for ( std::set<int>::const_iterator i = classnos.begin(); 
+				    i != classnos.end() ; 
+				    i++ )
+	    {
+			int classno = *i;
+			int count = base_nonconst[classno].size();
+			for ( int j = 0 ; j < count ; j++ )
+				positive.add_reference ( classno, base_nonconst[classno][j]);
+	    }
+
+	    for ( std::vector<int>::const_iterator i = classes.begin(); 
+				    i != classes.end() ; 
+				    i++ )
+	    {
+			int classno = *i;
+			if ( classnos.find(classno) != classnos.end() ) continue;
+			int count = base_nonconst[classno].size();
+			for ( int j = 0 ; j < count ; j++ )
+				negative.add_reference ( classno, base_nonconst[classno][j]);
+	    }
+
+	};
+
+};
+
+
+} // namespace
+
+#endif

+ 44 - 0
cbaselib/LabeledSetVectorTransform.cpp

@@ -0,0 +1,44 @@
+/** 
+* @file LabeledSet.h
+* @brief Transformations of Labeled set of vectors (only vectors are transformed)
+* @author Mi.Ke
+* @date 20.01.2010
+
+*/
+#include <vector>
+#include <map>
+
+#include "vislearning/cbaselib/LabeledSet.h"
+#include "vislearning/cbaselib/LabeledSetVectorTransform.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+		///transformation using no parameters.
+		LabeledSetVector* LabeledSetVectorTransform::transform (LabeledSetVector& labeledSet1 ){
+			LabeledSetVector* transformedLabeledSet = new LabeledSetVector();
+			
+			LOOP_ALL( labeledSet1 ) 
+			{
+				EACH(classno,vec)
+				transformedLabeledSet->add(classno, trans->transform(vec));
+			}
+			return transformedLabeledSet;
+		};
+		///transformation using one vectorial parameter (equal to many scalar ones).
+		LabeledSetVector* LabeledSetVectorTransform::transform (LabeledSetVector& labeledSet1, const NICE::Vector& params){
+			std::vector<NICE::Vector> param_vec;
+			param_vec.push_back(params);
+			return LabeledSetVectorTransform::transform( labeledSet1, param_vec );
+		}
+		///transformation using many vectorial parameters.
+		LabeledSetVector* LabeledSetVectorTransform::transform (LabeledSetVector& labeledSet1, const std::vector<NICE::Vector>& params){
+			LabeledSetVector* transformedLabeledSet = new LabeledSetVector();
+			LOOP_ALL( labeledSet1 ) 
+			{
+				EACH(classno,vec)
+				transformedLabeledSet->add(classno, trans->transform(vec,params));
+			}
+			return transformedLabeledSet;
+		};

+ 42 - 0
cbaselib/LabeledSetVectorTransform.h

@@ -0,0 +1,42 @@
+/** 
+* @file LabeledSet.h
+* @brief Transformations of Labeled set of vectors (only vectors are transformed)
+* @author Mi.Ke
+* @date 20.01.2010
+
+*/
+#ifndef LABELEDSETVECTORTRANSFORMINCLUDE
+#define LABELEDSETVECTORTRANSFORMINCLUDE
+
+#include <vislearning/nice_nonvis.h>
+
+#include <vector>
+#include <map>
+
+#include "vislearning/cbaselib/LabeledSet.h"
+#include "vislearning/cbaselib/VectorTransform.h"
+
+namespace OBJREC {
+/** simple labeled set of vectors as a specialization of std::map<> */
+   class LabeledSetVectorTransform{
+
+	private:
+
+		VectorTransform* trans;
+
+	public:
+
+		LabeledSetVectorTransform( OBJREC::VectorTransform* _trans) : trans(_trans) {} ;
+		~LabeledSetVectorTransform(){};
+
+		LabeledSetVector* transform (LabeledSetVector& labeledSet1);
+		LabeledSetVector* transform (LabeledSetVector& labeledSet1, const NICE::Vector& params);
+		LabeledSetVector* transform (LabeledSetVector& labeledSet1, const std::vector<NICE::Vector>& params);
+
+};
+
+
+
+} // namespace
+
+#endif

+ 330 - 0
cbaselib/LocalizationAnalysis.cpp

@@ -0,0 +1,330 @@
+/** 
+* @file LocalizationAnalysis.cpp
+* @brief Some methods for localization analysis
+* @author Erik Rodner
+* @date 09/01/2008
+
+*/
+#include <iostream>
+
+#include "LocalizationAnalysis.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+double LocalizationAnalysis::calcAveragePrecision ( const vector<double> & recall,
+			      const vector<double> & precision )
+{
+	// This is the PASCAL VOC version of computing 
+	// a kind of interpolated average precision
+	// "The intention in interpolating the precision/recall curve
+	// in this way is to reduce the impact of the “wiggles” in
+	// the precision/recall curve, caused by small variations in the
+	// ranking of examples"
+	//
+	// implementation:
+	// \int_0^1 (max_{recall(t') >= t) precision(t')) dt
+	//
+    double avgp = 0.0;
+    for (double t = 0.0 ; t <= 1.0 ; t+=0.1 )
+    {
+		double p = 0.0;
+		for ( uint k = 0 ; k < recall.size() ; k++ )
+			if ( recall[k] >= t ) {
+				if ( precision[k] >= p ) 
+					p = precision[k];
+			}
+
+		avgp += p / 11;
+    }
+
+    return avgp;
+}
+
+double LocalizationAnalysis::calcAveragePrecisionPrecise ( const vector<double> & recall,
+			      const vector<double> & precision )
+{
+	// average precision is defined as:
+	// int_0^1 precision(recall) drecall 
+	// = int_0^1 precision(t) recall'(t) dt
+    double avgp = 0.0;
+	double oldrec = recall[0];
+
+	if ( (recall[0] != 0.0) || (recall[recall.size()-1] != 1.0) )
+		fthrow(Exception, "Recall/Precision values have to include (0,x) and (1,y)");
+
+    for (uint t = 1 ; t < recall.size(); t++ )
+    {
+		double prec = precision[t];
+		double rec = recall[t];
+		// dt of recall' and of the integral are
+		// cancelling out
+		double drec = rec - oldrec;
+
+		avgp += prec * drec;
+
+		oldrec = rec;
+    }
+
+    return avgp;
+}
+
+double LocalizationAnalysis::trapezoidArea ( double x1, double y1,
+		double x2, double y2 )
+{
+    return ( x2 - x1 ) * ( y1 + y2 ) / 2.0;
+}
+
+double LocalizationAnalysis::calcAreaUnderROC ( const vector<double> & fprate,
+		const vector<double> & tprate )
+{
+	if ( tprate.size() != fprate.size() )
+		fthrow(Exception, "True positive rates and false positives rates do not match according to the" <<
+			" size of their vectors.");
+
+	double area = 0.0;
+	double oldfpr = 0.0;
+	double oldtpr = 0.0;
+
+	for ( uint k = 0 ; k < tprate.size() ; k++ )
+	{
+		double fpr = fprate[k];
+		double tpr = tprate[k];
+		double newArea = trapezoidArea ( oldfpr, oldtpr, fpr, tpr );	
+
+		area += newArea;
+	
+		oldfpr = fpr;
+		oldtpr = tpr;
+	}
+
+	return area;
+}
+
+void LocalizationAnalysis::matchResults ( LocalizationResult *l, 
+					  const LocalizationResult *l_gt,
+					  vector< pair<double, int> > & results,
+					  double matchThreshold,
+					  bool rejectMultipleDetections )
+{
+    if ( l == NULL ) return;
+
+    // stat: tp fp tn fn
+    set<SingleLocalizationResult *> matchedHypotheses;
+    l->sortDescendingConfidence();
+    double measureMax = 0.0;
+
+    for ( LocalizationResult::const_iterator i = l->begin();
+	    i != l->end(); i++ )
+    {
+		SingleLocalizationResult *slr_i = *i;
+		SingleLocalizationResult *matched_gt = NULL;
+		int classno_i = slr_i->r->classno;
+		double confidence = slr_i->r->confidence();
+
+		if ( l_gt != NULL )
+			for ( LocalizationResult::const_iterator j = l_gt->begin();
+			j != l_gt->end(); j++ )
+			{
+			SingleLocalizationResult *slr_j = *j;
+
+			if ( classno_i == slr_j->r->classno ) {
+				double m = slr_i->getBBOverlapMeasure ( *slr_j );
+				if ( m > measureMax ) measureMax = m;
+				if ( m > matchThreshold )
+				{
+				if ( matched_gt != NULL )
+				{
+					fprintf (stderr, "Something strange happened: object hypothesis matched with two different ground truth annotations !! : Overlap issue\n");
+					fprintf (stderr, "match score %f\n", m );
+					fprintf (stderr, "match threshold %f\n", matchThreshold);
+					fprintf (stderr, "sizes algorithm: %zd; sizes groundtruth: %zd\n", l->size(), l_gt->size() );
+					int xi, yi, xa, ya;
+					slr_i->getBoundingBox ( xi, yi, xa, ya );
+					fprintf (stderr, "algorithm: %d %d %d %d\n", xi, yi, xa, ya );
+					slr_j->getBoundingBox ( xi, yi, xa, ya );
+					fprintf (stderr, "groundtruth: %d %d %d %d\n", xi, yi, xa, ya );
+				}
+				matched_gt = slr_j;
+				}
+			}
+			}
+
+		if ( matched_gt == NULL )
+		{
+			results.push_back ( pair<double, int> ( confidence, 0 ) );
+		} else {
+			if ( matchedHypotheses.find(matched_gt) == matchedHypotheses.end() )
+			{
+			matchedHypotheses.insert ( matched_gt );
+			results.push_back ( pair<double, int> ( confidence, 1 ) );
+			} else {
+			// Multiple Detections
+			if (rejectMultipleDetections)
+				results.push_back ( pair<double, int> ( confidence, 0 ) );
+			}
+		}
+    }
+}
+
+void LocalizationAnalysis::calcRecallPrecisionCurve ( const vector< pair<double, int> > & results_unsorted,
+						      int count_positives,
+						      vector<double> & thresholdsv,
+						      vector<double> & recallv,
+						      vector<double> & precisionv )
+{
+    vector<pair<double, int> > results;
+
+    for ( vector<pair< double, int > >::const_iterator i = results_unsorted.begin();
+	 i != results_unsorted.end(); i++ )
+		results.push_back ( pair<double, int> ( - i->first, i->second ) );
+    
+    sort ( results.begin(), results.end() );
+	thresholdsv.clear();
+	recallv.clear();
+	precisionv.clear();
+
+    long fp = 0;
+    long tp = 0;
+    for ( vector<pair<double,int> >::const_iterator i = results.begin();
+						    i != results.end();
+						    i++ )
+    {
+		double confidence = - i->first;
+		int ok = i->second;
+
+		// at this step we have virtually defined a threshold of confidence-epsilon
+		tp += ok;
+		fp += 1-ok;
+
+		// wikipedia.org
+		// Recall in this context is defined as the number of true positives divided by the total number of elements that actually belong 
+		// to the positive class (i.e. the sum of true positives and false negatives, which are items which were not labeled as belonging to the positive class but should have been).
+		double recall = tp / (double)count_positives;
+		// In a statistical classification task, the Precision for a class is the number of true positives 
+		// (i.e. the number of items correctly labeled as belonging to the positive class) divided 
+		// by the total number of elements labeled as belonging to the positive class (i.e. the sum of true positives and false positives, 
+		// which are items incorrectly labeled as belonging to the class). 
+		double precision = tp / (double)(fp+tp);
+
+		thresholdsv.push_back ( confidence );
+		recallv.push_back ( recall );
+		precisionv.push_back ( precision );
+    }
+
+	if ( recallv.size() > 0 ) 
+	{
+		if ( recallv[0] != 0.0 )
+		{
+			// label everything as negative
+			recallv.insert ( recallv.begin(), 0.0 ); 
+			precisionv.insert ( precisionv.begin(), 0.0 ); 
+			thresholdsv.insert ( thresholdsv.begin(), std::numeric_limits<double>::max() );
+		}
+		
+		if ( recallv[recallv.size() - 1] != 0.0 )
+		{
+			// label everything as positive
+			// fp = count_negatives = results.size() - count_positives
+			// tp = count_positives
+			// recall = count_positives / count_positives = 1
+			// precision = count_positives / ( results.size() - count_positives + count_positives ); 
+			//           = count_positives / results.size()
+			recallv.insert ( recallv.end(), 1.0 ); 
+			precisionv.insert ( precisionv.end(), count_positives / (double)results.size() ); 
+			thresholdsv.insert ( thresholdsv.end(), - std::numeric_limits<double>::max() );
+		}
+
+	}
+		
+}
+
+void LocalizationAnalysis::calcROCCurve ( const vector< pair<double, int> > & results_unsorted,
+						      int count_positives,
+						      int count_negatives,
+						      vector<double> & thresholdsv,
+						      vector<double> & fprates,
+						      vector<double> & tprates )
+{
+	if ( (count_positives <= 0) )
+		fthrow(Exception, "ROC Calculation: number of positive examples is zero");
+	if ( (count_negatives <= 0) )
+		fthrow(Exception, "ROC Calculation: number of negative examples is zero");
+
+    vector<pair<double, int> > results;
+
+	// sort the results descending
+    for ( vector<pair< double, int > >::const_iterator i = results_unsorted.begin();
+	 i != results_unsorted.end(); i++ )
+		results.push_back ( pair<double, int> ( - i->first, i->second ) );
+    
+    sort ( results.begin(), results.end() );
+
+    long fp = 0;
+    long tp = 0;
+	double oldconfidence = - numeric_limits<double>::max();
+	// descending order of the results !!
+    for ( vector<pair<double,int> >::const_iterator i = results.begin();
+						    i != results.end();
+						    i++ )
+    {
+		// everything above the confidence
+		// is regarded as positive
+		double confidence = - i->first;
+		int ok = i->second;
+
+		if ( (ok != 1) && (ok != 0) )
+			fthrow(Exception, "ROC Calculation: results should be labeled as 0 or 1 !");
+
+		tp += ok;
+		fp += 1-ok;
+
+		//  This test ensures that we wait for the end of a span of
+		//  equal probabilities before emitting a point.
+		//  Instead of computing a pessimistic version of the ROC curve,
+		//  we use the expected ROC curve (see Tom Fawcetts paper)
+		//  I changed this in 7/6/2011 to ensure the compability of ROC.pl
+		if ( confidence == oldconfidence ) 
+			continue;
+
+		double tprate = tp / (double)count_positives;
+		double fprate = fp / (double)count_negatives;
+
+		thresholdsv.push_back ( confidence );
+		fprates.push_back ( fprate );
+		tprates.push_back ( tprate );
+
+		oldconfidence = confidence;
+    }
+
+	if ( tprates.size() > 0 ) 
+	{
+		if ( tprates[0] != 0.0 )
+		{
+			// label everything as negative
+			tprates.insert ( tprates.begin(), 0.0 ); 
+			fprates.insert ( fprates.begin(), 0.0 ); 
+			thresholdsv.insert ( thresholdsv.begin(), std::numeric_limits<double>::max() );
+		}
+		
+		if ( tprates[tprates.size() - 1] != 1.0 )
+		{
+			// label everything as positive
+			tprates.insert ( tprates.end(), 1.0 ); 
+			fprates.insert ( fprates.end(), 1.0 ); 
+			thresholdsv.insert ( thresholdsv.end(), - std::numeric_limits<double>::max() );
+		}
+
+	}
+}
+
+LocalizationAnalysis::LocalizationAnalysis()
+{
+}
+
+LocalizationAnalysis::~LocalizationAnalysis()
+{
+}
+

+ 71 - 0
cbaselib/LocalizationAnalysis.h

@@ -0,0 +1,71 @@
+/** 
+* @file LocalizationAnalysis.h
+* @brief Some methods for localization analysis
+* @author Erik Rodner
+* @date 09/01/2008
+
+*/
+#ifndef LOCALIZATIONANALYSISINCLUDE
+#define LOCALIZATIONANALYSISINCLUDE
+
+#include <vector>
+#include <map>
+
+#include "LocalizationResult.h"
+
+
+namespace OBJREC {
+
+/** Some methods for localization analysis */
+class LocalizationAnalysis
+{
+
+    protected:
+		double trapezoidArea ( double x1, double y1, double x2, double y2 );
+
+    public:
+  
+		/** simple constructor */
+		LocalizationAnalysis();
+		  
+		/** simple destructor */
+		virtual ~LocalizationAnalysis();
+	  
+		void matchResults ( LocalizationResult *l, 
+					const LocalizationResult *l_gt,
+					std::vector< std::pair<double, int> > & results,
+					double matchThreshold = 0.3,
+					bool rejectMultipleDetections = true);
+
+		void calcRecallPrecisionCurve ( const std::vector< std::pair<double, int> > & results_unsorted,
+						  int count_positives,
+						  std::vector<double> & thresholdsv,
+						  std::vector<double> & recallv,
+						  std::vector<double> & precisionv );
+
+		double calcAreaUnderROC ( const std::vector<double> & fprate,
+				const std::vector<double> & tprate );
+
+		void calcROCCurve ( const std::vector< std::pair<double, int> > & results_unsorted,
+								  int count_positives,
+								  int count_negatives,
+								  std::vector<double> & thresholdsv,
+								  std::vector<double> & fprates,
+								  std::vector<double> & tprates );
+
+		/** calculates the 11-point estimate of the average precision given
+			recall and precision values (used for PASCAL VOC) */
+		double calcAveragePrecision ( const std::vector<double> & recall,
+					  const std::vector<double> & precision );
+
+		/** calculates a precise estimate of the average precision, given
+			recall and precision values */
+		double calcAveragePrecisionPrecise ( const std::vector<double> & recall,
+					  const std::vector<double> & precision );
+
+};
+
+
+} // namespace
+
+#endif

+ 510 - 0
cbaselib/LocalizationResult.cpp

@@ -0,0 +1,510 @@
+/** 
+* @file LocalizationResult.cpp
+* @brief Localization result, what else?
+* @author Erik Rodner
+* @date 02/13/2008
+
+*/
+#include <vislearning/nice_nonvis.h>
+
+#include <iostream>
+
+#include <core/image/LineT.h>
+
+#include "vislearning/cbaselib/LocalizationResult.h"
+#include "core/basics/StringTools.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+/******** SingleLocalizationResult ********/
+
+SingleLocalizationResult::SingleLocalizationResult ( ClassificationResult *_r, const NICE::Region & _reg, int _controlPoints ) 
+    : controlPoints(_controlPoints), hasRegionInformation_bool(true), reg(_reg), r(_r)
+{
+    reg.getRect(xi,yi,xa,ya);
+}
+
+SingleLocalizationResult::SingleLocalizationResult ( ClassificationResult *_r, int _xi, int _yi, int _xa, int _ya ) 
+    : controlPoints(4), xi(_xi), yi(_yi), xa(_xa), ya(_ya), hasRegionInformation_bool(true), r(_r)
+{
+//    reg.add (xi,yi,xa,ya);
+//    this might lead to problems...in general the current Region representation is awful !
+}
+
+double SingleLocalizationResult::getBBOverlapMeasureMin ( const SingleLocalizationResult & y ) const
+{
+    double measure = 0.0;
+    int xxi, xyi, xxa, xya;
+    int yxi, yyi, yxa, yya;
+    getBoundingBox ( xxi, xyi, xxa, xya );
+    y.getBoundingBox ( yxi, yyi, yxa, yya );
+
+    int mxi = ( xxi > yxi ) ? xxi : yxi;
+    int myi = ( xyi > yyi ) ? xyi : yyi;
+    int mxa = ( xxa < yxa ) ? xxa : yxa;
+    int mya = ( xya < yya ) ? xya : yya;
+
+    int iw = mxa - mxi + 1;
+    int ih = mya - myi + 1;
+
+    if ( (iw > 0) && (ih > 0) )
+    {
+        // if iw>0 & ih>0
+	double A = (xxa - xxi + 1)*(xya - xyi + 1);
+	double B = (yxa - yxi + 1)*(yya - yyi + 1);
+
+	double overlap = A < B ? A : B;
+	measure = iw*ih / overlap;
+    }
+
+    return measure;
+}
+
+double SingleLocalizationResult::getBBOverlapMeasure ( const SingleLocalizationResult & y ) const
+{
+    double measure = 0.0;
+    int xxi, xyi, xxa, xya;
+    int yxi, yyi, yxa, yya;
+    getBoundingBox ( xxi, xyi, xxa, xya );
+    y.getBoundingBox ( yxi, yyi, yxa, yya );
+
+    int mxi = ( xxi > yxi ) ? xxi : yxi;
+    int myi = ( xyi > yyi ) ? xyi : yyi;
+    int mxa = ( xxa < yxa ) ? xxa : yxa;
+    int mya = ( xya < yya ) ? xya : yya;
+
+    int iw = mxa - mxi + 1;
+    int ih = mya - myi + 1;
+
+    if ( (iw > 0) && (ih > 0) )
+    {
+        // if iw>0 & ih>0
+	double overlap = (xxa - xxi + 1)*(xya - xyi + 1) +
+			 (yxa - yxi + 1)*(yya - yyi + 1) -
+			 iw*ih;
+	measure = iw*ih / overlap;
+    }
+
+    return measure;
+}
+
+void SingleLocalizationResult::getBoundingBox ( int & _xi, int & _yi, int & _xa, int & _ya ) const
+{
+    _xi = xi;
+    _yi = yi;
+    _xa = xa;
+    _ya = ya;
+}
+
+void SingleLocalizationResult::getBoundingBox ( RectT<int> & rectangle ) const
+{
+	rectangle = RectT<int> ( CoordT<int> ( xi, yi ), CoordT<int> ( xa, ya ) );
+}
+
+void SingleLocalizationResult::getCentroid ( double & x, double & y ) const
+{
+    reg.getCentroid ( x, y );
+}
+
+SingleLocalizationResult::~SingleLocalizationResult ()
+{
+    if ( r != NULL )
+        delete r;  
+}
+
+/******** LocalizationResult *********/
+
+LocalizationResult::LocalizationResult ( int xsize, int ysize ) : cn(NULL)
+{
+    hasLabeledImage = false;
+    this->xsize = xsize;
+    this->ysize = ysize;
+}
+
+LocalizationResult::LocalizationResult ( const ClassNames *_cn, int xsize, int ysize ) : cn(_cn)
+{
+    hasLabeledImage = false;
+    this->xsize = xsize;
+    this->ysize = ysize;
+}
+
+LocalizationResult::~LocalizationResult ()
+{
+    for ( iterator k = begin(); k != end() ; k++ )
+    {
+	SingleLocalizationResult *slr = *k;
+	delete slr;
+    }
+}
+#undef DEBUG_LOCALIZATIONREAD
+LocalizationResult::LocalizationResult ( const ClassNames *_cn, const NICE::Image & img, int classno ) : cn(_cn)
+{
+     const int t = 200; // FIXME
+     NICE::Region reg;
+
+#ifdef DEBUG_LOCALIZATIONREAD
+     NICE::Image imgo (img);
+     imgo.set(0);
+#endif
+
+     this->xsize = img.width();
+     this->ysize = img.height();
+
+     for ( int y = 0 ; y < img.height(); y++ )
+	 for ( int x = 0 ; x < img.width(); x++ )
+	 {
+	     // refactor-nice.pl: check this substitution
+	     // old: if ( GetVal(img, x, y) < t )
+	     if ( img.getPixel(x,y) < t )
+	     {
+#ifdef DEBUG_LOCALIZATIONREAD
+		 imgo.setPixel(x,y,1);
+#endif
+		 reg.add ( x, y );
+	     }
+	 }
+
+#ifdef DEBUG_LOCALIZATIONREAD
+     NICE::showImageOverlay ( imgo, imgo );
+#endif
+
+     ClassificationResult *r = new ClassificationResult (classno, 1.0, _cn->getMaxClassno());
+     push_back ( new SingleLocalizationResult ( r, reg ) );
+
+     hasLabeledImage = false;
+}
+
+LocalizationResult::LocalizationResult ( const ClassNames *_cn, const NICE::ColorImage & img) : cn(_cn)
+{
+     map<int, NICE::Region> regions;
+
+     xsize = img.width();
+     ysize = img.height();
+
+#ifdef DEBUG_LOCALIZATIONREAD
+     NICE::showImage ( img );
+     NICE::Image imgo (xsize,ysize);
+     imgo.set(0);
+#endif
+     
+     for ( int y = 0 ; y < ysize ; y++ )
+		 for ( int x = 0 ; x < xsize ; x++ )
+		 {
+			 int r = img.getPixel(x,y,0);
+			 int g = img.getPixel(x,y,1);
+			 int b = img.getPixel(x,y,2);
+
+			 int classno;
+
+			 _cn->getClassnoFromColor ( classno, r, g, b );
+
+			 if ( classno >= 0 )
+			regions[classno].add(x,y);
+			#ifdef DEBUG_LOCALIZATIONREAD
+			imgo.setPixel(x,y,classno);
+			#endif
+		 }
+
+
+     for ( map<int, NICE::Region>::const_iterator j  = regions.begin();
+					    j != regions.end();
+					    j++ )
+     {
+	 int classno = j->first;
+	 ClassificationResult *r = new ClassificationResult (classno, 1.0, _cn->getMaxClassno());
+	 push_back ( new SingleLocalizationResult ( r, j->second ) );
+     }
+
+     hasLabeledImage = false;
+}
+
+void LocalizationResult::restore (istream & is, int format)
+{
+    if ( format == FILEFORMAT_PASCAL2006_RESULT ) 
+    {
+	while ( ! is.eof() )
+	{
+	    double score;
+	    int xi, yi, xa, ya;
+	    // refactor-nice.pl: check this substitution
+	    // old: string classname;
+	    std::string classname;
+	    if ( ! (is >> classname) ) break;
+	    if ( ! (is >> score) ) break;
+	    if ( ! (is >> xi) ) break;
+	    if ( ! (is >> yi) ) break;
+	    if ( ! (is >> xa) ) break;
+	    if ( ! (is >> ya) ) break;
+	    
+	    ClassificationResult *r = new ClassificationResult ( cn->classno(classname), score, cn->getMaxClassno() ); 
+	    SingleLocalizationResult *sr = new SingleLocalizationResult ( r, xi, yi, xa, ya );
+	    push_back ( sr );
+	}
+    } else if ( format == FILEFORMAT_PASCAL2006_GROUNDTRUTH ) {
+#if 0
+	/* # Details for object 1 ("PAScat")
+	   Original label for object 1 "PAScat" : "PAScat"
+	   Bounding box for object 1 "PAScat" (Xmin, Ymin) - (Xmax, Ymax) : (11, 135) - (333, 410) */
+	// refactor-nice.pl: check this substitution
+	// old: string word;
+	std::string word;
+
+	while ( ! is.eof() )
+	{
+	    if ( ! (is >> word) ) break;
+	    if ( word != "Bounding" ) continue;
+
+	    char line[1024];
+	    is.getline (line, 1024);
+
+	    vector<string> submatches;
+	    bool result = StringTools::regexMatch ( line, "box for object ([:digit]+) \"([:alpha:]+)\" (Xmin, Ymin) - (Xmax, Ymax) : (([:digit:]+) *, *([:digit:]+)) *: *(([:digit:]+) *, *([:digit:]+))", submatches ); 
+
+	    cerr << "string: " << line << endl;
+	    for ( vector<string>::const_iterator i = submatches.begin(); i != submatches.end(); i++ )
+		cerr << "submatch " << *i << endl;
+	    exit(-1);
+
+	}
+#endif
+    } else if ( format == FILEFORMAT_POLYGON ) {
+		// This is limited to bounding boxes ...sorry
+		while (! is.eof()) {
+#define USE_CALTECH101_POLYGON_FORMAT
+#ifdef USE_CALTECH101_POLYGON_FORMAT
+			std::string filename;
+			if ( !(is >> filename) ) break;
+#endif
+
+			std::string classname;
+			if ( !(is >> classname) ) break;
+
+			const double score = 1.0;
+			int classno = cn->classnoFromText(classname);
+
+			uint polygon_points;
+			if ( !(is >> polygon_points) ) break;
+
+			int xi = std::numeric_limits<int>::max();
+			int xa = - std::numeric_limits<int>::max();
+			int yi = std::numeric_limits<int>::max();
+			int ya = - std::numeric_limits<int>::max();
+			for ( uint i = 0 ; i < polygon_points ; i++ )
+			{
+				double x,y;
+				if ( !(is >> x) ) break;
+				if ( !(is >> y) ) break;
+				if ( x < xi ) xi = x;
+				if ( x > xa ) xa = x;
+				if ( y < yi ) yi = y;
+				if ( y > ya ) ya = y;
+
+			}
+			if ( classno >= 0 ) {
+				ClassificationResult *r = new ClassificationResult ( classno, score, cn->getMaxClassno() );
+				SingleLocalizationResult *sr = new SingleLocalizationResult ( r, xi, yi, xa, ya );
+				push_back ( sr );
+			}
+		}
+
+		//sortEmpricalDepth();
+    } else {
+		fthrow(IOException, "LocalizationResult::restore: file format not yet supported !");
+    }
+}
+
+void LocalizationResult::store (ostream & os, int format) const
+{
+    if ( format == FILEFORMAT_PASCAL2006_RESULT ) 
+    {
+	for ( const_iterator i = begin(); i != end(); i++ )
+	{
+	    const SingleLocalizationResult *sr = *i;
+	    const ClassificationResult *r = sr->r;
+	    int classno = r->classno;
+	    double score = r->scores.get(classno);
+
+	    int xi, yi, xa, ya;
+	    sr->getBoundingBox ( xi, yi, xa, ya );
+
+	    os << cn->text(r->classno) << " " << score << " "
+	       << xi << " "
+	       << yi << " "
+	       << xa << " "
+	       << ya << " " << endl;
+	}
+    } else {
+	fprintf (stderr, "LocalizationResult::store: file format not yet supported !\n");
+	exit(-1);
+    }
+    
+
+}
+
+void LocalizationResult::clear ()
+{
+    for ( iterator k = begin(); k != end() ; k++ )
+    {
+	SingleLocalizationResult *slr = *k;
+	delete slr;
+    }
+    
+    vector<SingleLocalizationResult *>::clear();
+    hasLabeledImage = false;   
+}
+
+
+/** returns whether the depth of x is smaller than that of y 
+    !!! no transitivity !!! */
+bool depthCompare ( const SingleLocalizationResult *x, const SingleLocalizationResult *y )
+{
+    /** According to the LabelMe paper of Torralba et al., Murphy */
+    const NICE::Region & rx = x->getRegion();
+    const NICE::Region & ry = y->getRegion();
+
+    NICE::Region intersect;
+    intersect.setIntersection ( rx, ry );
+    int ax = rx.size();
+    int ay = ry.size();
+    int is = intersect.size();
+
+    if ( is == 0 )
+    {
+	int nx = x->getControlPoints();
+	int ny = y->getControlPoints();
+
+	return ( nx > ny );
+    } else {
+	double ratx = (double)is / ax;
+	double raty = (double)is / ay;
+
+	return ( ratx >  raty );
+    }
+}
+
+bool confidenceCompare ( const SingleLocalizationResult *x, const SingleLocalizationResult *y )
+{
+    return ( x->r->confidence() > y->r->confidence() );
+}
+
+void LocalizationResult::sortDescendingConfidence()
+{
+    sort ( begin(), end(), confidenceCompare );
+}
+
+void LocalizationResult::sortEmpricalDepth()
+{
+    sort ( begin(), end(), depthCompare );
+}
+
+void LocalizationResult::calcLabeledImage ( NICE::Image & mark, int backgroundClassNo ) const
+{
+    mark.set(backgroundClassNo);
+
+    fprintf (stderr, "LocalizationResult: calcLabeledImage %zd\n", size() );
+    for ( int y = 0 ; y < mark.height(); y++ )
+	for ( int x = 0 ; x < mark.width(); x++ )
+	{
+	    for ( LocalizationResult::const_iterator k = begin(); k != end() ; k++ )
+	    {
+			SingleLocalizationResult *slr = *k;
+			const NICE::Region & r = slr->getRegion();
+
+			if ( r.inside(x,y) ) {
+				mark.setPixel(x,y,slr->r->classno);
+				break;
+			}
+	    }
+	}
+}
+
+void LocalizationResult::getLabeledImageCache ( NICE::Image & mark ) const
+{
+    assert ( hasLabeledImage );
+    labeledImage->copyFrom ( mark );
+}
+    
+void LocalizationResult::setMap ( const NICE::Image & _labeledImage )
+{
+    labeledImage = new Image( _labeledImage );
+    hasLabeledImage = true;
+}
+
+void drawOrthoLine ( NICE::ColorImage & img, 
+		     int x1, int y1, int x2, int y2, 
+		     int width, int sign,
+		     int r,
+		     int g,
+		     int b )
+{
+    int xi = x1; int yi = y1;
+    int xa = x2; int ya = y2;
+    for ( int i = 0 ; i < width; i++ )
+    {
+		if ( yi == ya ) {
+			yi = yi + sign;
+			ya = ya + sign; 
+		} else if ( xi == xa ) {
+			xi = xi + sign;
+			xa = xa + sign;
+		} else {
+			assert ( 0 == 1 );
+		}
+		if ( (xi>=0) && (yi>=0) && (xa<=img.width())
+			 && (ya<=img.height()) )
+		{
+			NICE::Line l ( Coord(xi, yi), Coord(xa, ya) );
+			img.draw( l, NICE::Color(r, g, b) );
+		}
+    }
+}
+
+void LocalizationResult::displayBoxes ( NICE::ColorImage & img, const ClassNames *cn, 
+					bool display_confidence, bool invert, int width ) const
+{
+    for ( LocalizationResult::const_iterator k = begin(); k != end() ; k++ )
+    {
+		SingleLocalizationResult *slr = *k;
+		int xi, yi, xa, ya;
+		slr->getBoundingBox ( xi, yi, xa, ya );
+		
+		int classno = (slr->r == NULL ) ? 0 : slr->r->classno;
+		int r,g,b;
+		if ( cn != NULL ) {
+			cn->getRGBColor ( classno, r, g, b );	
+		} else {
+			r = 255;
+			g = 0;
+			b = 0;
+		}
+
+		if ( invert ) {
+			r = 255 - r;
+			g = 255 - g;
+			b = 255 - b;
+		}
+
+		if ( display_confidence && (cn != NULL)) {
+			std::string name = cn->text(classno);
+			char caption[1024];
+			sprintf ( caption, "%3.2lf %s", slr->r->confidence(), name.c_str() );
+			// refactor-nice.pl: check this substitution
+			// old: Text(caption, xi, yi, r, 0, img.RedImage());
+			// REFACTOR-FIXME Unable to map this statement
+			// refactor-nice.pl: check this substitution
+			// old: Text(caption, xi, yi, g, 0, img.GreenImage());
+			// REFACTOR-FIXME Unable to map this statement
+			// refactor-nice.pl: check this substitution
+			// old: Text(caption, xi, yi, b, 0, img.BlueImage());
+			// REFACTOR-FIXME Unable to map this statement
+		}
+
+		drawOrthoLine ( img, xi-width, yi, xa+width, yi, width, -1, r, g, b );
+		drawOrthoLine ( img, xa, yi, xa, ya, width, +1, r, g, b );
+		drawOrthoLine ( img, xa+width, ya, xi-width, ya, width, +1, r, g, b );
+		drawOrthoLine ( img, xi, ya, xi, yi, width, -1, r, g, b );
+    }
+}

+ 112 - 0
cbaselib/LocalizationResult.h

@@ -0,0 +1,112 @@
+/** 
+* @file LocalizationResult.h
+* @brief classification result, what else?
+* @author Erik Rodner
+* @date 02/13/2008
+
+*/
+#ifndef LocalizationResultINCLUDE
+#define LocalizationResultINCLUDE
+
+#include <vislearning/nice_nonvis.h>
+
+#include <string>
+#include <vector>
+#include <assert.h>
+ 
+#include "ClassificationResult.h"
+#include "ClassNames.h"
+
+#include "core/basics/Persistent.h"
+
+#include <core/image/Region.h>
+#include <core/image/RectT.h>
+
+
+namespace OBJREC {
+
+class SingleLocalizationResult 
+{
+    private:
+
+	/** used for depth ordering */
+	int controlPoints; 
+	int xi, yi, xa, ya;
+	
+	bool hasRegionInformation_bool;
+	NICE::Region reg;
+    
+    
+    public:
+    
+	ClassificationResult *r;
+
+
+	SingleLocalizationResult ( ClassificationResult *r, const NICE::Region & reg, int controlPoints = 0 );
+	SingleLocalizationResult ( ClassificationResult *r, int xi, int yi, int xa, int ya );
+	~SingleLocalizationResult ();
+
+	void getBoundingBox ( int & xi, int & yi, int & xa, int & ya ) const;
+	void getBoundingBox ( NICE::RectT<int> & rectangle ) const;
+
+	void getCentroid ( double & x, double & y ) const;
+	bool hasRegionInformation () const { return hasRegionInformation_bool; };
+	int getControlPoints () const { return controlPoints; };
+
+	const NICE::Region & getRegion () const { assert (hasRegionInformation_bool); return reg; };
+
+	void addPoint ( int x, int y ) { assert(hasRegionInformation_bool); reg.add(x,y); };
+
+	double getBBOverlapMeasure ( const SingleLocalizationResult & slr ) const;
+	double getBBOverlapMeasureMin ( const SingleLocalizationResult & slr ) const;
+};
+
+
+class LocalizationResult : public std::vector<SingleLocalizationResult *>, public NICE::Persistent
+{
+    private:
+	const ClassNames *cn;
+	NICE::Image *labeledImage;
+	
+    public:
+	bool hasLabeledImage;
+	int xsize;
+	int ysize;
+
+    
+    enum {
+		FILEFORMAT_PASCAL2006_RESULT = 0,
+		FILEFORMAT_PASCAL2006_GROUNDTRUTH,
+		FILEFORMAT_POLYGON
+    };
+
+    LocalizationResult ( int xsize = -1, int ysize = -1 );
+    LocalizationResult ( const ClassNames *cn, int xsize = -1, int ysize = -1);
+    LocalizationResult ( const ClassNames *cn, const NICE::Image & img, int classno );
+    LocalizationResult ( const ClassNames *cn, const NICE::ColorImage & img );
+
+    ~LocalizationResult ();
+
+    void sortEmpricalDepth();
+    void sortDescendingConfidence();
+    void getLabeledImageCache ( NICE::Image & mark ) const;
+    void calcLabeledImage ( NICE::Image & mark, int backgroundClassNo ) const;
+    void setMap ( const NICE::Image & labeledImage );
+
+    void displayBoxes ( NICE::ColorImage & img, 
+			const ClassNames *cn = NULL,
+			bool display_confidence = true,
+			bool invert = false,
+			int width = 1) const;
+
+    void restore (std::istream & is, int format = 0);
+    void store (std::ostream & os, int format = 0) const;
+    void clear ();
+    int getMaxClassno () { assert(cn != NULL); return cn->getMaxClassno(); };
+
+};
+
+
+} // namespace
+
+#endif

+ 8 - 0
cbaselib/Makefile

@@ -0,0 +1,8 @@
+#TARGETS_FROM:=$(notdir $(patsubst %/,%,$(shell pwd)))/$(TARGETS_FROM)
+#$(info recursivly going up: $(TARGETS_FROM) ($(shell pwd)))
+
+all:
+
+%:
+	$(MAKE) TARGETS_FROM=$(notdir $(patsubst %/,%,$(shell pwd)))/$(TARGETS_FROM) -C .. $@
+

+ 103 - 0
cbaselib/Makefile.inc

@@ -0,0 +1,103 @@
+# LIBRARY-DIRECTORY-MAKEFILE
+# conventions:
+# - all subdirectories containing a "Makefile.inc" are considered sublibraries
+#   exception: "progs/" and "tests/" subdirectories!
+# - all ".C", ".cpp" and ".c" files in the current directory are linked to a
+#   library
+# - the library depends on all sublibraries 
+# - the library name is created with $(LIBNAME), i.e. it will be somehow
+#   related to the directory name and with the extension .a
+#   (e.g. lib1/sublib -> lib1_sublib.a)
+# - the library will be added to the default build list ALL_LIBRARIES
+
+# --------------------------------
+# - 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)
+ifeq "$(SUBDIR)" "./"
+SUBDIR:=
+endif
+
+# ------------------------
+# - 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
+#
+# you can specify libraries needed by the individual objects or by the whole
+# directory. the object specific additional libraries are only considered
+# when compiling the specific object files
+# TODO: update documentation...
+
+-include $(SUBDIR)libdepend.inc
+
+$(foreach d,$(filter-out %progs %tests,$(SUBDIRS_OF_$(SUBDIR))),$(eval $(call PKG_DEPEND_INT,$(d))))
+
+# ---------------------------
+# - 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.
+
+LIBRARY_BASENAME:=$(call LIBNAME,$(SUBDIR))
+ifneq "$(SUBDIR)" ""
+ALL_LIBRARIES+=$(LIBDIR)$(LIBRARY_BASENAME).$(LINK_FILE_EXTENSION)
+endif
+
+# ---------------------
+# - binary dependencies
+#
+# there is no way of determining the binary dependencies automatically, so we
+# follow conventions. the current library depends on all sublibraries.
+# all other dependencies have to be added manually by specifying, that the
+# current .pc file depends on some other .pc file. binaries depending on
+# libraries should exclusivelly use the .pc files as well.
+
+ifeq "$(SKIP_BUILD_$(OBJDIR))" "1"
+$(LIBDIR)$(LIBRARY_BASENAME).a:
+else
+$(LIBDIR)$(LIBRARY_BASENAME).a:$(OBJS) \
+	$(call PRINT_INTLIB_DEPS,$(PKGDIR)$(LIBRARY_BASENAME).a,.$(LINK_FILE_EXTENSION))
+endif
+
+$(PKGDIR)$(LIBRARY_BASENAME).pc: \
+	$(call PRINT_INTLIB_DEPS,$(PKGDIR)$(LIBRARY_BASENAME).pc,.pc)
+
+# -------------------
+# - 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))
+

+ 359 - 0
cbaselib/MultiDataset.cpp

@@ -0,0 +1,359 @@
+/** 
+* @file MultiDataset.cpp
+* @brief multiple datasets
+* @author Erik Rodner
+* @date 02/08/2008
+
+*/
+#include <iostream>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "vislearning/cbaselib/ClassNames.h"
+
+#include "core/basics/StringTools.h"
+#include "core/basics/FileMgt.h"
+
+#include "vislearning/cbaselib/MultiDataset.h"
+
+using namespace OBJREC;
+
+using namespace std;
+using namespace NICE;
+
+#undef DEBUG_MultiDataset
+
+void MultiDataset::selectExamples ( const std::string & examples_command,
+		      const LabeledSet & base,
+		      LabeledSet & positives,
+		      LabeledSet & negatives,
+		      const ClassNames & cn ) const
+{
+    vector<string> examples;
+    StringTools::split ( examples_command, ';', examples );
+    set<int> processed_classes;
+
+    for ( vector<string>::const_iterator i  = examples.begin();
+					 i != examples.end();
+					 i++ )
+    {
+		const std::string & cmd = *i;
+		vector<string> parts;
+		StringTools::split ( cmd, ' ', parts );
+		
+		if ( (parts.size() != 3) && ((parts.size() != 2) || (parts[0] != "all")) ) 
+			fthrow( Exception, "Syntax error " << examples_command );
+		
+		const std::string & mode = parts[0];
+		const std::string & csel = parts[1];
+		double parameter = (parts.size() == 3 ) ? atof(parts[2].c_str()) : 0.0;
+		map<int, int> fpe;
+
+		set<int> selection;
+		cn.getSelection ( csel, selection );
+		for ( set<int>::const_iterator j  = selection.begin();
+						   j != selection.end();
+						   j++ )
+		{
+			int classno = *j;
+			if ( processed_classes.find(classno) == processed_classes.end() )
+			{
+#ifdef DEBUG_MultiDataset
+				fprintf (stderr, "class %s: %s %d\n", cn.text(classno).c_str(),
+					mode.c_str(), (int)parameter );
+#endif
+				fpe[*j] = (int)parameter;
+				processed_classes.insert(classno);
+			} else {
+				if ( csel != "*" ) {
+					fthrow ( Exception, "Example selection method for class %s has multiple specifications" << cn.text(classno) );
+				}
+			}
+		}
+
+		if ( mode == "seq" ) {
+			LabeledSetSelection<LabeledSet>::selectSequential ( 
+			fpe, base, positives, negatives );   
+#ifdef DEBUG_MultiDataset
+			fprintf (stderr, "MultiDataset: after special seq selection: %d\n", positives.count() );
+#endif
+		} else if ( mode == "step" ) {
+			LabeledSetSelection<LabeledSet>::selectSequentialStep ( 
+			fpe, base, positives, negatives );   
+#ifdef DEBUG_MultiDataset
+			fprintf (stderr, "MultiDataset: after special step selection: %d\n", positives.count() );
+#endif
+		} else if ( mode == "random" ) {
+			LabeledSetSelection<LabeledSet>::selectRandom ( 
+			fpe, base, positives, negatives );   
+#ifdef DEBUG_MultiDataset
+			fprintf (stderr, "MultiDataset: after special random selection: %d\n", positives.count() );
+#endif
+		} else if ( mode == "all" ) {
+			if ( (int)selection.size() == cn.numClasses() ) 
+			{
+				// preserve permutation
+				LabeledSet::Permutation permutation;
+				base.getPermutation ( permutation );
+				for ( LabeledSet::Permutation::iterator i = permutation.begin(); i != permutation.end(); i++ )
+				{
+					int classno = i->first;
+					ImageInfo *element = const_cast< ImageInfo * > ( i->second );
+					positives.add_reference ( classno, element );
+				}
+			} else {
+				LabeledSetSelection<LabeledSet>::selectClasses ( selection, base, positives, negatives );
+			}
+#ifdef DEBUG_MultiDataset
+			fprintf (stderr, "MultiDataset: after special class selection: %d\n", positives.count() );
+#endif
+		} else {
+			fthrow ( Exception, "Wrong value for parameter example\n");
+		}
+    }
+
+#ifdef DEBUG_MultiDataset
+    fprintf (stderr, "MultiDataset: after special selection operations: %d\n", positives.count() );
+#endif
+    
+    set<int> allclasses;
+    cn.getSelection ( "*", allclasses );
+
+    set<int> allnegative_classes;
+
+    // add all examples from allclasses \setminus processed_classes
+    set_difference(allclasses.begin(), allclasses.end(), processed_classes.begin(), processed_classes.end(),
+                      inserter(allnegative_classes, allnegative_classes.end()));
+
+    LabeledSet dummy;
+    LabeledSetSelection<LabeledSet>::selectClasses ( allnegative_classes, 
+	base, negatives, dummy );
+
+}
+
+/** MultiDataset ------- constructor */
+MultiDataset::MultiDataset( const Config *conf )
+{
+    std::set<string> blocks;
+    conf->getAllBlocks ( blocks );
+
+    map<string, Config> dsconfs;
+    map<string, string> dirs;
+    for ( set<string>::iterator i = blocks.begin();
+	    i != blocks.end();  )
+    {
+		if ( conf->gB(*i, "disable", false) )
+		{
+			i++;
+			continue;
+		}
+
+		std::string dataset = conf->gS( *i, "dataset", "unknown" );
+		if ( dataset == "unknown" )
+			blocks.erase(i++);
+		else {
+#ifdef DEBUG_MultiDataset
+			fprintf (stderr, "Reading dataset config for block [%s]\n", i->c_str() );
+#endif
+			Config dsconf ( (dataset + "/dataset.conf").c_str() );
+			
+			dirs[*i] = dataset;
+			dsconfs[*i] = dsconf;
+			i++;
+		}
+    }
+  
+    if ( blocks.find("traintest") != blocks.end() )
+    {
+		LabeledSet ls_base;
+		LabeledSet ls_train (true);
+		LabeledSet ls_nontrain (true);
+		LabeledSet ls_test (true);
+		LabeledSet dummy (true);
+		LabeledSet temp (true);
+
+		bool localizationInfoDisabled = conf->gB("traintest", "disable_localization_info", false );
+
+		std::string classselection_train = conf->gS("traintest", "classselection_train", "*");
+		std::string classselection_test = conf->gS("traintest", "classselection_test", "*");
+		classnames["traintest"] = ClassNames();
+		
+		std::string classNamesTxt = dirs["traintest"] + "/classnames.txt";
+		if ( FileMgt::fileExists ( classNamesTxt ) )
+		{
+			classnames["traintest"].read ( classNamesTxt );
+		} else {
+			classnames["traintest"].readFromConfig ( dsconfs["traintest"], classselection_train );
+		}
+		
+		lfl.get ( dirs["traintest"], dsconfs["traintest"], classnames["traintest"], ls_base,
+			localizationInfoDisabled, conf->gB("traintest", "debug_dataset", false ) ); 
+
+		std::string examples_train =  conf->gS("traintest", "examples_train" );
+		selectExamples ( examples_train, ls_base, ls_train, ls_nontrain, classnames["traintest"] );
+			
+		set<int> selection_test;
+		classnames["traintest"].getSelection ( classselection_test, selection_test );
+
+		std::string examples_test =  conf->gS("traintest", "examples_test" );
+		if ( examples_test == "reclassification" )
+		{
+			LabeledSetSelection<LabeledSet>::selectClasses 
+			( selection_test, ls_train, ls_test, dummy );
+
+		} else {
+			selectExamples ( examples_test, ls_nontrain, temp, dummy, classnames["traintest"] );
+			LabeledSetSelection<LabeledSet>::selectClasses 
+			( selection_test, temp, ls_test, dummy );
+		}
+
+		classnames["train"] = classnames["traintest"];
+		classnames["test"] = ClassNames ( classnames["traintest"], classselection_test );
+		datasets["test"] = ls_test;
+		datasets["train"] = ls_train;
+    }
+
+    for ( set<string>::const_iterator i = blocks.begin();
+				      i != blocks.end();
+				      i++ )
+    {
+		std::string name = *i;
+		if ( classnames.find(name) != classnames.end() )
+			continue;
+
+		if ( conf->gB(name, "disable", false) == true )
+			continue;
+
+		if ( dsconfs.find(name) == dsconfs.end() )
+			continue;
+
+		LabeledSet ls_base;
+		LabeledSet ls (true);
+		LabeledSet dummy (true);
+		LabeledSet temp (true);
+
+		bool localizationInfoDisabled = conf->gB(name, "disable_localization_info", false );
+
+		std::string classselection = conf->gS(name, "classselection", "*");
+		classnames[name] = ClassNames();
+
+		std::string classNamesTxt = dirs[name] + "/classnames.txt";
+		if ( FileMgt::fileExists ( classNamesTxt ) )
+		{
+#ifdef DEBUG_MultiDataset
+			fprintf (stderr, "MultiDataset: reading class names from %s\n", classNamesTxt.c_str() );
+#endif
+			classnames[name].read ( classNamesTxt );
+		} else {
+#ifdef DEBUG_MultiDataset
+			fprintf (stderr, "MultiDataset: reading class names from dataset config file\n" );
+#endif
+			classnames[name].readFromConfig ( dsconfs[name], classselection );
+		}
+		
+		lfl.get ( dirs[name], dsconfs[name], classnames[name], ls_base,
+			localizationInfoDisabled, conf->gB(name, "debug_dataset", false ) ); 
+#ifdef DEBUG_MultiDataset
+		fprintf (stderr, "MultiDataset: class names -->\n" );
+		classnames[name].store ( cerr );
+		fprintf (stderr, "MultiDataset: all information about %s set obtained ! (size %d)\n", name.c_str(), ls_base.count() );
+#endif
+
+		std::string examples = conf->gS(name, "examples", "all *" );
+		selectExamples ( examples, ls_base, ls, dummy, classnames[name] );
+		
+#ifdef DEBUG_MultiDataset
+		fprintf (stderr, "MultiDataset: size after selection %d\n", ls.count() );
+#endif
+
+		datasets[name] = ls;
+    }
+
+    bool dumpSelections = conf->gB("datasets", "dump_selection", false);
+    if ( dumpSelections )
+    {
+		for ( map<string, LabeledSet>::const_iterator i = datasets.begin();
+			i != datasets.end(); i++ )
+		{
+			const std::string & name = i->first;
+			const LabeledSet & ls = i->second;
+			const ClassNames & classNames = classnames[name];
+
+			mkdir ( name.c_str(), 0755 );
+
+			std::string filelist = name + "/files.txt";
+			ofstream olist ( filelist.c_str(), ios::out );
+			if ( !olist.good() )
+				fthrow (IOException, "Unable to dump selections to " << filelist );
+			
+			LOOP_ALL_S(ls)
+			{
+				EACH_S(classno, file);
+				std::string classtext = classNames.code(classno);
+				olist << classtext << " " << file << endl;
+			}
+			olist.close();
+
+			std::string datasetconf = name + "/dataset.conf";
+			ofstream oconf ( datasetconf.c_str(), ios::out );
+			if ( !oconf.good() )
+				fthrow (IOException, "Unable to dump selections to " << datasetconf );
+
+			set<int> classnos;
+			classNames.getSelection ( "*", classnos);
+
+			oconf << "[main]" << endl;
+			oconf << "filelist = \"files.txt\"" << endl << endl;
+
+			oconf << "[classnames]" << endl;
+			for ( set<int>::const_iterator i = classnos.begin();
+					i != classnos.end(); i++ )
+			{
+				const std::string & code = classNames.code(*i);
+				const std::string & text = classNames.text(*i);
+				oconf << code << "     =     \"" << text << "\"" << endl;
+			}
+			oconf.close();
+			
+			classNames.save ( name + "/classnames.txt" );
+		}
+    }
+
+}
+
+MultiDataset::~MultiDataset()
+{
+}
+
+const ClassNames & MultiDataset::getClassNames ( const std::string & key ) const
+{
+    map<string, ClassNames>::const_iterator i = classnames.find(key);
+    if ( i == classnames.end() )
+    {
+	fprintf (stderr, "MultiDataSet::getClassNames() FATAL ERROR: dataset <%s> not found !\n", key.c_str() );
+	exit(-1);
+    } 
+    return (i->second);
+
+}
+
+const LabeledSet *MultiDataset::operator[] ( const std::string & key ) const
+{
+    map<string, LabeledSet>::const_iterator i = datasets.find(key);
+    if ( i == datasets.end() )
+    {
+	fprintf (stderr, "MultiDataSet: FATAL ERROR: dataset <%s> not found !\n", key.c_str() );
+	exit(-1);
+    } 
+    return &(i->second);
+}
+
+const LabeledSet *MultiDataset::at ( const std::string & key ) const
+{
+    map<string, LabeledSet>::const_iterator i = datasets.find(key);
+    if ( i == datasets.end() )
+	return NULL;
+    else
+	return &(i->second);
+}

+ 60 - 0
cbaselib/MultiDataset.h

@@ -0,0 +1,60 @@
+/** 
+* @file MultiDataset.h
+* @brief multiple datasets
+* @author Erik Rodner
+* @date 02/08/2008
+
+*/
+#ifndef MULTIDATASETINCLUDE
+#define MULTIDATASETINCLUDE
+
+#include <string>
+#include <map>
+
+
+#include <core/basics/Config.h>
+
+
+#include "LabeledSetSelection.h"
+#include "LabeledFileList.h"
+#include "LabeledSet.h"
+#include "ClassNames.h"
+
+
+namespace OBJREC {
+
+/** multiple datasets */
+class MultiDataset
+{
+
+    protected:
+	LabeledFileList lfl;
+	std::map<std::string, ClassNames> classnames;
+	std::map<std::string, LabeledSet> datasets;
+
+	void selectExamples ( const std::string & examples_command,
+		      const LabeledSet & base,
+		      LabeledSet & positives,
+		      LabeledSet & negatives,
+		      const ClassNames & cn ) const;
+
+    public:
+  
+	/** simple constructor */
+	MultiDataset( const NICE::Config *conf );
+      
+	/** simple destructor */
+	virtual ~MultiDataset();
+    
+	const ClassNames & getClassNames ( const std::string & key ) const;
+	
+	const LabeledSet * operator[] ( const std::string & key ) const;
+
+	const LabeledSet * at ( const std::string & key ) const;
+
+};
+
+
+} // namespace
+
+#endif

+ 149 - 0
cbaselib/PascalResults.cpp

@@ -0,0 +1,149 @@
+/** 
+* @file PascalResults.cpp
+* @brief read and write pascal style results
+* @author Erik Rodner
+* @date 09/09/2008
+
+*/
+#include <iostream>
+
+#include "core/basics/StringTools.h"
+#include "PascalResults.h"
+
+using namespace OBJREC;
+
+using namespace std;
+// refactor-nice.pl: check this substitution
+// old: using namespace ice;
+using namespace NICE;
+
+void PascalResults::write ( char *templatefn, 
+			    // refactor-nice.pl: check this substitution
+			    // old: const string & imgfn,
+			    const std::string & imgfn,
+			    const LocalizationResult & l,
+			    const ClassNames & classNames )
+{
+    for ( LocalizationResult::const_iterator i = l.begin(); i != l.end(); i++ )
+    {
+	const SingleLocalizationResult *sr = *i;
+	const ClassificationResult *r = sr->r;
+	int classno = r->classno;
+	// refactor-nice.pl: check this substitution
+	// old: string classname = classNames.text(classno);
+	std::string classname = classNames.text(classno);
+
+	double score = r->scores.get(classno);
+
+	int xi, yi, xa, ya;
+	sr->getBoundingBox ( xi, yi, xa, ya );
+
+	char filename[1024];
+
+	sprintf ( filename, templatefn, classname.c_str() );
+	ofstream os ( filename, ios_base::app );
+
+	if ( !os.good() ) {
+	    fprintf (stderr, "Error writing to filename %s\n", filename );
+	    exit(-1);
+	}
+
+	// refactor-nice.pl: check this substitution
+	// old: string filetag = StringTools::baseName ( imgfn, false );
+	std::string filetag = StringTools::baseName ( imgfn, false );
+
+	os << filetag << " "
+	   << score << " "
+	   << xi << " "
+	   << yi << " "
+	   << xa << " "
+	   << ya << " " << endl;
+
+	os.close();
+    }
+}
+
+void PascalResults::read ( map<string, LocalizationResult *> & results, 
+			   // refactor-nice.pl: check this substitution
+			   // old: string filename,
+			   std::string filename,
+			   int classno, int backgroundClassno, bool calibrate )
+{
+    ifstream ifs ( filename.c_str(), ios::in );
+
+    if ( ! ifs.good() ) {
+	fprintf (stderr, "Unable to read file %s\n", filename.c_str() );
+	exit(-1);
+    }
+
+    // refactor-nice.pl: check this substitution
+    // old: string id;
+    std::string id;
+    double confidence;
+    double xi, yi, xa, ya;
+    double minconfidence = numeric_limits<double>::max();
+    double maxconfidence = - numeric_limits<double>::max();
+    long objects_count = 0;
+
+    vector<SingleLocalizationResult *> slrresults;
+
+    while (!ifs.eof())
+    {
+	if ( ! (ifs >> id) ) break;
+	ifs >> confidence;
+	ifs >> xi;
+	ifs >> yi;
+	ifs >> xa;
+	ifs >> ya;
+
+	if ( confidence < minconfidence ) 
+	    minconfidence = confidence;
+	if ( confidence > maxconfidence )
+	    maxconfidence = confidence;
+
+	map<string, LocalizationResult *>::iterator j = results.find(id);
+	LocalizationResult *l;
+	if ( j == results.end() )
+	{
+	    l = new LocalizationResult( ); // FIXME
+	    results.insert ( pair<string, LocalizationResult *> ( id, l ) );
+	} else {
+	    l = j->second;
+	}
+
+	SparseVector scores;
+	scores.insert ( pair<int, double> ( classno, confidence ) );
+	scores.insert ( pair<int, double> ( backgroundClassno, 1.0 - confidence ) );
+	SingleLocalizationResult *slr = new SingleLocalizationResult ( 
+	    new ClassificationResult( classno, scores ), (int)xi, (int)yi, (int)xa, (int)ya );
+
+	if ( calibrate )
+	    slrresults.push_back ( slr );
+
+	l->push_back ( slr );
+
+	objects_count++;
+    }
+    ifs.close();
+    fprintf (stderr, "max %f min %f\n", maxconfidence, minconfidence );
+
+    if ( calibrate )
+    {
+	if ( fabs(maxconfidence-minconfidence) < 1e-10 ) return;
+	for ( vector<SingleLocalizationResult *>::iterator i = slrresults.begin();
+		    i != slrresults.end(); i++ )
+	{
+	    SingleLocalizationResult *slr = *i;
+	    FullVector & scores = slr->r->scores;
+	    double s = scores.get ( classno );
+	    s =  (s-minconfidence)/(maxconfidence-minconfidence);
+	    s = 0.1 + 0.9*s;
+	    scores.reinit ( (backgroundClassno > classno) ? backgroundClassno + 1 : classno + 1 );	
+	    scores[classno] = s;
+	    scores[classno] = 1.0 - s;
+	}
+    }
+
+    fprintf (stderr, "PascalResults::read(%s) objects count %ld\n", filename.c_str(), objects_count );
+}
+

+ 46 - 0
cbaselib/PascalResults.h

@@ -0,0 +1,46 @@
+/** 
+* @file PascalResults.h
+* @brief read and write pascal style results
+* @author Erik Rodner
+* @date 09/09/2008
+
+*/
+#ifndef PASCALRESULTSINCLUDE
+#define PASCALRESULTSINCLUDE
+
+#include <map>
+#include <string>
+#include "LocalizationResult.h"
+#include "ClassNames.h"
+  
+
+namespace OBJREC {
+
+/** read and write pascal style results */
+class PascalResults
+{
+
+    protected:
+
+    public:
+    
+	static void read ( 
+	    std::map<std::string, LocalizationResult *> & results, 
+	    std::string filename,
+	    int classno = 1,
+	    int backgroundClassno = 0,
+	    bool calibrate = false);
+
+	static void write ( char *templatefn, 
+			    const std::string & imgfn,
+			    const LocalizationResult & l,
+			    const ClassNames & classNames );
+
+
+
+};
+
+
+} // namespace
+
+#endif

+ 102 - 0
cbaselib/Polygon.cpp

@@ -0,0 +1,102 @@
+/*!
+ * \file Polygon.cpp
+ * \brief
+ * \author Gapchich Vladislav
+ * \date 23/10/11
+ */
+
+#include "vislearning/cbaselib/Polygon.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+//! A constructor
+Polygon::Polygon()
+{
+	points_.clear();
+	id_ = -1;
+}
+
+// A copy-constructor
+Polygon::Polygon(const Polygon &copy)
+{
+	points_ = PointsList(*(copy.points()));
+	id_ = copy.id();
+}
+
+//! A desctructor
+Polygon::~Polygon()
+{
+	
+}
+
+//! appends aPoint coordinate to the end of the point list 
+void 
+Polygon::push(const CoordT< int > &aPoint)
+{
+	if (aPoint.x < 0 || aPoint.y < 0) {
+		return;
+		/* NOTREACHED */
+	}
+	
+	points_.push_back(aPoint);
+}
+
+//! overloaded
+/*!
+ * \see push(const CoordT< int > &aPoint)
+ */
+void
+Polygon::push(const int &x, const int &y)
+{
+	if (x < 0 || y < 0) {
+		return;
+		/* NOTREACHED */
+	}
+
+	CoordT< int > point;
+	point.x = x;
+	point.y = y;
+	points_.push_back(point);
+}
+
+//! Sets a category ID(label ID) for the polygon
+/*!
+ * /param[in] anID should not be less than zero 
+ */
+void 
+Polygon::setID(const int &anID)
+{
+	if (anID < 0) {
+		return;
+		/* NOTREACHED */
+	}
+}
+
+//! returns a constant pointer to the list of polygon points(coordinates)
+const PointsList * 
+Polygon::points() const
+{
+	return &points_;	
+}
+
+//! deletes last added point of the polygon and returns it
+CoordT< int > 
+Polygon::pop()
+{
+	CoordT< int > ret = points_.back();
+	points_.pop_back();
+	return ret;
+}
+
+//! returns a category ID of the polygon
+int 
+Polygon::id() const
+{
+	return id_;
+}
+	
+/*
+ * 
+ */

+ 47 - 0
cbaselib/Polygon.h

@@ -0,0 +1,47 @@
+/*!
+ * \file Polygon.h
+ * \brief
+ * \author Gapchich Vladislav
+ * \date 23/10/11
+ */
+
+#ifndef __POLYGON_H__
+#define __POLYGON_H__
+
+#include "core/image/CoordT.h"
+#include <list>
+
+using namespace NICE;
+
+typedef std::list< CoordT< int > > PointsList;
+
+namespace OBJREC {
+
+//! \brief Contains category ID and point list of the polygon
+class Polygon
+{
+public:
+	Polygon();
+	Polygon(const Polygon &copy);
+	~Polygon();
+	
+	void push(const CoordT< int > &aPoint);
+	void push(const int &x, const int &y);
+	void setID(const int &anID);
+	
+	const PointsList * points() const;
+	CoordT< int > pop();
+	int id() const;
+	
+private:
+	PointsList points_;
+	int id_;
+};
+
+} //namespace
+
+#endif /* __POLYGON_H__ */
+
+/*
+ * 
+ */

+ 65 - 0
cbaselib/VectorFeature.cpp

@@ -0,0 +1,65 @@
+#include <vislearning/nice.h>
+
+#include <iostream>
+
+#include "VectorFeature.h"
+#include "vislearning/cbaselib/FeaturePool.h"
+
+using namespace OBJREC;
+
+using namespace std;
+
+using namespace NICE;
+
+/** simple destructor */
+VectorFeature::~VectorFeature()
+{
+}
+
+double VectorFeature::val( const Example *example ) const
+{
+    return (*(example->vec))[feature_index];
+}
+
+void VectorFeature::explode ( FeaturePool & featurePool, bool variableWindow ) const
+{
+    for ( int i = 0 ; i < dimension ; i++ )
+    {
+		VectorFeature *f = new VectorFeature ( dimension );
+		f->feature_index = i;
+		featurePool.addFeature(f, 1.0 / dimension);
+    }
+}
+
+Feature *VectorFeature::clone() const
+{
+    VectorFeature *f = new VectorFeature( dimension );
+    f->feature_index = feature_index;
+    return f;
+}
+
+Feature *VectorFeature::generateFirstParameter () const
+{
+    return clone();
+}
+
+void VectorFeature::restore (istream & is, int format)
+{
+    is >> feature_index;
+}
+
+void VectorFeature::store (ostream & os, int format) const
+{
+    os << "VECTORFEATURE "
+       << feature_index;
+}
+
+void VectorFeature::clear ()
+{
+}
+
+void VectorFeature::getStump ( int & _feature_index, int & _dimension ) const
+{
+    _feature_index = feature_index;
+    _dimension = dimension;
+}

+ 50 - 0
cbaselib/VectorFeature.h

@@ -0,0 +1,50 @@
+/** 
+* @file VectorFeature.h
+* @brief feature class to use in Examples stored features
+* @author Erik Rodner
+* @date 05/07/2008
+
+*/
+#ifndef VectorFeatureINCLUDE
+#define VectorFeatureINCLUDE
+
+#include "core/basics/Config.h"
+#include "vislearning/cbaselib/Feature.h"
+
+
+namespace OBJREC {
+
+/** feature class to use in Examples stored features */
+class VectorFeature : public Feature
+{
+
+    protected:
+	int dimension;
+	
+
+    public:
+	int feature_index;
+  
+	/** internally used by VectorFeature::explode */
+	VectorFeature ( int _dimension, int _feature_index = 0 ) { dimension = _dimension; feature_index = _feature_index; };
+      
+	/** simple destructor */
+	virtual ~VectorFeature();
+     
+	double val( const Example *example ) const;
+	void explode ( FeaturePool & featurePool, bool variableWindow = true ) const;
+	Feature *clone() const;
+	Feature *generateFirstParameter () const;
+
+	void restore (std::istream & is, int format = 0);
+	void store (std::ostream & os, int format = 0) const;
+	void clear ();
+
+	void getStump ( int & feature_index, int & dimension ) const;
+
+};
+
+
+} // namespace
+
+#endif

+ 35 - 0
cbaselib/VectorTransform.h

@@ -0,0 +1,35 @@
+/** 
+* @file LabeledSet.h
+* @brief Transformation of vectors
+* @author MiKe
+* @date 20.01.2010
+
+*/
+#ifndef VECTORTRANSFORMINCLUDE
+#define VECTORTRANSFORMINCLUDE
+
+#include <vislearning/nice_nonvis.h>
+#include "core/vector/VVector.h"
+#include <vector>
+
+/** VIRTUAL CLASS FOR TRANSFORMATION OF VECTORS USING EITHER NO PARAMETERS OF A VECTOR OF VECTORS OF PARAMETERS */
+///Examples for implementations can be found in BasicVectorTransformations.cpp
+
+namespace OBJREC {
+   class VectorTransform{
+
+	public:
+		VectorTransform(){};
+		~VectorTransform(){};
+		///Transformation using no parameter
+		virtual NICE::Vector transform( const NICE::Vector& vec) = 0;
+		///Transformation using potentially many parameters
+		virtual NICE::Vector transform( const NICE::Vector& vec, const std::vector<NICE::Vector>& params) = 0;
+		
+    };
+
+
+
+} // namespace
+
+#endif

+ 6 - 0
cbaselib/libdepend.inc

@@ -0,0 +1,6 @@
+$(call PKG_DEPEND_INT,vislearning/baselib)
+$(call PKG_DEPEND_INT,vislearning/image)
+$(call PKG_DEPEND_INT,vislearning/math)
+$(call PKG_DEPEND_INT,core/image)
+$(call PKG_DEPEND_EXT,QT4)
+$(call PKG_DEPEND_EXT,QT4_XML)

+ 33 - 0
cbaselib/progs/ImageInfoTester.cpp

@@ -0,0 +1,33 @@
+#include "vislearning/cbaselib/ImageInfo.h"
+#include <iostream>
+#include <string>
+#include <list>
+
+using namespace std;
+using namespace OBJREC;
+
+int main (int argc, char **argv)
+{
+
+	if (1 == argc)
+		return 1;
+
+	string path;
+	path = string(argv[1]);
+
+	ImageInfo info;
+	info.loadImageInfo(path);
+
+	list< CategoryInfo >::const_iterator label;
+	label = info.labels()->begin();
+	label++;
+	label++;
+	cout << info.imagePath() << "\n";
+	cout << (*label).id() << "\n";
+	cout << (*label).color() << "\n";
+
+	cout << "10, 10 " << info.labeledImage().getPixel(10,10) << "\n";
+	cout << "140, 40 " << info.labeledImage().getPixel(140,40) << "\n";
+
+	return 0;
+}

+ 88 - 0
cbaselib/progs/Makefile.inc

@@ -0,0 +1,88 @@
+# 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))))
+$(eval $(call PKG_DEPEND_INT,$(PARENTDIR)))
+
+# ---------------------------
+# - 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.
+
+BINARIES:=$(patsubst %.o,$(BINDIR)%,$(filter-out moc_%,$(notdir $(OBJS))))
+ALL_BINARIES+=$(BINARIES)
+
+# ---------------------
+# - 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@')))
+-include $(OBJS:%.o=%.bd)
+
+# -------------------
+# - 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))
+

+ 155 - 0
cbaselib/progs/calcCurves.cpp

@@ -0,0 +1,155 @@
+/** 
+* @file analyseLocalization.cpp
+* @brief print recall/precision curves etc
+* @author Erik Rodner
+* @date 09/01/2008
+
+*/
+#include <vislearning/nice_nonvis.h>
+
+#include <core/basics/Config.h>
+#include <vislearning/baselib/Gnuplot.h>
+#include <core/basics/StringTools.h>
+#include <vislearning/cbaselib/LocalizationAnalysis.h>
+
+using namespace OBJREC;
+
+using namespace NICE;
+using namespace std;
+
+void readResults ( const string & resultsfn, vector<pair<double, int> > & results )
+{
+	ifstream ifs ( resultsfn.c_str(), ios::in );
+
+	if ( !ifs.good() ) 
+		fthrow(IOException, "Unable to open " << resultsfn << "." );
+
+	while ( !ifs.eof() ) 
+	{
+		char buf [1024];
+		ifs.getline( buf, 1024 );
+		if ( !ifs.good() ) break;
+		
+		Vector entry;
+		StringTools::splitVector ( string(buf), ',', entry );
+
+		if ( entry.size() != 4 )
+			fthrow(IOException, "Parse error in " << resultsfn << "." );
+
+		results.push_back ( pair<double, int> ( entry[2], (int)entry[1] ) );
+	}
+
+	ifs.close();
+}
+
+/** 
+    print recall/precision curves etc 
+*/
+int main (int argc, char **argv)
+{   
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+
+	Config conf ( argc, argv );
+
+	string resultssetting = conf.gS("main", "results", "results.txt" );
+	int graphtype = conf.gI("main", "graphtype", 0 );
+	string outfn = conf.gS("main", "out", "");
+	bool displayGraph = conf.gB("main", "display", false );
+	bool plainMode = conf.gB("main", "plain", false );
+
+	vector<string> submatches;
+	vector<string> resultsfiles;
+	if ( StringTools::regexMatch ( resultssetting, "^list:(.+)", submatches ) )
+	{
+		if ( !plainMode ) 
+			cerr << "reading file list" << endl;
+		string listfn = submatches[1];
+		ifstream ifs ( listfn.c_str(), ios::in );
+		if ( ifs.bad() )
+			fthrow(IOException, "Unable to open " << listfn << "." );
+		char buf[1024];
+		while ( !ifs.eof() )
+		{
+			ifs.getline(buf, 1024);
+			if ( strlen(buf) >= 1 ) 
+				resultsfiles.push_back ( StringTools::chomp(string(buf)) );
+		}
+		ifs.close();
+	} else {
+		StringTools::split ( resultssetting, ',', resultsfiles );
+	}
+	
+	for ( vector<string>::const_iterator i = resultsfiles.begin(); 
+		i != resultsfiles.end(); i++ )
+	{
+		vector<pair<double, int> > results;
+		string resultsfn = *i;
+
+		if ( !plainMode )
+			fprintf (stderr, "file: %s\n", resultsfn.c_str() );
+		readResults ( resultsfn, results );
+		if ( !plainMode ) 
+			fprintf (stderr, "results.size() = %d\n", (int)results.size() );
+	  
+		int count_positives = 0;
+		for ( vector<pair<double, int> >::const_iterator i = results.begin();
+			i != results.end(); i++ )
+			if ( i->second == 1 ) count_positives++;
+		
+		vector<double> thresholds;
+		vector<double> x;
+		vector<double> y;
+
+		LocalizationAnalysis la;
+		double areaMeasure = 0.0;
+		if ( (graphtype == 0) || (graphtype == 2) )
+		{
+			la.calcRecallPrecisionCurve ( results, count_positives, thresholds, x, y );
+			fprintf (stderr, "average precision (11-point): %f\n", la.calcAveragePrecision( x, y ) );
+			areaMeasure = la.calcAveragePrecisionPrecise( x, y );
+			if ( !plainMode ) 
+				fprintf (stderr, "average precision (precise): %f\n", areaMeasure );
+		} else {
+			la.calcROCCurve ( results, count_positives, results.size() - count_positives, thresholds, x, y );
+			areaMeasure = la.calcAreaUnderROC( x, y );
+			if ( !plainMode )
+				fprintf (stderr, "area under the ROC curve: %f\n", areaMeasure );
+		}
+		cerr << resultsfn << " " << areaMeasure << endl;
+
+
+		if ( displayGraph ) {
+			Gnuplot gp;
+			gp.set_xrange ( 0, 1 );
+			gp.set_yrange ( 0, 1 );
+			gp.set_style ( "lines" );
+			if ( graphtype == 0 )
+				gp.plot_xy ( x, y, "Recall/Precision");
+			else if ( graphtype == 2 ) {
+				for ( uint i = 0 ; i < x.size() ; i++ )
+				{
+					double recall = x[i];
+					x[i] = 1.0 - y[i];
+					y[i] = recall;
+				}
+				gp.plot_xy ( x, y, "1-Precision/Recall");
+			} else
+				gp.plot_xy ( x, y, "TP/FP (ROC)");
+
+			getchar();
+		}
+
+		if ( outfn.size() > 0 ) {
+			ofstream ofs ( outfn.c_str(), ios::out );
+			if ( !ofs.good() )
+				fthrow(IOException, "Unable to write graph results to " << outfn << "." );
+
+			for ( unsigned int i = 0 ; i < x.size(); i++ )
+				ofs << x[i] << " " << y[i] << " " << thresholds[i] << endl;
+			
+			ofs.close();
+		}
+	}
+    
+    return 0;
+}

+ 333 - 0
cbaselib/progs/createNormTrainingSet.cpp

@@ -0,0 +1,333 @@
+/** 
+* @file calcNormTrainingSet.cpp
+* @brief save normalized object images
+* @author Erik Rodner
+* @date 07/21/2008
+
+*/
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+
+#include <core/image/Convert.h>
+
+#include <sys/errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <core/basics/Config.h>
+#include <vislearning/baselib/cmdline.h>
+#include <vislearning/baselib/Preprocess.h>
+
+#include <vislearning/cbaselib/MultiDataset.h>
+
+#include <vislearning/baselib/ProgressBar.h>
+#include <vislearning/baselib/Globals.h>
+
+using namespace OBJREC;
+ 
+
+
+
+using namespace NICE;
+using namespace std;
+
+
+/** 
+    
+    save normalized object images 
+    
+*/
+int main (int argc, char **argv)
+{   
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+
+    char configfile [300];
+    char objectclass_c [1024];
+    char setname_c [1024];
+    bool scaleToAVG = false;
+
+    struct CmdLineOption options[] = {
+	{"config", "use config file", NULL, "%s", configfile},
+	{"ds", "use data set", "train", "%s", setname_c},
+	{"class", "create pictures of", "", "%s", objectclass_c},
+	{"scale", "scale pictures to average sizes", NULL, NULL, &scaleToAVG},
+	{NULL, NULL, NULL, NULL, NULL} 
+    };
+    int ret;
+    char *more_options[argc];
+    ret = parse_arguments( argc, (const char**)argv, options, more_options);
+    fprintf (stderr, "data set name: %s\n", setname_c );
+
+    if ( ret != 0 )
+    {
+	if ( ret != 1 ) fprintf (stderr, "Error parsing command line !\n");
+	exit (-1);
+    }
+
+    Config conf ( configfile );
+    Preprocess::Init ( &conf );
+    
+    MultiDataset md ( &conf );
+
+    // refactor-nice.pl: check this substitution
+    // old: string setname ( setname_c );
+    std::string setname ( setname_c );
+    const LabeledSet & ls = *(md[setname]);
+
+    map<int, double> maxwidth;
+    map<int, double> maxheight;
+    map<int, double> minwidth;
+    map<int, double> minheight;
+    map<int, double> avgheight;
+    map<int, double> avgwidth;
+    map<int, int> count;
+
+    const ClassNames & classNames = md.getClassNames( setname );
+    int objectclassno;
+    
+    // refactor-nice.pl: check this substitution
+    // old: string objectclass ( objectclass_c );
+    std::string objectclass ( objectclass_c );
+    if ( objectclass.size() > 0 ) 
+    {
+	cerr << "Object class " << objectclass << endl;
+
+	objectclassno = classNames.classno(objectclass);
+	if ( objectclassno < 0 ) {
+	    fprintf (stderr, "Unknown object class %s\n", objectclass_c );
+	    exit(-1);
+	}
+    } else {
+	objectclassno = -1;
+    }
+
+    ProgressBar pb ("Statistics");
+
+    pb.show();
+
+    LOOP_ALL_S(ls)
+    {
+	EACH_INFO(classno,info);
+	pb.update ( ls.count() );
+    
+	fprintf (stderr, "Filename %s\n", info.img().c_str());
+	if ( ! info.hasLocalizationInfo() ) {
+	    fprintf (stderr, "No localization information available !!\n");
+	    exit(-1);
+	}
+	const LocalizationResult *l = info.localization();
+
+	if ( l->size() <= 0 ) {
+	    fprintf (stderr, "No objects found in this image !!\n");
+	    exit(-1);
+	}
+	fprintf (stderr, "Analyzing bounding boxes\n");
+	for ( LocalizationResult::const_iterator i = l->begin();
+	      i != l->end(); i++ )
+	{
+	    SingleLocalizationResult *slr = *i;
+	    fprintf (stderr, "checking classno\n");
+	    assert ( slr->r != NULL );
+	    int c = slr->r->classno;
+	    if ( (objectclassno < 0 ) || (c == objectclassno) ) 
+	    {
+		fprintf (stderr, "getting bounding box\n");
+		int xi, xa, yi, ya;
+		slr->getBoundingBox ( xi, yi, xa, ya );
+
+		if ( !finite(xi) || !finite(yi) || !finite(xa) || !finite(ya) )
+		{
+		    fprintf (stderr, "illegal bounding box information: %s\n", info.img().c_str() );
+		    exit(-1);
+		}
+
+		double width = xa - xi;
+		double height = ya - yi;
+
+		if ( width <= 0 ) {
+		    fprintf (stderr, "negative width: %s !\n", info.img().c_str());
+		    exit(-1);
+		}
+		if ( height <= 0 ) {
+		    fprintf (stderr, "negative height %s !\n", info.img().c_str());
+		    exit(-1);
+		}
+
+		if ( (minwidth.find(c) == minwidth.end()) || (minwidth[c] > width ) )
+		    minwidth[c] = width;
+		if ( (maxwidth.find(c) == maxwidth.end()) || (maxwidth[c] > width ) )
+		    maxwidth[c] = width;
+
+		if ( (minheight.find(c) == minheight.end()) || (minheight[c] > height ) )
+		    minheight[c] = height;
+		if ( (maxheight.find(c) == maxheight.end()) || (maxheight[c] > height ) )
+		    maxheight[c] = height;
+
+		if ( avgheight.find(c) == avgheight.end() )
+		    avgheight[c] = height;
+		else
+		    avgheight[c] += height;
+
+		if ( avgwidth.find(c) == avgwidth.end() )
+		    avgwidth[c] = width;
+		else
+		    avgwidth[c] += width;
+
+		if ( count.find(c) == count.end() )
+		    count[c] = 0;
+		else
+		    count[c] ++;
+
+
+	    }
+	    fprintf (stderr, "ready for the next file\n");
+	}
+    }
+
+    if ( (objectclassno >= 0) && (count.find(objectclassno) == count.end() ) )
+    {
+	fprintf (stderr, "NO examples of class %s found !!\n", objectclass.c_str());
+	exit(-1);
+    }
+
+	
+    fprintf (stderr, "-- Object Statistics --\n");
+    for ( map<int, int>::iterator i = count.begin();
+				 i != count.end();
+				 i++ )
+    {
+	int c = i->first;
+	int count = i->second;
+
+	avgheight[c] /= count;
+	avgwidth[c] /= count;
+
+	// refactor-nice.pl: check this substitution
+	// old: string dir = classNames.text(c);
+	std::string dir = classNames.text(c);
+
+	int retcode = mkdir ( dir.c_str(), 0700 );
+	if ( (retcode < 0) && (retcode != EEXIST ) ) {
+	    fprintf (stderr, "Failed to create directory: %s\n", dir.c_str() );
+	    exit(-1);
+	}
+
+	fprintf (stderr, "[%s]\n", classNames.text(c).c_str() ); 
+	fprintf (stderr, "width: min %f max %f avg %f\n", minwidth[c], maxwidth[c], avgwidth[c] );
+	fprintf (stderr, "height: min %f max %f avg %f\n", minheight[c], maxheight[c], avgheight[c] );
+    }
+
+
+    pb.reset("Crop");
+
+
+    double borderx = conf.gD("crop", "borderx", 0.2);
+    double bordery = conf.gD("crop", "bordery", 0.2);
+    
+    int counter = 0;
+    
+    LOOP_ALL_S(ls)
+    {
+	EACH_INFO(classno,info);
+	pb.update ( ls.count() );
+	// refactor-nice.pl: check this substitution
+	// old: string filename = info.img();
+	std::string filename = info.img();
+
+	if ( ! info.hasLocalizationInfo() ) {
+	    fprintf (stderr, "createNormTrainingSet: file %s has no localization information\n", 
+		filename.c_str() );
+	    exit(-1);
+	}
+
+	// refactor-nice.pl: check this substitution
+	// old: ImageRGB img = Preprocess::ReadImgAdvRGB ( filename );
+	NICE::ColorImage img = Preprocess::ReadImgAdvRGB ( filename );
+	Globals::setCurrentImgFN ( filename );
+
+	const LocalizationResult *l = info.localization();
+    
+    	for ( LocalizationResult::const_iterator i = l->begin();
+	      i != l->end(); i++ )
+	{
+	    SingleLocalizationResult *slr = *i;
+	    int c = slr->r->classno;
+	    if ( (objectclassno < 0) || (c == objectclassno) ) 
+	    {
+		int xi, xa, yi, ya;
+		slr->getBoundingBox ( xi, yi, xa, ya );
+		double w = xa - xi;
+		double h = ya - yi;
+
+		if ( (w < 1) || (h < 1) ) {
+		    fprintf (stderr, "Illegal width or height: %s\n", filename.c_str() );
+		    exit(-1);
+		}
+
+
+		double dstwidth;
+		double dstheight;
+
+		if ( scaleToAVG )
+		{
+		    double normwidth  = avgwidth[c]*(1.0+borderx);
+		    double normheight = avgheight[c]*(1.0+bordery);
+
+		    dstwidth = normwidth;
+		    dstheight = normheight;
+		} else {
+		    dstwidth = w;
+		    dstheight = h;
+		}
+
+
+		double bxi = xi - borderx / 2.0;
+		double bxa = xa + borderx / 2.0;
+		double byi = yi - bordery / 2.0;
+		double bya = ya + bordery / 2.0;
+
+		if ( bxi < 0.0 ) bxi = 0.0;
+		if ( byi < 0.0 ) byi = 0.0;
+		// refactor-nice.pl: check this substitution
+		// old: if ( bxa > img.xsize() - 1 ) bxa = img.xsize() - 1;
+		if ( bxa > img.width() - 1 ) bxa = img.width() - 1;
+		// refactor-nice.pl: check this substitution
+		// old: if ( bya > img.ysize() - 1 ) bya = img.ysize() - 1;
+		if ( bya > img.height() - 1 ) bya = img.height() - 1;
+
+
+	        RectT<int> rect ( bxi, byi,
+                      bxa - bxi + 1, bya - byi + 1 );
+                NICE::ColorImage *subImage = img.createSubImage ( rect );
+
+		NICE::ColorImage dst ( (int)round(dstwidth), (int)round(dstheight) ); 
+		scale ( *subImage, &dst );
+#ifndef NOVISUAL
+		showImage(dst);
+#endif
+		std::string dir = classNames.text(c);
+
+		char imgfilename_s [1024];
+		sprintf ( imgfilename_s, "%s/image_%06d.jpg", dir.c_str(), counter );
+
+		// refactor-nice.pl: check this substitution
+		// old: fprintf (stderr, "%s: %d x %d\n", imgfilename_s, dst.xsize(), dst.ysize() );
+		fprintf (stderr, "%s: %d x %d\n", imgfilename_s, dst.width(), dst.height() );
+		ImageFile imgf ( imgfilename_s );
+		try {
+		    imgf.writer ( &dst );
+		} catch ( Exception ) {
+		    fprintf (stderr, "Failed to write filename %s\n", imgfilename_s );
+		    exit(-1);
+		}
+
+		counter++;
+	    }
+	}
+    }
+   
+    return 0;
+}

+ 143 - 0
cbaselib/progs/splitLabeledSetVector.cpp

@@ -0,0 +1,143 @@
+/** 
+ * @file splitLabeledSetVector.cpp
+ * @brief split train.vec/test.vec files
+ * @author Erik Rodner
+ * @date 03/23/2010
+ */
+#include "core/basics/Config.h"
+#include "core/basics/StringTools.h"
+#include "vislearning/cbaselib/LabeledSet.h"
+#include "vislearning/cbaselib/LabeledSetSelection.h"
+
+#include "core/basics/numerictools.h"
+
+using namespace std;
+using namespace OBJREC;
+using namespace NICE;
+
+//#stupid test for git
+
+void normalizeLabeledSetVector(const LabeledSetVector &teachSet,
+		LabeledSetVector &transformedSet)
+{
+	transformedSet.clear();
+	Vector vector_max, vector_min, vector_span;
+	int maxClassNo = teachSet.getMaxClassno();
+	int n = teachSet.count();
+	int d = teachSet.dimension();
+	vector_max.resize(d);
+	vector_min.resize(d);
+	vector_span.resize(d);
+	//get input data
+	uint featurecount = 0;
+	LOOP_ALL(teachSet)
+		{
+			EACH(classno,x);
+			for (uint k = 0; k < x.size(); ++k)
+			{
+				double value = x[k];
+				if (featurecount == 0)
+				{
+					vector_max[k] = value;
+					vector_min[k] = value;
+				}
+				else
+				{
+					if (value > vector_max[k])
+					{
+						vector_max[k] = value;
+					}
+					if (value < vector_min[k])
+					{
+						vector_min[k] = value;
+					}
+				}
+
+			}
+
+			++featurecount;
+		}
+	vector_span = vector_max - vector_min;
+
+	//save transformed Vectors
+	LOOP_ALL(teachSet)
+		{
+			EACH(classno,x);
+			NICE::Vector transformed_vector(x.size());
+			for (uint k = 0; k < vector_min.size(); ++k)
+			{
+				if (vector_span[k] > 1e-10)
+				{
+					transformed_vector[k] = (x[k] - vector_min[k])
+							/ vector_span[k];
+				}
+				else
+				{
+					transformed_vector[k] = 1.0;
+				}
+			}
+			transformedSet.add(classno, transformed_vector);
+		}
+
+}
+
+/** 
+
+ split train.vec/test.vec files
+
+ */
+int main(int argc, char **argv)
+{
+	std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+
+	Config conf(argc, argv);
+
+	int format = conf.gI("main", "format", 2);
+	LabeledSetVector all;
+
+	string setfn = conf.gS("main", "set");
+	all.read(setfn, format);
+
+	bool normalize = conf.gB("main", "normalize", false);
+	if (normalize)
+	{
+		LabeledSetVector all_tmp;
+		normalizeLabeledSetVector(all, all_tmp);
+		all = all_tmp;
+	}
+
+	bool random = conf.gB("main", "random", false);
+	if (random)
+		initRand();
+
+	map<int, int> fixedPositiveExamples;
+	string exampleList = conf.gS("main", "examples");
+
+	vector<string> list;
+	StringTools::split(exampleList, ';', list);
+	for (vector<string>::const_iterator i = list.begin(); i != list.end(); i++)
+	{
+		string e = *i;
+		vector<string> f;
+		StringTools::split(e, ':', f);
+		if (f.size() != 2)
+			fthrow(Exception, "Specify -examples classno:number;classno:number;...\n");
+		int classno;
+		int examples;
+		StringTools::convert<int>(f[0], classno);
+		StringTools::convert<int>(f[1], examples);
+		fixedPositiveExamples.insert(pair<int, int> (classno, examples));
+	}
+
+	LabeledSetVector train;
+	LabeledSetVector test;
+	LabeledSetSelection<LabeledSetVector>::selectRandom(fixedPositiveExamples,
+			all, train, test);
+
+	string trainfn = conf.gS("main", "train", "train.vec");
+	string testfn = conf.gS("main", "test", "test.vec");
+	train.save(trainfn, format);
+	test.save(testfn, format);
+
+	return 0;
+}

+ 52 - 0
cbaselib/progs/statisticsLabeledSetVector.cpp

@@ -0,0 +1,52 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <vislearning/cbaselib/LabeledSet.h>
+
+using namespace std;
+using namespace OBJREC;
+
+int main ( int argc, char **argv )
+{
+
+    Config conf ( argc, argv );
+
+    string setfn = conf.gS("main", "set", "train.vec" );
+    int format = conf.gI("main", "format", 2 );
+
+    LabeledSetVector set;
+
+    set.read ( setfn, format );
+
+    set.printInformation();
+
+    double maximum_value = - numeric_limits<double>::max();
+    double minimum_value = numeric_limits<double>::max();
+    double maximum_norm = 0;
+    double minimum_norm = numeric_limits<double>::max();
+
+    LOOP_ALL(set)
+    {
+	EACH(classno, x);
+
+	if ( x.Max() > maximum_value ) 
+	    maximum_value = x.Max();
+
+	if ( x.Min() < minimum_value ) 
+	    minimum_value = x.Min();
+
+	if ( x.normL2() > maximum_norm )
+	    maximum_norm = x.normL2();
+
+	if ( x.normL2() < minimum_norm )
+	    minimum_norm = x.normL2();
+
+    }
+
+    fprintf (stderr, "min value: %f\n", minimum_value );
+    fprintf (stderr, "max value: %f\n", maximum_value );
+    fprintf (stderr, "min L2-norm: %f\n", minimum_norm );
+    fprintf (stderr, "max L2-norm: %f\n", maximum_norm );
+    fprintf (stderr, "dimension: %d\n", set.dimension() );
+}

+ 244 - 0
cbaselib/progs/statisticsTrainingSet.cpp

@@ -0,0 +1,244 @@
+/** 
+* @file calcNormTrainingSet.cpp
+* @brief save normalized object images
+* @author Erik Rodner
+* @date 07/21/2008
+
+*/
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+
+#include <core/image/CrossT.h>
+
+#include <sys/errno.h>
+
+#include <core/basics/Config.h>
+#include <vislearning/baselib/cmdline.h>
+#include <vislearning/baselib/Preprocess.h>
+#include <core/vector/VVector.h>
+#include <vislearning/math/cluster/KMeans.h>
+
+#include <vislearning/cbaselib/MultiDataset.h>
+
+#include <vislearning/baselib/ProgressBar.h>
+#include <vislearning/baselib/Globals.h>
+
+using namespace OBJREC;
+
+
+
+// refactor-nice.pl: check this substitution
+// old: using namespace ice;
+using namespace NICE;
+using namespace std;
+
+
+/** 
+    
+    save normalized object images 
+    
+*/
+int main (int argc, char **argv)
+{   
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+
+    char configfile [300];
+    char objectclass_c [1024];
+    char setname_c [1024];
+
+    struct CmdLineOption options[] = {
+	{"config", "use config file", NULL, "%s", configfile},
+	{"ds", "use data set", "train", "%s", setname_c},
+	{NULL, NULL, NULL, NULL, NULL} 
+    };
+    int ret;
+    char *more_options[argc];
+    ret = parse_arguments( argc, (const char**)argv, options, more_options);
+    fprintf (stderr, "data set name: %s\n", setname_c );
+
+    if ( ret != 0 )
+    {
+	if ( ret != 1 ) fprintf (stderr, "Error parsing command line !\n");
+	exit (-1);
+    }
+
+    Config conf ( configfile );
+    Preprocess::Init ( &conf );
+    
+    MultiDataset md ( &conf );
+
+    // refactor-nice.pl: check this substitution
+    // old: string setname ( setname_c );
+    std::string setname ( setname_c );
+    const LabeledSet & ls = *(md[setname]);
+
+    map<int, double> maxwidth;
+    map<int, double> maxheight;
+    map<int, double> minwidth;
+    map<int, double> minheight;
+    map<int, double> avgheight;
+    map<int, double> avgwidth;
+    map<int, int> count;
+    map<int, VVector> objectpositions;
+
+    const ClassNames & classNames = md.getClassNames( setname );
+    
+    // refactor-nice.pl: check this substitution
+    // old: Image img = NewImg ( 1024, 1024, 255 );
+    NICE::Image img (1024, 1024);
+    // refactor-nice.pl: check this substitution
+    // old: ClearImg(img);
+    img.set(0);
+
+    ProgressBar pb ("Statistics");
+
+    pb.show();
+
+    LOOP_ALL_S(ls)
+    {
+	EACH_INFO(classno,info);
+	pb.update ( ls.count() );
+    
+	fprintf (stderr, "Filename %s\n", info.img().c_str());
+	if ( ! info.hasLocalizationInfo() ) {
+	    fprintf (stderr, "No localization information available !!\n");
+	    exit(-1);
+	}
+	const LocalizationResult *l = info.localization();
+
+	if ( l->size() <= 0 ) {
+	    fprintf (stderr, "No objects found in this image !!\n");
+	    exit(-1);
+	}
+	fprintf (stderr, "Analyzing bounding boxes\n");
+	for ( LocalizationResult::const_iterator i = l->begin();
+	      i != l->end(); i++ )
+	{
+	    SingleLocalizationResult *slr = *i;
+	    fprintf (stderr, "checking classno\n");
+	    assert ( slr->r != NULL );
+	    int c = slr->r->classno;
+		
+	    fprintf (stderr, "getting bounding box\n");
+	    int xi, xa, yi, ya;
+	    slr->getBoundingBox ( xi, yi, xa, ya );
+
+	    if ( !finite(xi) || !finite(yi) || !finite(xa) || !finite(ya) )
+	    {
+		fprintf (stderr, "illegal bounding box information: %s\n", info.img().c_str() );
+		exit(-1);
+	    }
+
+	    double width = xa - xi;
+	    double height = ya - yi;
+	
+	    if ( width <= 0 ) {
+		fprintf (stderr, "negative width: %s !\n", info.img().c_str());
+		exit(-1);
+	    }
+	    if ( height <= 0 ) {
+		fprintf (stderr, "negative height %s !\n", info.img().c_str());
+		exit(-1);
+	    }
+
+	    if ( objectpositions.find(c) == objectpositions.end() )
+		objectpositions[c] = VVector();
+
+	    // refactor-nice.pl: check this substitution
+	    // old: objectpositions[c].push_back ( Vector(width, height) );
+	    // REFACTOR-FIXME Unable to std::map this statement
+
+	    if ( (minwidth.find(c) == minwidth.end()) || (minwidth[c] > width ) )
+		minwidth[c] = width;
+	    if ( (maxwidth.find(c) == maxwidth.end()) || (maxwidth[c] < width ) )
+		maxwidth[c] = width;
+
+	    if ( (minheight.find(c) == minheight.end()) || (minheight[c] > height ) )
+		minheight[c] = height;
+	    if ( (maxheight.find(c) == maxheight.end()) || (maxheight[c] < height ) )
+		maxheight[c] = height;
+
+	    if ( avgheight.find(c) == avgheight.end() )
+		avgheight[c] = height;
+	    else
+		avgheight[c] += height;
+
+	    if ( avgwidth.find(c) == avgwidth.end() )
+		avgwidth[c] = width;
+	    else
+		avgwidth[c] += width;
+
+	    if ( count.find(c) == count.end() )
+		count[c] = 0;
+	    else
+		count[c] ++;
+	    
+	    fprintf (stderr, "ready for the next file\n");
+	}
+    }
+
+    fprintf (stderr, "-- Object Statistics --\n");
+    for ( map<int, int>::iterator i = count.begin();
+				 i != count.end();
+				 i++ )
+    {
+	int c = i->first;
+	int count = i->second;
+
+	avgheight[c] /= count;
+	avgwidth[c] /= count;
+
+	fprintf (stderr, "[%s]\n", classNames.text(c).c_str() ); 
+	fprintf (stderr, "width: min %f max %f avg %f\n", minwidth[c], maxwidth[c], avgwidth[c] );
+	fprintf (stderr, "height: min %f max %f avg %f\n", minheight[c], maxheight[c], avgheight[c] );
+
+	const VVector & pos = objectpositions[c];
+	KMeans kmeans (4);
+	VVector prototypes;
+	vector<double> weights;
+	vector<int> assignment;
+
+	kmeans.cluster ( pos, prototypes, weights, assignment );
+
+	// refactor-nice.pl: check this substitution
+	// old: Image img = NewImg ( (int)maxwidth[c]+5, (int)maxheight[c]+5, 255 );
+	NICE::Image img ((int)maxwidth[c]+5, (int)maxheight[c]+5);
+	// refactor-nice.pl: check this substitution
+	// old: ClearImg(img);
+	img.set(0);
+
+	for ( VVector::const_iterator j = pos.begin();
+		j != pos.end(); j++ )
+	{
+	    // refactor-nice.pl: check this substitution
+	    // old: const Vector & x = *j;
+	    const NICE::Vector & x = *j;
+	    Cross cross ( Coord((int)x[0], (int)x[1]), 4 );
+	    img.draw ( cross, 1 );
+	}
+
+	fprintf (stderr, "%s ", classNames.text(c).c_str() );
+	for ( VVector::const_iterator j = prototypes.begin();
+		j != prototypes.end(); j++ )
+	{
+	    // refactor-nice.pl: check this substitution
+	    // old: const Vector & x = *j;
+	    const NICE::Vector & x = *j;
+	    Cross cross ( Coord((int)x[0], (int)x[1]), 4 );
+	    img.draw ( cross, 2 );
+
+	    fprintf (stderr, "%dx%d ", (int)round(x[0]), (int)round(x[1]) );
+	}
+	fprintf (stderr, "\n");
+
+#ifndef NOVISUAL
+	NICE::showImageOverlay ( img, img );
+#endif
+
+    }
+
+    return 0;
+}

+ 79 - 0
cbaselib/progs/testCachedExample.cpp

@@ -0,0 +1,79 @@
+/** 
+* @file testCachedExample.cpp
+* @brief test cached example implementation
+* @author Erik Rodner
+* @date 09/12/2008
+
+*/
+
+#include <core/imagedisplay/ImageDisplay.h>
+#include <core/basics/Config.h>
+#include <vislearning/baselib/cmdline.h>
+#include <vislearning/image/GenericImageTools.h>
+
+#include <vislearning/cbaselib/CachedExample.h>
+
+using namespace OBJREC;
+
+using namespace NICE;
+using namespace std;
+
+
+int main (int argc, char **argv)
+{   
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+
+    char configfile [300];
+
+    struct CmdLineOption options[] = {
+	{"config", "use config file", NULL, "%s", configfile},
+	{NULL, NULL, NULL, NULL, NULL} 
+    };
+    int ret;
+    char *more_options[argc];
+    ret = parse_arguments( argc, (const char**)argv, options, more_options);
+
+    if ( ret != 0 )
+    {
+	if ( ret != 1 ) fprintf (stderr, "Error parsing command line !\n");
+	exit (-1);
+    }
+
+    Config conf ( configfile );
+    
+    int i = 0;
+    while ( more_options[i] != NULL )
+    {
+
+	std::string filename ( more_options[i] );
+	fprintf (stderr, "Filename: %s\n", filename.c_str() );
+	CachedExample ce ( filename );
+
+	NICE::MultiChannelImageT<int> & img = ce.getIChannel(CachedExample::I_COLOR);
+	NICE::MultiChannelImageT<double> & imgc = ce.getDChannel(CachedExample::D_INTEGRALCOLOR);
+
+	imgc.reInitFrom ( img, true );
+	for ( uint j = 0 ; j < img.numChannels; j++ )
+	    GenericImageTools::calcIntegralImage ( imgc.data[j], img.data[j], img.xsize, img.ysize );
+
+	Image visimg = imgc.getChannel(0);
+	showImage(visimg);
+
+	ce.dropPreCached();
+
+#ifndef NOVISUAL
+	getchar();
+#endif
+	
+	imgc = ce.getDChannel ( CachedExample::D_INTEGRALCOLOR );
+	
+	visimg = imgc.getChannel(0);
+	showImage(visimg);
+	
+
+	i++;
+    }
+    
+    
+    return 0;
+}

+ 81 - 0
cbaselib/progs/testLabeledSet.cpp

@@ -0,0 +1,81 @@
+/** 
+* @file testLabeledSet.cpp
+* @brief test multidataset
+* @author Erik Rodner
+* @date 03/03/2008
+
+*/
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+
+#include <core/basics/Config.h>
+#include <vislearning/baselib/cmdline.h>
+
+#include <vislearning/cbaselib/MultiDataset.h>
+
+using namespace OBJREC;
+
+
+
+// refactor-nice.pl: check this substitution
+// old: using namespace ice;
+using namespace NICE;
+using namespace std;
+
+
+/** 
+    
+    test multidataset 
+    
+*/
+int main (int argc, char **argv)
+{   
+    std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
+
+    char configfile [300];
+
+    struct CmdLineOption options[] = {
+	{"config", "use config file", NULL, "%s", configfile},
+	{NULL, NULL, NULL, NULL, NULL} 
+    };
+    int ret;
+    char *more_options[argc];
+    ret = parse_arguments( argc, (const char**)argv, options, more_options);
+
+    if ( ret != 0 )
+    {
+	if ( ret != 1 ) fprintf (stderr, "Error parsing command line !\n");
+	exit (-1);
+    }
+
+    Config conf ( configfile );
+    
+    
+    MultiDataset md ( &conf );
+
+    const LabeledSet *train = md["train"];
+    const LabeledSet *test = md["test"];
+    const ClassNames & cn = md.getClassNames ( "train" );
+    
+    
+    fprintf (stderr, "Training Dataset\n");
+    LOOP_ALL_S( *train )
+    {
+	EACH_S(classno, fn);
+	fprintf (stderr, "%s %s\n", cn.text(classno).c_str(), fn.c_str() );
+    }
+ 
+    fprintf (stderr, "Test Dataset\n");
+    LOOP_ALL_S( *test )
+    {
+	EACH_S(classno, fn);
+	fprintf (stderr, "%s %s\n", cn.text(classno).c_str(), fn.c_str() );
+    }
+   
+    
+    
+    return 0;
+}

+ 8 - 0
classifier/Makefile

@@ -0,0 +1,8 @@
+#TARGETS_FROM:=$(notdir $(patsubst %/,%,$(shell pwd)))/$(TARGETS_FROM)
+#$(info recursivly going up: $(TARGETS_FROM) ($(shell pwd)))
+
+all:
+
+%:
+	$(MAKE) TARGETS_FROM=$(notdir $(patsubst %/,%,$(shell pwd)))/$(TARGETS_FROM) -C .. $@
+

+ 103 - 0
classifier/Makefile.inc

@@ -0,0 +1,103 @@
+# LIBRARY-DIRECTORY-MAKEFILE
+# conventions:
+# - all subdirectories containing a "Makefile.inc" are considered sublibraries
+#   exception: "progs/" and "tests/" subdirectories!
+# - all ".C", ".cpp" and ".c" files in the current directory are linked to a
+#   library
+# - the library depends on all sublibraries 
+# - the library name is created with $(LIBNAME), i.e. it will be somehow
+#   related to the directory name and with the extension .a
+#   (e.g. lib1/sublib -> lib1_sublib.a)
+# - the library will be added to the default build list ALL_LIBRARIES
+
+# --------------------------------
+# - 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)
+ifeq "$(SUBDIR)" "./"
+SUBDIR:=
+endif
+
+# ------------------------
+# - 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
+#
+# you can specify libraries needed by the individual objects or by the whole
+# directory. the object specific additional libraries are only considered
+# when compiling the specific object files
+# TODO: update documentation...
+
+-include $(SUBDIR)libdepend.inc
+
+$(foreach d,$(filter-out %progs %tests,$(SUBDIRS_OF_$(SUBDIR))),$(eval $(call PKG_DEPEND_INT,$(d))))
+
+# ---------------------------
+# - 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.
+
+LIBRARY_BASENAME:=$(call LIBNAME,$(SUBDIR))
+ifneq "$(SUBDIR)" ""
+ALL_LIBRARIES+=$(LIBDIR)$(LIBRARY_BASENAME).$(LINK_FILE_EXTENSION)
+endif
+
+# ---------------------
+# - binary dependencies
+#
+# there is no way of determining the binary dependencies automatically, so we
+# follow conventions. the current library depends on all sublibraries.
+# all other dependencies have to be added manually by specifying, that the
+# current .pc file depends on some other .pc file. binaries depending on
+# libraries should exclusivelly use the .pc files as well.
+
+ifeq "$(SKIP_BUILD_$(OBJDIR))" "1"
+$(LIBDIR)$(LIBRARY_BASENAME).a:
+else
+$(LIBDIR)$(LIBRARY_BASENAME).a:$(OBJS) \
+	$(call PRINT_INTLIB_DEPS,$(PKGDIR)$(LIBRARY_BASENAME).a,.$(LINK_FILE_EXTENSION))
+endif
+
+$(PKGDIR)$(LIBRARY_BASENAME).pc: \
+	$(call PRINT_INTLIB_DEPS,$(PKGDIR)$(LIBRARY_BASENAME).pc,.pc)
+
+# -------------------
+# - 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
classifier/classifierbase/FeaturePoolClassifier.cpp

@@ -0,0 +1,84 @@
+/** 
+* @file FeaturePoolClassifier.cpp
+* @brief abstract interface for a classifier using feature selection
+* @author Erik Rodner
+* @date 04/21/2008
+
+*/
+
+#include <iostream>
+
+#include "vislearning/classifier/classifierbase/FeaturePoolClassifier.h"
+#include "vislearning/baselib/ICETools.h"
+#ifdef NOVISUAL
+#include <vislearning/nice_nonvis.h>
+#else
+#include <vislearning/nice.h>
+#endif
+
+using namespace OBJREC;
+
+using namespace std;
+// refactor-nice.pl: check this substitution
+// old: using namespace ice;
+using namespace NICE;
+
+FeaturePoolClassifier::FeaturePoolClassifier() : maxClassNo(-1)
+{
+}
+
+FeaturePoolClassifier::~FeaturePoolClassifier()
+{
+}
+
+// refactor-nice.pl: check this substitution
+// old: ClassificationResult FeaturePoolClassifier::classify ( const Image & img )
+ClassificationResult FeaturePoolClassifier::classify ( const NICE::Image & img )
+{
+    CachedExample ce ( img );
+    // refactor-nice.pl: check this substitution
+    // old: Example pce ( &ce, img->xsize/2, img->ysize/2 );
+    Example pce ( &ce, img.width()/2, img.height()/2 );
+    // refactor-nice.pl: check this substitution
+    // old: pce.width = img->xsize;
+    pce.width = img.width();
+    // refactor-nice.pl: check this substitution
+    // old: pce.height = img->ysize;
+    pce.height = img.height();
+
+    return classify ( pce );
+}
+    
+// refactor-nice.pl: check this substitution
+// old: ClassificationResult FeaturePoolClassifier::classifyRGB ( const ImageRGB & img )
+ClassificationResult FeaturePoolClassifier::classifyRGB ( const NICE::ColorImage & img )
+{
+    CachedExample ce ( img );
+    // refactor-nice.pl: check this substitution
+    // old: Example pce ( &ce, img.xsize()/2, img.ysize()/2 );
+    Example pce ( &ce, img.width()/2, img.height()/2 );
+    // refactor-nice.pl: check this substitution
+    // old: pce.width = img.xsize();
+    pce.width = img.width();
+    // refactor-nice.pl: check this substitution
+    // old: pce.height = img.ysize();
+    pce.height = img.height();
+
+    return classify ( pce );
+}
+	
+void FeaturePoolClassifier::setMaxClassNo( int classno )
+{
+    maxClassNo = classno;
+}
+
+int FeaturePoolClassifier::getMaxClassNo () const
+{
+    return maxClassNo;
+}
+
+void FeaturePoolClassifier::setComplexity ( int size )
+{
+    fprintf (stderr, "FeaturePoolClassifier::setComplexity: not yet implemented in subordinate class\n");
+    exit(-1);
+}

+ 59 - 0
classifier/classifierbase/FeaturePoolClassifier.h

@@ -0,0 +1,59 @@
+/** 
+* @file FeaturePoolClassifier.h
+* @brief abstract interface for a classifier using feature selection
+* @author Erik Rodner
+* @date 04/21/2008
+
+*/
+#ifndef FEATUREPOOLCLASSIFIERINCLUDE
+#define FEATUREPOOLCLASSIFIERINCLUDE
+
+#include "vislearning/cbaselib/FeaturePool.h"
+#include "vislearning/cbaselib/ClassificationResult.h"
+#include "vislearning/cbaselib/CachedExample.h"
+#include "vislearning/cbaselib/Example.h"
+
+#include "core/basics/Persistent.h"
+
+namespace OBJREC {
+
+/** abstract interface for a classifier using feature selection */
+class FeaturePoolClassifier : public NICE::Persistent
+{
+
+    public:
+	int maxClassNo;
+
+    public:
+  
+	/** simple constructor */
+	FeaturePoolClassifier( );
+   
+	/** simple destructor */
+	virtual ~FeaturePoolClassifier();
+    
+	/** more comfortable classification functions for whole images */
+	ClassificationResult classify ( const NICE::Image & img );
+	ClassificationResult classifyRGB ( const NICE::ColorImage & img );
+    
+	void setMaxClassNo ( int classno );       
+	int getMaxClassNo () const;  
+
+	/** classification */
+	virtual ClassificationResult classify ( Example & pe ) = 0;
+
+	/** training process */
+	virtual void train ( FeaturePool & fp, Examples & examples ) = 0;
+
+	/** clone this object */
+	virtual FeaturePoolClassifier *clone () const = 0;
+
+	/** set complexity for the next training process e.g. number of weak classifiers */
+	virtual void setComplexity ( int size );
+
+};
+
+
+} // namespace
+
+#endif

+ 103 - 0
classifier/classifierbase/KernelClassifier.cpp

@@ -0,0 +1,103 @@
+/** 
+* @file KernelClassifier.cpp
+* @brief classifier interface for kernel based methods
+* @author Erik Rodner
+* @date 12/02/2009
+
+*/
+#include <iostream>
+
+#include "KernelClassifier.h"
+
+using namespace std;
+using namespace NICE;
+using namespace OBJREC;
+
+#undef DEBUG
+
+KernelClassifier::KernelClassifier( const Config *_conf, Kernel *kernelFunction, int normalizationType ) : conf(*_conf)
+{
+	this->kernelFunction = kernelFunction;
+	this->normalizationType = normalizationType;
+}
+
+KernelClassifier::KernelClassifier ( const KernelClassifier & src ) : VecClassifier(), conf(src.conf)
+{
+	if ( src.kernelFunction != NULL )
+		this->kernelFunction = src.kernelFunction->clone();
+	else
+		this->kernelFunction = NULL;
+	
+	this->vecSetLabels = src.vecSetLabels;
+	this->normalizationType = src.normalizationType;
+	this->vecSet = src.vecSet;
+
+}
+
+KernelClassifier::~KernelClassifier()
+{
+}
+
+ClassificationResult KernelClassifier::classify ( const NICE::Vector & x ) const
+{
+	if ( kernelFunction == NULL )
+		fthrow( Exception, "KernelClassifier::classify: To use this function, you have to specify a kernel function using the constructor" );
+
+	NICE::Vector kstar;
+
+	// nothing happens, we should create a copy of x and then
+	// use normalization
+	//if ( this->normalizationType == KERNELCLASSIFIER_NORMALIZATION_EUCLIDEAN )
+	//	x.normL2();
+
+	kernelFunction->calcKernelVector ( vecSet, x, kstar );	
+
+#ifdef DEBUG
+	if ( kstar.normL2() == 0.0 )
+		cerr << "The kernel vector k_* has zero norm, you might want to adjust kernel parameters with e.g. Kernel:log_rbf_gamma." << endl;
+#endif
+
+
+	double kernelSelf = kernelFunction->K(x,x);
+	
+	return classifyKernel (kstar, kernelSelf);
+}
+
+void KernelClassifier::teach ( const LabeledSetVector & teachSet )
+{
+	if ( kernelFunction == NULL )
+		fthrow( Exception, "KernelClassifier::teach: To use this function, you have to specify a kernel function using the constructor" );
+
+	teachSet.getFlatRepresentation ( vecSet, vecSetLabels );
+	
+	if ( this->normalizationType == KERNELCLASSIFIER_NORMALIZATION_EUCLIDEAN )
+	{
+		for ( VVector::iterator i = vecSet.begin(); i != vecSet.end(); i++ )
+		{
+			Vector & v = *i;
+			v.normL2();
+		}
+	}
+
+	KernelData *kernelData = new KernelData ( &conf );
+
+	kernelFunction->calcKernelData ( vecSet, kernelData );
+
+	teach ( kernelData, vecSetLabels );
+	
+	// maybe problems with other kernel classifiers
+	delete kernelData;
+}
+
+
+void KernelClassifier::restore(std::istream& ifs, int type)
+{
+	vecSet.restore(ifs);
+	
+	//TODO: read and write kernel
+}
+
+void KernelClassifier::store(std::ostream& ofs, int type) const
+{
+	vecSet.store(ofs);
+}

+ 95 - 0
classifier/classifierbase/KernelClassifier.h

@@ -0,0 +1,95 @@
+/** 
+* @file KernelClassifier.h
+* @brief classifier interface for kernel based methods
+* @author Erik Rodner
+* @date 12/02/2009
+
+*/
+#ifndef KERNELCLASSIFIERINCLUDE
+#define KERNELCLASSIFIERINCLUDE
+
+#include "vislearning/math/kernels/Kernel.h"
+#include "vislearning/math/kernels/KernelData.h"
+#include "core/vector/VVector.h"
+
+#include "vislearning/cbaselib/ClassificationResult.h"
+#include "vislearning/cbaselib/LabeledSet.h"
+#include "vislearning/classifier/classifierbase/VecClassifier.h"
+
+namespace OBJREC {
+  
+/** classifier interface for kernel based methods */
+class KernelClassifier : public VecClassifier
+{
+	public:
+		enum {
+			KERNELCLASSIFIER_NORMALIZATION_EUCLIDEAN = 0,
+			KERNELCLASSIFIER_NORMALIZATION_NONE
+		};
+
+    protected:
+
+		/** This variable might be NULL, if you do not specify a kernel function */
+		Kernel *kernelFunction;
+		
+		/** This is the training set, if you specify a kernel function */
+		NICE::VVector vecSet;
+
+		/** These are the labels of the training set, if you specify a kernel function */
+		NICE::Vector vecSetLabels;
+
+		/** Maybe you want to normalize feature vectors before training */
+		int normalizationType;
+
+		/** stored config to initialize KernelData with noiseSigma, cholesky method etc. */
+		NICE::Config conf;
+
+    public:
+  		/** simple constructor */
+		KernelClassifier(){};
+	    
+		/** specify a kernel function which works on vectors and a normalization method ( use the enum defined in KernelClassifier ) */
+		KernelClassifier( const NICE::Config *conf, Kernel *kernelFunction = NULL, int normalizationType = KERNELCLASSIFIER_NORMALIZATION_EUCLIDEAN );
+
+		/** copy constructor which you should also call in subclasses */
+		KernelClassifier ( const KernelClassifier & src );
+
+		/** simple destructor */
+		virtual ~KernelClassifier();
+
+
+		// interface function
+
+		/** teach the classifier with a kernel matrix and the corresponding class labels @param y ! */
+		virtual void teach ( KernelData *kernelData, const NICE::Vector & y ) = 0;
+
+		/** classify an example by using its kernel values with the training set,
+			be careful with the order in @param kernelVector */
+		virtual ClassificationResult classifyKernel ( const NICE::Vector & kernelVector, double kernelSelf ) const = 0;
+
+
+		// functions to build an interface to VecClassifier
+
+		/** classify using simple vector, this works only if you specify a kernel function */
+		ClassificationResult classify ( const NICE::Vector & x ) const;
+
+		/** teach classifier with a labeled set of feature vectors, this works only if you specify a kernel function */
+		virtual void teach ( const LabeledSetVector & teachSet );
+		
+		/** calculate classifier stuff as the last training step, pretty useless, deprecated */
+		void finishTeaching() {};
+
+		/** clone this object */
+		KernelClassifier *clone(void) const {
+			fthrow(Exception, "clone() not yet implemented.");
+		}
+
+		Kernel *getKernelFunction () const { return kernelFunction; }; 
+		
+		virtual void restore(std::istream&, int);
+		virtual void store(std::ostream&, int) const;
+};
+
+}
+
+#endif

Some files were not shown because too many files changed in this diff