瀏覽代碼

split SemSeg and comments

Bjoern Froehlich 13 年之前
父節點
當前提交
d9ea4646e3

+ 1 - 697
semseg/SemSegContextTree.cpp

@@ -17,7 +17,6 @@
 #include <omp.h>
 #include <iostream>
 
-#define BOUND(x,min,max) (((x)<(min))?(min):((x)>(max)?(max):(x)))
 #undef LOCALFEATS
 #undef WRITEGLOB
 #undef TEXTONMAP
@@ -28,701 +27,6 @@ using namespace OBJREC;
 using namespace std;
 using namespace NICE;
 
-class MCImageAccess: public ValueAccess
-{
-
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y, const int &channel )
-    {
-      return feats.feats->get ( x, y, channel );
-    }
-
-    virtual string writeInfos()
-    {
-      return "raw";
-    }
-
-    virtual ValueTypes getType()
-    {
-      return RAWFEAT;
-    }
-};
-
-class ClassificationResultAcess: public ValueAccess
-{
-
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y, const int &channel )
-    {
-      return ( *feats.tree ) [feats.cfeats->get ( x,y,feats.cTree ) ].dist[channel];
-    }
-
-    virtual string writeInfos()
-    {
-      return "context";
-    }
-
-    virtual ValueTypes getType()
-    {
-      return CONTEXT;
-    }
-};
-
-class SparseImageAcess: public ValueAccess
-{
-  private:
-    double scale;
-
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y, const int &channel )
-    {
-      //MultiChannelImageT<SparseVectorInt> textonMap;
-      //TODO: implement access
-      return -1.0;
-    }
-
-    virtual string writeInfos()
-    {
-      return "context";
-    }
-
-    virtual ValueTypes getType()
-    {
-      return CONTEXT;
-    }
-};
-
-void Operation::restore ( std::istream &is )
-{
-  is >> x1;
-  is >> x2;
-  is >> y1;
-  is >> y2;
-  is >> channel1;
-  is >> channel2;
-
-  int tmp;
-  is >> tmp;
-
-  if ( tmp >= 0 )
-  {
-    if ( tmp == RAWFEAT )
-    {
-      values = new MCImageAccess();
-    }
-    else if ( tmp == CONTEXT )
-    {
-      values = new ClassificationResultAcess();
-    }
-    else
-    {
-      throw ( "no valid ValueAccess" );
-    }
-  }
-  else
-  {
-    values = NULL;
-  }
-}
-
-std::string Operation::writeInfos()
-{
-  std::stringstream ss;
-  ss << " x1: " << x1 << " y1: " << y1 << " x2: " << x2 << " y2: " << y2 << " c1: " << channel1 << " c2: " << channel2;
-  return ss.str();
-}
-
-void Operation::set ( int ws, int c1size, int c2size, int c3size, bool useGaussian )
-{
-  int types = 1;
-  if ( c2size > 0 )
-  {
-    types++;
-  }
-  if ( c3size > 0 )
-  {
-    types++;
-  }
-  
-  types = std::min(types, maxtypes);
-
-  int ft = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) types );
-
-  if ( ft > 0 )
-  {
-    ws *= 4;
-  }
-
-  if ( useGaussian )
-  {
-    double sigma = ( double ) ws * 2.0;
-    x1 = randGaussDouble ( sigma ) * ( double ) ws;
-    x2 = randGaussDouble ( sigma ) * ( double ) ws;
-    y1 = randGaussDouble ( sigma ) * ( double ) ws;
-    y2 = randGaussDouble ( sigma ) * ( double ) ws;
-  }
-  else
-  {
-    x1 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) ws ) - ws / 2;
-    x2 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) ws ) - ws / 2;
-    y1 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) ws ) - ws / 2;
-    y2 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) ws ) - ws / 2;
-  }
-
-  if ( ft == RAWFEAT )
-  {
-    values = new MCImageAccess();
-  }
-  else if ( ft == CONTEXT )
-  {
-    values = new ClassificationResultAcess();
-  }
-  else
-  {
-    values = new SparseImageAcess();
-  }
-}
-
-class Minus: public Operation
-{
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-      double v1 = values->getVal ( feats, BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 );
-      double v2 = values->getVal ( feats, BOUND ( x + x2, 0, xsize - 1 ), BOUND ( y + y2, 0, ysize - 1 ), channel2 );
-      return v1 -v2;
-    }
-
-    virtual Operation* clone()
-    {
-      return new Minus();
-    }
-
-    virtual string writeInfos()
-    {
-      string out = "Minus";
-
-      if ( values != NULL )
-        out += values->writeInfos();
-
-      return out + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return MINUS;
-    }
-};
-
-
-
-class MinusAbs: public Operation
-{
-
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-      double v1 = values->getVal ( feats, BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 );
-      double v2 = values->getVal ( feats, BOUND ( x + x2, 0, xsize - 1 ), BOUND ( y + y2, 0, ysize - 1 ), channel2 );
-      return abs ( v1 -v2 );
-    }
-
-    virtual Operation* clone()
-    {
-      return new MinusAbs();
-    };
-
-    virtual string writeInfos()
-    {
-      string out = "MinusAbs";
-
-      if ( values != NULL )
-        out += values->writeInfos();
-
-      return out;
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return MINUSABS;
-    }
-};
-
-class Addition: public Operation
-{
-
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-      double v1 = values->getVal ( feats, BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 );
-      double v2 = values->getVal ( feats, BOUND ( x + x2, 0, xsize - 1 ), BOUND ( y + y2, 0, ysize -
-                                   1 ), channel2 );
-      return v1 + v2;
-    }
-
-    virtual Operation* clone()
-    {
-      return new Addition();
-    }
-
-    virtual string writeInfos()
-    {
-      string out = "Addition";
-
-      if ( values != NULL )
-        out += values->writeInfos();
-
-      return out + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return ADDITION;
-    }
-};
-
-class Only1: public Operation
-{
-
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-      double v1 = values->getVal ( feats, BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 );
-      return v1;
-    }
-
-    virtual Operation* clone()
-    {
-      return new Only1();
-    }
-
-    virtual string writeInfos()
-    {
-      string out = "Only1";
-
-      if ( values != NULL )
-        out += values->writeInfos();
-
-      return out + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return ONLY1;
-    }
-};
-
-class RelativeXPosition: public Operation
-{
-
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-      return ( double ) x / ( double ) xsize;
-    }
-
-    virtual Operation* clone()
-    {
-      return new RelativeXPosition();
-    }
-
-    virtual string writeInfos()
-    {
-      return "RelativeXPosition" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return RELATIVEXPOSITION;
-    }
-};
-
-class RelativeYPosition: public Operation
-{
-
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-      return ( double ) x / ( double ) xsize;
-    }
-
-    virtual Operation* clone()
-    {
-      return new RelativeYPosition();
-    }
-
-    virtual string writeInfos()
-    {
-      return "RelativeYPosition" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return RELATIVEYPOSITION;
-    }
-};
-
-// uses mean of classification in window given by (x1,y1) (x2,y2)
-
-class IntegralOps: public Operation
-{
-
-  public:
-    virtual void set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values )
-    {
-      x1 = min ( _x1, _x2 );
-      y1 = min ( _y1, _y2 );
-      x2 = max ( _x1, _x2 );
-      y2 = max ( _y1, _y2 );
-      channel1 = _channel1;
-      channel2 = _channel2;
-      values = _values;
-    }
-
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-      return computeMean ( *feats.integralImg, BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), BOUND ( x + x2, 0, xsize - 1 ), BOUND ( y + y2, 0, ysize - 1 ), channel1 );
-    }
-
-    inline double computeMean ( const NICE::MultiChannelImageT<double> &intImg, const int &uLx, const int &uLy, const int &lRx, const int &lRy, const int &chan )
-    {
-      double val1 = intImg.get ( uLx, uLy, chan );
-      double val2 = intImg.get ( lRx, uLy, chan );
-      double val3 = intImg.get ( uLx, lRy, chan );
-      double val4 = intImg.get ( lRx, lRy, chan );
-      double area = ( lRx - uLx ) * ( lRy - uLy );
-
-      if ( area == 0 )
-        return 0.0;
-
-      return ( val1 + val4 - val2 - val3 ) / area;
-    }
-
-    virtual Operation* clone()
-    {
-      return new IntegralOps();
-    }
-
-    virtual string writeInfos()
-    {
-      return "IntegralOps" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return INTEGRAL;
-    }
-};
-
-//like a global bag of words to model the current appearance of classes in an image without local context
-
-class GlobalFeats: public IntegralOps
-{
-
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-      return computeMean ( *feats.integralImg, 0, 0, xsize - 1, ysize - 1, channel1 );
-    }
-
-    virtual Operation* clone()
-    {
-      return new GlobalFeats();
-    }
-
-    virtual string writeInfos()
-    {
-      return "GlobalFeats" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return GLOBALFEATS;
-    }
-};
-
-//uses mean of Integral image given by x1, y1 with current pixel as center
-
-class IntegralCenteredOps: public IntegralOps
-{
-
-  public:
-    virtual void set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values )
-    {
-      x1 = abs ( _x1 );
-      y1 = abs ( _y1 );
-      x2 = abs ( _x2 );
-      y2 = abs ( _y2 );
-      channel1 = _channel1;
-      channel2 = _channel2;
-      values = _values;
-    }
-
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-      return computeMean ( *feats.integralImg, BOUND ( x - x1, 0, xsize - 1 ), BOUND ( y - y1, 0, ysize - 1 ), BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 );
-    }
-
-    virtual Operation* clone()
-    {
-      return new IntegralCenteredOps();
-    }
-
-    virtual string writeInfos()
-    {
-      return "IntegralCenteredOps" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return INTEGRALCENT;
-    }
-};
-
-//uses different of mean of Integral image given by two windows, where (x1,y1) is the width and height of window1 and (x2,y2) of window 2
-
-class BiIntegralCenteredOps: public IntegralCenteredOps
-{
-
-  public:
-    virtual void set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values )
-    {
-      x1 = min ( abs ( _x1 ), abs ( _x2 ) );
-      y1 = min ( abs ( _y1 ), abs ( _y2 ) );
-      x2 = max ( abs ( _x1 ), abs ( _x2 ) );
-      y2 = max ( abs ( _y1 ), abs ( _y2 ) );
-      channel1 = _channel1;
-      channel2 = _channel2;
-      values = _values;
-    }
-
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-      return computeMean ( *feats.integralImg, BOUND ( x - x1, 0, xsize - 1 ), BOUND ( y - y1, 0, ysize - 1 ), BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 ) - computeMean ( *feats.integralImg, BOUND ( x - x2, 0, xsize - 1 ), BOUND ( y - y2, 0, ysize - 1 ), BOUND ( x + x2, 0, xsize - 1 ), BOUND ( y + y2, 0, ysize - 1 ), channel1 );
-    }
-
-    virtual Operation* clone()
-    {
-      return new BiIntegralCenteredOps();
-    }
-
-    virtual string writeInfos()
-    {
-      return "BiIntegralCenteredOps" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return BIINTEGRALCENT;
-    }
-};
-
-/** horizontal Haar features
- * ++
- * --
- */
-
-class HaarHorizontal: public IntegralCenteredOps
-{
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-
-      int tlx = BOUND ( x - x1, 0, xsize - 1 );
-      int tly = BOUND ( y - y1, 0, ysize - 1 );
-      int lrx = BOUND ( x + x1, 0, xsize - 1 );
-      int lry = BOUND ( y + y1, 0, ysize - 1 );
-
-      return computeMean ( *feats.integralImg, tlx, tly, lrx, y, channel1 ) - computeMean ( *feats.integralImg, tlx, y, lrx, lry, channel1 );
-    }
-
-    virtual Operation* clone()
-    {
-      return new HaarHorizontal();
-    }
-
-    virtual string writeInfos()
-    {
-      return "HaarHorizontal" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return HAARHORIZ;
-    }
-};
-
-/** vertical Haar features
- * +-
- * +-
- */
-
-class HaarVertical: public IntegralCenteredOps
-{
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-
-      int tlx = BOUND ( x - x1, 0, xsize - 1 );
-      int tly = BOUND ( y - y1, 0, ysize - 1 );
-      int lrx = BOUND ( x + x1, 0, xsize - 1 );
-      int lry = BOUND ( y + y1, 0, ysize - 1 );
-
-      return computeMean ( *feats.integralImg, tlx, tly, x, lry, channel1 ) - computeMean ( *feats.integralImg, x, tly, lrx, lry, channel1 );
-    }
-
-    virtual Operation* clone()
-    {
-      return new HaarVertical();
-    }
-
-    virtual string writeInfos()
-    {
-      return "HaarVertical" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return HAARVERT;
-    }
-};
-
-/** vertical Haar features
- * +-
- * -+
- */
-
-class HaarDiag: public IntegralCenteredOps
-{
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-
-      int tlx = BOUND ( x - x1, 0, xsize - 1 );
-      int tly = BOUND ( y - y1, 0, ysize - 1 );
-      int lrx = BOUND ( x + x1, 0, xsize - 1 );
-      int lry = BOUND ( y + y1, 0, ysize - 1 );
-
-      return computeMean ( *feats.integralImg, tlx, tly, x, y, channel1 ) + computeMean ( *feats.integralImg, x, y, lrx, lry, channel1 ) - computeMean ( *feats.integralImg, tlx, y, x, lry, channel1 ) - computeMean ( *feats.integralImg, x, tly, lrx, y, channel1 );
-    }
-
-    virtual Operation* clone()
-    {
-      return new HaarDiag();
-    }
-
-    virtual string writeInfos()
-    {
-      return "HaarDiag" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return HAARDIAG;
-    }
-};
-
-/** horizontal Haar features
- * +++
- * ---
- * +++
- */
-
-class Haar3Horiz: public BiIntegralCenteredOps
-{
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-
-      int tlx = BOUND ( x - x2, 0, xsize - 1 );
-      int tly = BOUND ( y - y2, 0, ysize - 1 );
-      int mtly = BOUND ( y - y1, 0, ysize - 1 );
-      int mlry = BOUND ( y + y1, 0, ysize - 1 );
-      int lrx = BOUND ( x + x2, 0, xsize - 1 );
-      int lry = BOUND ( y + y2, 0, ysize - 1 );
-
-      return computeMean ( *feats.integralImg, tlx, tly, lrx, mtly, channel1 ) - computeMean ( *feats.integralImg, tlx, mtly, lrx, mlry, channel1 ) + computeMean ( *feats.integralImg, tlx, mlry, lrx, lry, channel1 );
-    }
-
-    virtual Operation* clone()
-    {
-      return new Haar3Horiz();
-    }
-
-    virtual string writeInfos()
-    {
-      return "Haar3Horiz" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return HAAR3HORIZ;
-    }
-};
-
-/** vertical Haar features
- * +-+
- * +-+
- * +-+
- */
-
-class Haar3Vert: public BiIntegralCenteredOps
-{
-    virtual double getVal ( const Features &feats, const int &x, const int &y )
-    {
-      int xsize, ysize;
-      getXY ( feats, xsize, ysize );
-
-      int tlx = BOUND ( x - x2, 0, xsize - 1 );
-      int tly = BOUND ( y - y2, 0, ysize - 1 );
-      int mtlx = BOUND ( x - x1, 0, xsize - 1 );
-      int mlrx = BOUND ( x + x1, 0, xsize - 1 );
-      int lrx = BOUND ( x + x2, 0, xsize - 1 );
-      int lry = BOUND ( y + y2, 0, ysize - 1 );
-
-      return computeMean ( *feats.integralImg, tlx, tly, mtlx, lry, channel1 ) - computeMean ( *feats.integralImg, mtlx, tly, mlrx, lry, channel1 ) + computeMean ( *feats.integralImg, mlrx, tly, lrx, lry, channel1 );
-    }
-
-    virtual Operation* clone()
-    {
-      return new Haar3Vert();
-    }
-
-    virtual string writeInfos()
-    {
-      return "Haar3Vert" + Operation::writeInfos();
-    }
-
-    virtual OperationTypes getOps()
-    {
-      return HAAR3VERT;
-    }
-};
-
 SemSegContextTree::SemSegContextTree ( const Config *conf, const MultiDataset *md )
     : SemanticSegmentation ( conf, & ( md->getClassNames ( "train" ) ) )
 {
@@ -812,7 +116,7 @@ SemSegContextTree::SemSegContextTree ( const Config *conf, const MultiDataset *m
   contextOverview = vector<vector<double> > ( maxDepth, vector<double> ( 2, 0.0 ) );
 
   calcVal.push_back ( new MCImageAccess() );
-  calcVal.push_back ( new ClassificationResultAcess() );
+  calcVal.push_back ( new ClassificationResultAccess() );
 
   classnames = md->getClassNames ( "train" );
 

+ 2 - 158
semseg/SemSegContextTree.h

@@ -13,164 +13,9 @@
 #include "vislearning/features/localfeatures/LFColorWeijer.h"
 #include "objrec/segmentation/RegionSegmentationMethod.h"
 
-namespace OBJREC {
-
-class Operation;
-
-class TreeNode
-{
-
-  public:
-    /** left child node */
-    int left;
-
-    /** right child node */
-    int right;
-
-    /** position of feat for decision */
-    Operation *feat;
-
-    /** decision stamp */
-    double decision;
-
-    /** is the node a leaf or not */
-    bool isleaf;
-
-    /** distribution in current node */
-    std::vector<double> dist;
-
-    /** depth of the node in the tree */
-    int depth;
-
-    /** how many pixels are in this node */
-    int featcounter;
-
-    /** unique number */
-    int nodeNumber;
-
-    /** simple constructor */
-    TreeNode() : left ( -1 ), right ( -1 ), feat ( NULL ), decision ( -1.0 ), isleaf ( false ) {}
-
-    /** standard constructor */
-    TreeNode ( int _left, int _right, Operation *_feat, double _decision ) : left ( _left ), right ( _right ), feat ( _feat ), decision ( _decision ), isleaf ( false ) {}
-};
-
-struct Features {
-  NICE::MultiChannelImageT<double> *feats;
-  NICE::MultiChannelImageT<unsigned short int> *cfeats;
-  int cTree;
-  std::vector<TreeNode> *tree;
-  NICE::MultiChannelImageT<double> *integralImg;
-};
-
-enum ValueTypes
-{
-  RAWFEAT,
-  CONTEXT,
-  SPARSE,
-  NBVALUETYPES
-};
-
-class ValueAccess
-{
-
-  public:
-    virtual double getVal ( const Features &feats, const int &x, const int &y, const int &channel ) = 0;
-    virtual std::string writeInfos() = 0;
-    virtual ValueTypes getType() = 0;
-};
-
-enum OperationTypes {
-  MINUS,
-  MINUSABS,
-  ADDITION,
-  ONLY1,
-  INTEGRAL,
-  INTEGRALCENT,
-  BIINTEGRALCENT,
-  HAARHORIZ,
-  HAARVERT,
-  HAARDIAG,
-  HAAR3HORIZ,
-  HAAR3VERT,
-  RELATIVEXPOSITION,
-  RELATIVEYPOSITION,
-  GLOBALFEATS,
-  NBOPERATIONS
-};
-
-class Operation
-{
+#include "objrec-froehlichexp/semseg/operations/Operations.h"
 
-  protected:
-    int x1, y1, x2, y2, channel1, channel2, maxtypes;
-    ValueAccess *values;
-
-    bool context;
-
-  public:
-
-    Operation()
-    {
-      values = NULL;
-      maxtypes = 1000;
-    }
-
-    virtual void set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values )
-    {
-      x1 = _x1;
-      y1 = _y1;
-      x2 = _x2;
-      y2 = _y2;
-      channel1 = _channel1;
-      channel2 = _channel2;
-      values = _values;
-    }
-
-    virtual void set ( int ws, int c1size, int c2size, int c3size, bool useGaussian );
-
-    void setContext ( bool _context )
-    {
-      context = _context;
-    }
-
-    bool getContext()
-    {
-      return context;
-    }
-
-    /**
-     * @brief abstract interface for feature computation
-     * @param feats features
-     * @param cfeats number of tree node for each pixel
-     * @param tree current tree
-     * @param x current x position
-     * @param y current y position
-     * @return double distance
-     **/
-    virtual double getVal ( const Features &feats, const int &x, const int &y ) = 0;
-    virtual Operation* clone() = 0;
-    virtual std::string writeInfos();
-
-    inline void getXY ( const Features &feats, int &xsize, int &ysize )
-    {
-      xsize = feats.feats->width();
-      ysize = feats.feats->height();
-    }
-
-    virtual OperationTypes getOps() = 0;
-
-    virtual void store ( std::ostream & os )
-    {
-      os << x1 << " " << x2 << " " << y1 << " " << y2 << " " << channel1 << " " << channel2 << std::endl;
-      if ( values == NULL )
-        os << -1 << std::endl;
-      else
-        os << values->getType() << std::endl;
-    }
-
-    virtual void restore ( std::istream & is );
-};
+namespace OBJREC {
 
 /** Localization system */
 
@@ -351,7 +196,6 @@ class SemSegContextTree : public SemanticSegmentation, public NICE::Persistent
 
 };
 
-
 } // namespace
 
 #endif

+ 108 - 50
semseg/SemSegCsurka.cpp

@@ -65,7 +65,7 @@ SemSegCsurka::SemSegCsurka ( const Config *conf,
   usecolorfeats = conf->gB ( "SemSegCsurka", "usecolorfeats", false );
 
   string rsMethod = conf->gS ( "SemSegCsurka", "segmentation", "meanshift" );
-  
+
   g = NULL;
   k = NULL;
   relloc = NULL;
@@ -117,8 +117,8 @@ SemSegCsurka::SemSegCsurka ( const Config *conf,
     classifier = new FPCRandomForests ( conf, "ClassifierForest" );
   else if ( cname == "SMLR" )
     classifier = new FPCSMLR ( conf, "ClassifierSMLR" );
-  else if ( cname == "GPHIK")
-    classifier = new GPHIKClassifier(conf, "ClassiferGPHIK");
+  else if ( cname == "GPHIK" )
+    classifier = new GPHIKClassifier ( conf, "ClassiferGPHIK" );
   else
     vclassifier = CSGeneric::selectVecClassifier ( conf, "main" );
   //classifier = new FPCSparseMultinomialLogisticRegression(conf, "ClassifierSMLR");
@@ -1482,18 +1482,25 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
       }
     }
   }
