|
@@ -19,6 +19,77 @@ using namespace OBJREC;
|
|
|
using namespace std;
|
|
|
using namespace NICE;
|
|
|
|
|
|
+class Minus:public Operation
|
|
|
+{
|
|
|
+public:
|
|
|
+ virtual double getVal(const vector<vector<vector<double> > > &feats, const int &x, const int &y)
|
|
|
+ {
|
|
|
+ int xsize = feats.size();
|
|
|
+ int ysize = feats[0].size();
|
|
|
+ double v1 = feats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][channel1];
|
|
|
+ double v2 = feats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)][channel2];
|
|
|
+ return v1-v2;
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual Operation* clone()
|
|
|
+ {
|
|
|
+ return new Minus();
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+class MinusAbs:public Operation
|
|
|
+{
|
|
|
+public:
|
|
|
+ virtual double getVal(const vector<vector<vector<double> > > &feats, const int &x, const int &y)
|
|
|
+ {
|
|
|
+ int xsize = feats.size();
|
|
|
+ int ysize = feats[0].size();
|
|
|
+ double v1 = feats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][channel1];
|
|
|
+ double v2 = feats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)][channel2];
|
|
|
+ return abs(v1-v2);
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual Operation* clone()
|
|
|
+ {
|
|
|
+ return new MinusAbs();
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+class Addition:public Operation
|
|
|
+{
|
|
|
+public:
|
|
|
+ virtual double getVal(const vector<vector<vector<double> > > &feats, const int &x, const int &y)
|
|
|
+ {
|
|
|
+ int xsize = feats.size();
|
|
|
+ int ysize = feats[0].size();
|
|
|
+ double v1 = feats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][channel1];
|
|
|
+ double v2 = feats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)][channel2];
|
|
|
+ return v1+v2;
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual Operation* clone()
|
|
|
+ {
|
|
|
+ return new Addition();
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+class Only1:public Operation
|
|
|
+{
|
|
|
+public:
|
|
|
+ virtual double getVal(const vector<vector<vector<double> > > &feats, const int &x, const int &y)
|
|
|
+ {
|
|
|
+ int xsize = feats.size();
|
|
|
+ int ysize = feats[0].size();
|
|
|
+ double v1 = feats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][channel1];
|
|
|
+ return v1;
|
|
|
+ }
|
|
|
+
|
|
|
+ virtual Operation* clone()
|
|
|
+ {
|
|
|
+ return new Only1();
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
|
|
|
SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md )
|
|
|
: SemanticSegmentation ( conf, &(md->getClassNames("train")) )
|
|
@@ -38,9 +109,12 @@ SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md
|
|
|
|
|
|
featsPerSplit = conf->gI(section, "feats_per_split", 200);
|
|
|
|
|
|
+ useShannonEntropy = conf->gB(section, "use_shannon_entropy", true);
|
|
|
+
|
|
|
ops.push_back(new Minus());
|
|
|
ops.push_back(new MinusAbs());
|
|
|
ops.push_back(new Addition());
|
|
|
+ ops.push_back(new Only1());
|
|
|
|
|
|
///////////////////////////////////
|
|
|
// Train Segmentation Context Trees
|
|
@@ -53,13 +127,13 @@ SemSegContextTree::~SemSegContextTree()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
-void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> > > > &feats, vector<vector<vector<int> > > ¤tfeats,const vector<vector<vector<int> > > &labels, int node, int &splitfeat, double &splitval)
|
|
|
+void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> > > > &feats, vector<vector<vector<int> > > ¤tfeats,const vector<vector<vector<int> > > &labels, int node, Operation *&splitop, double &splitval)
|
|
|
{
|
|
|
- int imgCount, featsize;
|
|
|
+ int imgCount, featdim;
|
|
|
try
|
|
|
{
|
|
|
imgCount = (int)feats.size();
|
|
|
- featsize = feats[0][0][0].size();
|
|
|
+ featdim = feats[0][0][0].size();
|
|
|
}
|
|
|
catch(Exception)
|
|
|
{
|
|
@@ -67,7 +141,7 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
|
|
|
}
|
|
|
|
|
|
double bestig = -numeric_limits< double >::max();
|
|
|
- splitfeat = -1;
|
|
|
+ splitop = NULL;
|
|
|
splitval = -1.0;
|
|
|
|
|
|
set<vector<int> >selFeats;
|
|
@@ -93,9 +167,11 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
|
|
|
vector<double> fraction(a.size(),0.0);
|
|
|
for(uint i = 0; i < fraction.size(); i++)
|
|
|
{
|
|
|
- fraction[i] = ((double)maxSamples)/(a[i]*(double)featcounter*8);
|
|
|
- //cout << "fraction["<<i<<"]: "<< fraction[i] << endl;
|
|
|
+ fraction[i] = ((double)maxSamples)/((double)featcounter*a[i]*a.size());
|
|
|
+ //cout << "fraction["<<i<<"]: "<< fraction[i] << " a[" << i << "]: " << a[i] << endl;
|
|
|
}
|
|
|
+ //cout << "a.size(): " << a.size() << endl;
|
|
|
+ //getchar();
|
|
|
featcounter = 0;
|
|
|
|
|
|
|
|
@@ -128,7 +204,8 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- //cout << "size: " << selFeats.size() << endl;
|
|
|
+ cout << "size: " << selFeats.size() << endl;
|
|
|
+ //getchar();
|
|
|
|
|
|
map<int,int>::iterator mapit;
|
|
|
double globent = 0.0;
|
|
@@ -152,25 +229,27 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- vector<int> featsubset;
|
|
|
+ featsel.clear();
|
|
|
for(int i = 0; i < featsPerSplit; i++)
|
|
|
{
|
|
|
- int randI = ((double)rand()/(double)RAND_MAX*(double)allfeatsize);
|
|
|
- featsubset.push_back(randI);
|
|
|
+ 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 f1 = (int)((double)rand()/(double)RAND_MAX*(double)featdim);
|
|
|
+ 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);
|
|
|
+ featsel.push_back(op);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
#pragma omp parallel for private(mapit)
|
|
|
for(int f = 0; f < featsPerSplit; f++)
|
|
|
{
|
|
|
-
|
|
|
- int x1 = featsel[featsubset[f]][0];
|
|
|
- int y1 = featsel[featsubset[f]][1];
|
|
|
- int x2 = featsel[featsubset[f]][2];
|
|
|
- int y2 = featsel[featsubset[f]][3];
|
|
|
- int chan = featsel[featsubset[f]][4];
|
|
|
- int o = featsel[featsubset[f]][5];
|
|
|
-
|
|
|
double l_bestig = -numeric_limits< double >::max();
|
|
|
double l_splitval = -1.0;
|
|
|
set<vector<int> >::iterator it;
|
|
@@ -178,11 +257,7 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
|
|
|
|
|
|
for ( it=selFeats.begin() ; it != selFeats.end(); it++ )
|
|
|
{
|
|
|
- int xsize = (int)feats[(*it)[0]].size();
|
|
|
- int ysize = (int)feats[(*it)[0]][0].size();
|
|
|
- double val1 = feats[(*it)[0]][BOUND((*it)[1]+x1,0,xsize-1)][BOUND((*it)[2]+y1,0,ysize-1)][chan];
|
|
|
- double val2 = feats[(*it)[0]][BOUND((*it)[1]+x2,0,xsize-1)][BOUND((*it)[2]+y2,0,ysize-1)][chan];
|
|
|
- vals.push_back(ops[o]->getVal(val1,val2));
|
|
|
+ vals.push_back(featsel[f]->getVal(feats[(*it)[0]],(*it)[1], (*it)[2]));
|
|
|
}
|
|
|
|
|
|
int counter = 0;
|
|
@@ -217,19 +292,26 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
|
|
|
for ( mapit=eL.begin() ; mapit != eL.end(); mapit++ )
|
|
|
{
|
|
|
double p = (double)(*mapit).second/(double)counterL;
|
|
|
- leftent += p*log2(p);
|
|
|
+ leftent -= p*log2(p);
|
|
|
}
|
|
|
- leftent = -leftent;
|
|
|
+
|
|
|
|
|
|
double rightent = 0.0;
|
|
|
for ( mapit=eR.begin() ; mapit != eR.end(); mapit++ )
|
|
|
{
|
|
|
double p = (double)(*mapit).second/(double)counterR;
|
|
|
- rightent += p*log2(p);
|
|
|
+ rightent -= p*log2(p);
|
|
|
}
|
|
|
- rightent = -rightent;
|
|
|
//cout << "rightent: " << rightent << " leftent: " << leftent << endl;
|
|
|
- double ig = globent - rightent - leftent;
|
|
|
+
|
|
|
+ double pl = counterL/(counterL+counterR);
|
|
|
+ double ig = globent - (1.0-pl) * rightent - pl*leftent;
|
|
|
+
|
|
|
+ if(useShannonEntropy)
|
|
|
+ {
|
|
|
+ double esplit = - ( pl*log(pl) + (1-pl)*log(1-pl) );
|
|
|
+ ig = 2*ig / ( globent + esplit );
|
|
|
+ }
|
|
|
|
|
|
if(ig > l_bestig)
|
|
|
{
|
|
@@ -246,12 +328,18 @@ void SemSegContextTree::getBestSplit(const vector<vector<vector<vector<double> >
|
|
|
if(l_bestig > bestig)
|
|
|
{
|
|
|
bestig = l_bestig;
|
|
|
- splitfeat = featsubset[f];
|
|
|
+ splitop = featsel[f];
|
|
|
splitval = l_splitval;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- cout << "globent: " << globent << " bestig " << bestig << " splitfeat: " << splitfeat << " splitval: " << splitval << endl;
|
|
|
+
|
|
|
+ /*for(int i = 0; i < featsPerSplit; i++)
|
|
|
+ {
|
|
|
+ if(featsel[i] != splitop)
|
|
|
+ delete featsel[i];
|
|
|
+ }*/
|
|
|
+ cout << "globent: " << globent << " bestig " << bestig << " splitval: " << splitval << endl;
|
|
|
}
|
|
|
|
|
|
void SemSegContextTree::train ( const MultiDataset *md )
|
|
@@ -346,10 +434,10 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
pb.hide();
|
|
|
|
|
|
- int opsize = (int)ops.size();
|
|
|
+ /*int opsize = (int)ops.size();
|
|
|
int featdim = (int)allfeats[0][0][0].size();
|
|
|
- allfeatsize = windowSize*windowSize*windowSize*windowSize*featdim*opsize;
|
|
|
|
|
|
+
|
|
|
for(int x1 = -windowSize/2; x1 < windowSize/2+1; x1++)
|
|
|
{
|
|
|
for(int y1 = -windowSize/2; y1 < windowSize/2+1; y1++)
|
|
@@ -375,7 +463,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
+ }*/
|
|
|
|
|
|
map<int,int>::iterator mapit;
|
|
|
int classes = 0;
|
|
@@ -419,35 +507,23 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
while(!allleaf && depth < maxDepth)
|
|
|
{
|
|
|
allleaf = true;
|
|
|
- //TODO vielleicht parallel wenn nächste schleife auch noch parallelsiert würde, die hat mehr gewicht
|
|
|
- //#pragma omp parallel for
|
|
|
+ //TODO vielleicht parallel wenn nächste schleife trotzdem noch parallelsiert würde, die hat mehr gewicht
|
|
|
+
|
|
|
int t = (int) tree.size();
|
|
|
+//#pragma omp parallel for
|
|
|
for(int i = 0; i < t; i++)
|
|
|
{
|
|
|
- printf("tree[%i]: left: %i, right: %i ", i, tree[i].left, tree[i].right);
|
|
|
- for(int d = 0; d < (int)tree[i].dist.size(); d++)
|
|
|
- {
|
|
|
- cout << " " << tree[i].dist[d];
|
|
|
- }
|
|
|
- cout << endl;
|
|
|
if(!tree[i].isleaf && tree[i].left < 0)
|
|
|
{
|
|
|
- int splitfeat;
|
|
|
+ Operation *splitfeat = NULL;
|
|
|
double splitval;
|
|
|
|
|
|
getBestSplit(allfeats, currentfeats,labels, i, splitfeat, splitval);
|
|
|
tree[i].feat = splitfeat;
|
|
|
tree[i].decision = splitval;
|
|
|
- cout << "splitfeat: " << splitfeat << " splitval: " << splitval << endl;
|
|
|
- if(splitfeat >= 0)
|
|
|
+
|
|
|
+ if(splitfeat != NULL)
|
|
|
{
|
|
|
- int x1 = featsel[splitfeat][0];
|
|
|
- int y1 = featsel[splitfeat][1];
|
|
|
- int x2 = featsel[splitfeat][2];
|
|
|
- int y2 = featsel[splitfeat][3];
|
|
|
- int p = featsel[splitfeat][4];
|
|
|
- int o = featsel[splitfeat][5];
|
|
|
-
|
|
|
allleaf = false;
|
|
|
int left = tree.size();
|
|
|
tree.push_back(Node());
|
|
@@ -459,7 +535,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
tree[right].dist = vector<double>(classes, 0.0);
|
|
|
tree[left].depth = depth+1;
|
|
|
tree[right].depth = depth+1;
|
|
|
-
|
|
|
#pragma omp parallel for
|
|
|
for(int iCounter = 0; iCounter < imgcounter; iCounter++)
|
|
|
{
|
|
@@ -471,11 +546,8 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
{
|
|
|
if(currentfeats[iCounter][x][y] == i)
|
|
|
{
|
|
|
- int xsize = (int)allfeats[iCounter].size();
|
|
|
- int ysize = (int)allfeats[iCounter][0].size();
|
|
|
- double val1 = allfeats[iCounter][BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][p];
|
|
|
- double val2 = allfeats[iCounter][BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)][p];
|
|
|
- double val = ops[o]->getVal(val1,val2);
|
|
|
+ double val = splitfeat->getVal(allfeats[iCounter],x,y);
|
|
|
+
|
|
|
if(val < splitval)
|
|
|
{
|
|
|
currentfeats[iCounter][x][y] = left;
|
|
@@ -490,12 +562,13 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
double lcounter = 0.0, rcounter = 0.0;
|
|
|
for(uint d = 0; d < tree[left].dist.size(); d++)
|
|
|
{
|
|
|
- tree[left].dist[d]/=a[d];
|
|
|
+ //tree[left].dist[d]/=a[d];
|
|
|
lcounter +=tree[left].dist[d];
|
|
|
- tree[right].dist[d]/=a[d];
|
|
|
+ //tree[right].dist[d]/=a[d];
|
|
|
rcounter +=tree[right].dist[d];
|
|
|
}
|
|
|
assert(lcounter > 0 && rcounter > 0);
|
|
@@ -509,7 +582,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
{
|
|
|
tree[i].isleaf = true;
|
|
|
}
|
|
|
- //TODO: probability ermitteln
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -517,6 +589,19 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
depth++;
|
|
|
cout << "d: " << depth << endl;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ int t = (int) tree.size();
|
|
|
+ for(int i = 0; i < t; i++)
|
|
|
+ {
|
|
|
+ printf("tree[%i]: left: %i, right: %i ", i, tree[i].left, tree[i].right);
|
|
|
+ for(int d = 0; d < (int)tree[i].dist.size(); d++)
|
|
|
+ {
|
|
|
+ cout << " " << tree[i].dist[d];
|
|
|
+ }
|
|
|
+ cout << endl;
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
@@ -584,17 +669,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
if(tree[t].left > 0)
|
|
|
{
|
|
|
allleaf = false;
|
|
|
- int splitfeat = tree[t].feat;
|
|
|
- int x1 = featsel[splitfeat][0];
|
|
|
- int y1 = featsel[splitfeat][1];
|
|
|
- int x2 = featsel[splitfeat][2];
|
|
|
- int y2 = featsel[splitfeat][3];
|
|
|
- int p = featsel[splitfeat][4];
|
|
|
- int o = featsel[splitfeat][5];
|
|
|
-
|
|
|
- double val1 = feats[BOUND(x+x1,0,xsize-1)][BOUND(y+y1,0,ysize-1)][p];
|
|
|
- double val2 = feats[BOUND(x+x2,0,xsize-1)][BOUND(y+y2,0,ysize-1)][p];
|
|
|
- double val = ops[o]->getVal(val1,val2);
|
|
|
+ double val = tree[t].feat->getVal(feats,x,y);
|
|
|
|
|
|
if(val < tree[t].decision)
|
|
|
{
|
|
@@ -615,7 +690,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
}
|
|
|
|
|
|
//finales labeln:
|
|
|
- long int offset = 0;
|
|
|
+ long int offset = 0;
|
|
|
for(int x = 0; x < xsize; x++)
|
|
|
{
|
|
|
for(int y = 0; y < ysize; y++,offset++)
|