15 Commits cfbf356bba ... 7f13dae95b

Autor SHA1 Mensaje Fecha
  Sven Sickert 7f13dae95b removed dependencies on deprecated Filter.h hace 9 años
  Sven Sickert d02a2068ff removed redundant KernelStd definition and declaration hace 9 años
  Sven Sickert 6a202623a9 reactivated parallel training of multiple trees hace 9 años
  Sven Sickert 45f6a7288c modified DTBObliqueLS for the use of SplittingCriterion objects hace 9 años
  Sven Sickert 10a60e8cde added own class for splitting criteria of decision trees hace 9 años
  Sven Sickert 359f36b626 reading labels from csv file (experimental) hace 9 años
  Sven Sickert 04e93a6d69 substituted MCI by MCI3D in CachedExample; modified FPFeatures accordingly hace 9 años
  Sven Sickert 34dd34de61 workaround for empty ichannels when using CachedExample in 2D scenarios -> needs proper solution hace 9 años
  Sven Sickert ecb6a21db0 initialization of zsize=1 in ConvolutionFeature hace 9 años
  Sven Sickert dedf824de4 code formatting in Example.* hace 9 años
  Sven Sickert 74fbbfb2e5 added missing 'format' forward in FPCRandomForests::restore hace 10 años
  Sven Sickert 3aadf237b6 controlable rand seed for DTBObliqueLS hace 10 años
  Sven Sickert 2d4d55716e bugfix in convolutional feature hace 10 años
  Sven Sickert be2a706525 modified ConvFeature for 3d examples hace 10 años
  Sven Sickert 6d489c68da extended Example and CachedExample for the use of 3d images hace 10 años
Se han modificado 38 ficheros con 1816 adiciones y 806 borrados
  1. 42 42
      baselib/FastFilter.h
  2. 10 10
      baselib/FastFilter.tcc
  3. 11 16
      baselib/ICETools.cpp
  4. 361 205
      cbaselib/CachedExample.cpp
  5. 177 23
      cbaselib/CachedExample.h
  6. 192 111
      cbaselib/Example.cpp
  7. 27 1
      cbaselib/Example.h
  8. 35 1
      cbaselib/LabeledFileList.cpp
  9. 3 0
      cbaselib/LabeledFileList.h
  10. 4 4
      cbaselib/progs/testCachedExample.cpp
  11. 94 138
      classifier/fpclassifier/randomforest/DTBObliqueLS.cpp
  12. 11 43
      classifier/fpclassifier/randomforest/DTBObliqueLS.h
  13. 2 2
      classifier/fpclassifier/randomforest/FPCRandomForests.cpp
  14. 149 0
      classifier/fpclassifier/randomforest/SCGiniIndex.cpp
  15. 83 0
      classifier/fpclassifier/randomforest/SCGiniIndex.h
  16. 143 0
      classifier/fpclassifier/randomforest/SCInformationGain.cpp
  17. 73 0
      classifier/fpclassifier/randomforest/SCInformationGain.h
  18. 69 0
      classifier/fpclassifier/randomforest/SplittingCriterion.cpp
  19. 115 0
      classifier/fpclassifier/randomforest/SplittingCriterion.h
  20. 2 2
      features/fpfeatures/ColorHistogramFeature.cpp
  21. 77 28
      features/fpfeatures/ConvolutionFeature.cpp
  22. 9 1
      features/fpfeatures/ConvolutionFeature.h
  23. 1 1
      features/fpfeatures/EOHFeature.cpp
  24. 11 11
      features/fpfeatures/FIGradients.cpp
  25. 5 4
      features/fpfeatures/FIHistograms.cpp
  26. 4 4
      features/fpfeatures/HOGFeature.cpp
  27. 2 2
      features/fpfeatures/HaarFeature.cpp
  28. 1 1
      features/fpfeatures/HistFeature.cpp
  29. 2 2
      features/fpfeatures/PixelPairFeature.cpp
  30. 1 1
      features/fpfeatures/SemanticFeature.cpp
  31. 60 18
      features/gradientfeatures/Image_tools.h
  32. 14 22
      image/ImagePyramid.cpp
  33. 13 13
      image/ImagePyramid.h
  34. 0 39
      math/distances/KernelStd.cpp
  35. 0 40
      math/distances/KernelStd.h
  36. 0 1
      math/ftransform/PCA.h
  37. 3 10
      math/kernels/KernelStd.cpp
  38. 10 10
      math/kernels/KernelStd.h

+ 42 - 42
baselib/FastFilter.h

@@ -17,47 +17,47 @@ 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
-	 **/
+         * 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 );
+	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
-	 **/
+         * 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 );
+	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 );
@@ -68,11 +68,11 @@ class FastFilter
 	///lazy attempt for realizing fast histogram of oriented gradients
 	///since (neg.) double values are allowed, fast filtering based on look-up tables is no longer possible
 	template <class GrayValueType, class OrientedGradientHistogramType>
-	static void calcOrientedGradientHistogram ( const GrayValueType *gray, 
-						    int xsize, int ysize,
-						    OrientedGradientHistogramType *hog, 
-						    int numBins, 
-						    bool usesigned );
+	static void calcOrientedGradientHistogram ( const GrayValueType *gray,
+                                                    int xsize, int ysize,
+                                                    OrientedGradientHistogramType *hog,
+                                                    int numBins,
+                                                    bool usesigned );
 
 };
 

+ 10 - 10
baselib/FastFilter.tcc

@@ -1,4 +1,4 @@
-/** 
+/**
 * @file FastFilter.cpp
 * @brief color gradient
 * @author Erik Rodner
@@ -26,7 +26,7 @@ void FastFilter::calcGradientX ( const SrcValueType *img, int xsize, int ysize,
 	d[k] = 0.0;
 	k++;
 	for ( int x = 1 ; x < xsize-1 ; x++,k++ )
-	    d[k] = - img[k-1] + img[k+1];
+            d[k] = - img[k-1] + img[k+1];
 	d[k] = 0.0;
 	k++;
     }
@@ -43,18 +43,18 @@ void FastFilter::calcGradientY ( const SrcValueType *img, int xsize, int ysize,
 
     for ( int y = 1 ; y < ysize-1; y++ )
 	for ( int x = 0 ; x < xsize ; x++,k++ )
-	    d[k] = - img[k-xsize] + img[k+xsize];
+            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, 
+void FastFilter::calcColorGradient (
+			  const GrayValueType *r,
+			  const GrayValueType *g,
+			  const GrayValueType *b,
 			  int xsize, int ysize,
-			  GradientMagnitudeType *gradient, 
-			  GradientDirectionType *dir, 
-			  int numBins, 
+			  GradientMagnitudeType *gradient,
+			  GradientDirectionType *dir,
+			  int numBins,
 			  bool usesigned )
 {
     double *atan2Table = FastMath::getSingleton().atan2Table;

+ 11 - 16
baselib/ICETools.cpp

@@ -5,27 +5,22 @@
 * @date 03/13/2008
 
 */
-#include "core/image/ImageT.h"
+#include "core/basics/Exception.h"
 #include "core/vector/VectorT.h"
 #include "core/vector/MatrixT.h"
-#include <core/image/Filter.h>
-#include <core/image/Convert.h>
-
-#include <core/imagedisplay/ImageDisplay.h>
-
-#include <iostream>
-
-#include <core/image/RectT.h>
-
+#include "core/image/ImageT.h"
+#include "core/image/Convert.h"
+#include "core/image/RectT.h"
+#include "core/imagedisplay/ImageDisplay.h"
 #include "vislearning/baselib/ICETools.h"
 
-#include "core/basics/Exception.h"
+#include <iostream>
 
 using namespace OBJREC;
 
 using namespace std;
 
-using namespace NICE;
+//using namespace NICE;
 
 ICETools::ICETools()
 {
@@ -35,14 +30,14 @@ ICETools::~ICETools()
 {
 }
 
-void ICETools::selectRectangles ( const NICE::Image & panel, NICE::Image & overlay, vector<Vector> & x, int color )
+void ICETools::selectRectangles ( const NICE::Image & panel, NICE::Image & overlay, vector<NICE::Vector> & x, int color )
 {
-  fthrow ( Exception, "ICETools::selectRectangles -- not yet implemented due to old ICE version." );
+  fthrow ( NICE::Exception, "ICETools::selectRectangles -- not yet implemented due to old ICE version." );
 }
 
-void ICETools::selectPoints ( const NICE::Image & panel, NICE::Image & overlay, vector<Vector> & x, int color )
+void ICETools::selectPoints ( const NICE::Image & panel, NICE::Image & overlay, vector<NICE::Vector> & x, int color )
 {
-  fthrow ( Exception, "ICETools::selectPoints -- not yet implemented due to old ICE version." );
+  fthrow ( NICE::Exception, "ICETools::selectPoints -- not yet implemented due to old ICE version." );
 }
 
 void ICETools::convertToRGB ( const NICE::Matrix & m, NICE::ColorImage & img )

+ 361 - 205
cbaselib/CachedExample.cpp

@@ -1,13 +1,13 @@
 /**
 * @file CachedExample.cpp
 * @brief data caching
-* @author Erik Rodner
-* @date 04/21/2008
+* @author Erik Rodner, Sven Sickert
+* @date 04/21/2008 (modified 03/18/2016)
 
 */
 #include <iostream>
 
-#include "vislearning/cbaselib/CachedExample.h"
+#include "CachedExample.h"
 #include "vislearning/baselib/Conversions.h"
 #include "vislearning/baselib/ProgressBar.h"
 
@@ -17,275 +17,431 @@
 
 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;
-  }
+//    dchannels = new NICE::MultiChannelImageT<double> [D_NUMCHANNELS];
+//    ichannels = new NICE::MultiChannelImageT<int> [I_NUMCHANNELS];
+//    lchannels = new NICE::MultiChannelImageT<long> [L_NUMCHANNELS];
+
+    dchannels = new NICE::MultiChannelImage3DT<double> [D_NUMCHANNELS];
+    ichannels = new NICE::MultiChannelImage3DT<int> [I_NUMCHANNELS];
+    lchannels = new NICE::MultiChannelImage3DT<long> [L_NUMCHANNELS];
+
+    svmap = new NICE::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.push_back(_imgfn);
+    newWidth = _newWidth;
+    newHeight = _newHeight;
+    newDepth = 1;
+    Preprocess::getImageSize ( _imgfn, oxsize, oysize );
+    ozsize = 1;
+    init();
+    hasColorInformation = true;
 }
 
-CachedExample::CachedExample ( const std::string & _imgfn,
-                               int _newWidth,
-                               int _newHeight )
+CachedExample::CachedExample (
+        const std::vector<std::string> & _imgfn,
+        int _newWidth,
+        int _newHeight,
+        int _newDepth )
 {
-  imgfn = _imgfn;
-  newWidth = _newWidth;
-  newHeight = _newHeight;
-  Preprocess::getImageSize ( _imgfn, oxsize, oysize );
-  init();
-  hasColorInformation = true;
+    imgfn = _imgfn;
+    newWidth = _newWidth;
+    newHeight = _newHeight;
+    newDepth = _newDepth;
+    Preprocess::getImageSize ( _imgfn[0], oxsize, oysize );
+    ozsize = _imgfn.size();
+    init();
+    hasColorInformation = true;
 }
 
 CachedExample::CachedExample ( const NICE::Image & _img )
 {
-  imgfn = "";
-  newWidth = -1;
-  newHeight = -1;
-  init();
-
-  oxsize = _img.width();
-  oysize = _img.height();
-  
-  ichannels[I_GRAYVALUES].freeData();
-  ichannels[I_GRAYVALUES].addChannel(_img);
-  hasColorInformation = false;
+    imgfn.push_back("");
+    newWidth = -1;
+    newHeight = -1;
+    newDepth = -1;
+    init();
+
+    oxsize = _img.width();
+    oysize = _img.height();
+    ozsize = 1;
+
+    ichannels[I_GRAYVALUES].freeData();
+    ichannels[I_GRAYVALUES].addChannel(_img);
+    hasColorInformation = false;
 }
 
-CachedExample::CachedExample ( const NICE::ColorImage & img, bool disableGrayConversion )
+CachedExample::CachedExample (
+        const NICE::MultiChannelImageT<int> & _img )
 {
-  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 );
+    newWidth = -1;
+    newHeight = -1;
+    newDepth = -1;
+    init();
+
+    oxsize = _img.width();
+    oysize = _img.height();
+    ozsize = _img.channels();
+
+    for ( unsigned int i = 0; i < ozsize; i++ )
+        imgfn.push_back("");
 
     ichannels[I_GRAYVALUES].freeData();
-    ichannels[I_GRAYVALUES].addChannel(imggray);
-  }
+    ichannels[I_GRAYVALUES].addChannel(_img);
+    hasColorInformation = false;
+}
+
+CachedExample::CachedExample (
+        const NICE::ColorImage & img,
+        bool disableGrayConversion )
+{
+    imgfn.push_back("");
+    oxsize = img.width();
+    oysize = img.height();
+    ozsize = 1;
+    newWidth = -1;
+    newHeight = -1;
+    newDepth = -1;
+    init();
+
+    if ( ! disableGrayConversion )
+    {
+        // refactor-nice.pl: check this substitution
+        // old: Image imggray;
+        NICE::Image imggray;
+        ICETools::calcGrayImage ( img, imggray );
 
-  ichannels[I_COLOR].reInit ( oxsize, oysize, 3);
+        ichannels[I_GRAYVALUES].freeData();
+        ichannels[I_GRAYVALUES].addChannel(imggray);
+    }
+
+    ichannels[I_COLOR].reInit ( oxsize, oysize, 3);
+
+    for ( int y = 0 ; y < oysize ; y++ )
+        for ( int x = 0 ; x < oxsize ; x++ )
+        {
+            ichannels[I_COLOR](x,y,0,0) = img.getPixel ( x, y, 0 );
+            ichannels[I_COLOR](x,y,0,1) = img.getPixel ( x, y, 1 );
+            ichannels[I_COLOR](x,y,0,2) = img.getPixel ( x, y, 2 );
+        }
 
-  for ( int y = 0 ; y < oysize ; y++ )
-    for ( int x = 0 ; x < oxsize ; x++ )
+    hasColorInformation = true;
+}
+
+CachedExample::CachedExample (
+        const NICE::MultiChannelImage3DT<int> & img,
+        bool disableGrayConversion )
+{
+    oxsize = img.width();
+    oysize = img.height();
+    ozsize = img.depth();
+    newWidth = -1;
+    newHeight = -1;
+    newDepth = -1;
+    for ( unsigned int i = 0; i < ozsize; i++ )
+        imgfn.push_back("");
+
+    init();
+
+    int ochannels = img.channels();
+
+    if ( ! disableGrayConversion && (ochannels > 2) )
     {
-      ichannels[I_COLOR](x,y,0) = img.getPixel ( x, y, 0 );
-      ichannels[I_COLOR](x,y,1) = img.getPixel ( x, y, 1 );
-      ichannels[I_COLOR](x,y,2) = img.getPixel ( x, y, 2 );
+        ichannels[I_GRAYVALUES].freeData();
+        ichannels[I_GRAYVALUES].addChannel(1);
+        for ( int z = 0; z < ozsize; z++ )
+        {
+            NICE::Image imggray;
+            ICETools::calcGrayImage ( img.getColor(z), imggray );
+
+            for ( int y = 0; y < oysize; y++ )
+                for ( int x = 0; x < oxsize; x++ )
+                    ichannels[I_GRAYVALUES](x,y,z,0) = imggray.getPixel(x,y);
+        }
     }
 
-  hasColorInformation = true;
+    ichannels[I_COLOR].addChannel ( img );
+
+    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 );
-  }
+    delete [] dchannels;
+    delete [] ichannels;
+    delete [] lchannels;
+
+//    delete [] dchannels3;
+//    delete [] ichannels3;
+//    delete [] lchannels3;
+
+    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 ( std::map<int, std::string>::const_iterator j = dtemps.begin();
+          j != dtemps.end();
+          j++ )
+    {
+        //fprintf (stderr, "CachedExample: removing temp file %s\n", j->second.c_str() );
+        NICE::FileMgt::deleteTempFile ( j->second );
+    }
+
+    for ( std::map<int, std::string>::const_iterator j = itemps.begin();
+          j != itemps.end();
+          j++ )
+    {
+        //fprintf (stderr, "CachedExample: removing temp file %s\n", j->second.c_str() );
+        NICE::FileMgt::deleteTempFile ( j->second );
+    }
+
+    for ( std::map<int, std::string>::const_iterator j = ltemps.begin();
+          j != ltemps.end();
+          j++ )
+    {
+        //fprintf (stderr, "CachedExample: removing temp file %s\n", j->second.c_str() );
+        NICE::FileMgt::deleteTempFile ( j->second );
+    }
 
 }
 
 void CachedExample::readImageData ()
 {
-  if ( imgfn == "" ) return;
+    ozsize = imgfn.size();
 
-  NICE::Image orig = Preprocess::ReadImgAdv ( imgfn );
-  NICE::Image imggray;
+    if ( ozsize == 0 || imgfn[0] == "" )
+        return;
 
-  if ( newWidth > 0 )
-    Conversions::resizeImage ( orig, imggray, newWidth, newHeight );
-  else
-    imggray = orig;
-
-  oxsize = imggray.width();
-  oysize = imggray.height();
-
-  ichannels[I_GRAYVALUES].freeData();
-  ichannels[I_GRAYVALUES].addChannel(imggray);
+    for ( int z = 0; z < ozsize; z++ )
+    {
+        NICE::Image orig = Preprocess::ReadImgAdv ( imgfn[z] );
+        NICE::Image imggray;
+
+        if ( newWidth > 0 )
+            Conversions::resizeImage ( orig, imggray, newWidth, newHeight );
+        else
+            imggray = orig;
+
+	// FIXME: gray values are saved twice (ichannels and ichannels3)
+        // for compatibility with all 2D programs that refer to ichannels
+        // which is of type MultiChannelImageT instead of MultiChannelImage3DT
+        if ( z == 0 )
+        {
+            oxsize = imggray.width();
+            oysize = imggray.height();
+
+            ichannels[I_GRAYVALUES].reInit( oxsize, oysize, ozsize, 1);
+            //ichannels[I_GRAYVALUES].freeData();
+            //ichannels[I_GRAYVALUES].addChannel(imggray);
+        }
+
+        for ( int y = 0; y < oysize; y++ )
+            for ( int x = 0; x < oxsize; x++ )
+                ichannels[I_GRAYVALUES](x,y,z,0) = 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;
-  }
+    ozsize = imgfn.size();
 
-  oxsize = img.width();
-  oysize = img.height();
+    if ( ozsize == 0 || imgfn[0] == "" )
+        return;
 
-  hasColorInformation = true;
-
-  ichannels[I_COLOR].reInit ( oxsize, oysize, 3);
-  
-  for ( int y = 0 ; y < oysize ; y++ )
-    for ( int x = 0 ; x < oxsize ; x++)
+    for ( int z = 0; z < ozsize; z++ )
     {
-      ichannels[I_COLOR](x,y,0) = img.getPixel ( x, y, 0 );
-      ichannels[I_COLOR](x,y,1) = img.getPixel ( x, y, 1 );
-      ichannels[I_COLOR](x,y,2) = img.getPixel ( x, y, 2 );
+        NICE::ColorImage img;
+        try {
+            img = Preprocess::ReadImgAdvRGB ( imgfn[z] );
+        } catch ( NICE::ImageException & ) {
+            fprintf ( stderr, "error reading rgb image %s\n", imgfn[z].c_str() );
+            hasColorInformation = false;
+            return;
+        }
+
+        if ( z == 0 )
+        {
+            oxsize = img.width();
+            oysize = img.height();
+
+            hasColorInformation = true;
+
+            // FIXME: see readImageData issue
+            ichannels[I_COLOR].reInit ( oxsize, oysize, ozsize, 3);
+            //ichannels[I_COLOR].reInit ( oxsize, oysize, 3);
+        }
+
+        for ( int y = 0; y < oysize; y++ )
+            for ( int x = 0; x < oxsize; x++ )
+            {
+                ichannels[I_COLOR](x,y,z,0) = img.getPixel(x,y,0);
+                ichannels[I_COLOR](x,y,z,1) = img.getPixel(x,y,1);
+                ichannels[I_COLOR](x,y,z,2) = img.getPixel(x,y,2);
+                //ichannels[I_COLOR](x,y,0) = img.getPixel ( x, y, 0 );
+                //ichannels[I_COLOR](x,y,1) = img.getPixel ( x, y, 1 );
+                //ichannels[I_COLOR](x,y,2) = img.getPixel ( x, y, 2 );
+            }
     }
 }
 
 void CachedExample::calcIntegralImage ()
 {
-  if ( ichannels[I_GRAYVALUES].width() == 0 )
-  {
-    readImageData ();
-    if ( ichannels[I_GRAYVALUES].width() == 0 )
+    // in case of standard 2D images
+/*
+    if ( ozsize == 1 )
     {
-      fprintf ( stderr, "CachedExample::getChannel: unable to recover data channel\n" );
-      exit ( -1 );
+        if ( ichannels[I_GRAYVALUES].width() == 0 )
+        {
+            readImageData ();
+            if ( ichannels[I_GRAYVALUES].width() == 0 )
+            {
+                fprintf ( stderr, "CachedExample::getChannel: unable to recover data channel\n" );
+                exit ( -1 );
+            }
+        }
+
+        lchannels[L_INTEGRALIMAGE].reInit (
+                    ichannels[I_GRAYVALUES].width(),
+                    ichannels[I_GRAYVALUES].height(),
+                    1 );
+
+        NICE::ImageT<long int> tmp = lchannels[L_INTEGRALIMAGE][0];
+
+        GenericImageTools::calcIntegralImage (
+                    tmp,
+                    ichannels[I_GRAYVALUES][0],
+                    ichannels[I_GRAYVALUES].width(),
+                    ichannels[I_GRAYVALUES].height() );
     }
-  }
-
-  lchannels[L_INTEGRALIMAGE].reInit ( ichannels[I_GRAYVALUES].width(),
-                                      ichannels[I_GRAYVALUES].height(),
-                                      1);
-
-  ImageT<long int> tmp = lchannels[L_INTEGRALIMAGE][0];
-
-  GenericImageTools::calcIntegralImage (
-    tmp,
-    ichannels[I_GRAYVALUES][0],
-    ichannels[I_GRAYVALUES].width(),
-    ichannels[I_GRAYVALUES].height() );
+    // in case of a 3D images
+    else
+    {*/
+        if ( ichannels[I_GRAYVALUES].width() == 0 )
+        {
+            readImageData ();
+            if ( ichannels[I_GRAYVALUES].width() == 0 )
+            {
+                fprintf ( stderr, "CachedExample::getChannel: unable to recover data channel\n" );
+                exit ( -1 );
+            }
+        }
+
+        int nwidth = ichannels[I_GRAYVALUES].width();
+        int nheight = ichannels[I_GRAYVALUES].height();
+        int ndepth = ichannels[I_GRAYVALUES].depth();
+        int nchannels = ichannels[I_GRAYVALUES].channels();
+        lchannels[L_INTEGRALIMAGE].reInit( nwidth, nheight, ndepth, nchannels);
+        for ( int c = 0; c < nchannels; c++ )
+        {
+            for ( int z = 0; z < ndepth; z++ )
+                for ( int y = 0; y < nheight; y++ )
+                    for ( int x = 0; x < nwidth; x++ )
+                    {
+                        lchannels[L_INTEGRALIMAGE](x,y,z,c) =
+                                (long)ichannels[L_INTEGRALIMAGE].get(x,y,z,c);
+                    }
+
+            lchannels[L_INTEGRALIMAGE].calcIntegral(c);
+        }
+//    }
 }
 
-void CachedExample::buildIntegralSV ( int svchannel,
-                                      SparseVector *_map,
-                                      int xsize_s, int ysize_s )
+void CachedExample::buildIntegralSV (
+        int svchannel,
+        NICE::SparseVector *_map,
+        int xsize_s, int ysize_s )
 {
-  SparseVector *map = _map;
-  svmap[svchannel] = _map;
-  svmap_xsize[svchannel] = xsize_s;
-  svmap_ysize[svchannel] = ysize_s;
+    NICE::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] ) );
+    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 = 1;
+    for ( int x = 1 ; x < xsize_s; x++, k++ )
+        map[k].add ( ( map[k-1] ) );
 
-  k = xsize_s + 1;
+    k = xsize_s + 1;
 
-  for ( int y = 1 ; y < ysize_s ; y++, k++ )
-  {
-    for ( int x = 1 ; x < xsize_s ; x++, k++ )
+    for ( int y = 1 ; y < ysize_s ; y++, k++ )
     {
-      map[k].add ( ( map[k-1] ) );
-      map[k].add ( ( map[k-xsize_s] ) );
-      map[k].add ( ( map[k-xsize_s-1] ), -1.0 );
+        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 )
+void CachedExample::setSVMap (
+        int svchannel,
+        NICE::SparseVector *_map,
+        int xsize_s, int ysize_s )
 {
-  svmap[svchannel] = _map;
-  svmap_xsize[svchannel] = xsize_s;
-  svmap_ysize[svchannel] = ysize_s;
+    svmap[svchannel] = _map;
+    svmap_xsize[svchannel] = xsize_s;
+    svmap_ysize[svchannel] = ysize_s;
 }
 
-SparseVector *CachedExample::getSVMap ( int svchannel,
+NICE::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];
+    _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;
-    int tmp_nr = imgfheader.channel;
-
-    if ( tmp_nr > 1 ) return true;
-    else return false;
-  }
+    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 );
+        NICE::ImageFile imgf ( imgfn[0] );
+        const NICE::ImageFile::Header & imgfheader = imgf.getHeader();
+        //     tmp_xsize = imgfheader.width;
+        //     tmp_ysize = imgfheader.height;
+        //     tmp_maxval = 255;
+        int 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 );
+    dropImages<double> ( dchannels, dtemps, D_NUMCHANNELS );
+    dropImages<int> ( ichannels, itemps, I_NUMCHANNELS );
+    dropImages<long> ( lchannels, ltemps, L_NUMCHANNELS );
 }

+ 177 - 23
cbaselib/CachedExample.h

@@ -1,8 +1,8 @@
 /**
 * @file CachedExample.h
 * @brief data caching of several feature images and many more
-* @author Erik Rodner
-* @date 04/21/2008
+* @author Erik Rodner, Sven Sickert
+* @date 04/21/2008 (modified 03/18/2016)
 
 */
 #ifndef CACHEDEXAMPLEINCLUDE
@@ -13,6 +13,7 @@
 
 #include "core/vector/SparseVectorT.h"
 #include "core/image/MultiChannelImageT.h"
+#include "core/image/MultiChannelImage3DT.h"
 #include "core/basics/FileMgt.h"
 
 namespace OBJREC
@@ -31,23 +32,30 @@ class CachedExample
     int newWidth;
     /** resize image to this fixed height */
     int newHeight;
+    /** resize image to this fixed depth */
+    int newDepth;
 
     /** original image width */
     int oxsize;
     /** original image height */
     int oysize;
+    /** original image depth */
+    int ozsize;
 
-    /** filename of image */
-    std::string imgfn;
+    /** list of filenames of images */
+    std::vector<std::string> imgfn;
 
     /** array of double images */
-    NICE::MultiChannelImageT<double> *dchannels;
+//    NICE::MultiChannelImageT<double> *dchannels;
+    NICE::MultiChannelImage3DT<double> *dchannels;
 
     /** array of integer images */
-    NICE::MultiChannelImageT<int> *ichannels;
+//    NICE::MultiChannelImageT<int> *ichannels;
+    NICE::MultiChannelImage3DT<int> *ichannels;
 
     /** array of histogram images */
-    NICE::MultiChannelImageT<long> *lchannels;
+//    NICE::MultiChannelImageT<long> *lchannels;
+    NICE::MultiChannelImage3DT<long> *lchannels;
 
     /** maps for temporary files */
     std::map<int, std::string> dtemps;
@@ -118,20 +126,44 @@ class CachedExample
         @param newWidth resize raw image to this width
         @param newHeight resize raw image to this height
     */
-    CachedExample ( const std::string & imgfn, int newWidth = -1,
+    CachedExample ( const std::string & imgfn,
+                    int newWidth = -1,
                     int newHeight = -1 );
 
+    /** simple 3d constructor
+        @param imgfn image filename
+        @param newWidth resize raw image to this width
+        @param newHeight resize raw image to this height
+        @param newDepth resize raw image to this depth
+    */
+    CachedExample ( const std::vector<std::string> & imgfn,
+                    int newWidth = -1,
+                    int newHeight = -1,
+                    int newDepth = -1 );
+
     /** constructor (disabled buffering)
         @param img gray-value image
     */
     CachedExample ( const NICE::Image & img );
 
+    /** constructor (disabled buffering)
+        @param img gray-value multi channel image
+    */
+    CachedExample ( const NICE::MultiChannelImageT<int> & 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 );
 
+    /** constructor (disabled buffering)
+        @param img multi channel image 3D
+        @param disableGrayConversion whether to provide gray values or not
+    */
+    CachedExample ( const NICE::MultiChannelImage3DT<int> & img,
+                    bool disableGrayConversion = false );
+
     /** simple destructor */
     virtual ~CachedExample();
 
@@ -139,16 +171,25 @@ class CachedExample
      * get the NICE::Image Filename
      * @return NICE::Image Filename
      */
-    inline std::string getFilename();
+    inline std::string getFilename(const int z = 0);
 
+    /**
+     * @brief get amount of images
+     * @return amount of images
+     */
+    inline int getNumImages ();
 
     /** 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 NICE::MultiChannelImageT<double> & getDChannel ( int channel );
+//    inline NICE::MultiChannelImageT<double> & getDChannel ( int channel );
+
+    /** get double image channel 3d
+        @param channel channel type (choose from enum type)
+        @return buffer to image data
+    */
+    inline NICE::MultiChannelImage3DT<double> & getDChannel ( int channel );
 
     /** get integer image channel
         @param channel channel type (choose from enum type)
@@ -156,7 +197,13 @@ class CachedExample
         @param[out] ysize height of image
         @return buffer to image data
     */
-    inline NICE::MultiChannelImageT<int> & getIChannel ( int channel );
+//    inline NICE::MultiChannelImageT<int> & getIChannel ( int channel );
+
+    /** get integer image channel 3d
+        @param channel channel type (choose from enum type)
+        @return buffer to image data
+    */
+    inline NICE::MultiChannelImage3DT<int> & getIChannel ( int channel );
 
     /** get long image channel
         @param channel channel type (choose from enum type)
@@ -164,7 +211,13 @@ class CachedExample
         @param[out] ysize height of image
         @return buffer to image data
     */
-    inline NICE::MultiChannelImageT<long> & getLChannel ( int channel );
+//    inline NICE::MultiChannelImageT<long> & getLChannel ( int channel );
+
+    /** get long image channel 3d
+        @param channel channel type (choose from enum type)
+        @return buffer to image data
+    */
+    inline NICE::MultiChannelImage3DT<long> & getLChannel ( int channel );
 
     /** get histogram image
         @param svchannel channel type (choose from histogram channel enum)
@@ -200,7 +253,16 @@ class CachedExample
     {
       xsize = oxsize;
       ysize = oysize;
-    };
+    }
+
+    /** get image sizes 3d */
+    void getImageSize3 ( int & xsize, int & ysize, int & zsize ) const
+    {
+        xsize = oxsize;
+        ysize = oysize;
+        zsize = ozsize;
+    }
+
 
     /** drop precached data:
      (1) this is only possible if an image filename is given
@@ -209,13 +271,23 @@ class CachedExample
     void dropPreCached();
 
     template<class ImgPixelValue>
-    void dropImages ( NICE::MultiChannelImageT<ImgPixelValue> *images,
+    void dropImages ( NICE::MultiChannelImage3DT<ImgPixelValue> *images,
                       std::map<int, std::string> & temps,
                       int numImages );
 };
 
 
 /********************** INLINE FUNCTIONS *****************************/
+inline std::string CachedExample::getFilename( const int z )
+{
+    return imgfn[z];
+}
+
+inline int CachedExample::getNumImages ()
+{
+    return imgfn.size();
+}
+/*
 inline NICE::MultiChannelImageT<double> & CachedExample::getDChannel ( int channel )
 {
   assert ( ( channel >= 0 ) && ( channel < D_NUMCHANNELS ) );
@@ -238,23 +310,41 @@ inline NICE::MultiChannelImageT<double> & CachedExample::getDChannel ( int chann
 
   return dchannels[channel];
 }
-
-inline std::string CachedExample::getFilename()
+*/
+inline NICE::MultiChannelImage3DT<double> & CachedExample::getDChannel ( int channel )
 {
-  return imgfn;
-}
+    assert ( ( channel >= 0 ) && ( channel < D_NUMCHANNELS ) );
+
+    if ( dchannels[channel].channels() == 0 )
+    {
+        std::map<int, std::string>::const_iterator j = dtemps.find ( channel );
+        if ( j == dtemps.end() )
+        {
+            //fprintf (stderr, "NICE::MultiChannelImageT: unable to recover data channel %s (double %d)!\n",
+            //imgfn[0].c_str(), channel);
+        }
+        else
+        {
+            //fprintf (stderr, "NICE::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 NICE::MultiChannelImageT<int> & CachedExample::getIChannel ( int channel )
 {
   assert ( ( channel >= 0 ) && ( channel < I_NUMCHANNELS ) );
 
   if ( ( ichannels[channel].channels() == 0 ) )
   {
-    if ( ( imgfn != "" ) && ( channel == I_GRAYVALUES ) )
+      if ( ( imgfn[0] != "" ) && ( channel == I_GRAYVALUES ) )
     {
       readImageData();
     }
-    else if ( ( imgfn != "" ) && ( channel == I_COLOR ) )
+      else if ( ( imgfn[0] != "" ) && ( channel == I_COLOR ) )
     {
       readImageDataRGB();
       assert ( hasColorInformation );
@@ -277,7 +367,41 @@ inline NICE::MultiChannelImageT<int> & CachedExample::getIChannel ( int channel
 
   return ichannels[channel];
 }
+*/
+inline NICE::MultiChannelImage3DT<int> & CachedExample::getIChannel ( int channel )
+{
+    assert ( ( channel >= 0 ) && ( channel < I_NUMCHANNELS ) );
 
+    if ( ( ichannels[channel].channels() == 0 ) )
+    {
+        if ( ( imgfn[0] != "" ) && ( channel == I_GRAYVALUES ) )
+        {
+            readImageData();
+        }
+        else if ( ( imgfn[0] != "" ) && ( channel == I_COLOR ) )
+        {
+            readImageDataRGB();
+            assert ( hasColorInformation );
+        }
+        else
+        {
+            std::map<int, std::string>::const_iterator j = itemps.find ( channel );
+            if ( j == itemps.end() )
+            {
+                //fprintf (stderr, "NICE::MultiChannelImageT: unable to recover data channel (int %d)!\n", channel);
+                //exit(-1);
+            }
+            else
+            {
+                //fprintf (stderr, "NICE::MultiChannelImageT: restoring data from %s\n", j->second.c_str() );
+                ichannels[channel].restore ( j->second );
+            }
+        }
+    }
+
+    return ichannels[channel];
+}
+/*
 inline NICE::MultiChannelImageT<long> & CachedExample::getLChannel ( int channel )
 {
   assert ( ( channel >= 0 ) && ( channel < L_NUMCHANNELS ) );
@@ -307,9 +431,39 @@ inline NICE::MultiChannelImageT<long> & CachedExample::getLChannel ( int channel
 
   return lchannels[channel];
 }
+*/
+inline NICE::MultiChannelImage3DT<long> & CachedExample::getLChannel ( int channel )
+{
+    assert ( ( channel >= 0 ) && ( channel < L_NUMCHANNELS ) );
+
+    if ( lchannels[channel].channels() == 0 )
+    {
+        std::map<int, std::string>::const_iterator j = ltemps.find ( channel );
+        if ( j == ltemps.end() )
+        {
+
+            if ( channel == L_INTEGRALIMAGE )
+            {
+                calcIntegralImage();
+            }
+            else
+            {
+                //fprintf (stderr, "NICE::MultiChannelImageT: unable to recover data channel (long %d)!\n", channel);
+                //exit(-1);
+            }
+        }
+        else
+        {
+            //fprintf (stderr, "NICE::MultiChannelImageT: restoring data from %s\n", j->second.c_str() );
+            lchannels[channel].restore ( j->second );
+        }
+    }
+
+    return lchannels[channel];
+}
 
 template<class ImgPixelValue>
-void CachedExample::dropImages ( NICE::MultiChannelImageT<ImgPixelValue> *images, std::map<int, std::string> & temps, int numImages )
+void CachedExample::dropImages ( NICE::MultiChannelImage3DT<ImgPixelValue> *images, std::map<int, std::string> & temps, int numImages )
 {
   for ( int i = 0 ; i < numImages; i++ )
   {

+ 192 - 111
cbaselib/Example.cpp

@@ -10,15 +10,15 @@ using namespace NICE;
 
 Example::Example()
 {
-	weight = 0.0;
-	height = 0;
-	width = 0;
-	x = 0;
-	y = 0;
-	vec = NULL;
-	svec = NULL;
-  ce = NULL;
-	position = 0;
+    weight = 0.0;
+    height = 0;
+    depth = 0;
+    width = 0;
+    x = y = z = 0;
+    vec = NULL;
+    svec = NULL;
+    ce = NULL;
+    position = 0;
 }
 
 Example::~Example ()
@@ -27,91 +27,147 @@ Example::~Example ()
 
 Example::Example ( CachedExample *_ce )
 {
-    _ce->getImageSize ( width, height );
+    if ( _ce->getNumImages() > 1 )
+    {
+        _ce->getImageSize3 ( width, height, depth );
+    }
+    else
+    {
+        _ce->getImageSize( width, height );
+        depth = 1;
+    }
 
-    if ( width % 2 == 0 )
-	width--;
+    if ( width % 2 == 0 ) width--;
 
-    if ( height % 2 == 0 )
-	height--;
+    if ( height % 2 == 0 ) height--;
+
+    if ( depth % 2 == 0 ) depth--;
 
     x = width/2;
     y = height/2;
+    z = depth/2;
 
-    ce = _ce; 
+    ce = _ce;
     vec = NULL;
     svec = NULL;
     weight = 1.0;
-	position = 0;
+    position = 0;
 }
 
-Example::Example ( CachedExample *_ce, 
-						   int _x,
-						   int _y,
-						   double _weight )
+Example::Example ( CachedExample *_ce,
+                   int _x,
+                   int _y,
+                   double _weight )
 {
     ce = _ce;
     x  = _x;
     y  = _y;
+    z  = 0;
     width = 0;
     height = 0;
+    depth = 0;
     vec = NULL;
     svec = NULL;
     weight = _weight;
-	position = 0;
+    position = 0;
 }
 
-Example::Example ( CachedExample *_ce, 
-						   int _x,
-						   int _y,
-						   int _width,
-						   int _height,
-						   double _weight )
+Example::Example ( CachedExample *_ce,
+                   int _x,
+                   int _y,
+                   int _z,
+                   double _weight )
 {
     ce = _ce;
     x  = _x;
     y  = _y;
+    z  = _z;
+    width = 0;
+    height = 0;
+    depth = 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;
+    z  = 0;
     width = _width;
     height = _height;
+    depth = 1;
     assert ( (width > 0) && (height > 0) );
 
     vec = NULL;
     svec = NULL;
     weight = _weight;
-	position = 0;
+    position = 0;
+}
+
+Example::Example ( CachedExample *_ce,
+                   int _x,
+                   int _y,
+                   int _z,
+                   int _width,
+                   int _height,
+                   int _depth,
+                   double _weight )
+{
+    ce = _ce;
+    x  = _x;
+    y  = _y;
+    z  = _z;
+    width = _width;
+    height = _height;
+    depth = _depth;
+    assert ( (width > 0) && (height > 0) && assert(depth > 0) );
+
+    vec = NULL;
+    svec = NULL;
+    weight = _weight;
+    position = 0;
 }
 
-Example::Example ( NICE::Vector *_vec, 
-						   double _weight )
+Example::Example ( NICE::Vector *_vec,
+                   double _weight )
 {
-    x = y = 0;
-    width = height = 0;
+    x = y = z = 0;
+    width = height = depth = 0;
     ce = NULL;
     vec = _vec;
     svec = NULL;
     weight = _weight;
-	position = 0;
+    position = 0;
 }
 
 void Example::clean ()
 {
-	if ( ce != NULL )
-	{
-		delete ce;
-		ce =  NULL;
-	}
+    if ( ce != NULL )
+    {
+        delete ce;
+        ce =  NULL;
+    }
+
+    if ( vec != NULL )
+    {
+        delete vec;
+        vec = NULL;
+    }
 
-	if ( vec != NULL )
-	{
-		delete vec;
-		vec = NULL;
-	}
-    
-	if ( svec != NULL )
-	{
-		delete svec;
-		svec = NULL;
-	}
+    if ( svec != NULL )
+    {
+        delete svec;
+        svec = NULL;
+    }
 }
 
 
@@ -122,79 +178,104 @@ Example::Example ( const Example &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;
+    vec = ex.vec;
+    svec = ex.svec;
+    weight = ex.weight;
+    position = ex.position;
+    width = ex.width;
+    height = ex.height;
+    depth = ex.depth;
+    x = ex.x;
+    y = ex.y;
+    z = ex.z;
+    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;
+    if ( format == 1 )
+    {
+        is >> weight;
+        is >> x;
+        is >> y;
+        is >> z;
+        is >> width;
+        is >> height;
+        is >> depth;
+        is >> position;
+    }
+    else
+    {
+        is >> weight;
+        is >> x;
+        is >> y;
+        is >> width;
+        is >> height;
+        is >> position;
+
+        depth = 1;
+        z = 0;
+    }
+
+    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] << " ";
-		}
-	}
+    if ( format == 1 )
+        os << weight << " " <<  x << " " << y << " " << z << " " << width << " " << height << " " << depth << " " << position << endl;
+    else
+        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();
-	}
+    for ( iterator i = begin(); i != end(); i++ )
+    {
+        Example & example = i->second;
+        example.clean();
+    }
     clear();
 }
 
@@ -230,7 +311,7 @@ bool Examples::wrapExamplesAroundFeatureMatrix(const Matrix &p_MatFeaturesColumW
         return false;
     p_Examples.resize( t_iNumSamples );
     const double *pDataPtr = p_MatFeaturesColumWiseSamples.getDataPointer();
-    
+
 #ifdef NICE_USELIB_OPENMP
 #pragma omp parallel for default(none) shared(p_VecLabels, p_Examples, t_iNumFeatures, t_iNumSamples, pDataPtr)
 #endif

+ 27 - 1
cbaselib/Example.h

@@ -4,7 +4,7 @@
 /**
 * @file Example.h
 * @brief data caching of several feature images and many more
-* @author Erik Rodner
+* @author Erik Rodner, Johannes Ruehle, Sven Sickert
 * @date 04/21/2008
 */
 
@@ -26,11 +26,15 @@ class Example
     long long int x;
     /** y position of window */
     long long int y;
+    /** z position of window */
+    long long int z;
 
     /** width of window */
     int width;
     /** height of window */
     int height;
+    /** depth of window */
+    int depth;
 
     //! if some examples are related, they have the same position
     int position;
@@ -61,6 +65,15 @@ class Example
     */
     Example ( CachedExample *ce, int x, int y, double weight = 1.0 );
 
+    /** constructor 3d
+        @param ce associated image data
+        @param x x position of window
+        @param y y position of window
+        @param z z position of window
+        @param weight weight of example
+    */
+    Example ( CachedExample *ce, int x, int y, int z, double weight = 1.0 );
+
     /** constructor
         @param ce associated image data
         @param x x position of window
@@ -69,6 +82,19 @@ class Example
     */
     Example ( CachedExample *ce, int x, int y, int width, int height, double weight = 1.0 );
 
+    /** constructor 3d
+        @param ce associated image data
+        @param x x position of window
+        @param y y position of window
+        @param z z position of window
+        @param width width of window
+        @param height height of window
+        @param depth depth of window
+        @param weight weight of example
+    */
+    Example ( CachedExample *ce, int x, int y, int z,
+                int width, int height, int depth, double weight = 1.0 );
+
     /** evil workaround: simple constructors for std::vector examples
         @param vec simple feature vector
         @param weight optional weight

+ 35 - 1
cbaselib/LabeledFileList.cpp

@@ -31,6 +31,27 @@ LabeledFileList::~LabeledFileList()
 {
 }
 
+int LabeledFileList::getClassFromNumber (
+    const std::string & lfile,
+    const int exampleID ) const
+{
+  int cvalue = -1;
+
+  std::ifstream file( lfile.c_str() );
+  std::string str;
+  while ( std::getline(file, str) )
+  {
+    NICE::Vector valList(2,0);
+    NICE::StringTools::splitVector( str, ',', valList );
+    if ( (int)valList[0] == exampleID )
+    {
+      cvalue = (int)valList[1];
+      break;
+    }
+  }
+
+  return cvalue;
+}
 
 /**
  * @brief Loads the label information according to a given label file format.
@@ -107,6 +128,19 @@ LocalizationResult *LabeledFileList::getLocalizationInfo ( const ClassNames & cl
     lr = new LocalizationResult ( &classnames, mask );
 
   }
+  else if ( format == "csv" ) {
+      // CAUTION! This is for experimental use only and needs a certain configuration of
+      // the csv file and scheme for the image file names!
+      NICE::ColorImage mask;
+      mask.read( file );
+      int exampleID = -1;
+      std::size_t found = file.find( "ID" );
+      std::string exampleIDStr = file.substr(found+2,found+8);
+      exampleID = std::atoi(exampleIDStr.c_str());
+      int g = getClassFromNumber( lfile, exampleID );
+      mask.set((uchar)g,(uchar)g,(uchar)g);
+      lr = new LocalizationResult ( &classnames, mask );
+  }
   else if ( format == "polygon" ) {
       lr = new LocalizationResult ( &classnames );
 
@@ -131,7 +165,7 @@ LocalizationResult *LabeledFileList::getLocalizationInfo ( const ClassNames & cl
   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() );

+ 3 - 0
cbaselib/LabeledFileList.h

@@ -53,6 +53,9 @@ class LabeledFileList
     * ( ::setFactory() ). [Johannes Ruehle]
     * @see LabeledSetFactory
     */
+        int getClassFromNumber( const std::string & lfile,
+                                const int exampleID ) const;
+
 	void get ( const std::string & dir,
 		   const NICE::Config & datasetconf,
 		   const ClassNames & classnames, 

+ 4 - 4
cbaselib/progs/testCachedExample.cpp

@@ -53,14 +53,14 @@ int main ( int argc, char **argv )
     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 );
+    NICE::MultiChannelImage3DT<int> & img = ce.getIChannel ( CachedExample::I_COLOR );
+    NICE::MultiChannelImage3DT<double> & imgc = ce.getDChannel ( CachedExample::D_INTEGRALCOLOR );
 
     imgc.reInitFrom ( img );
     for ( uint j = 0 ; j < img.channels(); j++ )
     {
-      ImageT<double> tmp = imgc[j];
-      GenericImageTools::calcIntegralImage ( tmp, img[j], img.width(), img.height() );
+      ImageT<double> tmp = imgc.getChannelT(j);
+      GenericImageTools::calcIntegralImage ( tmp, img.getChannel(j), img.width(), img.height() );
     }
 
     Image visimg = imgc.getChannel ( 0 );

+ 94 - 138
classifier/fpclassifier/randomforest/DTBObliqueLS.cpp

@@ -9,6 +9,9 @@
 #include <time.h>
 
 #include "DTBObliqueLS.h"
+#include "SCInformationGain.h"
+#include "SCGiniIndex.h"
+
 #include "vislearning/features/fpfeatures/ConvolutionFeature.h"
 
 #include "core/vector/Algorithms.h"
@@ -17,86 +20,37 @@ using namespace OBJREC;
 
 //#define DEBUGTREE
 
-
-using namespace std;
-using namespace NICE;
-
-DTBObliqueLS::DTBObliqueLS ( const Config *conf, string section )
+DTBObliqueLS::DTBObliqueLS ( const NICE::Config *conf, std::string section )
 {
     saveIndices = conf->gB( section, "save_indices", false);
-    useShannonEntropy = conf->gB( section, "use_shannon_entropy", false );
-    useOneVsOne = conf->gB( section, "use_one_vs_one", false );
     useDynamicRegularization = conf->gB( section, "use_dynamic_regularization", true );
+    multiClassMode = conf->gB( section, "multi_class_mode", 0 );
 
     splitSteps = conf->gI( section, "split_steps", 20 );
     maxDepth = conf->gI( section, "max_depth", 10 );
-    minExamples = conf->gI( section, "min_examples", 50);
     regularizationType = conf->gI( section, "regularization_type", 1 );
 
-    minimumEntropy = conf->gD( section, "minimum_entropy", 10e-5 );
-    minimumInformationGain = conf->gD( section, "minimum_information_gain", 10e-7 );
     lambdaInit = conf->gD( section, "lambda_init", 0.5 );
 
-}
-
-DTBObliqueLS::~DTBObliqueLS()
-{
+    std::string splitCrit = conf->gS( section, "split_criterion", "information_gain" );
+    if (splitCrit == "information_gain")
+        splitCriterion = new SCInformationGain( conf );
+    else if (splitCrit == "gini_index")
+        splitCriterion = new SCGiniIndex( conf );
+    else
+    {
+        std::cerr << "DTBObliqueLS::DTBObliqueLS: No valid splitting criterion defined!" << std::endl;
+        splitCriterion = NULL;
+    }
 
+    if ( conf->gB(section, "start_random_generator", true ) )
+        srand(time(NULL));
 }
 
-bool DTBObliqueLS::entropyLeftRight (
-        const FeatureValuesUnsorted & values,
-        double threshold,
-        double* stat_left,
-        double* stat_right,
-        double & entropy_left,
-        double & entropy_right,
-        double & count_left,
-        double & count_right,
-        int maxClassNo )
+DTBObliqueLS::~DTBObliqueLS()
 {
-    count_left = 0;
-    count_right = 0;
-    int count_unweighted_left = 0;
-    int count_unweighted_right = 0;
-    for ( FeatureValuesUnsorted::const_iterator i = values.begin();
-          i != values.end();
-          i++ )
-    {
-        int classno = i->second;
-        double value = i->first;
-        if ( value < threshold ) {
-            stat_left[classno] += i->fourth;
-            count_left+=i->fourth;
-            count_unweighted_left++;
-        }
-        else
-        {
-            stat_right[classno] += i->fourth;
-            count_right+=i->fourth;
-            count_unweighted_right++;
-        }
-    }
-
-    if (  (count_unweighted_left < minExamples)
-       || (count_unweighted_right < minExamples) )
-        return false;
-
-    entropy_left = 0.0;
-    for ( int j = 0 ; j <= maxClassNo ; j++ )
-        if ( stat_left[j] != 0 )
-            entropy_left -= stat_left[j] * log(stat_left[j]);
-    entropy_left /= count_left;
-    entropy_left += log(count_left);
-
-    entropy_right = 0.0;
-    for ( int j = 0 ; j <= maxClassNo ; j++ )
-        if ( stat_right[j] != 0 )
-            entropy_right -= stat_right[j] * log(stat_right[j]);
-    entropy_right /= count_right;
-    entropy_right += log (count_right);
-
-    return true;
+    if (splitCriterion != NULL)
+        delete splitCriterion;
 }
 
 bool DTBObliqueLS::adaptDataAndLabelForMultiClass (
@@ -105,25 +59,21 @@ bool DTBObliqueLS::adaptDataAndLabelForMultiClass (
         NICE::Matrix & X,
         NICE::Vector & y )
 {
-    bool posHasExamples = false;
-    bool negHasExamples = false;
     int posCount = 0;
     int negCount = 0;
 
     // One-vs-one: Transforming into {-1,0,+1} problem
-    if ( useOneVsOne )
+    if ( multiClassMode == 0 )
         for ( int i = 0; i < y.size(); i++ )
         {
             if ( y[i] == posClass )
             {
                 y[i] = 1.0;
-                posHasExamples = true;
                 posCount++;
             }
             else if ( y[i] == negClass )
             {
                 y[i] = -1.0;
-                negHasExamples = true;
                 negCount++;
             }
             else
@@ -133,27 +83,58 @@ bool DTBObliqueLS::adaptDataAndLabelForMultiClass (
             }
         }
     // One-vs-all: Transforming into {-1,+1} problem
-    else
+    else if ( multiClassMode == 1 )
         for ( int i = 0; i < y.size(); i++ )
         {
             if ( y[i] == posClass )
             {
                 y[i] = 1.0;
-                posHasExamples = true;
                 posCount++;
             }
             else
             {
                 y[i] = -1.0;
-                negHasExamples = true;
                 negCount++;
             }
         }
-
-    if ( posHasExamples && negHasExamples )
-        return true;
+    // Many-vs-many: Transforming into {-1,+1}
     else
-        return false;
+    {
+        // get existing classes
+        std::vector<double> unClass = y.std_vector();
+        std::sort( unClass.begin(), unClass.end() );
+        unClass.erase( std::unique( unClass.begin(), unClass.end() ), unClass.end() );
+
+        // randomly split set of classes into two buckets
+        std::random_shuffle ( unClass.begin(), unClass.end() );
+        int firstHalf = std::ceil(unClass.size()/2.0);
+        for ( int i = 0; i < y.size(); i++ )
+        {
+           bool wasFound = false;
+           int c = 0;
+           //assign new labels
+           while ( (!wasFound) && (c<firstHalf) )
+           {
+               if ( y[i] == unClass[c] )
+               {
+                   wasFound = true;
+               }
+               c++;
+           }
+           if (wasFound)
+           {
+               y[i] = 1.0;
+               posCount++;
+           }
+           else
+           {
+               y[i] = -1.0;
+               negCount++;
+           }
+        }
+    }
+
+    return ( (posCount>0) && (negCount>0));
 }
 
 /** refresh data matrix X and label vector y */
@@ -174,11 +155,11 @@ void DTBObliqueLS::getDataAndLabel(
     w = NICE::Vector(amountExamples, 1.0);
 
     int matIndex = 0;
-    for ( vector<int>::const_iterator si = examples_selection.begin();
+    for ( std::vector<int>::const_iterator si = examples_selection.begin();
           si != examples_selection.end();
           si++ )
     {
-        const pair<int, Example> & p = examples[*si];
+        const std::pair<int, Example> & p = examples[*si];
         const Example & ex = p.second;
 
         NICE::Vector pixelRepr (amountParams, 1.0);
@@ -277,7 +258,6 @@ void DTBObliqueLS::findBestSplitThreshold (
         FeatureValuesUnsorted &values,
         SplitInfo &bestSplitInfo,
         const NICE::Vector &params,
-        const double &e,
         const int &maxClassNo )
 {
     double *distribution_left = new double [maxClassNo+1];
@@ -295,7 +275,6 @@ void DTBObliqueLS::findBestSplitThreshold (
         double threshold = (i * (maxValue - minValue ) / (double)splitSteps)
                             + minValue;
         // preparations
-        double el, er;
         for ( int k = 0 ; k <= maxClassNo ; k++ )
         {
             distribution_left[k] = 0.0;
@@ -303,27 +282,20 @@ void DTBObliqueLS::findBestSplitThreshold (
         }
 
         /** Test the current split */
-        // Does another split make sense?
-        double count_left;
-        double count_right;
-        if ( ! entropyLeftRight ( values, threshold,
-                                  distribution_left, distribution_right,
-                                  el, er, count_left, count_right, maxClassNo ) )
-            continue;
+        SplittingCriterion *curSplit = splitCriterion->clone();
 
-        // information gain and entropy
-        double pl = (count_left) / (count_left + count_right);
-        double ig = e - pl*el - (1-pl)*er;
+        if ( ! curSplit->evaluateSplit ( values, threshold,
+                 distribution_left, distribution_right, maxClassNo ) )
+            continue;
 
-        if ( useShannonEntropy )
-        {
-            double esplit = - ( pl*log(pl) + (1-pl)*log(1-pl) );
-            ig = 2*ig / ( e + esplit );
-        }
+        // get value for impurity
+        double purity = curSplit->computePurity();
+        double entropy = curSplit->getEntropy();
 
-        if ( ig > bestSplitInfo.informationGain )
+        if ( purity > bestSplitInfo.purity )
         {
-            bestSplitInfo.informationGain = ig;
+            bestSplitInfo.purity = purity;
+            bestSplitInfo.entropy = entropy;
             bestSplitInfo.threshold = threshold;
             bestSplitInfo.params = params;
 
@@ -332,9 +304,9 @@ void DTBObliqueLS::findBestSplitThreshold (
                 bestSplitInfo.distLeft[k] = distribution_left[k];
                 bestSplitInfo.distRight[k] = distribution_right[k];
             }
-            bestSplitInfo.entropyLeft = el;
-            bestSplitInfo.entropyRight = er;
         }
+
+        delete curSplit;
     }
 
     //cleaning up
@@ -348,22 +320,22 @@ DecisionNode *DTBObliqueLS::buildRecursive(
         const Examples & examples,
         std::vector<int> & examples_selection,
         FullVector & distribution,
-        double e,
+        double entropy,
         int maxClassNo,
         int depth,
         double lambdaCurrent )
 {
 
     std::cerr << "DTBObliqueLS: Examples: " << (int)examples_selection.size()
-              << ", Depth: " << (int)depth << ", Entropy: " << e << std::endl;
+              << ", Depth: " << (int)depth << ", Entropy: " << entropy << std::endl;
 
     // initialize new node
     DecisionNode *node = new DecisionNode ();
     node->distribution = distribution;
 
-    // stop criteria: maxDepth, minExamples, min_entropy
-    if (    ( e <= minimumEntropy )
-//         || ( (int)examples_selection.size() < minExamples )
+    // stopping criteria
+    if (    ( entropy <= splitCriterion->getMinimumEntropy() )
+         || ( (int)examples_selection.size() < splitCriterion->getMinimumExamples() )
          || ( depth > maxDepth ) )
 
     {
@@ -378,11 +350,10 @@ DecisionNode *DTBObliqueLS::buildRecursive(
     FeatureValuesUnsorted values;
     SplitInfo bestSplitInfo;
     bestSplitInfo.threshold = 0.0;
-    bestSplitInfo.informationGain = -1.0;
+    bestSplitInfo.purity = -1.0;
+    bestSplitInfo.entropy = 0.0;
     bestSplitInfo.distLeft = new double [maxClassNo+1];
     bestSplitInfo.distRight = new double [maxClassNo+1];
-    bestSplitInfo.entropyLeft = 0.0;
-    bestSplitInfo.entropyRight = 0.0;
 
     ConvolutionFeature *f = (ConvolutionFeature*)fp.begin()->second;
     bestSplitInfo.params = f->getParameterVector();
@@ -402,10 +373,7 @@ DecisionNode *DTBObliqueLS::buildRecursive(
         int posClass, negClass;
 
         posClass = rand() % (maxClassNo+1);
-        negClass = posClass;
-
-        while ( posClass == negClass )
-            negClass = rand() % (maxClassNo+1);
+        negClass = (posClass + (rand() % maxClassNo)) % (maxClassNo+1);
 
         yCur = y;
         XCur = X;
@@ -434,22 +402,13 @@ DecisionNode *DTBObliqueLS::buildRecursive(
     f->calcFeatureValues( examples, examples_selection, values);
 
     // complete search for threshold
-    findBestSplitThreshold ( values, bestSplitInfo, params, e, maxClassNo );
+    findBestSplitThreshold ( values, bestSplitInfo, params, maxClassNo );
 
-//    f->setRandomParameterVector();
-//    params = f->getParameterVector();
-//    f->calcFeatureValues( examples, examples_selection, values);
-//    findBestSplitThreshold ( values, bestSplitInfo, params, e, maxClassNo );
-
-    // supress strange behaviour for values near zero (8.88178e-16)
-    if (bestSplitInfo.entropyLeft < 1.0e-10 ) bestSplitInfo.entropyLeft = 0.0;
-    if (bestSplitInfo.entropyRight < 1.0e-10 ) bestSplitInfo.entropyRight = 0.0;
-
-    // stop criteria: minimum information gain
-    if ( bestSplitInfo.informationGain < minimumInformationGain )
+    // stop criteria: minimum purity reached?
+    if ( bestSplitInfo.purity < splitCriterion->getMinimumPurity() )
     {
 #ifdef DEBUGTREE
-        std::cerr << "DTBObliqueLS: Minimum information gain reached!" << std::endl;
+        std::cerr << "DTBObliqueLS: Minimum purity reached!" << std::endl;
 #endif
         delete [] bestSplitInfo.distLeft;
         delete [] bestSplitInfo.distRight;
@@ -465,8 +424,8 @@ DecisionNode *DTBObliqueLS::buildRecursive(
     node->threshold = bestSplitInfo.threshold;
 
     /** Split examples according to best split function */
-    vector<int> examples_left;
-    vector<int> examples_right;
+    std::vector<int> examples_left;
+    std::vector<int> examples_right;
 
     examples_left.reserve ( values.size() / 2 );
     examples_right.reserve ( values.size() / 2 );
@@ -482,9 +441,6 @@ DecisionNode *DTBObliqueLS::buildRecursive(
 #ifdef DEBUGTREE
 //    node->f->store( std::cerr );
 //    std::cerr << std::endl;
-    std::cerr << "DTBObliqueLS: Information Gain: " << bestSplitInfo.informationGain
-              << ", Left Entropy: " <<  bestSplitInfo.entropyLeft << ", Right Entropy: "
-              << bestSplitInfo.entropyRight << std::endl;
 #endif
 
     FullVector distribution_left_sparse ( distribution.size() );
@@ -497,10 +453,10 @@ DecisionNode *DTBObliqueLS::buildRecursive(
             distribution_left_sparse[k] = l;
         if ( r != 0 )
             distribution_right_sparse[k] = r;
-//#ifdef DEBUGTREE
-//        std::cerr << "DTBObliqueLS: Split of Class " << k << " ("
-//                  << l << " <-> " << r << ") " << std::endl;
-//#endif
+#ifdef DEBUGTREE
+        std::cerr << "DTBObliqueLS: Split of Class " << k << " ("
+                  << l << " <-> " << r << ") " << std::endl;
+#endif
     }
 
     delete [] bestSplitInfo.distLeft;
@@ -526,11 +482,11 @@ DecisionNode *DTBObliqueLS::buildRecursive(
     /** Recursion */
     // left child
     node->left  = buildRecursive ( fp, examples, examples_left,
-                                   distribution_left_sparse, bestSplitInfo.entropyLeft,
+                                   distribution_left_sparse, bestSplitInfo.entropy,
                                    maxClassNo, depth+1, lambdaLeft );
     // right child
     node->right = buildRecursive ( fp, examples, examples_right,
-                                   distribution_right_sparse, bestSplitInfo.entropyRight,
+                                   distribution_right_sparse, bestSplitInfo.entropy,
                                    maxClassNo, depth+1, lambdaRight );
 
     return node;
@@ -544,7 +500,7 @@ DecisionNode *DTBObliqueLS::build ( const FeaturePool & fp,
     int index = 0;
 
     FullVector distribution ( maxClassNo+1 );
-    vector<int> all;
+    std::vector<int> all;
 
     all.reserve ( examples.size() );
     for ( Examples::const_iterator j = examples.begin();

+ 11 - 43
classifier/fpclassifier/randomforest/DTBObliqueLS.h

@@ -10,9 +10,11 @@
 
 #include "core/vector/VectorT.h"
 #include "core/vector/MatrixT.h"
-
 #include "core/basics/Config.h"
+
 #include "DecisionTreeBuilder.h"
+#include "SplittingCriterion.h"
+
 #include "vislearning/cbaselib/CachedExample.h"
 
 
@@ -20,9 +22,8 @@ namespace OBJREC {
 
 struct SplitInfo {
     double threshold;
-    double informationGain;
-    double entropyLeft;
-    double entropyRight;
+    double purity;
+    double entropy;
     double *distLeft;
     double *distRight;
     NICE::Vector params;
@@ -39,14 +40,14 @@ class DTBObliqueLS : public DecisionTreeBuilder
     /////////////////////////
     /////////////////////////
 
-    /** Whether to use shannon entropy or not */
-    bool useShannonEntropy;
-
+    /** Splitting criterion */
+    SplittingCriterion *splitCriterion;
+    
     /** Whether to save indices in leaves or not */
     bool saveIndices;
 
-    /** Whether to use one-vs-one or one-vs-all for multiclass scenarios */
-    bool useOneVsOne;
+    /** Whether to use one-vs-one (0), one-vs-all (1) or many-vs-many (2) for multiclass scenarios */
+    int multiClassMode;
 
     /** Whether to increase the influence of regularization over time or not */
     bool useDynamicRegularization;
@@ -57,18 +58,9 @@ class DTBObliqueLS : public DecisionTreeBuilder
     /** Maximum allowed depth of a tree */
     int maxDepth;
 
-    /* Minimum amount of features in a leaf node */
-    int minExamples;
-
     /** Regularization type */
     int regularizationType;
 
-    /** Minimum entropy to continue with splitting */
-    double minimumEntropy;
-
-    /** Minimum information gain to continue with splitting */
-    double minimumInformationGain;
-
     /** Regularization parameter */
     double lambdaInit;
 
@@ -126,14 +118,13 @@ class DTBObliqueLS : public DecisionTreeBuilder
      * @brief find best threshold for current splitting
      * @param values feature values
      * @param bestSplitInfo struct including best split information
-     * @param e entropy before split
+     * @param params parameter vector for oblique decision
      * @param maxClassNo maximum class number
      */
     void findBestSplitThreshold (
             FeatureValuesUnsorted & values,
             SplitInfo & bestSplitInfo,
             const NICE::Vector & params,
-            const double & e,
             const int & maxClassNo );
 
     /**
@@ -157,29 +148,6 @@ class DTBObliqueLS : public DecisionTreeBuilder
            int depth,
            double curLambda );
 
-    /**
-     * @brief compute entropy for left and right child
-     * @param values feature values
-     * @param threshold threshold for split
-     * @param stat_left statistics for left child
-     * @param stat_right statistics for right child
-     * @param entropy_left entropy for left child
-     * @param entropy_right entropy for right child
-     * @param count_left amount of features in left child
-     * @param count_right amount of features in right child
-     * @param maxClassNo maximum class number
-     * @return whether another split is possible or not
-     */
-    bool entropyLeftRight ( const FeatureValuesUnsorted & values,
-           double threshold,
-           double* stat_left,
-           double* stat_right,
-           double & entropy_left,
-           double & entropy_right,
-           double & count_left,
-           double & count_right,
-           int maxClassNo );
-
   public:
 
     /** simple constructor */

+ 2 - 2
classifier/fpclassifier/randomforest/FPCRandomForests.cpp

@@ -357,7 +357,7 @@ void FPCRandomForests::train(FeaturePool & fp, Examples & examples)
 		/******* training of an individual tree ****/
 		DecisionTree *tree = new DecisionTree(conf, maxClassNo);
 
-        #pragma omp critical
+        //#pragma omp critical
         builder->build(*tree, fp_subset, examples_subset, maxClassNo);
 
 		/******* prune tree using a simple minimum entropy criterion *****/
@@ -406,7 +406,7 @@ void FPCRandomForests::restore(istream & is, int format)
         {
             is >> index;
             DecisionTree *dt = new DecisionTree ( conf, maxClassNo );
-            dt->restore ( is );
+            dt->restore ( is, format );
             if ( minimum_entropy != 0.0 )
                 dt->pruneTreeEntropy ( minimum_entropy );
 

+ 149 - 0
classifier/fpclassifier/randomforest/SCGiniIndex.cpp

@@ -0,0 +1,149 @@
+/**
+ * @file SCGiniIndex.cpp
+ * @brief the Gini index splitting criterion
+ * @author Sven Sickert
+ * @date 01/16/2017
+
+*/
+#include "SCGiniIndex.h"
+
+using namespace OBJREC;
+
+/* default constructor */
+SCGiniIndex::SCGiniIndex()
+    : SplittingCriterion ()
+{
+    count_left  = 0.0;
+    count_right = 0.0;
+    gini_left   = 0.0;
+    gini_right  = 0.0;
+}
+
+/* simple constructor */
+SCGiniIndex::SCGiniIndex( int _min_examples )
+    : SplittingCriterion ( _min_examples )
+{
+    count_left  = 0.0;
+    count_right = 0.0;
+    gini_left   = 0.0;
+    gini_right  = 0.0;
+}
+
+/* config constructor */
+SCGiniIndex::SCGiniIndex( const NICE::Config *conf )
+    : SplittingCriterion ( conf )
+{
+    count_left  = 0.0;
+    count_right = 0.0;
+    gini_left   = 0.0;
+    gini_right  = 0.0;
+}
+
+/* copy constructor */
+SCGiniIndex::SCGiniIndex( const SCGiniIndex &obj )
+{
+    min_examples  = obj.min_examples;
+    min_entropy   = obj.min_entropy;
+    min_purity    = obj.min_purity;
+    entropy_cur   = obj.entropy_cur;
+    count_left    = obj.count_left;
+    count_right   = obj.count_right;
+    gini_left     = obj.gini_left;
+    gini_right    = obj.gini_right;
+}
+
+/* simple destructor */
+SCGiniIndex::~SCGiniIndex()
+{
+}
+
+/* cloning function */
+SplittingCriterion* SCGiniIndex::clone()
+{
+    SplittingCriterion* sc = new SCGiniIndex( *this );
+    return sc;
+}
+
+double SCGiniIndex::computeGiniIndex(
+        const double* distribution,
+        const double count,
+        const int maxClassNo )
+{
+    double g_sum = 0.0;
+
+    for ( int j = 0 ; j <= maxClassNo ; j++ )
+    {
+        double p = distribution[j] / count;
+        g_sum += p*p;
+    }
+
+    return (1-g_sum);
+}
+
+bool SCGiniIndex::evaluateSplit(
+        const FeatureValuesUnsorted & values,
+        double threshold,
+        double* distribution_left,
+        double* distribution_right,
+        int maxClassNo )
+{
+    this->count_left = 0;
+    this->count_right = 0;
+    int count_unweighted_left = 0;
+    int count_unweighted_right = 0;
+
+    double *distribution = new double [maxClassNo+1];
+    for ( int c = 0; c <= maxClassNo; c++ )
+        distribution[c] = 0.0;
+
+    for ( FeatureValuesUnsorted::const_iterator i = values.begin();
+          i != values.end();
+          i++ )
+    {
+        int classno = i->second;
+        double value = i->first;
+        double weight = i->fourth;
+        
+        distribution[classno] += weight;
+        if ( value < threshold ) {
+            distribution_left[classno] += weight;
+            this->count_left += weight;
+            count_unweighted_left++;
+        }
+        else
+        {
+            distribution_right[classno] += weight;
+            this->count_right += weight;
+            count_unweighted_right++;
+        }
+    }
+
+    if (  (count_unweighted_left < this->min_examples)
+       || (count_unweighted_right < this->min_examples) )
+    {
+        delete [] distribution;
+        return false;
+    }
+
+    // current entropy
+    this->entropy_cur = computeEntropy( distribution, this->count_left+this->count_right, maxClassNo );
+
+    // left Gini index
+    this->gini_left   = computeGiniIndex( distribution_left, this->count_left, maxClassNo );
+
+    // right Gini index
+    this->gini_right  = computeGiniIndex( distribution_right, this->count_right, maxClassNo );
+    
+    delete [] distribution;
+    return true;
+}
+
+double SCGiniIndex::computePurity() const
+{
+    double p_left = (this->count_left) / (this->count_left + this->count_right);
+
+    // computing Gini impurity
+    double gi = p_left*this->gini_left + (1-p_left)*this->gini_right;
+
+    return (1-gi);
+}

+ 83 - 0
classifier/fpclassifier/randomforest/SCGiniIndex.h

@@ -0,0 +1,83 @@
+/**
+ * @file SCGiniIndex.h
+ * @brief the Gini index splitting criterion
+ * @author Sven Sickert
+ * @date 01/16/2017
+
+*/
+#ifndef SCGiniIndexINCLUDE
+#define SCGiniIndexINCLUDE
+
+#include "SplittingCriterion.h"
+
+namespace OBJREC {
+
+class SCGiniIndex : public SplittingCriterion
+{
+  protected:
+
+    double gini_left,
+           gini_right,
+           count_left,
+           count_right;
+
+    /**
+     * @brief computation of Gini index
+     * @param distribution given distribution
+     * @param count amount of samples
+     * @param maxClassNo maximum class number
+     * @return computed Gini index
+     */
+    double computeGiniIndex(
+        const double* distribution,
+        const double count ,
+        const int maxClassNo );
+
+  public:
+
+    /* default constructor */
+    SCGiniIndex();
+
+    /* simple constructor */
+    SCGiniIndex( int _min_examples );
+
+    /** config constructor */
+    SCGiniIndex( const NICE::Config *conf );
+
+    /** copy constructor */
+    SCGiniIndex( const SCGiniIndex &obj );
+
+    /* simple destructor */
+    virtual ~SCGiniIndex();
+
+    /* cloning function */
+    virtual SplittingCriterion* clone();
+
+    /**
+     * @brief evaluate the split and return if split is possible
+     * @param values unsorted list of feature values of a certain dimension
+     * @param threshold threshold for current feature dimension
+     * @param distribution_left class distribution for left child node after splitting
+     * @param distribution_right class distribution for right child node after splitting
+     * @param maxClassNo maximum class number
+     * @return possible split or not
+     */
+    virtual bool evaluateSplit(
+        const FeatureValuesUnsorted & values,
+        double threshold,
+        double* distribution_left,
+        double* distribution_right,
+        int maxClassNo );
+
+    /**
+     * @brief compute purity based on given split
+     * @return purity value
+     */
+    double computePurity() const;
+
+};
+
+} // namespace
+
+
+#endif

+ 143 - 0
classifier/fpclassifier/randomforest/SCInformationGain.cpp

@@ -0,0 +1,143 @@
+/**
+ * @file SCInformationGain.cpp
+ * @brief the information gain splitting criterion
+ * @author Sven Sickert
+ * @date 01/12/2017
+
+*/
+#include "SCInformationGain.h"
+
+using namespace OBJREC;
+
+/* default constructor */
+SCInformationGain::SCInformationGain()
+    : SplittingCriterion ()
+{
+    entropy_left  = 0.0;
+    entropy_right = 0.0;
+    count_left  = 0.0;
+    count_right = 0.0;
+    use_shannon_entropy = false;
+}
+
+/* simple constructor */
+SCInformationGain::SCInformationGain( int _min_examples )
+    : SplittingCriterion ( _min_examples )
+{
+    entropy_left  = 0.0;
+    entropy_right = 0.0;
+    count_left  = 0.0;
+    count_right = 0.0;
+    use_shannon_entropy = false;
+}
+
+/* config constructor */
+SCInformationGain::SCInformationGain( const NICE::Config *conf )
+    : SplittingCriterion ( conf )
+{
+    entropy_left = 0.0;
+    entropy_right = 0.0;
+    count_left  = 0.0;
+    count_right = 0.0;
+    use_shannon_entropy = conf->gB ( "SplittingCriterion",
+                                     "use_shannon_entropy",
+                                     false );
+}
+
+/* copy constructor */
+SCInformationGain::SCInformationGain( const SCInformationGain &obj )
+{
+    min_examples  = obj.min_examples;
+    min_entropy   = obj.min_entropy;
+    min_purity    = obj.min_purity;
+    entropy_left  = obj.entropy_left;
+    entropy_right = obj.entropy_right;
+    entropy_cur   = obj.entropy_cur;
+    count_left    = obj.count_left;
+    count_right   = obj.count_right;
+    use_shannon_entropy = obj.use_shannon_entropy;
+}
+
+/* simple destructor */
+SCInformationGain::~SCInformationGain()
+{
+}
+
+/* cloning function */
+SplittingCriterion* SCInformationGain::clone()
+{
+    SplittingCriterion* sc = new SCInformationGain( *this );
+    return sc;
+}
+
+bool SCInformationGain::evaluateSplit(
+        const FeatureValuesUnsorted & values,
+        double threshold,
+        double* distribution_left,
+        double* distribution_right,
+        int maxClassNo )
+{
+    this->count_left = 0;
+    this->count_right = 0;
+    int count_unweighted_left = 0;
+    int count_unweighted_right = 0;
+
+    double *distribution = new double [maxClassNo+1];
+    for ( int c = 0; c <= maxClassNo; c++ )
+        distribution[c] = 0.0;
+
+    for ( FeatureValuesUnsorted::const_iterator i = values.begin();
+          i != values.end();
+          i++ )
+    {
+        int classno = i->second;
+        double value = i->first;
+        double weight = i->fourth;
+        
+        distribution[classno] += weight;
+        if ( value < threshold ) {
+            distribution_left[classno] += weight;
+            this->count_left += weight;
+            count_unweighted_left++;
+        }
+        else
+        {
+            distribution_right[classno] += weight;
+            this->count_right += weight;
+            count_unweighted_right++;
+        }
+    }
+
+    if (  (count_unweighted_left < this->min_examples)
+       || (count_unweighted_right < this->min_examples) )
+    {
+        delete [] distribution;
+        return false;
+    }
+
+    // current entropy
+    this->entropy_cur  = computeEntropy( distribution, this->count_left+this->count_right, maxClassNo );
+
+    // entropy for left child
+    this->entropy_left = computeEntropy( distribution_left, this->count_left, maxClassNo );
+
+    // entropy for right child
+    this->entropy_right = computeEntropy( distribution_right, this->count_right, maxClassNo );
+
+    delete [] distribution;
+    return true;
+}
+
+double SCInformationGain::computePurity() const
+{
+    double p_left = (this->count_left) / (this->count_left + this->count_right);
+    double ig = this->entropy_cur - p_left*this->entropy_left - (1-p_left)*this->entropy_right;
+
+    if ( use_shannon_entropy )
+    {
+        double entropy_split = -( p_left*log(p_left) + (1-p_left)*log(1-p_left) );
+        ig = 2*ig / ( this->entropy_cur + entropy_split );
+    }
+    
+    return ig;
+}

+ 73 - 0
classifier/fpclassifier/randomforest/SCInformationGain.h

@@ -0,0 +1,73 @@
+/**
+ * @file SCInformationGain.h
+ * @brief the information gain splitting criterion
+ * @author Sven Sickert
+ * @date 01/12/2017
+
+*/
+#ifndef SCInformationGainINCLUDE
+#define SCInformationGainINCLUDE
+
+#include "SplittingCriterion.h"
+
+namespace OBJREC {
+
+class SCInformationGain : public SplittingCriterion
+{
+  protected:
+
+    double entropy_left,
+           entropy_right,
+           count_left,
+           count_right;
+
+    bool   use_shannon_entropy;
+
+  public:
+
+    /* default constructor */
+    SCInformationGain();
+
+    /* simple constructor */
+    SCInformationGain( int _min_examples );
+
+    /** config constructor */
+    SCInformationGain( const NICE::Config *conf );
+
+    /** copy constructor */
+    SCInformationGain( const SCInformationGain &obj );
+
+    /* simple destructor */
+    virtual ~SCInformationGain();
+
+    /* cloning function */
+    virtual SplittingCriterion* clone();
+
+    /**
+     * @brief evaluate the split and return if split is possible
+     * @param values unsorted list of feature values of a certain dimension
+     * @param threshold threshold for current feature dimension
+     * @param distribution_left class distribution for left child node after splitting
+     * @param distribution_right class distribution for right child node after splitting
+     * @param maxClassNo maximum class number
+     * @return possible split or not
+     */
+    virtual bool evaluateSplit(
+        const FeatureValuesUnsorted & values,
+        double threshold,
+        double* distribution_left,
+        double* distribution_right,
+        int maxClassNo );
+
+    /**
+     * @brief compute purity based on given split
+     * @return purity value
+     */
+    double computePurity() const;
+
+};
+    
+} // namespace
+
+
+#endif

+ 69 - 0
classifier/fpclassifier/randomforest/SplittingCriterion.cpp

@@ -0,0 +1,69 @@
+/**
+ * @file SplittingCriterion.cpp
+ * @brief abstract interface for splitting criteria
+ * @author Sven Sickert
+ * @date 01/12/2017
+
+*/
+#include "SplittingCriterion.h"
+
+using namespace OBJREC;
+
+/* default constructor */
+SplittingCriterion::SplittingCriterion()
+{
+    min_examples = 50;
+    entropy_cur = 0.0;
+    min_entropy = 10e-5;
+    min_purity = 10e-7;
+}
+
+/* simple constructor */
+SplittingCriterion::SplittingCriterion( int _min_examples )
+{
+    min_examples = _min_examples;
+    entropy_cur = 0.0;
+    min_entropy = 10e-5;
+    min_purity = 10e-7;
+}
+
+/* config constructor */
+SplittingCriterion::SplittingCriterion( const NICE::Config *conf )
+{
+    min_examples = conf->gI ( "SplittingCriterion", "min_examples", 50 );
+    min_entropy = conf->gD ( "SplittingCriterion", "min_entropy", 10e-5 );
+    min_purity = conf->gD ( "SplittingCriterion", "min_purity", 10e-7 );
+    entropy_cur = 0.0;
+}
+
+/* copy constructor */
+SplittingCriterion::SplittingCriterion( const SplittingCriterion &obj )
+{
+    min_examples = obj.min_examples;
+    min_entropy = obj.min_entropy;
+    min_purity = obj.min_purity;
+    entropy_cur = obj.entropy_cur;
+}
+
+/* default destructor */
+SplittingCriterion::~SplittingCriterion()
+{
+}
+
+/* computation of entropy */
+double SplittingCriterion::computeEntropy(
+        const double* distribution,
+        const double count,
+        const int maxClassNo )
+{
+    double e = 0.0;
+
+    for ( int j = 0 ; j <= maxClassNo ; j++ )
+        if ( distribution[j] != 0 )
+            e -= distribution[j] * log(distribution[j]);
+
+    e /= count;
+    e += log(count);
+
+    return e;
+}

+ 115 - 0
classifier/fpclassifier/randomforest/SplittingCriterion.h

@@ -0,0 +1,115 @@
+/**
+ * @file SplittingCriterion.h
+ * @brief abstract interface for splitting criteria
+ * @author Sven Sickert
+ * @date 01/12/2017
+
+*/
+#ifndef SplittingCriterionINCLUDE
+#define SplittingCriterionINCLUDE
+
+#include "core/basics/Config.h"
+#include "vislearning/cbaselib/Feature.h"
+
+namespace OBJREC {
+    
+/* abstract interface for splitting criteria */
+class SplittingCriterion
+{
+  protected:
+    int min_examples;
+    double entropy_cur;
+    double min_entropy;
+    double min_purity;
+
+    /**
+     * @brief computation of entropy
+     * @param distribution given distribution
+     * @param count amount of samples
+     * @param maxClassNo maximum class number
+     * @return computed entropy
+     */
+    double computeEntropy(
+        const double* distribution,
+        const double count ,
+        const int maxClassNo );
+
+  public:
+
+    /** default constructor */
+    SplittingCriterion( );
+    
+    /** simple constructor */
+    SplittingCriterion( int _min_examples );
+
+    /** config constructor */
+    SplittingCriterion( const NICE::Config *conf );
+
+    /** copy constructor */
+    SplittingCriterion( const SplittingCriterion &obj );
+
+    /** default destructor */
+    virtual ~SplittingCriterion();
+
+    /** cloning functioning */
+    virtual SplittingCriterion* clone() = 0;
+
+    /**
+     * @brief evaluate the split and return if split is possible
+     * @param values unsorted list of feature values of a certain dimension
+     * @param threshold threshold for current feature dimension
+     * @param distribution_left class distribution for left child node after splitting
+     * @param distribution_right class distribution for right child node after splitting
+     * @param maxClassNo maximum class number
+     * @return possible split or not
+     */
+    virtual bool evaluateSplit(
+        const FeatureValuesUnsorted & values,
+        double threshold,
+        double* distribution_left,
+        double* distribution_right,
+        int maxClassNo ) = 0;
+
+    /**
+     * @brief compute purity based on given split
+     * @return purity value
+     */
+    virtual double computePurity() const = 0;
+
+    /**
+     * @brief return entropy value
+     */
+    double getEntropy() const
+    {
+        return entropy_cur;
+    }
+
+    /**
+     * @brief return minimum allowed entropy value
+     */
+    double getMinimumEntropy() const
+    {
+        return min_entropy;
+    }
+
+    /**
+     * @brief return target purity value
+     */
+    double getMinimumPurity() const
+    {
+        return min_purity;
+    }
+
+    /**
+     * @brief return allowed minmum amount of examples
+     */
+    int getMinimumExamples() const
+    {
+        return min_examples;
+    }
+
+};
+    
+}  // namespace
+
+#endif

+ 2 - 2
features/fpfeatures/ColorHistogramFeature.cpp

@@ -39,8 +39,8 @@ ColorHistogramFeature::~ColorHistogramFeature()
 
 double ColorHistogramFeature::val ( const Example *example ) const
 {
-  const NICE::MultiChannelImageT<double> & img =
-    example->ce->getDChannel ( CachedExample::D_INTEGRALCOLOR );
+  const NICE::MultiChannelImage3DT<double> & img =
+  example->ce->getDChannel ( CachedExample::D_INTEGRALCOLOR );
   int tm_xsize = img.width();
   int tm_ysize = img.height();
 

+ 77 - 28
features/fpfeatures/ConvolutionFeature.cpp

@@ -2,7 +2,7 @@
 * @file ConvolutionFeature.cpp
 * @brief convolutional feature
 * @author Sven Sickert
-* @date 10/13/2008
+* @date 10/13/2014
 
 */
 #include <iostream>
@@ -25,6 +25,7 @@ ConvolutionFeature::ConvolutionFeature ( )
 {
     window_size_x = 15;
     window_size_y = 15;
+    window_size_z = 1;
     isColor = false;
     useSpatialPriors = false;
 
@@ -40,6 +41,24 @@ ConvolutionFeature::ConvolutionFeature (
 {
     window_size_x = wsize_x;
     window_size_y = wsize_y;
+    window_size_z = 1;
+    isColor = color;
+    useSpatialPriors = prior;
+
+    initializeParameterVector();
+}
+
+/** alternative 3d constructor */
+ConvolutionFeature::ConvolutionFeature (
+        const int wsize_x,
+        const int wsize_y,
+        const int wsize_z,
+        const bool color,
+        const bool prior )
+{
+    window_size_x = wsize_x;
+    window_size_y = wsize_y;
+    window_size_z = wsize_z;
     isColor = color;
     useSpatialPriors = prior;
 
@@ -52,6 +71,7 @@ ConvolutionFeature::ConvolutionFeature ( const Config *conf )
     std::string section = "ConvolutionFeature";
     window_size_x = conf->gI ( section, "window_size_x", 15 );
     window_size_y = conf->gI ( section, "window_size_y", 15 );
+    window_size_z = conf->gI ( section, "window_size_z", 1 );
     isColor = conf->gB ( section, "is_color", false );
     useSpatialPriors = conf->gB ( section, "use_spatial_priors", false );
 
@@ -63,6 +83,7 @@ ConvolutionFeature::ConvolutionFeature ( const ConvolutionFeature *confFeat )
 {
     window_size_x = confFeat->window_size_x;
     window_size_y = confFeat->window_size_y;
+    window_size_z = confFeat->window_size_z;
     paramsLength = confFeat->paramsLength;
     isColor = confFeat->isColor;
     useSpatialPriors = confFeat->useSpatialPriors;
@@ -88,14 +109,14 @@ ConvolutionFeature::~ConvolutionFeature ( )
 /** (re)initialize parameter vector */
 void ConvolutionFeature::initializeParameterVector()
 {
-    if (window_size_x > 0 && window_size_y > 0)
+    if (window_size_x > 0 && window_size_y > 0 && window_size_z > 0)
     {
         if (isColor)
             numChannels = 3;
         else
             numChannels = 1;
 
-        paramsLength = numChannels*window_size_x*window_size_y + 1;
+        paramsLength = numChannels*window_size_x*window_size_y*window_size_z + 1;
 
         if (useSpatialPriors) paramsLength += 2;
 
@@ -124,33 +145,38 @@ void ConvolutionFeature::getFeatureVector(
         const Example *example,
         NICE::Vector & vec ) const
 {
-    NICE::MultiChannelImageT<double> * imgD = NULL;
+    NICE::MultiChannelImage3DT<double> * imgD = NULL;
     imgD = & example->ce->getDChannel( CachedExample::D_EOH );
-    double** data = imgD->getDataPointer();
+    std::vector<double*> data = imgD->getDataPointer();
 
-    int xsize, ysize;
-    example->ce->getImageSize( xsize, ysize );
+    int xsize, ysize, zsize;
+    example->ce->getImageSize3( xsize, ysize, zsize );
 
     const int x = example->x;
     const int y = example->y;
+    const int z = example->z;
     const int halfwsx = std::floor ( window_size_x / 2 );
     const int halfwsy = std::floor ( window_size_y / 2 );
+    const int halfwsz = std::floor ( window_size_z / 2 );
     //const int step = window_size_x*window_size_y;
 
     int k = 1;
     for ( int c = 0; c < numChannels; c++)
-        for ( int v = -halfwsy; v <= halfwsy; v++ )
-            for ( int u = -halfwsx; u <= halfwsx; u++, k++ )
-            {
-                int uu = u;
-                int vv = v;
-                if (x+u < 0 || x+u >= xsize) uu=-u;
-                if (y+v < 0 || y+v >= ysize) vv=-v;
-
-                //vec[k] = imgD->get(x+uu,y+vv,c);
-                vec[k] = data[c][(x+uu)+(y+vv)*xsize];
-
-            }
+        for ( int w = -halfwsz; w <= halfwsz; w++ )
+            for ( int v = -halfwsy; v <= halfwsy; v++ )
+                for ( int u = -halfwsx; u <= halfwsx; u++, k++ )
+                {
+                    int uu = u;
+                    int vv = v;
+                    int ww = w;
+                    if (x+u < 0 || x+u >= xsize) uu=-u;
+                    if (y+v < 0 || y+v >= ysize) vv=-v;
+                    if (z+w < 0 || z+w >= zsize) ww=-w;
+
+                    //vec[k] = imgD->get(x+uu,y+vv,c);
+                    vec[k] = data[c][(x+uu)+(y+vv)*xsize+(z+ww)*xsize*ysize];
+
+                }
 
     if (useSpatialPriors)
     {
@@ -228,6 +254,7 @@ void ConvolutionFeature::explode ( FeaturePool &featurePool, bool variableWindow
     ConvolutionFeature *f = new ConvolutionFeature (
                 this->window_size_x,
                 this->window_size_y,
+                this->window_size_z,
                 this->isColor,
                 this->useSpatialPriors );
 
@@ -240,6 +267,7 @@ Feature *ConvolutionFeature::clone ( ) const
     ConvolutionFeature *f = new ConvolutionFeature (
                 this->window_size_x,
                 this->window_size_y,
+                this->window_size_z,
                 this->isColor,
                 this->useSpatialPriors );
 
@@ -255,24 +283,34 @@ Feature *ConvolutionFeature::generateFirstParameter () const
 
 void ConvolutionFeature::restore ( std::istream & is, int format )
 {
-    is >> window_size_x;
-    is >> window_size_y;
+    if ( format == 1 )
+    {
+        is >> window_size_x;
+        is >> window_size_y;
+        is >> window_size_z;
+    }
+    else
+    {
+        is >> window_size_x;
+        is >> window_size_y;
+        window_size_z = 1;
+    }
     is >> paramsLength;
 
     isColor = false;
     useSpatialPriors = false;
     numChannels = 1;
 
-    if ( paramsLength == (window_size_x*window_size_y+3) )
+    if ( paramsLength == (window_size_x*window_size_y*window_size_z+3) )
     {
         useSpatialPriors = true;
     }
-    else if ( paramsLength == (3*window_size_x*window_size_y+1) )
+    else if ( paramsLength == (3*window_size_x*window_size_y*window_size_z+1) )
     {
         isColor = true;
         numChannels = 3;
     }
-    else if ( paramsLength == (3*window_size_x*window_size_y+3) )
+    else if ( paramsLength == (3*window_size_x*window_size_y*window_size_z+3) )
     {
         isColor = true;
         numChannels = 3;
@@ -287,10 +325,21 @@ void ConvolutionFeature::restore ( std::istream & is, int format )
 
 void ConvolutionFeature::store ( std::ostream & os, int format ) const
 {
-    os << "ConvolutionFeature "
-       << window_size_x << " "
-       << window_size_y << " "
-       << paramsLength;
+    if ( format == 1 )
+    {
+        os << "ConvolutionFeature "
+           << window_size_x << " "
+           << window_size_y << " "
+           << window_size_z << " "
+           << paramsLength;
+    }
+    else
+    {
+        os << "ConvolutionFeature "
+           << window_size_x << " "
+           << window_size_y << " "
+           << paramsLength;
+    }
 
     for ( NICE::Vector::const_iterator it = params->begin();
           it != params->end(); ++it )

+ 9 - 1
features/fpfeatures/ConvolutionFeature.h

@@ -2,7 +2,7 @@
 * @file ConvolutionFeature.h
 * @brief convolutional feature
 * @author Sven Sickert
-* @date 10/13/2008
+* @date 10/13/2014
 
 */
 #ifndef ConvolutionFeatureINCLUDE
@@ -32,6 +32,7 @@ class ConvolutionFeature : public Feature
     /** feature parameter */
     int window_size_x;
     int window_size_y;
+    int window_size_z;
     int paramsLength;
     int numChannels;
     bool isColor;
@@ -59,6 +60,13 @@ class ConvolutionFeature : public Feature
                          const bool color = false,
                          const bool prior = false );
 
+    /** alternative 3d constructor */
+    ConvolutionFeature ( const int wsize_x,
+                         const int wsize_y,
+                         const int wsize_z,
+                         const bool color = false,
+                         const bool prior = false );
+
     /** default constructor */
     ConvolutionFeature ( const NICE::Config *conf );
 

+ 1 - 1
features/fpfeatures/EOHFeature.cpp

@@ -39,7 +39,7 @@ EOHFeature::~EOHFeature()
 
 double EOHFeature::val ( const Example *example ) const
 {
-  const NICE::MultiChannelImageT<double> & img = example->ce->getDChannel (
+  const NICE::MultiChannelImage3DT<double> & img = example->ce->getDChannel (
         CachedExample::D_INTEGRALEOH );
 
   int xsize;

+ 11 - 11
features/fpfeatures/FIGradients.cpp

@@ -17,29 +17,29 @@ void FIGradients::buildEOHMap ( CachedExample *ce,
   int xsize_s = xsize / subsamplex;
   int ysize_s = ysize / subsampley;
 
-  NICE::MultiChannelImageT<double> & eohimg = ce->getDChannel ( CachedExample::D_EOH );
-  eohimg.reInit ( xsize_s, ysize_s, numBins);
+  NICE::MultiChannelImage3DT<double> & eohimg = ce->getDChannel ( CachedExample::D_EOH );
+  eohimg.reInit ( xsize_s, ysize_s, 1, numBins);
 
   double *gradient = new double[xsize*ysize];
   int *dir = new int[xsize*ysize];
 
   if ( ce->colorInformationAvailable() ) {
-    NICE::MultiChannelImageT<int> & colorimg = ce->getIChannel ( CachedExample::I_COLOR );
-    int **data = colorimg.getDataPointer();
+    NICE::MultiChannelImage3DT<int> & colorimg = ce->getIChannel ( CachedExample::I_COLOR );
+    std::vector<int*> data = colorimg.getDataPointer();
     const int *r = data[0];
     const int *g = data[1];
     const int *b = data[2];
     FastFilter::calcColorGradient ( r, g, b, xsize, ysize,
                                     gradient, dir, numBins, usesigned );
   } else {
-    NICE::MultiChannelImageT<int> & grayvalues = ce->getIChannel ( CachedExample::I_GRAYVALUES );
-    int **data = grayvalues.getDataPointer();
+    NICE::MultiChannelImage3DT<int> & grayvalues = ce->getIChannel ( CachedExample::I_GRAYVALUES );
+    std::vector<int*> data = grayvalues.getDataPointer();
     const int *gr = data[0];
     FastFilter::calcGradient ( gr, xsize, ysize, gradient, dir, numBins, usesigned );
   }
 
   eohimg.setAll ( 0 );
-  double **data = eohimg.getDataPointer();
+  std::vector<double*> data = eohimg.getDataPointer();
   long korig = 0;
   for ( int y = 0 ; y < ysize ; y++ )
     for ( int x = 0 ; x < xsize ; x++, korig++ )
@@ -68,12 +68,12 @@ void FIGradients::buildEOHMap ( CachedExample *ce,
   delete [] gradient;
   delete [] dir;
 
-  NICE::MultiChannelImageT<double> & eohintimg = ce->getDChannel ( CachedExample::D_INTEGRALEOH );
-  eohintimg.reInit ( xsize_s, ysize_s, numBins );
+  NICE::MultiChannelImage3DT<double> & eohintimg = ce->getDChannel ( CachedExample::D_INTEGRALEOH );
+  eohintimg.reInit ( xsize_s, ysize_s, 1, numBins );
   for ( uint i = 0 ; i < ( uint ) numBins ; i++ )
   {
-    ImageT<double> tmpEohImg         = eohimg[i];
-    ImageT<double> tmpEohIntegralImg = eohintimg[i];
+    ImageT<double> tmpEohImg         = eohimg.getChannelT(i);
+    ImageT<double> tmpEohIntegralImg = eohintimg.getChannelT(i);
     GenericImageTools::calcIntegralImage ( tmpEohIntegralImg, tmpEohImg, xsize_s, ysize_s );
   }
 

+ 5 - 4
features/fpfeatures/FIHistograms.cpp

@@ -34,12 +34,13 @@ void FIHistograms::buildHSVMap (
     exit ( -1 );
   }
 
-  NICE::MultiChannelImageT<int> & colorimg = ce->getIChannel ( CachedExample::I_COLOR );
+  NICE::MultiChannelImage3DT<int> & colorimg = ce->getIChannel ( CachedExample::I_COLOR );
   assert ( colorimg.channels() == 3 );
 
   NICE::MultiChannelImageT<double> hsvimg ( xsize, ysize, colorimg.channels() );
 
-  ColorSpace::convert ( hsvimg, colorimg,
+  ColorSpace::convert ( hsvimg,
+                        colorimg.getColorMCI(0),
                         ColorSpace::COLORSPACE_HSL,
                         ColorSpace::COLORSPACE_RGB,
                         1.0, 255.0 );
@@ -68,8 +69,8 @@ void FIHistograms::buildHSVMap (
 
   hsvimg.freeData();
 
-  NICE::MultiChannelImageT<double> & colorhist = ce->getDChannel ( CachedExample::D_INTEGRALCOLOR );
-  colorhist.reInit ( xsize_s, ysize_s, numBins);
+  NICE::MultiChannelImage3DT<double> & colorhist = ce->getDChannel ( CachedExample::D_INTEGRALCOLOR );
+  colorhist.reInit ( xsize_s, ysize_s, 1, numBins);
   colorhist.setAll ( 0 );
 
   long korig = 0;

+ 4 - 4
features/fpfeatures/HOGFeature.cpp

@@ -39,7 +39,7 @@ HOGFeature::~HOGFeature()
 
 double HOGFeature::val ( const Example *example ) const
 {
-  const NICE::MultiChannelImageT<double> & img =
+  const NICE::MultiChannelImage3DT<double> & img =
     example->ce->getDChannel ( CachedExample::D_INTEGRALEOH );
   int tm_xsize = img.width();
   int tm_ysize = img.height();
@@ -52,12 +52,12 @@ double HOGFeature::val ( const Example *example ) const
 
   int wsx2, wsy2;
   int exwidth = example->width;
-  if ( exwidth == 0 ) 
+  if ( exwidth == 0 )
   {
     wsx2 = window_size_x * tm_xsize / ( 2 * xsize );
     wsy2 = window_size_y * tm_ysize / ( 2 * ysize );
-  } 
-  else 
+  }
+  else
   {
     int exheight = example->height;
     wsx2 = exwidth * tm_xsize / ( 2 * xsize );

+ 2 - 2
features/fpfeatures/HaarFeature.cpp

@@ -87,9 +87,9 @@ HaarFeature::~HaarFeature()
 
 double HaarFeature::val ( const Example *example ) const
 {
-  NICE::MultiChannelImageT<long> & img = example->ce->getLChannel ( CachedExample::L_INTEGRALIMAGE );
+  NICE::MultiChannelImage3DT<long> & img = example->ce->getLChannel ( CachedExample::L_INTEGRALIMAGE );
 
-  long **data = img.getDataPointer();
+  std::vector<long*> data = img.getDataPointer();
   const long *integralImage = data[0];
   int xsize = img.width();
   int ysize = img.height();

+ 1 - 1
features/fpfeatures/HistFeature.cpp

@@ -46,7 +46,7 @@ HistFeature::~HistFeature()
 
 double HistFeature::val ( const Example *example ) const
 {
-  const NICE::MultiChannelImageT<double> & img = example->ce->getDChannel ( histtype );
+  const NICE::MultiChannelImage3DT<double> & img = example->ce->getDChannel ( histtype );
   int tm_xsize = img.width();
   int tm_ysize = img.height();
 

+ 2 - 2
features/fpfeatures/PixelPairFeature.cpp

@@ -111,7 +111,7 @@ double PixelPairFeature::val ( const Example *example ) const
 {
   int xl = example->x;
   int yl = example->y;
-  NICE::MultiChannelImageT<int> & img = example->ce->getIChannel ( imagetype );
+  NICE::MultiChannelImage3DT<int> & img = example->ce->getIChannel ( imagetype );
 
   int xx1 = x1;
   int yy1 = y1;
@@ -139,7 +139,7 @@ double PixelPairFeature::val ( const Example *example ) const
   {
     int p2x = BOUND ( xl + xx2, 0, xsize - 1 );
     int p2y = BOUND ( yl + yy2, 0, ysize - 1 );
-    
+
     int v2 = img.get(p2x,p2y,b2);
 
     if ( type == PPTYPE_DIFF )

+ 1 - 1
features/fpfeatures/SemanticFeature.cpp

@@ -47,7 +47,7 @@ SemanticFeature::~SemanticFeature()
 
 double SemanticFeature::val ( const Example *example ) const
 {
-  const NICE::MultiChannelImageT<double> & img = example->ce->getDChannel (
+  const NICE::MultiChannelImage3DT<double> & img = example->ce->getDChannel (
         CachedExample::D_INTEGRALPRIOR );
 
   int xsize;

+ 60 - 18
features/gradientfeatures/Image_tools.h

@@ -1,6 +1,6 @@
-/** 
+/**
 * @file Image_tools.h
-* @author Alexander Lütz
+* @author Alexander Freytag
 * @date 18/11/2010
 * @brief Contains tools for Image_Processing
 */
@@ -9,11 +9,10 @@
 
 #include "core/image/ImageT.h"
 #include "core/image/ColorImageT.h"
-// #include "core/image/Filter.h"
 #include <utility>
 
 namespace OBJREC {
-class Image_tools 
+class Image_tools
 {
 
     protected:
@@ -26,26 +25,69 @@ class Image_tools
 	/** simple destructor */
 	~Image_tools();
 
+	/**
+         * @author Alexander Freytag
+         * @brief Calculate gradient-images for x- and y-direction, using [1 0 -1] without smoothing
+         */
+	void calculateGradients(
+            const NICE::Image & origImage,
+            NICE::ImageT<float> & grad_x_Image,
+            NICE::ImageT<float> & grad_y_Image );
 
-	/** calculate gradient-images for x- and y-direction, using [1 0 -1] without smoothing*/
-	void calculateGradients(const NICE::Image & origImage, NICE::ImageT<float> & grad_x_Image, NICE::ImageT<float> & grad_y_Image );
-	/** calculate gradient-images for x- and y-direction, using [1 0 -1] without smoothing, considering the chanel with the greatest magnitude als resulting gradient*/
-	void calculateGradients(NICE::ColorImage origColorImage, NICE::ImageT<float> & grad_x_Image, NICE::ImageT<float> & grad_y_Image );
+	/**
+         * @author Alexander Freytag
+         * @brief Calculate gradient-images for x- and y-direction, using [1 0 -1] without smoothing, considering the chanel with the greatest magnitude als resulting gradient
+         */
+	void calculateGradients(
+            NICE::ColorImage origColorImage,
+            NICE::ImageT<float> & grad_x_Image,
+            NICE::ImageT<float> & grad_y_Image );
 
-	/** calculate gradient-orientations*/
-	void calculateGradientOrientations(const NICE::ImageT<float> & grad_x_Image, const NICE::ImageT<float> & grad_y_Image , const int & number_Of_Bins, NICE::Image & gradient_orientations, const bool unsignedBins=true);
+	/**
+         * @author Alexander Freytag
+         * @brief Calculate gradient-orientations
+         */
+	void calculateGradientOrientations(
+            const NICE::ImageT<float> & grad_x_Image,
+            const NICE::ImageT<float> & grad_y_Image,
+            const int & number_Of_Bins,
+            NICE::Image & gradient_orientations,
+            const bool unsignedBins=true );
 
-	void calculateGradientOrientations(const NICE::GrayImage16s & grad_x_Image, const NICE::GrayImage16s & grad_y_Image , const int & number_Of_Bins, NICE::Image & gradient_orientations, const bool unsignedBins=true);
+	void calculateGradientOrientations(
+            const NICE::GrayImage16s & grad_x_Image,
+            const NICE::GrayImage16s & grad_y_Image,
+            const int & number_Of_Bins,
+            NICE::Image & gradient_orientations,
+            const bool unsignedBins=true );
 
-	/** calculate gradient-magnitudes*/
-	void calculateGradientMagnitudes(const NICE::ImageT<float>  & grad_x_Image, const NICE::ImageT<float> & grad_y_Image, NICE::ImageT<float> & gradient_magnitudes);
+	/**
+          *@author Alexander Freytag
+          *@brief Calculate gradient-magnitudes
+          */
+	void calculateGradientMagnitudes(
+            const NICE::ImageT<float> & grad_x_Image,
+            const NICE::ImageT<float> & grad_y_Image,
+            NICE::ImageT<float> & gradient_magnitudes );
 
-	/** Normalizes the descriptor-vector of the specified block, using L2-norm*/
-	std::vector<float> normalizeBlockDescriptor(const std::vector<float> & orig_Block_Descriptor, const float epsilon = 0.01);
+	/**
+          *@author Alexander Freytag
+          *@brief Normalizes the descriptor-vector of the specified block, using L2-norm
+          */
+	std::vector<float> normalizeBlockDescriptor(
+            const std::vector<float> & orig_Block_Descriptor,
+            const float epsilon = 0.01 );
 
-	/** calculates the resulting HoG-Features for an image by normalizing spatial blocks und storing the resulting normalized histograms in a vector - not implemented up to now*/
-	std::vector< std::vector<float> > calculateResultingHogFeatures(const NICE::Image & gradient_orientations, const NICE::ImageT<float> & gradient_magnitudes, const int & blocksize = 2, const int & cellsize = 8);
+	/**
+          *author Alexander Freytag
+          *@brief Calculates the resulting HoG-Features for an image by normalizing spatial blocks und storing the resulting normalized histograms in a vector - not implemented up to now
+          */
+	std::vector< std::vector<float> > calculateResultingHogFeatures(
+            const NICE::Image & gradient_orientations,
+            const NICE::ImageT<float> & gradient_magnitudes,
+            const int & blocksize = 2,
+            const int & cellsize = 8 );
 };
 }
 
-#endif
+#endif

+ 14 - 22
image/ImagePyramid.cpp

@@ -10,19 +10,13 @@
 #include "vislearning/image/ImagePyramid.h"
 
 using namespace OBJREC;
-
 using namespace std;
 
-using namespace NICE;
-
-
-
-
-ImagePyramid::ImagePyramid( const NICE::Image & img, 
-			    int maxLevels,
-			    double scaleSpacing,
-			    int max_xsize,
-			    int max_ysize )
+ImagePyramid::ImagePyramid( const NICE::Image & img,
+                            int maxLevels,
+                            double scaleSpacing,
+                            int max_xsize,
+                            int max_ysize )
 {
     pyramid.push_back ( NICE::Image(img) );
     for ( int i = 1 ; i < maxLevels ; i++ )
@@ -31,30 +25,28 @@ ImagePyramid::ImagePyramid( const NICE::Image & img,
 	int old_xsize = pyramid[i-1].width();
 
 	int old_ysize = pyramid[i-1].height();
-	double new_xsize = old_xsize / scaleSpacing; 
-	double new_ysize = old_ysize / scaleSpacing; 
+	double new_xsize = old_xsize / scaleSpacing;
+	double new_ysize = old_ysize / scaleSpacing;
 
 	if ( (new_xsize < max_xsize) || (new_ysize < max_ysize) )
-	    break;
+            break;
 
 
 	NICE::Image gauss (old_xsize, old_ysize);
 
-	filterGauss(pyramid[i-1], 2, &gauss);
-
+        NICE::FilterT<unsigned char, unsigned char, unsigned char> filter;
+        filter.filterGaussSigmaApproximate ( *(&pyramid[i-1]), 1.0, &gauss );
+	//deprecated: filterGauss(pyramid[i-1], 2, &gauss);
 
 	NICE::Image newLevel ((int)new_xsize, (int)new_ysize);
 
-
 	// Trafo trafo;
 	// trafo.Scale(0, 0, (new_xsize-1)/(old_xsize-1),
-	//		  (new_ysize-1)/(old_ysize-1));
+	//                   (new_ysize-1)/(old_ysize-1));
 	// Transform(trafo, gauss, newLevel);
 	NICE::scale ( gauss, &newLevel );
-
-		NICE::scale ( gauss, &newLevel );
-
-		pyramid.push_back(newLevel);
+        NICE::scale ( gauss, &newLevel );
+        pyramid.push_back(newLevel);
     }
 }
 

+ 13 - 13
image/ImagePyramid.h

@@ -1,4 +1,4 @@
-/** 
+/**
 * @file ImagePyramid.h
 * @brief gauss image pyramid
 * @author Erik Rodner
@@ -11,10 +11,10 @@
 #include "core/image/ImageT.h"
 #include "core/vector/VectorT.h"
 #include "core/vector/MatrixT.h"
-#include "core/image/Filter.h"
+#include "core/image/FilterT.h"
 
 #include "core/imagedisplay/ImageDisplay.h"
-  
+
 
 namespace OBJREC {
 
@@ -23,18 +23,18 @@ class ImagePyramid
 {
 
   protected:
-	  std::vector<NICE::Image> pyramid;
-	  double scaleSpacing;
+          std::vector<NICE::Image> pyramid;
+          double scaleSpacing;
 
     public:
-  
+
       /** simple constructor */
-      ImagePyramid ( const NICE::Image & img, 
-               int maxLevels = 10,
-               double scaleSpacing = 1.18921,
-               int max_xsize = 11,
-               int max_ysize = 11 );
-          
+      ImagePyramid ( const NICE::Image & img,
+                     int maxLevels = 10,
+                     double scaleSpacing = 1.18921,
+                     int max_xsize = 11,
+                     int max_ysize = 11 );
+
       /** simple destructor */
       virtual ~ImagePyramid();
 
@@ -43,7 +43,7 @@ class ImagePyramid
       void show() const;
       void getOriginalCoordinates ( int x, int y, int level, double & xo, double & yo ) const;
       void getLevelCoordinates ( double xo, double yo, int level, double & xl, double & yl ) const;
-     
+
 };
 
 

+ 0 - 39
math/distances/KernelStd.cpp

@@ -1,39 +0,0 @@
-/** 
-* @file KernelStd.cpp
-* @brief Standard kernel
-* @author Erik Rodner
-* @date 10/24/2007
-
-*/
-
-#include <iostream>
-
-#include "vislearning/math/distances/KernelStd.h"
-
-using namespace OBJREC;
-
-using namespace std;
-// refactor-nice.pl: check this substitution
-// old: using namespace ice;
-using namespace NICE;
-
-
-
-KernelStd::KernelStd() : Kernel(true)
-{
-}
-
-KernelStd::~KernelStd()
-{
-}
-
-double KernelStd::K (const NICE::Vector & x, const NICE::Vector & y) const
-{
-	if ( x.size() != y.size() ) 
-		fthrow (Exception, "KernelStd::K: vectors must have the same dimension\n");
-    double sum = 0.0;
-    for ( int i = 0 ; i < (int)x.size() ; i++ )
-		sum += x[i] * y[i];
-
-    return sum;
-}

+ 0 - 40
math/distances/KernelStd.h

@@ -1,40 +0,0 @@
-/** 
-* @file KernelStd.h
-* @brief Standard kernel
-* @author Erik Rodner
-* @date 10/24/2007
-
-*/
-#ifndef KERNELSTDINCLUDE
-#define KERNELSTDINCLUDE
-
-#include "core/vector/VectorT.h"
-#include "core/vector/MatrixT.h"
-  
-#include "vislearning/math/kernels/Kernel.h"
-
-/** Standard kernel */
-
-namespace OBJREC {
-
-class KernelStd : public Kernel
-{
-
-    protected:
-
-    public:
-  
-	/** simple constructor */
-	KernelStd();
-      
-	/** simple destructor */
-	virtual ~KernelStd();
-	
-	double K (const NICE::Vector & x, const NICE::Vector & y) const;
-     
-};
-
-
-} // namespace
-
-#endif

+ 0 - 1
math/ftransform/PCA.h

@@ -8,7 +8,6 @@
 #ifndef PCAINCLUDE
 #define PCAINCLUDE
 
-//#include "core/image/Filter.h"
 #include "core/vector/VectorT.h"
 #include "core/vector/MatrixT.h"
 

+ 3 - 10
math/kernels/KernelStd.cpp

@@ -6,17 +6,10 @@
 
 */
 
-#include <iostream>
-
 #include "KernelStd.h"
 
 using namespace OBJREC;
 
-using namespace std;
-using namespace NICE;
-
-
-
 KernelStd::KernelStd() : Kernel(true)
 {
 }
@@ -27,11 +20,11 @@ KernelStd::~KernelStd()
 
 double KernelStd::K (const NICE::Vector & x, const NICE::Vector & y) const
 {
-	if ( x.size() != y.size() ) 
-		fthrow (Exception, "KernelStd::K: vectors must have the same dimension\n");
+    if ( x.size() != y.size() )
+        fthrow (NICE::Exception, "KernelStd::K: vectors must have the same dimension\n");
     double sum = 0.0;
     for ( int i = 0 ; i < (int)x.size() ; i++ )
-		sum += x[i] * y[i];
+        sum += x[i] * y[i];
 
     return sum;
 }

+ 10 - 10
math/kernels/KernelStd.h

@@ -1,4 +1,4 @@
-/** 
+/**
 * @file KernelStd.h
 * @brief Standard kernel
 * @author Erik Rodner
@@ -20,15 +20,15 @@ class KernelStd : public Kernel
     protected:
 
     public:
-  
-	/** simple constructor */
-	KernelStd();
-      
-	/** simple destructor */
-	virtual ~KernelStd();
-	
-	double K (const NICE::Vector & x, const NICE::Vector & y) const;
-     
+
+        /** simple constructor */
+        KernelStd();
+
+        /** simple destructor */
+        virtual ~KernelStd();
+
+        double K (const NICE::Vector & x, const NICE::Vector & y) const;
+
 };