-  
+
 #ifdef UNCERTAINTY
-  FloatImage uncert(xsize, ysize);
-  ColorImage imgrgb(xsize,ysize);
-  uncert.set(0.0);
+  vector<FloatImage> uncert;
+  for(int s = 0; s < scalesize; s++)
+  {
+    uncert.push_back(FloatImage(xsize, ysize));
+    uncert[s].set(0.0);
+  }
+  ColorImage imgrgb ( xsize, ysize );
   std::string s;
   std::stringstream out;
   std::vector< std::string > list2;
   StringTools::split ( Globals::getCurrentImgFN (), '/', list2 );
   out << "uncertainty/" << list2.back();
-#endif
   
+  double maxu = -numeric_limits<double>::max();
+  double minu = numeric_limits<double>::max();
+#endif
+
   if ( classifier != NULL )
   {
     clog << "[log] SemSegCsruka::classifyregions: Wahrscheinlichkeitskarten erstellen: classifier != NULL" << endl;
@@ -1504,7 +1511,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
       for ( int i = s; i < ( int ) pce.size(); i += scalesize )
       {
         ClassificationResult r = classifier->classify ( pce[i].second );
-              
+
         for ( int j = 0 ; j < r.scores.size(); j++ )
         {
           if ( useclass[j] == 0 )
@@ -1512,11 +1519,13 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
           fV[j] += r.scores[j];
           preMap.set ( pce[i].second.x, pce[i].second.y, r.scores[j], j + s*klassen );
         }
-        
+
 #ifdef UNCERTAINTY
-        uncert(pce[i].second.x, pce[i].second.y) = r.uncertainty;
+        uncert[s] ( pce[i].second.x, pce[i].second.y ) = r.uncertainty;
+        maxu = std::max ( r.uncertainty, maxu );
+        minu = std::min ( r.uncertainty, minu );
 #endif
-        
+
         /*if(s == 0 && i == pce.size()/2)
         {
           cout << "scores: ";
@@ -1528,12 +1537,13 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
           }
           cout << endl;
         }*/
-        
+
       }
     }
   }
   else
   {
+    
 //#pragma omp parallel for
     for ( int s = 0; s < scalesize; s++ )
     {
@@ -1549,12 +1559,21 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
           preMap.set ( pce[i].second.x, pce[i].second.y, r.scores[j], j + s*klassen );
         }
 #ifdef UNCERTAINTY
-        uncert(pce[i].second.x, pce[i].second.y) = r.uncertainty;
+        uncert[s] ( pce[i].second.x, pce[i].second.y ) = r.uncertainty;
+        maxu = std::max ( r.uncertainty, maxu );
+        minu = std::min ( r.uncertainty, minu );
 #endif
       }
     }
   }
-  
+
+#ifdef UNCERTAINTY
+  cout << "maxvdirect: " << maxu << " minvdirect: " << minu << endl;
+  FloatImage gaussUncert ( xsize, ysize );
+  ICETools::convertToRGB ( uncert[0], imgrgb );
+  imgrgb.write ( out.str() + "rough.png" );
+#endif
+
   vector<double> scalesVec;
   for ( set<double>::const_iterator iter = scales.begin();
         iter != scales.end();
@@ -1565,7 +1584,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
 
 #undef VISSEMSEG
 #ifdef VISSEMSEG
-  
+
   for ( int j = 0 ; j < ( int ) preMap.numChannels; j++ )
   {
     cout << "klasse: " << j << endl;//" " << cn.text ( j ) << endl;
@@ -1579,7 +1598,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
         tmp ( y, x ) = val;
         maxval = std::max ( val, maxval );
       }
-      
+
     NICE::ColorImage imgrgb ( preMap.xsize, preMap.ysize );
     ICETools::convertToRGB ( tmp, imgrgb );
 
@@ -1609,7 +1628,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
     {
       if ( forbidden_classes.find ( i ) != forbidden_classes.end() )
         continue;
-      
+
       int pos = i + s * klassen;
 
       double maxval = preMap.data[pos][0];
@@ -1644,19 +1663,11 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
         }
       }
     }
