|
@@ -7,6 +7,7 @@
|
|
|
#include "vislearning/cbaselib/PascalResults.h"
|
|
|
#include "objrec/segmentation/RSMeanShift.h"
|
|
|
#include "objrec/segmentation/RSGraphBased.h"
|
|
|
+#include "core/basics/numerictools.h"
|
|
|
|
|
|
#include <omp.h>
|
|
|
|
|
@@ -35,7 +36,7 @@ public:
|
|
|
virtual Operation* clone()
|
|
|
{
|
|
|
return new Minus();
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
@@ -81,7 +82,7 @@ public:
|
|
|
virtual Operation* clone()
|
|
|
{
|
|
|
return new Addition();
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
@@ -103,7 +104,7 @@ public:
|
|
|
virtual Operation* clone()
|
|
|
{
|
|
|
return new Only1();
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
@@ -126,7 +127,7 @@ public:
|
|
|
virtual Operation* clone()
|
|
|
{
|
|
|
return new ContextMinus();
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
@@ -149,7 +150,7 @@ public:
|
|
|
virtual Operation* clone()
|
|
|
{
|
|
|
return new ContextMinusAbs();
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
@@ -172,7 +173,7 @@ public:
|
|
|
virtual Operation* clone()
|
|
|
{
|
|
|
return new ContextAddition();
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
@@ -194,14 +195,82 @@ public:
|
|
|
virtual Operation* clone()
|
|
|
{
|
|
|
return new ContextOnly1();
|
|
|
- };
|
|
|
+ }
|
|
|
|
|
|
virtual string writeInfos()
|
|
|
{
|
|
|
return "ContextOnly1";
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
+// 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)
|
|
|
+ {
|
|
|
+ x1 = min(_x1,_x2);
|
|
|
+ y1 = min(_y1,_y2);
|
|
|
+ x2 = max(_x1,_x2);
|
|
|
+ y2 = max(_y1,_y2);
|
|
|
+ channel1 = _channel1;
|
|
|
+ channel2 = _channel2;
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, const int &x, const int &y)
|
|
|
+ {
|
|
|
+ MultiChannelImageT<double> intImg;
|
|
|
+ return computeMean(intImg,x1,y1,x2,y2,channel1);
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual Operation* clone()
|
|
|
+ {
|
|
|
+ return new IntegralOps();
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual string writeInfos()
|
|
|
+ {
|
|
|
+ return "IntegralOps";
|
|
|
+ }
|
|
|
+
|
|
|
+ inline double computeMean(const NICE::MultiChannelImageT<double> &intImg, int &uLx, int &uLy, int &lRx, int &lRy, 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);
|
|
|
+ return (val1+val4-val2-val3)/area;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+//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)
|
|
|
+ {
|
|
|
+ x1 = _x1;
|
|
|
+ y1 = _y1;
|
|
|
+ x2 = -x1;
|
|
|
+ y2 = -y1;
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual Operation* clone()
|
|
|
+ {
|
|
|
+ return new IntegralCenteredOps();
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual string writeInfos()
|
|
|
+ {
|
|
|
+ return "IntegralCenteredOps";
|
|
|
+ }
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+//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
|
|
|
+//TODO von Integral ops ableiten
|
|
|
+
|
|
|
|
|
|
SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md )
|
|
|
: SemanticSegmentation ( conf, &(md->getClassNames("train")) )
|
|
@@ -226,16 +295,22 @@ SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md
|
|
|
|
|
|
string segmentationtype = conf->gS(section, "segmentation_type", "meanshift");
|
|
|
|
|
|
- pixelWiseLabeling = conf->gB(section, "use_pixelwise_labeling", false);
|
|
|
+ useGaussian = conf->gB(section, "use_gaussian", true);
|
|
|
+
|
|
|
+ pixelWiseLabeling = false;
|
|
|
|
|
|
if(segmentationtype == "meanshift")
|
|
|
segmentation = new RSMeanShift(conf);
|
|
|
+ else if (segmentationtype == "none")
|
|
|
+ {
|
|
|
+ segmentation = NULL;
|
|
|
+ pixelWiseLabeling = true;
|
|
|
+ }
|
|
|
else if (segmentationtype == "felzenszwalb")
|
|
|
segmentation = new RSGraphBased(conf);
|
|
|
else
|
|
|
- throw("no valid segmenation_type\n please choose between meanshift and felzenswalb\n");
|
|
|
-
|
|
|
-
|
|
|
+ throw("no valid segmenation_type\n please choose between none, meanshift and felzenszwalb\n");
|
|
|
+
|
|
|
|
|
|
ftypes = conf->gI(section, "features", 2);;
|
|
|
|
|
@@ -370,10 +445,23 @@ void SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> > &
|
|
|
featsel.clear();
|
|
|
for(int i = 0; i < featsPerSplit; i++)
|
|
|
{
|
|
|
- int x1 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
|
|
|
- int x2 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
|
|
|
- int y1 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
|
|
|
- int y2 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
|
|
|
+ int x1, x2, y1, y2;
|
|
|
+
|
|
|
+ if(useGaussian)
|
|
|
+ {
|
|
|
+ double sigma = (double)windowSize/2.0;
|
|
|
+ x1 = randGaussDouble(sigma)*(double)windowSize;
|
|
|
+ x2 = randGaussDouble(sigma)*(double)windowSize;
|
|
|
+ y1 = randGaussDouble(sigma)*(double)windowSize;
|
|
|
+ y2 = randGaussDouble(sigma)*(double)windowSize;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ x1 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
|
|
|
+ x2 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
|
|
|
+ y1 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
|
|
|
+ y2 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
|
|
|
+ }
|
|
|
|
|
|
int ft = (int)((double)rand()/(double)RAND_MAX*(double)ftypes);
|
|
|
|
|
@@ -436,7 +524,6 @@ void SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> > &
|
|
|
eR[cn] = eR[cn]+1;
|
|
|
counterR++;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
double leftent = 0.0;
|
|
@@ -655,6 +742,9 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
int s = startnode;
|
|
|
startnode = t;
|
|
|
vector<vector<vector<int> > > lastfeats = currentfeats;
|
|
|
+
|
|
|
+ vector<MultiChannelImageT<double> > integralImgs;
|
|
|
+
|
|
|
//#pragma omp parallel for
|
|
|
for(int i = s; i < t; i++)
|
|
|
{
|
|
@@ -743,6 +833,57 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
}
|
|
|
//TODO: features neu berechnen!
|
|
|
+
|
|
|
+#if 1
|
|
|
+ //compute integral image
|
|
|
+ int channels = (int)labelmap.size();
|
|
|
+
|
|
|
+ if(integralImgs.size() == 0)
|
|
|
+ {
|
|
|
+ for(int i = 0; i < imgcounter; i++)
|
|
|
+ {
|
|
|
+ int xsize = allfeats[i].width();
|
|
|
+ int ysize = allfeats[i].height();
|
|
|
+
|
|
|
+ integralImgs.push_back(MultiChannelImageT<double>(xsize, ysize, channels));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int i = 0; i < imgcounter; i++)
|
|
|
+ {
|
|
|
+ int xsize = allfeats[i].width();
|
|
|
+ int ysize = allfeats[i].height();
|
|
|
+
|
|
|
+ for(int c = 0; c < channels; c++)
|
|
|
+ {
|
|
|
+ integralImgs[i].set(0,0,tree[currentfeats[i][0][0]].dist[c], c);
|
|
|
+
|
|
|
+ //first column
|
|
|
+ for(int y = 1; y < ysize; y++)
|
|
|
+ {
|
|
|
+ integralImgs[i].set(0,0,tree[currentfeats[i][0][y]].dist[c]+integralImgs[i].get(0,y,c), c);
|
|
|
+ }
|
|
|
+
|
|
|
+ //first row
|
|
|
+ for(int x = 1; x < xsize; x++)
|
|
|
+ {
|
|
|
+ integralImgs[i].set(0,0,tree[currentfeats[i][x][0]].dist[c]+integralImgs[i].get(x,0,c), c);
|
|
|
+ }
|
|
|
+
|
|
|
+ //rest
|
|
|
+ for(int y = 1; y < ysize; y++)
|
|
|
+ {
|
|
|
+ for(int x = 1; x < xsize; x++)
|
|
|
+ {
|
|
|
+ double val = tree[currentfeats[i][x][y]].dist[c]+integralImgs[i].get(x,y-1,c)+integralImgs[i].get(x-1,y,c)-integralImgs[i].get(x-1,y-1,c);
|
|
|
+ integralImgs[i].set(0, 0, val, c);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
depth++;
|
|
|
#ifdef DEBUG
|
|
|
cout << "depth: " << depth << endl;
|