|
@@ -9,11 +9,15 @@
|
|
#include "objrec/segmentation/RSGraphBased.h"
|
|
#include "objrec/segmentation/RSGraphBased.h"
|
|
#include "core/basics/numerictools.h"
|
|
#include "core/basics/numerictools.h"
|
|
|
|
|
|
|
|
+#include "core/basics/Timer.h"
|
|
|
|
+
|
|
#include <omp.h>
|
|
#include <omp.h>
|
|
#include <iostream>
|
|
#include <iostream>
|
|
|
|
|
|
#define BOUND(x,min,max) (((x)<(min))?(min):((x)>(max)?(max):(x)))
|
|
#define BOUND(x,min,max) (((x)<(min))?(min):((x)>(max)?(max):(x)))
|
|
#undef LOCALFEATS
|
|
#undef LOCALFEATS
|
|
|
|
+
|
|
|
|
+
|
|
//#define LOCALFEATS
|
|
//#define LOCALFEATS
|
|
|
|
|
|
using namespace OBJREC;
|
|
using namespace OBJREC;
|
|
@@ -322,6 +326,8 @@ SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md
|
|
|
|
|
|
useShannonEntropy = conf->gB(section, "use_shannon_entropy", true);
|
|
useShannonEntropy = conf->gB(section, "use_shannon_entropy", true);
|
|
|
|
|
|
|
|
+ nbTrees = conf->gI(section, "amount_trees", 1);
|
|
|
|
+
|
|
string segmentationtype = conf->gS(section, "segmentation_type", "meanshift");
|
|
string segmentationtype = conf->gS(section, "segmentation_type", "meanshift");
|
|
|
|
|
|
useGaussian = conf->gB(section, "use_gaussian", true);
|
|
useGaussian = conf->gB(section, "use_gaussian", true);
|
|
@@ -642,7 +648,7 @@ void SemSegContextTree::computeIntegralImage(const NICE::MultiChannelImageT<int>
|
|
int xsize = currentfeats.width();
|
|
int xsize = currentfeats.width();
|
|
int ysize = currentfeats.height();
|
|
int ysize = currentfeats.height();
|
|
|
|
|
|
- int channels = (int)labelmap.size();
|
|
|
|
|
|
+ int channels = (int)forest[0][0].dist.size();
|
|
#pragma omp parallel for
|
|
#pragma omp parallel for
|
|
for(int c = 0; c < channels; c++)
|
|
for(int c = 0; c < channels; c++)
|
|
{
|
|
{
|
|
@@ -718,9 +724,11 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
int xsize, ysize;
|
|
int xsize, ysize;
|
|
ce->getImageSize ( xsize, ysize );
|
|
ce->getImageSize ( xsize, ysize );
|
|
|
|
|
|
- MultiChannelImageT<int> tmp(xsize, ysize, nbTrees);
|
|
|
|
MatrixT<int> tmpMat(xsize,ysize);
|
|
MatrixT<int> tmpMat(xsize,ysize);
|
|
- currentfeats.push_back(tmp);
|
|
|
|
|
|
+
|
|
|
|
+ currentfeats.push_back(MultiChannelImageT<int>(xsize,ysize,nbTrees));
|
|
|
|
+ currentfeats[imgcounter].setAll(0);
|
|
|
|
+
|
|
labels.push_back(tmpMat);
|
|
labels.push_back(tmpMat);
|
|
|
|
|
|
try {
|
|
try {
|
|
@@ -833,12 +841,18 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
while(!allleaf && depth < maxDepth)
|
|
while(!allleaf && depth < maxDepth)
|
|
{
|
|
{
|
|
allleaf = true;
|
|
allleaf = true;
|
|
|
|
+ vector<MultiChannelImageT<int> > lastfeats = currentfeats;
|
|
|
|
+
|
|
|
|
+#if 1
|
|
|
|
+ Timer timer;
|
|
|
|
+ timer.start();
|
|
|
|
+#endif
|
|
|
|
+
|
|
for(int tree = 0; tree < nbTrees; tree++)
|
|
for(int tree = 0; tree < nbTrees; tree++)
|
|
{
|
|
{
|
|
int t = (int) forest[tree].size();
|
|
int t = (int) forest[tree].size();
|
|
int s = startnode[tree];
|
|
int s = startnode[tree];
|
|
startnode[tree] = t;
|
|
startnode[tree] = t;
|
|
- vector<MultiChannelImageT<int> > lastfeats = currentfeats;
|
|
|
|
//TODO vielleicht parallel wenn nächste schleife trotzdem noch parallelsiert würde, die hat mehr gewicht
|
|
//TODO vielleicht parallel wenn nächste schleife trotzdem noch parallelsiert würde, die hat mehr gewicht
|
|
//#pragma omp parallel for
|
|
//#pragma omp parallel for
|
|
for(int i = s; i < t; i++)
|
|
for(int i = s; i < t; i++)
|
|
@@ -847,8 +861,8 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
{
|
|
{
|
|
Operation *splitfeat = NULL;
|
|
Operation *splitfeat = NULL;
|
|
double splitval;
|
|
double splitval;
|
|
-
|
|
|
|
double bestig = getBestSplit(allfeats, lastfeats, integralImgs, labels, i, splitfeat, splitval, tree);
|
|
double bestig = getBestSplit(allfeats, lastfeats, integralImgs, labels, i, splitfeat, splitval, tree);
|
|
|
|
+
|
|
forest[tree][i].feat = splitfeat;
|
|
forest[tree][i].feat = splitfeat;
|
|
forest[tree][i].decision = splitval;
|
|
forest[tree][i].decision = splitval;
|
|
|
|
|
|
@@ -875,17 +889,17 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
{
|
|
{
|
|
for(int y = 0; y < ysize; y++)
|
|
for(int y = 0; y < ysize; y++)
|
|
{
|
|
{
|
|
- if(currentfeats[iCounter].get(x, y, t) == i)
|
|
|
|
|
|
+ if(currentfeats[iCounter].get(x, y, tree) == i)
|
|
{
|
|
{
|
|
double val = splitfeat->getVal(allfeats[iCounter],lastfeats[iCounter], tree, forest[tree], integralImgs[iCounter],x,y);
|
|
double val = splitfeat->getVal(allfeats[iCounter],lastfeats[iCounter], tree, forest[tree], integralImgs[iCounter],x,y);
|
|
if(val < splitval)
|
|
if(val < splitval)
|
|
{
|
|
{
|
|
- currentfeats[iCounter].set(x,y,left,t);
|
|
|
|
|
|
+ currentfeats[iCounter].set(x,y,left,tree);
|
|
forest[tree][left].dist[labelmap[labels[iCounter](x,y)]]++;
|
|
forest[tree][left].dist[labelmap[labels[iCounter](x,y)]]++;
|
|
}
|
|
}
|
|
else
|
|
else
|
|
{
|
|
{
|
|
- currentfeats[iCounter].set(x,y,right,t);
|
|
|
|
|
|
+ currentfeats[iCounter].set(x,y,right,tree);
|
|
forest[tree][right].dist[labelmap[labels[iCounter](x,y)]]++;
|
|
forest[tree][right].dist[labelmap[labels[iCounter](x,y)]]++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -948,10 +962,16 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+#if 1
|
|
|
|
+ timer.stop();
|
|
|
|
+ cout << "time for depth " << depth << ": " << timer.getLast() << endl;
|
|
|
|
+#endif
|
|
|
|
+
|
|
//TODO: features neu berechnen!
|
|
//TODO: features neu berechnen!
|
|
|
|
|
|
//compute integral image
|
|
//compute integral image
|
|
- int channels = (int)labelmap.size();
|
|
|
|
|
|
+ int channels = classes;
|
|
|
|
|
|
if(integralImgs[0].width() == 0)
|
|
if(integralImgs[0].width() == 0)
|
|
{
|
|
{
|
|
@@ -959,7 +979,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
{
|
|
{
|
|
int xsize = allfeats[i].width();
|
|
int xsize = allfeats[i].width();
|
|
int ysize = allfeats[i].height();
|
|
int ysize = allfeats[i].height();
|
|
-
|
|
|
|
integralImgs[i].reInit(xsize, ysize, channels);
|
|
integralImgs[i].reInit(xsize, ysize, channels);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -968,13 +987,11 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
{
|
|
{
|
|
computeIntegralImage(currentfeats[i],integralImgs[i]);
|
|
computeIntegralImage(currentfeats[i],integralImgs[i]);
|
|
}
|
|
}
|
|
-
|
|
|
|
- depth++;
|
|
|
|
|
|
+ }
|
|
|
|
+ depth++;
|
|
#ifdef DEBUG
|
|
#ifdef DEBUG
|
|
cout << "depth: " << depth << endl;
|
|
cout << "depth: " << depth << endl;
|
|
#endif
|
|
#endif
|
|
- }
|
|
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1045,6 +1062,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
MultiChannelImageT<double> integralImg;
|
|
MultiChannelImageT<double> integralImg;
|
|
|
|
|
|
MultiChannelImageT<int> currentfeats(xsize, ysize, nbTrees);
|
|
MultiChannelImageT<int> currentfeats(xsize, ysize, nbTrees);
|
|
|
|
+ currentfeats.setAll(0);
|
|
int depth = 0;
|
|
int depth = 0;
|
|
while(!allleaf)
|
|
while(!allleaf)
|
|
{
|
|
{
|
|
@@ -1052,39 +1070,41 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
//TODO vielleicht parallel wenn nächste schleife auch noch parallelsiert würde, die hat mehr gewicht
|
|
//TODO vielleicht parallel wenn nächste schleife auch noch parallelsiert würde, die hat mehr gewicht
|
|
//#pragma omp parallel for
|
|
//#pragma omp parallel for
|
|
MultiChannelImageT<int> lastfeats = currentfeats;
|
|
MultiChannelImageT<int> lastfeats = currentfeats;
|
|
- for(int x = 0; x < xsize; x++)
|
|
|
|
|
|
+ for(int tree = 0; tree < nbTrees; tree++)
|
|
{
|
|
{
|
|
- for(int y = 0; y < ysize; y++)
|
|
|
|
|
|
+ for(int x = 0; x < xsize; x++)
|
|
{
|
|
{
|
|
- int t = currentfeats.get(x,y,tree);
|
|
|
|
- if(tree[t].left > 0)
|
|
|
|
|
|
+ for(int y = 0; y < ysize; y++)
|
|
{
|
|
{
|
|
- allleaf = false;
|
|
|
|
- double val = tree[t].feat->getVal(feats,lastfeats,tree, forest[tree], integralImg,x,y);
|
|
|
|
-
|
|
|
|
- if(val < tree[t].decision)
|
|
|
|
- {
|
|
|
|
- currentfeats.set(x, y, tree[t].left, tree);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
|
|
+ int t = currentfeats.get(x,y,tree);
|
|
|
|
+ if(forest[tree][t].left > 0)
|
|
{
|
|
{
|
|
- currentfeats.set(x, y, tree[t].right, tree);
|
|
|
|
|
|
+ allleaf = false;
|
|
|
|
+ double val = forest[tree][t].feat->getVal(feats,lastfeats,tree, forest[tree], integralImg,x,y);
|
|
|
|
+
|
|
|
|
+ if(val < forest[tree][t].decision)
|
|
|
|
+ {
|
|
|
|
+ currentfeats.set(x, y, forest[tree][t].left, tree);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ currentfeats.set(x, y, forest[tree][t].right, tree);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- }
|
|
|
|
-
|
|
|
|
- //compute integral image
|
|
|
|
- int channels = (int)labelmap.size();
|
|
|
|
-
|
|
|
|
- if(integralImg.width() == 0)
|
|
|
|
- {
|
|
|
|
- int xsize = feats.width();
|
|
|
|
- int ysize = feats.height();
|
|
|
|
|
|
|
|
- integralImg.reInit(xsize, ysize, channels);
|
|
|
|
|
|
+ //compute integral image
|
|
|
|
+ int channels = (int)labelmap.size();
|
|
|
|
+
|
|
|
|
+ if(integralImg.width() == 0)
|
|
|
|
+ {
|
|
|
|
+ int xsize = feats.width();
|
|
|
|
+ int ysize = feats.height();
|
|
|
|
+
|
|
|
|
+ integralImg.reInit(xsize, ysize, channels);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
|
|
computeIntegralImage(currentfeats,integralImg);
|
|
computeIntegralImage(currentfeats,integralImg);
|
|
|
|
|
|
depth++;
|
|
depth++;
|
|
@@ -1098,15 +1118,15 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
{
|
|
{
|
|
for(int y = 0; y < ysize; y++,offset++)
|
|
for(int y = 0; y < ysize; y++,offset++)
|
|
{
|
|
{
|
|
- int t = currentfeats.get(x,y,tree);
|
|
|
|
double maxvalue = - numeric_limits<double>::max(); //TODO: das muss nur pro knoten gemacht werden, nicht pro pixel
|
|
double maxvalue = - numeric_limits<double>::max(); //TODO: das muss nur pro knoten gemacht werden, nicht pro pixel
|
|
int maxindex = 0;
|
|
int maxindex = 0;
|
|
- for(uint i = 0; i < tree[i].dist.size(); i++)
|
|
|
|
|
|
+ uint s = forest[0][0].dist.size();
|
|
|
|
+ for(uint i = 0; i < s; i++)
|
|
{
|
|
{
|
|
- probabilities.data[labelmapback[i]][offset] = tree[t].dist[i];
|
|
|
|
- if(tree[t].dist[i] > maxvalue)
|
|
|
|
|
|
+ probabilities.data[labelmapback[i]][offset] = getMeanProb(x,y,i,currentfeats);
|
|
|
|
+ if(probabilities.data[labelmapback[i]][offset] > maxvalue)
|
|
{
|
|
{
|
|
- maxvalue = tree[t].dist[i];
|
|
|
|
|
|
+ maxvalue = probabilities.data[labelmapback[i]][offset];
|
|
maxindex = labelmapback[i];
|
|
maxindex = labelmapback[i];
|
|
}
|
|
}
|
|
segresult.setPixel(x,y,maxindex);
|
|
segresult.setPixel(x,y,maxindex);
|
|
@@ -1129,11 +1149,10 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
{
|
|
{
|
|
for(int x = 0; x < img.width(); x++)
|
|
for(int x = 0; x < img.width(); x++)
|
|
{
|
|
{
|
|
- int cnode = currentfeats.get(x, y, tree);
|
|
|
|
int cregion = regions(x,y);
|
|
int cregion = regions(x,y);
|
|
for(int d = 0; d < dSize; d++)
|
|
for(int d = 0; d < dSize; d++)
|
|
{
|
|
{
|
|
- regionProbs[cregion][d]+=tree[cnode].dist[d];
|
|
|
|
|
|
+ regionProbs[cregion][d]+=getMeanProb(x,y,d,currentfeats);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|