-
-  }
-  
 #ifdef UNCERTAINTY
-  ICETools::convertToRGB ( uncert, imgrgb );
-  imgrgb.write(out.str()+"rough.png");
-  double sigma = sigmaweight * 16.0 * 4.0;
-  FloatImage gaussUncert(xsize,ysize);
-  filterGaussSigmaApproximate<float, float, float> ( uncert, sigma, &gaussUncert );
-  ICETools::convertToRGB ( gaussUncert, imgrgb );
-  imgrgb.write(out.str()+"filtered.png");
+    filterGaussSigmaApproximate<float, float, float> ( uncert[s], sigma, &gaussUncert );
+    uncert[s] = gaussUncert;
 #endif
-
+  }
 
   // Zusammenfassen und auswerten
   clog << "[log] SemSegCsruka::classifyregions: Wahrscheinlichkeitskarten erstellen -> zusammenfassen und auswerten" << endl;
@@ -1670,9 +1681,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
         double prob = 0.0;
         for ( int s = 0; s < ( int ) scalesize; s++ )
         {
-
           prob += preMap.get ( x, y, j + s * klassen );
-
         }
 
         double val = prob / ( double ) ( scalesize );
@@ -1680,6 +1689,53 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
       }
     }
   }
+  
+#ifdef UNCERTAINTY
+  for ( int x = 0; x < xsize; x++ )
+  {
+    for ( int y = 0; y < ysize; y++ )
+    {
+      for ( int s = 0; s < ( int ) scalesize; s++ )
+      {
+        gaussUncert(x,y) += uncert[s](x,y);
+      }
+      gaussUncert(x,y)/=scalesize;
+    }
+  }
+
+  maxu = -numeric_limits<double>::max();
+  minu = numeric_limits<double>::max();
+  for ( int y = 0; y < ysize; y++ )
+  {
+    for ( int x = 0; x < xsize; x++ )
+    {
+      double val = uncert[0] ( x, y );
+      maxu = std::max ( val, maxu );
+      minu = std::min ( val, minu );
+    }
+  }
+  cout << "maxvo = " << maxu << " minvo = " << minu << endl;
+
+  maxu = -numeric_limits<float>::max();
+  minu = numeric_limits<float>::max();
+
+  for ( int y = 0; y < ysize; y++ )
+  {
+    for ( int x = 0; x < xsize; x++ )
+    {
+      double val = gaussUncert ( x, y );
+      maxu = std::max ( val, maxu );
+      minu = std::min ( val, minu );
+    }
+  }
+  cout << "maxvf = " << maxu << " minvf = " << minu << endl;
+  
+  gaussUncert(0,0) = 0.0;
+  gaussUncert(0,1) = 0.04;
+  ICETools::convertToRGB ( gaussUncert, imgrgb );
+  imgrgb.write ( out.str() + "filtered.png" );
+
+#endif
 
 #undef VISSEMSEG
 #ifdef VISSEMSEG
@@ -1694,7 +1750,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
   s = out.str();
 
   probabilities.store ( s );
-  
+
   for ( int j = 0 ; j < ( int ) probabilities.numChannels; j++ )
   {
     cout << "klasse: " << j << endl;//" " << cn.text ( j ) << endl;
@@ -1709,7 +1765,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
         tmp ( y, x ) = val;
         maxval = std::max ( val, maxval );
       }
-      
+
     NICE::ColorImage imgrgb ( probabilities.xsize, probabilities.ysize );
     ICETools::convertToRGB ( tmp, imgrgb );
 
@@ -1742,7 +1798,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
 
     Regionen.clear();
     vector<vector <double> > regionprob;
-    
+
 #ifdef UNCERTAINTY
     vector<double> regionUncert;
 #endif
@@ -1758,7 +1814,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
       regionprob.push_back ( tmp );
       Regionen.push_back ( pair<int, Example> ( 0, Example() ) );
 #ifdef UNCERTAINTY
-      regionUncert.push_back(0.0);
+      regionUncert.push_back ( 0.0 );
 #endif
     }
 
@@ -1777,7 +1833,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
           regionprob[pos][j] += val;
         }
 #ifdef UNCERTAINTY
