Browse Source

added basics to vislearning and corrected the include paths

Alexander Luetz 13 năm trước cách đây
commit
4f62dcb0ac
100 tập tin đã thay đổi với 13484 bổ sung0 xóa
  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

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác