|
@@ -16,193 +16,128 @@
|
|
|
|
|
|
#define BOUND(x,min,max) (((x)<(min))?(min):((x)>(max)?(max):(x)))
|
|
|
#undef LOCALFEATS
|
|
|
-
|
|
|
-
|
|
|
//#define LOCALFEATS
|
|
|
|
|
|
using namespace OBJREC;
|
|
|
using namespace std;
|
|
|
using namespace NICE;
|
|
|
|
|
|
-class Minus:public Operation
|
|
|
+class MCImageAccess:public ValueAccess
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const MultiChannelImageT<int> &cfeats, const int &cTree, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
- {
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- double v1 = feats.get(BOUND(x+x1,0,xsize-1),BOUND(y+y1,0,ysize-1),channel1);
|
|
|
- double v2 = feats.get(BOUND(x+x2,0,xsize-1),BOUND(y+y2,0,ysize-1),channel2);
|
|
|
- return v1-v2;
|
|
|
- }
|
|
|
-
|
|
|
- virtual Operation* clone()
|
|
|
+ virtual double getVal(const Features &feats, const int &x, const int &y, const int &channel)
|
|
|
{
|
|
|
- return new Minus();
|
|
|
+ return feats.feats->get(x,y,channel);
|
|
|
}
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
|
- return "Minus";
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-class MinusAbs:public Operation
|
|
|
-{
|
|
|
-public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const MultiChannelImageT<int> &cfeats, const int &cTree, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
- {
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- double v1 = feats.get(BOUND(x+x1,0,xsize-1),BOUND(y+y1,0,ysize-1),channel1);
|
|
|
- double v2 = feats.get(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()
|
|
|
- {
|
|
|
- return "MinusAbs";
|
|
|
+ return "raw";
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-class Addition:public Operation
|
|
|
+class ClassificationResultAcess:public ValueAccess
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const MultiChannelImageT<int> &cfeats, const int &cTree, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
- {
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- double v1 = feats.get(BOUND(x+x1,0,xsize-1),BOUND(y+y1,0,ysize-1),channel1);
|
|
|
- double v2 = feats.get(BOUND(x+x2,0,xsize-1),BOUND(y+y2,0,ysize-1),channel2);
|
|
|
- return v1+v2;
|
|
|
- }
|
|
|
-
|
|
|
- virtual Operation* clone()
|
|
|
+ virtual double getVal(const Features &feats, const int &x, const int &y, const int &channel)
|
|
|
{
|
|
|
- return new Addition();
|
|
|
+ return (*feats.tree)[feats.cfeats->get(x,y,feats.cTree)].dist[channel];
|
|
|
}
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
|
- return "Addition";
|
|
|
+ return "context";
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-class Only1:public Operation
|
|
|
-{
|
|
|
-public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const MultiChannelImageT<int> &cfeats, const int &cTree, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
- {
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- double v1 = feats.get(BOUND(x+x1,0,xsize-1),BOUND(y+y1,0,ysize-1),channel1);
|
|
|
- return v1;
|
|
|
- }
|
|
|
-
|
|
|
- virtual Operation* clone()
|
|
|
- {
|
|
|
- return new Only1();
|
|
|
- }
|
|
|
-
|
|
|
- virtual string writeInfos()
|
|
|
- {
|
|
|
- return "Only1";
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-class ContextMinus:public Operation
|
|
|
+class Minus:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const MultiChannelImageT<int> &cfeats, const int &cTree, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ virtual double getVal(const Features &feats, const int &x, const int &y)
|
|
|
{
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- double v1 = tree[cfeats.get(BOUND(x+x1,0,xsize-1),BOUND(y+y1,0,ysize-1),cTree)].dist[channel1];
|
|
|
- double v2 = tree[cfeats.get(BOUND(x+x2,0,xsize-1),BOUND(y+y2,0,ysize-1),cTree)].dist[channel2];
|
|
|
+ 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 ContextMinus();
|
|
|
+ return new Minus();
|
|
|
}
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
|
- return "ContextMinus";
|
|
|
+ return "Minus"+values->writeInfos();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-class ContextMinusAbs:public Operation
|
|
|
+class MinusAbs:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const MultiChannelImageT<int> &cfeats, const int &cTree, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ virtual double getVal(const Features &feats, const int &x, const int &y)
|
|
|
{
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- double v1 = tree[cfeats.get(BOUND(x+x1,0,xsize-1),BOUND(y+y1,0,ysize-1),cTree)].dist[channel1];
|
|
|
- double v2 = tree[cfeats.get(BOUND(x+x2,0,xsize-1),BOUND(y+y2,0,ysize-1),cTree)].dist[channel2];
|
|
|
+ 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 ContextMinusAbs();
|
|
|
- }
|
|
|
+ return new MinusAbs();
|
|
|
+ };
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
|
- return "ContextMinusAbs";
|
|
|
+ return "MinusAbs"+values->writeInfos();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-class ContextAddition:public Operation
|
|
|
+class Addition:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const MultiChannelImageT<int> &cfeats, const int &cTree, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ virtual double getVal(const Features &feats, const int &x, const int &y)
|
|
|
{
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- double v1 = tree[cfeats.get(BOUND(x+x1,0,xsize-1),BOUND(y+y1,0,ysize-1),cTree)].dist[channel1];
|
|
|
- double v2 = tree[cfeats.get(BOUND(x+x2,0,xsize-1),BOUND(y+y2,0,ysize-1),cTree)].dist[channel2];
|
|
|
+ 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 ContextAddition();
|
|
|
+ return new Addition();
|
|
|
}
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
|
- return "ContextAddition";
|
|
|
+ return "Addition"+values->writeInfos();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-class ContextOnly1:public Operation
|
|
|
+class Only1:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const MultiChannelImageT<int> &cfeats, const int &cTree, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ virtual double getVal(const Features &feats, const int &x, const int &y)
|
|
|
{
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- double v1 = tree[cfeats.get(BOUND(x+x1,0,xsize-1),BOUND(y+y1,0,ysize-1),cTree)].dist[channel1];
|
|
|
+ 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 ContextOnly1();
|
|
|
+ return new Only1();
|
|
|
}
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
|
- return "ContextOnly1";
|
|
|
+ return "Only1"+values->writeInfos();
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -210,7 +145,7 @@ public:
|
|
|
class IntegralOps:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual void set(int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2)
|
|
|
+ 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);
|
|
@@ -218,13 +153,14 @@ public:
|
|
|
y2 = max(_y1,_y2);
|
|
|
channel1 = _channel1;
|
|
|
channel2 = _channel2;
|
|
|
+ values = _values;
|
|
|
}
|
|
|
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const MultiChannelImageT<int> &cfeats, const int &cTree, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ virtual double getVal(const Features &feats, const int &x, const int &y)
|
|
|
{
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- return computeMean(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);
|
|
|
+ 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)
|
|
@@ -254,14 +190,21 @@ class IntegralCenteredOps:public IntegralOps
|
|
|
public:
|
|
|
virtual void set(int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2)
|
|
|
{
|
|
|
- x1 = min(_x1,-_x1);
|
|
|
- y1 = min(_y1,-_y1);
|
|
|
- x2 = -x1;
|
|
|
- y2 = -y1;
|
|
|
+ x1 = abs(_x1);
|
|
|
+ y1 = abs(_y1);
|
|
|
+ x2 = abs(_x2);
|
|
|
+ y2 = abs(_y2);
|
|
|
channel1 = _channel1;
|
|
|
channel2 = _channel2;
|
|
|
}
|
|
|
|
|
|
+ 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();
|
|
@@ -274,7 +217,7 @@ public:
|
|
|
};
|
|
|
|
|
|
//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 IntegralOps
|
|
|
+class BiIntegralCenteredOps:public IntegralCenteredOps
|
|
|
{
|
|
|
public:
|
|
|
virtual void set(int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2)
|
|
@@ -287,11 +230,11 @@ public:
|
|
|
channel2 = _channel2;
|
|
|
}
|
|
|
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const MultiChannelImageT<int> &cfeats, const int &cTree, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ virtual double getVal(const Features &feats, const int &x, const int &y)
|
|
|
{
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- return computeMean(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(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);
|
|
|
+ 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()
|
|
@@ -305,6 +248,137 @@ public:
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+/** 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 string writeInfos()
|
|
|
+ {
|
|
|
+ return "HaarHorizontal";
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 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 string writeInfos()
|
|
|
+ {
|
|
|
+ return "HaarVertical";
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 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 string writeInfos()
|
|
|
+ {
|
|
|
+ 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 string writeInfos()
|
|
|
+ {
|
|
|
+ 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 string writeInfos()
|
|
|
+ {
|
|
|
+ return "Haar3Vert";
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md )
|
|
|
: SemanticSegmentation ( conf, &(md->getClassNames("train")) )
|
|
|
{
|
|
@@ -357,13 +431,17 @@ SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md
|
|
|
ops.push_back(new Addition());
|
|
|
ops.push_back(new Only1());
|
|
|
|
|
|
- cops.push_back(new ContextMinus());
|
|
|
- cops.push_back(new ContextMinusAbs());
|
|
|
- cops.push_back(new ContextAddition());
|
|
|
- cops.push_back(new ContextOnly1());
|
|
|
cops.push_back(new BiIntegralCenteredOps());
|
|
|
cops.push_back(new IntegralCenteredOps());
|
|
|
cops.push_back(new IntegralOps());
|
|
|
+ cops.push_back(new HaarHorizontal());
|
|
|
+ cops.push_back(new HaarVertical());
|
|
|
+ cops.push_back(new HaarDiag());
|
|
|
+ cops.push_back(new Haar3Horiz());
|
|
|
+ cops.push_back(new Haar3Vert());
|
|
|
+
|
|
|
+ calcVal.push_back(new MCImageAccess());
|
|
|
+ calcVal.push_back(new ClassificationResultAcess());
|
|
|
|
|
|
classnames = md->getClassNames ( "train" );
|
|
|
|
|
@@ -378,9 +456,8 @@ SemSegContextTree::~SemSegContextTree()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
-double SemSegContextTree::getBestSplit(const std::vector<NICE::MultiChannelImageT<double> > &feats, std::vector<NICE::MultiChannelImageT<int> > ¤tfeats, std::vector<NICE::MultiChannelImageT<double> > &integralImgs, const std::vector<NICE::MatrixT<int> > &labels, int node, Operation *&splitop, double &splitval, const int &tree)
|
|
|
+double SemSegContextTree::getBestSplit(std::vector<NICE::MultiChannelImageT<double> > &feats, std::vector<NICE::MultiChannelImageT<int> > ¤tfeats, std::vector<NICE::MultiChannelImageT<double> > &integralImgs, const std::vector<NICE::MatrixT<int> > &labels, int node, Operation *&splitop, double &splitval, const int &tree)
|
|
|
{
|
|
|
-
|
|
|
int imgCount = 0, featdim = 0;
|
|
|
try
|
|
|
{
|
|
@@ -391,7 +468,7 @@ double SemSegContextTree::getBestSplit(const std::vector<NICE::MultiChannelImage
|
|
|
{
|
|
|
cerr << "no features computed?" << endl;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
double bestig = -numeric_limits< double >::max();
|
|
|
splitop = NULL;
|
|
|
splitval = -1.0;
|
|
@@ -399,7 +476,7 @@ double SemSegContextTree::getBestSplit(const std::vector<NICE::MultiChannelImage
|
|
|
set<vector<int> >selFeats;
|
|
|
map<int,int> e;
|
|
|
int featcounter = 0;
|
|
|
-
|
|
|
+
|
|
|
for(int iCounter = 0; iCounter < imgCount; iCounter++)
|
|
|
{
|
|
|
int xsize = (int)currentfeats[iCounter].width();
|
|
@@ -415,7 +492,7 @@ double SemSegContextTree::getBestSplit(const std::vector<NICE::MultiChannelImage
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if(featcounter < minFeats)
|
|
|
{
|
|
|
cout << "only " << featcounter << " feats in current node -> it's a leaf" << endl;
|
|
@@ -434,7 +511,7 @@ double SemSegContextTree::getBestSplit(const std::vector<NICE::MultiChannelImage
|
|
|
//cout << "a.size(): " << a.size() << endl;
|
|
|
//getchar();
|
|
|
featcounter = 0;
|
|
|
-
|
|
|
+
|
|
|
for(int iCounter = 0; iCounter < imgCount; iCounter++)
|
|
|
{
|
|
|
int xsize = (int)currentfeats[iCounter].width();
|
|
@@ -479,7 +556,7 @@ double SemSegContextTree::getBestSplit(const std::vector<NICE::MultiChannelImage
|
|
|
cout << "globent to small: " << globent << endl;
|
|
|
return 0.0;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
int classes = (int)forest[tree][0].dist.size();
|
|
|
featsel.clear();
|
|
|
for(int i = 0; i < featsPerSplit; i++)
|
|
@@ -519,16 +596,27 @@ double SemSegContextTree::getBestSplit(const std::vector<NICE::MultiChannelImage
|
|
|
int f2 = (int)((double)rand()/(double)RAND_MAX*(double)featdim);
|
|
|
int o = (int)((double)rand()/(double)RAND_MAX*(double)ops.size());
|
|
|
Operation *op = ops[o]->clone();
|
|
|
- op->set(x1,y1,x2,y2,f1,f2);
|
|
|
+ op->set(x1,y1,x2,y2,f1,f2, calcVal[ft]);
|
|
|
featsel.push_back(op);
|
|
|
}
|
|
|
else if(ft == 1)
|
|
|
{
|
|
|
+ int opssize = (int)ops.size();
|
|
|
int f1 = (int)((double)rand()/(double)RAND_MAX*(double)classes);
|
|
|
int f2 = (int)((double)rand()/(double)RAND_MAX*(double)classes);
|
|
|
- int o = (int)((double)rand()/(double)RAND_MAX*(double)cops.size());
|
|
|
- Operation *op = cops[o]->clone();
|
|
|
- op->set(x1,y1,x2,y2,f1,f2);
|
|
|
+ int o = (int)((double)rand()/(double)RAND_MAX*((double)cops.size())+(double)opssize);
|
|
|
+ Operation *op;
|
|
|
+ if(o < opssize)
|
|
|
+ {
|
|
|
+ op = ops[o]->clone();
|
|
|
+ op->set(x1,y1,x2,y2,f1,f2, calcVal[ft]);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ o -= opssize;
|
|
|
+ op = cops[o]->clone();
|
|
|
+ op->set(x1,y1,x2,y2,f1,f2, calcVal[ft]);
|
|
|
+ }
|
|
|
featsel.push_back(op);
|
|
|
}
|
|
|
}
|
|
@@ -543,7 +631,13 @@ double SemSegContextTree::getBestSplit(const std::vector<NICE::MultiChannelImage
|
|
|
|
|
|
for ( it=selFeats.begin() ; it != selFeats.end(); it++ )
|
|
|
{
|
|
|
- vals.push_back(featsel[f]->getVal(feats[(*it)[0]],currentfeats[(*it)[0]], tree, forest[tree], integralImgs[(*it)[0]], (*it)[1], (*it)[2]));
|
|
|
+ Features feat;
|
|
|
+ feat.feats = &feats[(*it)[0]];
|
|
|
+ feat.cfeats = ¤tfeats[(*it)[0]];
|
|
|
+ feat.cTree = tree;
|
|
|
+ feat.tree = &forest[tree];
|
|
|
+ feat.integralImg = &integralImgs[(*it)[0]];
|
|
|
+ vals.push_back(featsel[f]->getVal(feat, (*it)[1], (*it)[2]));
|
|
|
}
|
|
|
|
|
|
int counter = 0;
|
|
@@ -757,7 +851,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-#endif
|
|
|
+#endif
|
|
|
|
|
|
// getting groundtruth
|
|
|
NICE::Image pixelLabels (xsize, ysize);
|
|
@@ -775,6 +869,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
imgcounter++;
|
|
|
pb.update ( trainp->count());
|
|
|
delete ce;
|
|
@@ -891,7 +986,13 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
{
|
|
|
if(currentfeats[iCounter].get(x, y, tree) == i)
|
|
|
{
|
|
|
- double val = splitfeat->getVal(allfeats[iCounter],lastfeats[iCounter], tree, forest[tree], integralImgs[iCounter],x,y);
|
|
|
+ Features feat;
|
|
|
+ feat.feats = &allfeats[iCounter];
|
|
|
+ feat.cfeats = &lastfeats[iCounter];
|
|
|
+ feat.cTree = tree;
|
|
|
+ feat.tree = &forest[tree];
|
|
|
+ feat.integralImg = &integralImgs[iCounter];
|
|
|
+ double val = splitfeat->getVal(feat,x,y);
|
|
|
if(val < splitval)
|
|
|
{
|
|
|
currentfeats[iCounter].set(x,y,left,tree);
|
|
@@ -924,32 +1025,8 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if(lcounter <= 0 || rcounter <= 0)
|
|
|
- {
|
|
|
- cout << "lcounter : " << lcounter << " rcounter: " << rcounter << endl;
|
|
|
- cout << "splitval: " << splitval << " splittype: " << splitfeat->writeInfos() << endl;
|
|
|
- cout << "bestig: " << bestig << endl;
|
|
|
- for(int iCounter = 0; iCounter < imgcounter; iCounter++)
|
|
|
- {
|
|
|
- int xsize = currentfeats[iCounter].width();
|
|
|
- int ysize = currentfeats[iCounter].height();
|
|
|
- int counter = 0;
|
|
|
- for(int x = 0; x < xsize; x++)
|
|
|
- {
|
|
|
- for(int y = 0; y < ysize; y++)
|
|
|
- {
|
|
|
- if(lastfeats[iCounter].get(x,y,tree) == i)
|
|
|
- {
|
|
|
- if(++counter > 30)
|
|
|
- break;
|
|
|
- double val = splitfeat->getVal(allfeats[iCounter],lastfeats[iCounter], tree, forest[tree], integralImgs[iCounter],x,y);
|
|
|
- cout << "splitval: " << splitval << " val: " << val << endl;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- assert(lcounter > 0 && rcounter > 0);
|
|
|
- }
|
|
|
+ assert(lcounter > 0 && rcounter > 0);
|
|
|
+
|
|
|
for(uint d = 0; d < forest[tree][left].dist.size(); d++)
|
|
|
{
|
|
|
forest[tree][left].dist[d]/=lcounter;
|
|
@@ -962,32 +1039,30 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+ //TODO: features neu berechnen!
|
|
|
|
|
|
-#if 1
|
|
|
- timer.stop();
|
|
|
- cout << "time for depth " << depth << ": " << timer.getLast() << endl;
|
|
|
-#endif
|
|
|
-
|
|
|
- //TODO: features neu berechnen!
|
|
|
-
|
|
|
- //compute integral image
|
|
|
- int channels = classes;
|
|
|
-
|
|
|
- if(integralImgs[0].width() == 0)
|
|
|
- {
|
|
|
- for(int i = 0; i < imgcounter; i++)
|
|
|
- {
|
|
|
- int xsize = allfeats[i].width();
|
|
|
- int ysize = allfeats[i].height();
|
|
|
- integralImgs[i].reInit(xsize, ysize, channels);
|
|
|
- }
|
|
|
- }
|
|
|
+ //compute integral image
|
|
|
+ int channels = classes;
|
|
|
|
|
|
+ if(integralImgs[0].width() == 0)
|
|
|
+ {
|
|
|
for(int i = 0; i < imgcounter; i++)
|
|
|
{
|
|
|
- computeIntegralImage(currentfeats[i],integralImgs[i]);
|
|
|
+ int xsize = allfeats[i].width();
|
|
|
+ int ysize = allfeats[i].height();
|
|
|
+ integralImgs[i].reInit(xsize, ysize, channels);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ for(int i = 0; i < imgcounter; i++)
|
|
|
+ {
|
|
|
+ computeIntegralImage(currentfeats[i],integralImgs[i]);
|
|
|
+ }
|
|
|
+#if 1
|
|
|
+ timer.stop();
|
|
|
+ cout << "time for depth " << depth << ": " << timer.getLast() << endl;
|
|
|
+#endif
|
|
|
depth++;
|
|
|
#ifdef DEBUG
|
|
|
cout << "depth: " << depth << endl;
|
|
@@ -1080,7 +1155,14 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
if(forest[tree][t].left > 0)
|
|
|
{
|
|
|
allleaf = false;
|
|
|
- double val = forest[tree][t].feat->getVal(feats,lastfeats,tree, forest[tree], integralImg,x,y);
|
|
|
+ Features feat;
|
|
|
+ feat.feats = &feats;
|
|
|
+ feat.cfeats = &lastfeats;
|
|
|
+ feat.cTree = tree;
|
|
|
+ feat.tree = &forest[tree];
|
|
|
+ feat.integralImg = &integralImg;
|
|
|
+
|
|
|
+ double val = forest[tree][t].feat->getVal(feat,x,y);
|
|
|
|
|
|
if(val < forest[tree][t].decision)
|
|
|
{
|