-        regionUncert[pos] += gaussUncert(x,y);
+        regionUncert[pos] += gaussUncert ( x, y );
 #endif
       }
     }
@@ -1812,7 +1868,7 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
       {
         if ( forbidden_classes.find ( j ) != forbidden_classes.end() )
           continue;
-        
+
         regionprob[i][j] /= Regionen[i].second.weight;
 
         if ( maxval < regionprob[i][j] )
@@ -1837,28 +1893,30 @@ void SemSegCsurka::classifyregions ( CachedExample *ce, NICE::Image & segresult,
         int pos = mask ( x, y );
         segresult.setPixel ( x, y, Regionen[pos].first );
 #ifdef UNCERTAINTY
-        uncert(x,y) = regionUncert[pos];
+        gaussUncert ( x, y ) = regionUncert[pos];
 #endif
       }
     }
 #ifdef UNCERTAINTY
-    float maxu = -numeric_limits<double>::max();
-    float minu = numeric_limits<double>::min();
-    for ( int y = 0; y < ( int ) mask.cols(); y++ )
+    maxu = -numeric_limits<float>::max();
+    minu = numeric_limits<float>::max();
+    for ( int y = 0; y < ysize; y++ )
     {
-      for ( int x = 0; x < ( int ) mask.rows(); x++ )
+      for ( int x = 0; x < xsize; x++ )
       {
-        maxu = std::max(uncert(x,y),maxu);
-        minu = std::min(uncert(x,y),minu);
+        //float val = uncert(x,y);
+        double val = gaussUncert ( x, y );
+        maxu = std::max ( val, maxu );
+        minu = std::min ( val, minu );
       }
     }
-    cout << "maxv = " << maxu << " minv = " << minu << endl;
-    uncert(0,0) = 1;
-    uncert(0,1) = 0;
-    ICETools::convertToRGB ( uncert, imgrgb );
-    imgrgb.write(out.str()+"region.png");
+    cout << "maxvr = " << maxu << " minvr = " << minu << endl;
+//    uncert(0,0) = 1;
+//    uncert(0,1) = 0;
+    ICETools::convertToRGB ( gaussUncert, imgrgb );
+    imgrgb.write ( out.str() + "region.png" );
 #endif
-    
+
 #undef WRITEREGIONS
 #ifdef WRITEREGIONS
     RegionGraph rg;

+ 8 - 0
semseg/operations/Makefile

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

+ 103 - 0
semseg/operations/Makefile.inc

