|
@@ -23,7 +23,7 @@ using namespace NICE;
|
|
|
class Minus:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ 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();
|
|
@@ -46,7 +46,7 @@ public:
|
|
|
class MinusAbs:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ 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();
|
|
@@ -69,7 +69,7 @@ public:
|
|
|
class Addition:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ 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();
|
|
@@ -92,7 +92,7 @@ public:
|
|
|
class Only1:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ 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();
|
|
@@ -114,12 +114,12 @@ public:
|
|
|
class ContextMinus:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ 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 = tree[cfeats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)]].dist[channel1];
|
|
|
- double v2 = tree[cfeats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)]].dist[channel2];
|
|
|
+ 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];
|
|
|
return v1-v2;
|
|
|
}
|
|
|
|
|
@@ -137,12 +137,12 @@ public:
|
|
|
class ContextMinusAbs:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ 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 = tree[cfeats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)]].dist[channel1];
|
|
|
- double v2 = tree[cfeats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)]].dist[channel2];
|
|
|
+ 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];
|
|
|
return abs(v1-v2);
|
|
|
}
|
|
|
|
|
@@ -160,12 +160,12 @@ public:
|
|
|
class ContextAddition:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ 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 = tree[cfeats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)]].dist[channel1];
|
|
|
- double v2 = tree[cfeats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)]].dist[channel2];
|
|
|
+ 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];
|
|
|
return v1+v2;
|
|
|
}
|
|
|
|
|
@@ -183,11 +183,11 @@ public:
|
|
|
class ContextOnly1:public Operation
|
|
|
{
|
|
|
public:
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ 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 = tree[cfeats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)]].dist[channel1];
|
|
|
+ double v1 = tree[cfeats.get(BOUND(x+x1,0,xsize-1),BOUND(y+y1,0,ysize-1),cTree)].dist[channel1];
|
|
|
return v1;
|
|
|
}
|
|
|
|
|
@@ -216,7 +216,7 @@ public:
|
|
|
channel2 = _channel2;
|
|
|
}
|
|
|
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ 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();
|
|
@@ -283,7 +283,7 @@ public:
|
|
|
channel2 = _channel2;
|
|
|
}
|
|
|
|
|
|
- virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, MultiChannelImageT<double> &integralImg, const int &x, const int &y)
|
|
|
+ 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();
|
|
@@ -372,7 +372,7 @@ SemSegContextTree::~SemSegContextTree()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
-double SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> > &feats, vector<vector<vector<int> > > ¤tfeats, vector<MultiChannelImageT<double> > &integralImgs, const vector<vector<vector<int> > > &labels, int node, Operation *&splitop, double &splitval)
|
|
|
+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)
|
|
|
{
|
|
|
|
|
|
int imgCount = 0, featdim = 0;
|
|
@@ -396,13 +396,13 @@ double SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> >
|
|
|
|
|
|
for(int iCounter = 0; iCounter < imgCount; iCounter++)
|
|
|
{
|
|
|
- int xsize = (int)currentfeats[iCounter].size();
|
|
|
- int ysize = (int)currentfeats[iCounter][0].size();
|
|
|
+ int xsize = (int)currentfeats[iCounter].width();
|
|
|
+ int ysize = (int)currentfeats[iCounter].height();
|
|
|
for(int x = 0; x < xsize; x++)
|
|
|
{
|
|
|
for(int y = 0; y < ysize; y++)
|
|
|
{
|
|
|
- if(currentfeats[iCounter][x][y] == node)
|
|
|
+ if(currentfeats[iCounter].get(x,y,tree) == node)
|
|
|
{
|
|
|
featcounter++;
|
|
|
}
|
|
@@ -431,15 +431,15 @@ double SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> >
|
|
|
|
|
|
for(int iCounter = 0; iCounter < imgCount; iCounter++)
|
|
|
{
|
|
|
- int xsize = (int)currentfeats[iCounter].size();
|
|
|
- int ysize = (int)currentfeats[iCounter][0].size();
|
|
|
+ int xsize = (int)currentfeats[iCounter].width();
|
|
|
+ int ysize = (int)currentfeats[iCounter].height();
|
|
|
for(int x = 0; x < xsize; x++)
|
|
|
{
|
|
|
for(int y = 0; y < ysize; y++)
|
|
|
{
|
|
|
- if(currentfeats[iCounter][x][y] == node)
|
|
|
+ if(currentfeats[iCounter].get(x,y,tree) == node)
|
|
|
{
|
|
|
- int cn = labels[iCounter][x][y];
|
|
|
+ int cn = labels[iCounter](x,y);
|
|
|
double randD = (double)rand()/(double)RAND_MAX;
|
|
|
if(randD < fraction[labelmap[cn]])
|
|
|
{
|
|
@@ -474,7 +474,7 @@ double SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> >
|
|
|
return 0.0;
|
|
|
}
|
|
|
|
|
|
- int classes = (int)tree[0].dist.size();
|
|
|
+ int classes = (int)forest[tree][0].dist.size();
|
|
|
featsel.clear();
|
|
|
for(int i = 0; i < featsPerSplit; i++)
|
|
|
{
|
|
@@ -537,7 +537,7 @@ double SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> >
|
|
|
|
|
|
for ( it=selFeats.begin() ; it != selFeats.end(); it++ )
|
|
|
{
|
|
|
- vals.push_back(featsel[f]->getVal(feats[(*it)[0]],currentfeats[(*it)[0]],tree, integralImgs[(*it)[0]], (*it)[1], (*it)[2]));
|
|
|
+ vals.push_back(featsel[f]->getVal(feats[(*it)[0]],currentfeats[(*it)[0]], tree, forest[tree], integralImgs[(*it)[0]], (*it)[1], (*it)[2]));
|
|
|
}
|
|
|
|
|
|
int counter = 0;
|
|
@@ -551,7 +551,7 @@ double SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> >
|
|
|
int counter2 = 0;
|
|
|
for ( it2=selFeats.begin() ; it2 != selFeats.end(); it2++, counter2++ )
|
|
|
{
|
|
|
- int cn = labels[(*it2)[0]][(*it2)[1]][(*it2)[2]];
|
|
|
+ int cn = labels[(*it2)[0]]((*it2)[1], (*it2)[2]);
|
|
|
//cout << "vals[counter2] " << vals[counter2] << " val: " << val << endl;
|
|
|
if(vals[counter2] < val)
|
|
|
{
|
|
@@ -626,29 +626,38 @@ double SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> >
|
|
|
return bestig;
|
|
|
}
|
|
|
|
|
|
-void SemSegContextTree::computeIntegralImage(const vector<vector<int> > ¤tfeats, MultiChannelImageT<double> &integralImage)
|
|
|
+inline double SemSegContextTree::getMeanProb(const int &x,const int &y,const int &channel, const MultiChannelImageT<int> ¤tfeats)
|
|
|
{
|
|
|
- int xsize = currentfeats.size();
|
|
|
- assert(xsize > 0);
|
|
|
- int ysize = currentfeats[0].size();
|
|
|
+ double val = 0.0;
|
|
|
+ for(int tree = 0; tree < nbTrees; tree++)
|
|
|
+ {
|
|
|
+ val += forest[tree][currentfeats.get(x,y,tree)].dist[channel];
|
|
|
+ }
|
|
|
+
|
|
|
+ return val / (double)nbTrees;
|
|
|
+}
|
|
|
+
|
|
|
+void SemSegContextTree::computeIntegralImage(const NICE::MultiChannelImageT<int> ¤tfeats, NICE::MultiChannelImageT<double> &integralImage)
|
|
|
+{
|
|
|
+ int xsize = currentfeats.width();
|
|
|
+ int ysize = currentfeats.height();
|
|
|
|
|
|
int channels = (int)labelmap.size();
|
|
|
#pragma omp parallel for
|
|
|
for(int c = 0; c < channels; c++)
|
|
|
{
|
|
|
- integralImage.set(0,0,tree[currentfeats[0][0]].dist[c], c);
|
|
|
-
|
|
|
+ integralImage.set(0,0,getMeanProb(0,0,c, currentfeats), c);
|
|
|
|
|
|
//first column
|
|
|
for(int y = 1; y < ysize; y++)
|
|
|
{
|
|
|
- integralImage.set(0,y,tree[currentfeats[0][y]].dist[c]+integralImage.get(0,y,c), c);
|
|
|
+ integralImage.set(0,y,getMeanProb(0,y,c, currentfeats)+integralImage.get(0,y,c), c);
|
|
|
}
|
|
|
|
|
|
//first row
|
|
|
for(int x = 1; x < xsize; x++)
|
|
|
{
|
|
|
- integralImage.set(x,0,tree[currentfeats[x][0]].dist[c]+integralImage.get(x,0,c), c);
|
|
|
+ integralImage.set(x,0,getMeanProb(x,0,c, currentfeats)+integralImage.get(x,0,c), c);
|
|
|
}
|
|
|
|
|
|
//rest
|
|
@@ -656,7 +665,7 @@ void SemSegContextTree::computeIntegralImage(const vector<vector<int> > ¤t
|
|
|
{
|
|
|
for(int x = 1; x < xsize; x++)
|
|
|
{
|
|
|
- double val = tree[currentfeats[x][y]].dist[c]+integralImage.get(x,y-1,c)+integralImage.get(x-1,y,c)-integralImage.get(x-1,y-1,c);
|
|
|
+ double val = getMeanProb(x,y,c,currentfeats)+integralImage.get(x,y-1,c)+integralImage.get(x-1,y,c)-integralImage.get(x-1,y-1,c);
|
|
|
integralImage.set(x, y, val, c);
|
|
|
}
|
|
|
}
|
|
@@ -673,8 +682,8 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
|
|
|
//TODO: Speichefresser!, lohnt sich sparse?
|
|
|
vector<MultiChannelImageT<double> > allfeats;
|
|
|
- vector<vector<vector<int> > > currentfeats;
|
|
|
- vector<vector<vector<int> > > labels;
|
|
|
+ vector<MultiChannelImageT<int> > currentfeats;
|
|
|
+ vector<MatrixT<int> > labels;
|
|
|
|
|
|
std::string forbidden_classes_s = conf->gS ( "analysis", "donttrain", "" );
|
|
|
if ( forbidden_classes_s == "" )
|
|
@@ -708,10 +717,11 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
|
|
|
int xsize, ysize;
|
|
|
ce->getImageSize ( xsize, ysize );
|
|
|
-
|
|
|
- vector<vector<int> > tmp = vector<vector<int> >(xsize, vector<int>(ysize,0));
|
|
|
+
|
|
|
+ MultiChannelImageT<int> tmp(xsize, ysize, nbTrees);
|
|
|
+ MatrixT<int> tmpMat(xsize,ysize);
|
|
|
currentfeats.push_back(tmp);
|
|
|
- labels.push_back(tmp);
|
|
|
+ labels.push_back(tmpMat);
|
|
|
|
|
|
try {
|
|
|
img = ColorImage(currentFile);
|
|
@@ -750,7 +760,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
for(int y = 0; y < ysize; y++)
|
|
|
{
|
|
|
classno = pixelLabels.getPixel(x, y);
|
|
|
- labels[imgcounter][x][y] = classno;
|
|
|
+ labels[imgcounter](x,y) = classno;
|
|
|
if ( forbidden_classes.find ( classno ) != forbidden_classes.end() )
|
|
|
continue;
|
|
|
labelcounter[classno]++;
|
|
@@ -778,14 +788,14 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
a = vector<double>(classes,0.0);
|
|
|
for(int iCounter = 0; iCounter < imgcounter; iCounter++)
|
|
|
{
|
|
|
- int xsize = (int)currentfeats[iCounter].size();
|
|
|
- int ysize = (int)currentfeats[iCounter][0].size();
|
|
|
+ int xsize = (int)currentfeats[iCounter].width();
|
|
|
+ int ysize = (int)currentfeats[iCounter].height();
|
|
|
for(int x = 0; x < xsize; x++)
|
|
|
{
|
|
|
for(int y = 0; y < ysize; y++)
|
|
|
{
|
|
|
featcounter++;
|
|
|
- int cn = labels[iCounter][x][y];
|
|
|
+ int cn = labels[iCounter](x,y);
|
|
|
a[labelmap[cn]] ++;
|
|
|
}
|
|
|
}
|
|
@@ -804,11 +814,17 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
cout << "a.size: " << a.size() << endl;
|
|
|
#endif
|
|
|
|
|
|
- tree.push_back(TreeNode());
|
|
|
- tree[0].dist = vector<double>(classes,0.0);
|
|
|
int depth = 0;
|
|
|
- tree[0].depth = depth;
|
|
|
- int startnode = 0;
|
|
|
+ for(int t = 0; t < nbTrees; t++)
|
|
|
+ {
|
|
|
+ vector<TreeNode> tree;
|
|
|
+ tree.push_back(TreeNode());
|
|
|
+ tree[0].dist = vector<double>(classes,0.0);
|
|
|
+ tree[0].depth = depth;
|
|
|
+ forest.push_back(tree);
|
|
|
+ }
|
|
|
+
|
|
|
+ vector<int> startnode(nbTrees,0);
|
|
|
bool allleaf = false;
|
|
|
//int baseFeatSize = allfeats[0].size();
|
|
|
|
|
@@ -817,159 +833,166 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
while(!allleaf && depth < maxDepth)
|
|
|
{
|
|
|
allleaf = true;
|
|
|
- int t = (int) tree.size();
|
|
|
- int s = startnode;
|
|
|
- startnode = t;
|
|
|
- vector<vector<vector<int> > > lastfeats = currentfeats;
|
|
|
-//TODO vielleicht parallel wenn nächste schleife trotzdem noch parallelsiert würde, die hat mehr gewicht
|
|
|
-//#pragma omp parallel for
|
|
|
- for(int i = s; i < t; i++)
|
|
|
+ for(int tree = 0; tree < nbTrees; tree++)
|
|
|
{
|
|
|
- if(!tree[i].isleaf && tree[i].left < 0)
|
|
|
- {
|
|
|
- Operation *splitfeat = NULL;
|
|
|
- double splitval;
|
|
|
-
|
|
|
- double bestig = getBestSplit(allfeats, lastfeats, integralImgs, labels, i, splitfeat, splitval);
|
|
|
- tree[i].feat = splitfeat;
|
|
|
- tree[i].decision = splitval;
|
|
|
-
|
|
|
- if(splitfeat != NULL)
|
|
|
- {
|
|
|
- allleaf = false;
|
|
|
- int left = tree.size();
|
|
|
- tree.push_back(TreeNode());
|
|
|
- tree.push_back(TreeNode());
|
|
|
- int right = left+1;
|
|
|
- tree[i].left = left;
|
|
|
- tree[i].right = right;
|
|
|
- tree[left].dist = vector<double>(classes, 0.0);
|
|
|
- tree[right].dist = vector<double>(classes, 0.0);
|
|
|
- tree[left].depth = depth+1;
|
|
|
- tree[right].depth = depth+1;
|
|
|
+ int t = (int) forest[tree].size();
|
|
|
+ int s = startnode[tree];
|
|
|
+ startnode[tree] = t;
|
|
|
+ vector<MultiChannelImageT<int> > lastfeats = currentfeats;
|
|
|
+ //TODO vielleicht parallel wenn nächste schleife trotzdem noch parallelsiert würde, die hat mehr gewicht
|
|
|
+ //#pragma omp parallel for
|
|
|
+ for(int i = s; i < t; i++)
|
|
|
+ {
|
|
|
+ if(!forest[tree][i].isleaf && forest[tree][i].left < 0)
|
|
|
+ {
|
|
|
+ Operation *splitfeat = NULL;
|
|
|
+ double splitval;
|
|
|
|
|
|
-#pragma omp parallel for
|
|
|
- for(int iCounter = 0; iCounter < imgcounter; iCounter++)
|
|
|
+ double bestig = getBestSplit(allfeats, lastfeats, integralImgs, labels, i, splitfeat, splitval, tree);
|
|
|
+ forest[tree][i].feat = splitfeat;
|
|
|
+ forest[tree][i].decision = splitval;
|
|
|
+
|
|
|
+ if(splitfeat != NULL)
|
|
|
{
|
|
|
- int xsize = currentfeats[iCounter].size();
|
|
|
- int ysize = currentfeats[iCounter][0].size();
|
|
|
- for(int x = 0; x < xsize; x++)
|
|
|
+ allleaf = false;
|
|
|
+ int left = forest[tree].size();
|
|
|
+ forest[tree].push_back(TreeNode());
|
|
|
+ forest[tree].push_back(TreeNode());
|
|
|
+ int right = left+1;
|
|
|
+ forest[tree][i].left = left;
|
|
|
+ forest[tree][i].right = right;
|
|
|
+ forest[tree][left].dist = vector<double>(classes, 0.0);
|
|
|
+ forest[tree][right].dist = vector<double>(classes, 0.0);
|
|
|
+ forest[tree][left].depth = depth+1;
|
|
|
+ forest[tree][right].depth = depth+1;
|
|
|
+
|
|
|
+ #pragma omp parallel for
|
|
|
+ for(int iCounter = 0; iCounter < imgcounter; iCounter++)
|
|
|
{
|
|
|
- for(int y = 0; y < ysize; y++)
|
|
|
+ int xsize = currentfeats[iCounter].width();
|
|
|
+ int ysize = currentfeats[iCounter].height();
|
|
|
+ for(int x = 0; x < xsize; x++)
|
|
|
{
|
|
|
- if(currentfeats[iCounter][x][y] == i)
|
|
|
+ for(int y = 0; y < ysize; y++)
|
|
|
{
|
|
|
- double val = splitfeat->getVal(allfeats[iCounter],lastfeats[iCounter], tree, integralImgs[iCounter],x,y);
|
|
|
- if(val < splitval)
|
|
|
- {
|
|
|
- currentfeats[iCounter][x][y] = left;
|
|
|
- tree[left].dist[labelmap[labels[iCounter][x][y]]]++;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- currentfeats[iCounter][x][y] = right;
|
|
|
- tree[right].dist[labelmap[labels[iCounter][x][y]]]++;
|
|
|
+ if(currentfeats[iCounter].get(x, y, t) == i)
|
|
|
+ {
|
|
|
+ double val = splitfeat->getVal(allfeats[iCounter],lastfeats[iCounter], tree, forest[tree], integralImgs[iCounter],x,y);
|
|
|
+ if(val < splitval)
|
|
|
+ {
|
|
|
+ currentfeats[iCounter].set(x,y,left,t);
|
|
|
+ forest[tree][left].dist[labelmap[labels[iCounter](x,y)]]++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ currentfeats[iCounter].set(x,y,right,t);
|
|
|
+ forest[tree][right].dist[labelmap[labels[iCounter](x,y)]]++;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- double lcounter = 0.0, rcounter = 0.0;
|
|
|
- for(uint d = 0; d < tree[left].dist.size(); d++)
|
|
|
- {
|
|
|
- if ( forbidden_classes.find ( labelmapback[d] ) != forbidden_classes.end() )
|
|
|
- {
|
|
|
- tree[left].dist[d] = 0;
|
|
|
- tree[right].dist[d] = 0;
|
|
|
- }
|
|
|
- else
|
|
|
+
|
|
|
+ double lcounter = 0.0, rcounter = 0.0;
|
|
|
+ for(uint d = 0; d < forest[tree][left].dist.size(); d++)
|
|
|
{
|
|
|
- tree[left].dist[d]/=a[d];
|
|
|
- lcounter +=tree[left].dist[d];
|
|
|
- tree[right].dist[d]/=a[d];
|
|
|
- rcounter +=tree[right].dist[d];
|
|
|
+ if ( forbidden_classes.find ( labelmapback[d] ) != forbidden_classes.end() )
|
|
|
+ {
|
|
|
+ forest[tree][left].dist[d] = 0;
|
|
|
+ forest[tree][right].dist[d] = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ forest[tree][left].dist[d]/=a[d];
|
|
|
+ lcounter +=forest[tree][left].dist[d];
|
|
|
+ forest[tree][right].dist[d]/=a[d];
|
|
|
+ rcounter +=forest[tree][right].dist[d];
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- 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++)
|
|
|
+
|
|
|
+ if(lcounter <= 0 || rcounter <= 0)
|
|
|
{
|
|
|
- int xsize = currentfeats[iCounter].size();
|
|
|
- int ysize = currentfeats[iCounter][0].size();
|
|
|
- int counter = 0;
|
|
|
- for(int x = 0; x < xsize; x++)
|
|
|
+ cout << "lcounter : " << lcounter << " rcounter: " << rcounter << endl;
|
|
|
+ cout << "splitval: " << splitval << " splittype: " << splitfeat->writeInfos() << endl;
|
|
|
+ cout << "bestig: " << bestig << endl;
|
|
|
+ for(int iCounter = 0; iCounter < imgcounter; iCounter++)
|
|
|
{
|
|
|
- for(int y = 0; y < ysize; y++)
|
|
|
+ int xsize = currentfeats[iCounter].width();
|
|
|
+ int ysize = currentfeats[iCounter].height();
|
|
|
+ int counter = 0;
|
|
|
+ for(int x = 0; x < xsize; x++)
|
|
|
{
|
|
|
- if(lastfeats[iCounter][x][y] == i)
|
|
|
+ for(int y = 0; y < ysize; y++)
|
|
|
{
|
|
|
- if(++counter > 30)
|
|
|
- break;
|
|
|
- double val = splitfeat->getVal(allfeats[iCounter],lastfeats[iCounter], tree, integralImgs[iCounter],x,y);
|
|
|
- cout << "splitval: " << splitval << " val: " << val << endl;
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ for(uint d = 0; d < forest[tree][left].dist.size(); d++)
|
|
|
+ {
|
|
|
+ forest[tree][left].dist[d]/=lcounter;
|
|
|
+ forest[tree][right].dist[d]/=rcounter;
|
|
|
}
|
|
|
- assert(lcounter > 0 && rcounter > 0);
|
|
|
}
|
|
|
- for(uint d = 0; d < tree[left].dist.size(); d++)
|
|
|
+ else
|
|
|
{
|
|
|
- tree[left].dist[d]/=lcounter;
|
|
|
- tree[right].dist[d]/=rcounter;
|
|
|
+ forest[tree][i].isleaf = true;
|
|
|
}
|
|
|
}
|
|
|
- else
|
|
|
+ }
|
|
|
+ //TODO: features neu berechnen!
|
|
|
+
|
|
|
+ //compute integral image
|
|
|
+ int channels = (int)labelmap.size();
|
|
|
+
|
|
|
+ if(integralImgs[0].width() == 0)
|
|
|
+ {
|
|
|
+ for(int i = 0; i < imgcounter; i++)
|
|
|
{
|
|
|
- tree[i].isleaf = true;
|
|
|
+ int xsize = allfeats[i].width();
|
|
|
+ int ysize = allfeats[i].height();
|
|
|
+
|
|
|
+ integralImgs[i].reInit(xsize, ysize, channels);
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- //TODO: features neu berechnen!
|
|
|
-
|
|
|
- //compute integral image
|
|
|
- int channels = (int)labelmap.size();
|
|
|
-
|
|
|
- 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);
|
|
|
+ computeIntegralImage(currentfeats[i],integralImgs[i]);
|
|
|
}
|
|
|
+
|
|
|
+ depth++;
|
|
|
+ #ifdef DEBUG
|
|
|
+ cout << "depth: " << depth << endl;
|
|
|
+ #endif
|
|
|
}
|
|
|
|
|
|
- for(int i = 0; i < imgcounter; i++)
|
|
|
- {
|
|
|
- computeIntegralImage(currentfeats[i],integralImgs[i]);
|
|
|
- }
|
|
|
-
|
|
|
- depth++;
|
|
|
-#ifdef DEBUG
|
|
|
- cout << "depth: " << depth << endl;
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
- int t = (int) tree.size();
|
|
|
- for(int i = 0; i < t; i++)
|
|
|
+ for(int tree = 0; tree < nbTrees; tree++)
|
|
|
{
|
|
|
- printf("tree[%i]: left: %i, right: %i", i, tree[i].left, tree[i].right);
|
|
|
- if(!tree[i].isleaf && tree[i].left != -1)
|
|
|
- cout << ", feat: " << tree[i].feat->writeInfos() << " ";
|
|
|
- for(int d = 0; d < (int)tree[i].dist.size(); d++)
|
|
|
+ int t = (int) forest[tree].size();
|
|
|
+ for(int i = 0; i < t; i++)
|
|
|
{
|
|
|
- cout << " " << tree[i].dist[d];
|
|
|
+ printf("tree[%i]: left: %i, right: %i", i, forest[tree][i].left, forest[tree][i].right);
|
|
|
+ if(!forest[tree][i].isleaf && forest[tree][i].left != -1)
|
|
|
+ cout << ", feat: " << forest[tree][i].feat->writeInfos() << " ";
|
|
|
+ for(int d = 0; d < (int)forest[tree][i].dist.size(); d++)
|
|
|
+ {
|
|
|
+ cout << " " << forest[tree][i].dist[d];
|
|
|
+ }
|
|
|
+ cout << endl;
|
|
|
}
|
|
|
- cout << endl;
|
|
|
}
|
|
|
#endif
|
|
|
}
|
|
@@ -1021,31 +1044,31 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
|
|
|
MultiChannelImageT<double> integralImg;
|
|
|
|
|
|
- vector<vector<int> > currentfeats = vector<vector<int> >(xsize, vector<int>(ysize,0));
|
|
|
+ MultiChannelImageT<int> currentfeats(xsize, ysize, nbTrees);
|
|
|
int depth = 0;
|
|
|
while(!allleaf)
|
|
|
{
|
|
|
allleaf = true;
|
|
|
//TODO vielleicht parallel wenn nächste schleife auch noch parallelsiert würde, die hat mehr gewicht
|
|
|
//#pragma omp parallel for
|
|
|
- vector<vector<int> > lastfeats = currentfeats;
|
|
|
+ MultiChannelImageT<int> lastfeats = currentfeats;
|
|
|
for(int x = 0; x < xsize; x++)
|
|
|
{
|
|
|
for(int y = 0; y < ysize; y++)
|
|
|
{
|
|
|
- int t = currentfeats[x][y];
|
|
|
+ int t = currentfeats.get(x,y,tree);
|
|
|
if(tree[t].left > 0)
|
|
|
{
|
|
|
allleaf = false;
|
|
|
- double val = tree[t].feat->getVal(feats,lastfeats,tree,integralImg,x,y);
|
|
|
+ double val = tree[t].feat->getVal(feats,lastfeats,tree, forest[tree], integralImg,x,y);
|
|
|
|
|
|
if(val < tree[t].decision)
|
|
|
{
|
|
|
- currentfeats[x][y] = tree[t].left;
|
|
|
+ currentfeats.set(x, y, tree[t].left, tree);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- currentfeats[x][y] = tree[t].right;
|
|
|
+ currentfeats.set(x, y, tree[t].right, tree);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1075,7 +1098,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
{
|
|
|
for(int y = 0; y < ysize; y++,offset++)
|
|
|
{
|
|
|
- int t = currentfeats[x][y];
|
|
|
+ int t = currentfeats.get(x,y,tree);
|
|
|
double maxvalue = - numeric_limits<double>::max(); //TODO: das muss nur pro knoten gemacht werden, nicht pro pixel
|
|
|
int maxindex = 0;
|
|
|
for(uint i = 0; i < tree[i].dist.size(); i++)
|
|
@@ -1106,7 +1129,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
{
|
|
|
for(int x = 0; x < img.width(); x++)
|
|
|
{
|
|
|
- int cnode = currentfeats[x][y];
|
|
|
+ int cnode = currentfeats.get(x, y, tree);
|
|
|
int cregion = regions(x,y);
|
|
|
for(int d = 0; d < dSize; d++)
|
|
|
{
|