@@ -0,0 +1,103 @@
+# LIBRARY-DIRECTORY-MAKEFILE
+# conventions:
+# - all subdirectories containing a "Makefile.inc" are considered sublibraries
+#   exception: "progs/" and "tests/" subdirectories!
+# - all ".C", ".cpp" and ".c" files in the current directory are linked to a
+#   library
+# - the library depends on all sublibraries 
+# - the library name is created with $(LIBNAME), i.e. it will be somehow
+#   related to the directory name and with the extension .a
+#   (e.g. lib1/sublib -> lib1_sublib.a)
+# - the library will be added to the default build list ALL_LIBRARIES
+
+# --------------------------------
+# - remember the last subdirectory
+#
+# set the variable $(SUBDIR) correctly to the current subdirectory. this
+# variable can be used throughout the current makefile.inc. The many 
+# SUBDIR_before, _add, and everything are only required so that we can recover
+# the previous content of SUBDIR before exitting the makefile.inc
+
+SUBDIR_add:=$(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
+SUBDIR_before:=$(SUBDIR)
+SUBDIR:=$(strip $(SUBDIR_add))
+SUBDIR_before_$(SUBDIR):=$(SUBDIR_before)
+ifeq "$(SUBDIR)" "./"
+SUBDIR:=
+endif
+
+# ------------------------
+# - include subdirectories
+#
+# note the variables $(SUBDIRS_OF_$(SUBDIR)) are required later on to recover
+# the dependencies automatically. if you handle dependencies on your own, you
+# can also dump the $(SUBDIRS_OF_$(SUBDIR)) variable, and include the
+# makefile.inc of the subdirectories on your own...
+
+SUBDIRS_OF_$(SUBDIR):=$(patsubst %/Makefile.inc,%,$(wildcard $(SUBDIR)*/Makefile.inc))
+include $(SUBDIRS_OF_$(SUBDIR):%=%/Makefile.inc)
+
+# ----------------------------
+# - include local dependencies
+#
+# you can specify libraries needed by the individual objects or by the whole
+# directory. the object specific additional libraries are only considered
+# when compiling the specific object files
+# TODO: update documentation...
+
+-include $(SUBDIR)libdepend.inc
+
+$(foreach d,$(filter-out %progs %tests,$(SUBDIRS_OF_$(SUBDIR))),$(eval $(call PKG_DEPEND_INT,$(d))))
+
+# ---------------------------
+# - objects in this directory
+#
+# the use of the variable $(OBJS) is not mandatory. it is mandatory however
+# to update $(ALL_OBJS) in a way that it contains the path and name of
+# all objects. otherwise we can not include the appropriate .d files.
+
+OBJS:=$(patsubst %.cpp,$(OBJDIR)%.o,$(notdir $(wildcard $(SUBDIR)*.cpp))) \
+      $(patsubst %.C,$(OBJDIR)%.o,$(notdir $(wildcard $(SUBDIR)*.C))) \
+	  $(shell grep -ls Q_OBJECT $(SUBDIR)*.h | sed -e's@^@/@;s@.*/@$(OBJDIR)moc_@;s@\.h$$@.o@') \
+      $(patsubst %.c,$(OBJDIR)%.o,$(notdir $(wildcard $(SUBDIR)*.c)))
+ALL_OBJS += $(OBJS)
+
+# ----------------------------
+# - binaries in this directory
+#
+# output of binaries in this directory. none of the variables has to be used.
+# but everything you add to $(ALL_LIBRARIES) and $(ALL_BINARIES) will be
+# compiled with `make all`. be sure again to add the files with full path.
+
+LIBRARY_BASENAME:=$(call LIBNAME,$(SUBDIR))
+ifneq "$(SUBDIR)" ""
+ALL_LIBRARIES+=$(LIBDIR)$(LIBRARY_BASENAME).$(LINK_FILE_EXTENSION)
+endif
+
+# ---------------------
+# - binary dependencies
+#
+# there is no way of determining the binary dependencies automatically, so we
+# follow conventions. the current library depends on all sublibraries.
+# all other dependencies have to be added manually by specifying, that the
+# current .pc file depends on some other .pc file. binaries depending on
+# libraries should exclusivelly use the .pc files as well.
+
+ifeq "$(SKIP_BUILD_$(OBJDIR))" "1"
+$(LIBDIR)$(LIBRARY_BASENAME).a:
+else
+$(LIBDIR)$(LIBRARY_BASENAME).a:$(OBJS) \
+	$(call PRINT_INTLIB_DEPS,$(PKGDIR)$(LIBRARY_BASENAME).a,.$(LINK_FILE_EXTENSION))
+endif
+
+$(PKGDIR)$(LIBRARY_BASENAME).pc: \
+	$(call PRINT_INTLIB_DEPS,$(PKGDIR)$(LIBRARY_BASENAME).pc,.pc)
+
+# -------------------
+# - subdir management
+#
+# as the last step, always add this line to correctly recover the subdirectory
+# of the makefile including this one!
+
+SUBDIR:=$(SUBDIR_before_$(SUBDIR))
+

+ 282 - 0
semseg/operations/Operations.cpp

@@ -0,0 +1,282 @@
+#include "Operations.h"
+
+using namespace OBJREC;
+using namespace std;
+using namespace NICE;
+
+Operation::Operation()
+{
+  values = NULL;
+  maxtypes = 1000;
+}
+
+void Operation::set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values )
+{
+  x1 = _x1;
+  y1 = _y1;
+  x2 = _x2;
+  y2 = _y2;
+  channel1 = _channel1;
+  channel2 = _channel2;
+  values = _values;
+}
+
+void Operation::setContext ( bool _context )
+{
+  context = _context;
+}
+
+bool Operation::getContext()
+{
+  return context;
+}
+
+void Operation::getXY ( const Features &feats, int &xsize, int &ysize )
+{
+  xsize = feats.feats->width();
+  ysize = feats.feats->height();
+}
+
+
+void Operation::store ( std::ostream & os )
+{
+  os << x1 << " " << x2 << " " << y1 << " " << y2 << " " << channel1 << " " << channel2 << std::endl;
+  if ( values == NULL )
+    os << -1 << std::endl;
+  else
+    os << values->getType() << std::endl;
+}
+
+void Operation::restore ( std::istream &is )
+{
+  is >> x1;
+  is >> x2;
+  is >> y1;
+  is >> y2;
+  is >> channel1;
+  is >> channel2;
+
+  int tmp;
+  is >> tmp;
+
+  if ( tmp >= 0 )
+  {
+    if ( tmp == RAWFEAT )
+    {
+      values = new MCImageAccess();
+    }
+    else if ( tmp == CONTEXT )
+    {
+      values = new ClassificationResultAccess();
+    }
+    else
+    {
+      throw ( "no valid ValueAccess" );
+    }
+  }
+  else
+  {
+    values = NULL;
+  }
+}
+
+std::string Operation::writeInfos()
+{
+  std::stringstream ss;
+  ss << " x1: " << x1 << " y1: " << y1 << " x2: " << x2 << " y2: " << y2 << " c1: " << channel1 << " c2: " << channel2;
+  return ss.str();
+}
+
+double Minus::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+  double v1 = values->getVal ( feats, BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 );
+  double v2 = values->getVal ( feats, BOUND ( x + x2, 0, xsize - 1 ), BOUND ( y + y2, 0, ysize - 1 ), channel2 );
+  return v1 -v2;
+}
+
+double MinusAbs::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+  double v1 = values->getVal ( feats, BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 );
+  double v2 = values->getVal ( feats, BOUND ( x + x2, 0, xsize - 1 ), BOUND ( y + y2, 0, ysize - 1 ), channel2 );
+  return abs ( v1 -v2 );
+}
+
+double Addition::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+  double v1 = values->getVal ( feats, BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 );
+  double v2 = values->getVal ( feats, BOUND ( x + x2, 0, xsize - 1 ), BOUND ( y + y2, 0, ysize -
+                               1 ), channel2 );
+  return v1 + v2;
+}
+
+double Only1::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+  double v1 = values->getVal ( feats, BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 );
+  return v1;
+}
+
+double RelativeXPosition::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+  return ( double ) x / ( double ) xsize;
+}
+
+double RelativeYPosition::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+  return ( double ) x / ( double ) xsize;
+}
+
+double IntegralOps::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+  return computeMean ( *feats.integralImg, BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), BOUND ( x + x2, 0, xsize - 1 ), BOUND ( y + y2, 0, ysize - 1 ), channel1 );
+}
+
+double GlobalFeats::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+  return computeMean ( *feats.integralImg, 0, 0, xsize - 1, ysize - 1, channel1 );
+}
+
+double IntegralCenteredOps::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+  return computeMean ( *feats.integralImg, BOUND ( x - x1, 0, xsize - 1 ), BOUND ( y - y1, 0, ysize - 1 ), BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 );
+}
+
+double BiIntegralCenteredOps::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+  return computeMean ( *feats.integralImg, BOUND ( x - x1, 0, xsize - 1 ), BOUND ( y - y1, 0, ysize - 1 ), BOUND ( x + x1, 0, xsize - 1 ), BOUND ( y + y1, 0, ysize - 1 ), channel1 ) - computeMean ( *feats.integralImg, BOUND ( x - x2, 0, xsize - 1 ), BOUND ( y - y2, 0, ysize - 1 ), BOUND ( x + x2, 0, xsize - 1 ), BOUND ( y + y2, 0, ysize - 1 ), channel1 );
+}
+
+double HaarHorizontal::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+
+  int tlx = BOUND ( x - x1, 0, xsize - 1 );
+  int tly = BOUND ( y - y1, 0, ysize - 1 );
+  int lrx = BOUND ( x + x1, 0, xsize - 1 );
+  int lry = BOUND ( y + y1, 0, ysize - 1 );
+
+  return computeMean ( *feats.integralImg, tlx, tly, lrx, y, channel1 ) - computeMean ( *feats.integralImg, tlx, y, lrx, lry, channel1 );
+}
+
+double HaarVertical::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+
+  int tlx = BOUND ( x - x1, 0, xsize - 1 );
+  int tly = BOUND ( y - y1, 0, ysize - 1 );
+  int lrx = BOUND ( x + x1, 0, xsize - 1 );
+  int lry = BOUND ( y + y1, 0, ysize - 1 );
+
+  return computeMean ( *feats.integralImg, tlx, tly, x, lry, channel1 ) - computeMean ( *feats.integralImg, x, tly, lrx, lry, channel1 );
+}
+
+double HaarDiag::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+
+  int tlx = BOUND ( x - x1, 0, xsize - 1 );
+  int tly = BOUND ( y - y1, 0, ysize - 1 );
+  int lrx = BOUND ( x + x1, 0, xsize - 1 );
+  int lry = BOUND ( y + y1, 0, ysize - 1 );
+
+  return computeMean ( *feats.integralImg, tlx, tly, x, y, channel1 ) + computeMean ( *feats.integralImg, x, y, lrx, lry, channel1 ) - computeMean ( *feats.integralImg, tlx, y, x, lry, channel1 ) - computeMean ( *feats.integralImg, x, tly, lrx, y, channel1 );
+}
+
+double Haar3Horiz::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+
+  int tlx = BOUND ( x - x2, 0, xsize - 1 );
+  int tly = BOUND ( y - y2, 0, ysize - 1 );
+  int mtly = BOUND ( y - y1, 0, ysize - 1 );
+  int mlry = BOUND ( y + y1, 0, ysize - 1 );
+  int lrx = BOUND ( x + x2, 0, xsize - 1 );
+  int lry = BOUND ( y + y2, 0, ysize - 1 );
+
+  return computeMean ( *feats.integralImg, tlx, tly, lrx, mtly, channel1 ) - computeMean ( *feats.integralImg, tlx, mtly, lrx, mlry, channel1 ) + computeMean ( *feats.integralImg, tlx, mlry, lrx, lry, channel1 );
+}
+
+double Haar3Vert::getVal ( const Features &feats, const int &x, const int &y )
+{
+  int xsize, ysize;
+  getXY ( feats, xsize, ysize );
+
+  int tlx = BOUND ( x - x2, 0, xsize - 1 );
+  int tly = BOUND ( y - y2, 0, ysize - 1 );
+  int mtlx = BOUND ( x - x1, 0, xsize - 1 );
+  int mlrx = BOUND ( x + x1, 0, xsize - 1 );
+  int lrx = BOUND ( x + x2, 0, xsize - 1 );
+  int lry = BOUND ( y + y2, 0, ysize - 1 );
+
+  return computeMean ( *feats.integralImg, tlx, tly, mtlx, lry, channel1 ) - computeMean ( *feats.integralImg, mtlx, tly, mlrx, lry, channel1 ) + computeMean ( *feats.integralImg, mlrx, tly, lrx, lry, channel1 );
+}
+
+void IntegralOps::set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values )
+{
+  x1 = std::min ( _x1, _x2 );
+  y1 = std::min ( _y1, _y2 );
+  x2 = std::max ( _x1, _x2 );
+  y2 = std::max ( _y1, _y2 );
+  channel1 = _channel1;
+  channel2 = _channel2;
+  values = _values;
+}
+
+double IntegralOps::computeMean ( const NICE::MultiChannelImageT<double> &intImg, const int &uLx, const int &uLy, const int &lRx, const int &lRy, const int &chan )
+{
+  double val1 = intImg.get ( uLx, uLy, chan );
+  double val2 = intImg.get ( lRx, uLy, chan );
+  double val3 = intImg.get ( uLx, lRy, chan );
+  double val4 = intImg.get ( lRx, lRy, chan );
+  double area = ( lRx - uLx ) * ( lRy - uLy );
+
+  if ( area == 0 )
+    return 0.0;
+
+  return ( val1 + val4 - val2 - val3 ) / area;
+}
+
+void IntegralCenteredOps::set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values )
+{
+  x1 = abs ( _x1 );
+  y1 = abs ( _y1 );
+  x2 = abs ( _x2 );
+  y2 = abs ( _y2 );
+  channel1 = _channel1;
+  channel2 = _channel2;
+  values = _values;
+}
+
+void BiIntegralCenteredOps::set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values )
+{
+  x1 = std::min ( abs ( _x1 ), abs ( _x2 ) );
+  y1 = std::min ( abs ( _y1 ), abs ( _y2 ) );
+  x2 = std::max ( abs ( _x1 ), abs ( _x2 ) );
+  y2 = std::max ( abs ( _y1 ), abs ( _y2 ) );
+  channel1 = _channel1;
+  channel2 = _channel2;
+  values = _values;
+}

+ 1106 - 0
semseg/operations/Operations.h

@@ -0,0 +1,1106 @@
+/**
+* @file Operation.h
+* @brief abstract class for any kind of feature extraction from images
+* @author Björn Fröhlich
+* @date 24.04.2012
+
+*/
+
+#include "core/image/MultiChannelImageT.h"
+
+#define BOUND(x,min,max) (((x)<(min))?(min):((x)>(max)?(max):(x)))
+
+namespace OBJREC {
+
+class Operation;
+
+/**
+ * @brief methods for value access
+ **/
+enum ValueTypes
+{
+  RAWFEAT,
+  CONTEXT,
+  SPARSE,
+  NBVALUETYPES
+};
+
+/**
+ * @brief feature extraction methods
+ **/
+enum OperationTypes {
+  MINUS,
+  MINUSABS,
+  ADDITION,
+  ONLY1,
+  INTEGRAL,
+  INTEGRALCENT,
+  BIINTEGRALCENT,
+  HAARHORIZ,
+  HAARVERT,
+  HAARDIAG,
+  HAAR3HORIZ,
+  HAAR3VERT,
+  RELATIVEXPOSITION,
+  RELATIVEYPOSITION,
+  GLOBALFEATS,
+  NBOPERATIONS
+};
+
+/**
+ * @brief node class for context tree
+ **/
+class TreeNode
+{
+
+  public:
+    /** left child node */
+    int left;
+
+    /** right child node */
+    int right;
+
+    /** position of feat for decision */
+    Operation *feat;
+
+    /** decision stamp */
+    double decision;
+
+    /** is the node a leaf or not */
+    bool isleaf;
+
+    /** distribution in current node */
+    std::vector<double> dist;
+
+    /** depth of the node in the tree */
+    int depth;
+
+    /** how many pixels are in this node */
+    int featcounter;
+
+    /** unique number */
+    int nodeNumber;
+
+    /** simple constructor */
+    TreeNode() : left ( -1 ), right ( -1 ), feat ( NULL ), decision ( -1.0 ), isleaf ( false ) {}
+
+    /** standard constructor */
+    TreeNode ( int _left, int _right, Operation *_feat, double _decision ) : left ( _left ), right ( _right ), feat ( _feat ), decision ( _decision ), isleaf ( false ) {}
+};
+
+/**
+ * @brief holds all necessary information for feature extraction
+ **/
+struct Features {
+  /** simple features like RGB values */
+  NICE::MultiChannelImageT<double> *feats;
+
+  /** current leaf position for each pixel and each tree */
+  NICE::MultiChannelImageT<unsigned short int> *cfeats;
+
+  /** amount of trees */
+  int cTree;
+
+  /** tree nodes */
+  std::vector<TreeNode> *tree;
+
+  /** integral images for faster feature computation */
+  NICE::MultiChannelImageT<double> *integralImg;
+};
+
+/**
+ * @brief abstract values access class
+ **/
+class ValueAccess
+{
+  public:
+    /**
+     * @brief extract value on specific position x,y and channel;
+     *
+     * @param feats see struct Features
+     * @param x position of feature
+     * @param y position of feature
+     * @param channel position of feature
+     * @return double value
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y, const int &channel ) = 0;
+
+    /**
+     * @brief print some infos about feature type
+     *
+     * @return string feature type
+     **/
+    virtual std::string writeInfos() = 0;
+
+    /**
+     * @brief get feature type
+     *
+     * @return feature type
+     **/
+    virtual ValueTypes getType() = 0;
+};
+
+/**
+ * @brief simple MultiChannelImageT access
+ **/
+class MCImageAccess: public ValueAccess
+{
+
+  public:
+    /**
+     * @brief extract value on specific position x,y and channel;
+     *
+     * @param feats see struct Features
+     * @param x position of feature
+     * @param y position of feature
+     * @param channel position of feature
+     * @return double value
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y, const int &channel )
+    {
+      return feats.feats->get ( x, y, channel );
+    }
+
+    /**
+     * @brief print some infos about feature type
+     *
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "raw";
+    }
+
+    /**
+     * @brief get feature type
+     *
+     * @return feature type
+     **/
+    virtual ValueTypes getType()
+    {
+      return RAWFEAT;
+    }
+};
+
+class ClassificationResultAccess: public ValueAccess
+{
+
+  public:
+    /**
+     * @brief extract value on specific position x,y and channel;
+     *
+     * @param feats see struct Features
+     * @param x position of feature
+     * @param y position of feature
+     * @param channel position of feature
+     * @return double value
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y, const int &channel )
+    {
+      return ( *feats.tree ) [feats.cfeats->get ( x,y,feats.cTree ) ].dist[channel];
+    }
+
+    /**
+     * @brief print some infos about feature type
+     *
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "context";
+    }
+
+    /**
+     * @brief get feature type
+     *
+     * @return feature type
+     **/
+    virtual ValueTypes getType()
+    {
+      return CONTEXT;
+    }
+};
+
+/**
+ * @brief not finished yet, do we really need sparse feature representation or ClassificationResultAccess sufficient
+ **/
+class SparseImageAccess: public ValueAccess
+{
+  private:
+    double scale;
+
+  public:
+    /**
+     * @brief extract value on specific position x,y and channel;
+     *
+     * @param feats see struct Features
+     * @param x position of feature
+     * @param y position of feature
+     * @param channel position of feature
+     * @return double value
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y, const int &channel )
+    {
+      //MultiChannelImageT<SparseVectorInt> textonMap;
+      //TODO: implement access
+      return -1.0;
+    }
+
+    /**
+     * @brief print some infos about feature type
+     *
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "context";
+    }
+
+    /**
+     * @brief get feature type
+     *
+     * @return feature type
+     **/
+    virtual ValueTypes getType()
+    {
+      return CONTEXT;
+    }
+};
+
+/**
+ * @brief abstract operation class
+ **/
+class Operation
+{
+  protected:
+    /** two different points (e.g. for an rectangle or two positions), channels and size  */
+    int x1, y1, x2, y2, channel1, channel2, maxtypes;
+    ValueAccess *values;
+
+    bool context;
+
+  public:
+
+    /** simple constructor */
+    Operation();
+
+    /**
+     * @brief set all parameters
+     * @param _x1 position 1
+     * @param _y1 position 1
+     * @param _x2 position 2
+     * @param _y2 position 2
+     * @param _channel1 channel 1
+     * @param _channel2 channel 2
+     * @param _values value extraction method
+     * @return void nothing
+     **/
+    virtual void set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values );
+
+    /**
+     * @brief set whether it is a context feature or not
+     * @param _context context boolean
+     * @return void nothing
+     **/
+    void setContext ( bool _context );
+
+    /**
+     * @brief return context information (set by setContext(bool)
+     *
+     * @return bool whether context is used or not
+     **/
+    bool getContext();
+
+    /**
+     * @brief abstract interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y ) = 0;
+
+    /**
+     * @brief virtual clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone() = 0;
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos();
+
+    /**
+     * @brief exctract current image boarders
+     * @param feats image information
+     * @param xsize width
+     * @param ysize height
+     * @return void
+     **/
+    inline void getXY ( const Features &feats, int &xsize, int &ysize );
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps() = 0;
+
+    /**
+     * @brief store all information for current operation in stream
+     * @param os out stream
+     * @return void
+     **/
+    virtual void store ( std::ostream & os );
+
+    /**
+     * @brief restore all information for current operation from stream
+     * @param is in stream
+     * @return void
+     **/
+    virtual void restore ( std::istream & is );
+};
+
+/**
+ * @brief simple difference operation A-B
+ **/
+class Minus: public Operation
+{
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new Minus();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      std::string out = "Minus";
+
+      if ( values != NULL )
+        out += values->writeInfos();
+
+      return out + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return MINUS;
+    }
+};
+
+/**
+ * @brief simple absolute difference operation |A-B|
+ **/
+class MinusAbs: public Operation
+{
+
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new MinusAbs();
+    };
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      std::string out = "MinusAbs";
+
+      if ( values != NULL )
+        out += values->writeInfos();
+
+      return out;
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return MINUSABS;
+    }
+};
+
+/**
+ * @brief simple addition operation A+B
+ **/
+class Addition: public Operation
+{
+
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new Addition();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      std::string out = "Addition";
+
+      if ( values != NULL )
+        out += values->writeInfos();
+
+      return out + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return ADDITION;
+    }
+};
+
+/**
+ * @brief simple single element access operation
+ **/
+class Only1: public Operation
+{
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new Only1();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      std::string out = "Only1";
+
+      if ( values != NULL )
+        out += values->writeInfos();
+
+      return out + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return ONLY1;
+    }
+};
+
+/**
+ * @brief get current relative x position
+ **/
+class RelativeXPosition: public Operation
+{
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new RelativeXPosition();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "RelativeXPosition" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return RELATIVEXPOSITION;
+    }
+};
+
+/**
+ * @brief get current relative y position
+ **/
+class RelativeYPosition: public Operation
+{
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new RelativeYPosition();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "RelativeYPosition" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return RELATIVEYPOSITION;
+    }
+};
+
+
+/**
+ * @brief uses mean in a window given by (x1,y1) (x2,y2)
+ **/
+class IntegralOps: public Operation
+{
+  public:
+    /**
+     * @brief set all parameters
+     * @param _x1 position 1
+     * @param _y1 position 1
+     * @param _x2 position 2
+     * @param _y2 position 2
+     * @param _channel1 channel 1
+     * @param _channel2 channel 2
+     * @param _values value extraction method
+     * @return void nothing
+     **/
+    virtual void set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values );
+
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    inline double computeMean ( const NICE::MultiChannelImageT<double> &intImg, const int &uLx, const int &uLy, const int &lRx, const int &lRy, const int &chan );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new IntegralOps();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "IntegralOps" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return INTEGRAL;
+    }
+};
+
+
+/**
+ * @brief like a global bag of words to model the current appearance of classes in an image without local context
+ **/
+class GlobalFeats: public IntegralOps
+{
+
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new GlobalFeats();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "GlobalFeats" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return GLOBALFEATS;
+    }
+};
+
+/**
+ * @brief uses mean of Integral image given by x1, y1 with current pixel as center
+ **/
+class IntegralCenteredOps: public IntegralOps
+{
+  public:
+    /**
+     * @brief set all parameters
+     * @param _x1 position 1
+     * @param _y1 position 1
+     * @param _x2 position 2
+     * @param _y2 position 2
+     * @param _channel1 channel 1
+     * @param _channel2 channel 2
+     * @param _values value extraction method
+     * @return void nothing
+     **/
+    virtual void set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values );
+
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new IntegralCenteredOps();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "IntegralCenteredOps" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return INTEGRALCENT;
+    }
+};
+
+/**
+ * @brief uses different of mean of Integral image given by two windows, where (x1,y1) is the width and height of window1 and (x2,y2) of window 2
+ **/
+class BiIntegralCenteredOps: public IntegralCenteredOps
+{
+  public:
+    /**
+     * @brief set all parameters
+     * @param _x1 position 1
+     * @param _y1 position 1
+     * @param _x2 position 2
+     * @param _y2 position 2
+     * @param _channel1 channel 1
+     * @param _channel2 channel 2
+     * @param _values value extraction method
+     * @return void nothing
+     **/
+    virtual void set ( int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2, ValueAccess *_values );
+
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new BiIntegralCenteredOps();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "BiIntegralCenteredOps" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return BIINTEGRALCENT;
+    }
+};
+
+/**
+ * @brief horizontal Haar features
+ * ++
+ * --
+ **/
+class HaarHorizontal: public IntegralCenteredOps
+{
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new HaarHorizontal();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "HaarHorizontal" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return HAARHORIZ;
+    }
+};
+
+/**
+ * @brief vertical Haar features
+ * +-
+ * +-
+ **/
+class HaarVertical: public IntegralCenteredOps
+{
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new HaarVertical();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "HaarVertical" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return HAARVERT;
+    }
+};
+
+/**
+ * @brief diagonal Haar features
+ * +-
+ * -+
+ **/
+class HaarDiag: public IntegralCenteredOps
+{
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new HaarDiag();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "HaarDiag" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return HAARDIAG;
+    }
+};
+
+/**
+ * @brief horizontal Haar features
+ * +++
+ * ---
+ * +++
+ */
+
+class Haar3Horiz: public BiIntegralCenteredOps
+{
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new Haar3Horiz();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "Haar3Horiz" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return HAAR3HORIZ;
+    }
+};
+
+/**
+ * @brief vertical Haar features
+ * +-+
+ * +-+
+ * +-+
+ */
+class Haar3Vert: public BiIntegralCenteredOps
+{
+  public:
+    /**
+     * @brief interface for feature computation
+     * @param feats features
+     * @param cfeats number of tree node for each pixel
+     * @param tree current tree
+     * @param x current x position
+     * @param y current y position
+     * @return double distance
+     **/
+    virtual double getVal ( const Features &feats, const int &x, const int &y );
+
+    /**
+     * @brief clone operation instead of copy constructor (copy constructor does not work)
+     **/
+    virtual Operation* clone()
+    {
+      return new Haar3Vert();
+    }
+
+    /**
+     * @brief print some infos about operation extraction type
+     * @return string feature type
+     **/
+    virtual std::string writeInfos()
+    {
+      return "Haar3Vert" + Operation::writeInfos();
+    }
+
+    /**
+     * @brief return operation type (for store and restor)
+     * @return OperationTypes
+     **/
+    virtual OperationTypes getOps()
+    {
+      return HAAR3VERT;
+    }
+};
+
+} //end namespace
+