|
@@ -5,13 +5,16 @@
|
|
|
|
|
|
#include "vislearning/cbaselib/CachedExample.h"
|
|
|
#include "vislearning/cbaselib/PascalResults.h"
|
|
|
+#include "objrec/segmentation/RSMeanShift.h"
|
|
|
+#include "objrec/segmentation/RSGraphBased.h"
|
|
|
|
|
|
#include <omp.h>
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
#define BOUND(x,min,max) (((x)<(min))?(min):((x)>(max)?(max):(x)))
|
|
|
-#define LOCALFEATS
|
|
|
+#undef LOCALFEATS
|
|
|
+//#define LOCALFEATS
|
|
|
|
|
|
using namespace OBJREC;
|
|
|
using namespace std;
|
|
@@ -34,9 +37,9 @@ public:
|
|
|
return new Minus();
|
|
|
};
|
|
|
|
|
|
- virtual void writeInfos()
|
|
|
+ virtual string writeInfos()
|
|
|
{
|
|
|
- cout << "Minus: " << endl;
|
|
|
+ return "Minus";
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -57,9 +60,9 @@ public:
|
|
|
return new MinusAbs();
|
|
|
};
|
|
|
|
|
|
- virtual void writeInfos()
|
|
|
+ virtual string writeInfos()
|
|
|
{
|
|
|
- cout << "MinusAbs: " << endl;
|
|
|
+ return "MinusAbs";
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -80,9 +83,9 @@ public:
|
|
|
return new Addition();
|
|
|
};
|
|
|
|
|
|
- virtual void writeInfos()
|
|
|
+ virtual string writeInfos()
|
|
|
{
|
|
|
- cout << "Addition: " << endl;
|
|
|
+ return "Addition";
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -102,9 +105,9 @@ public:
|
|
|
return new Only1();
|
|
|
};
|
|
|
|
|
|
- virtual void writeInfos()
|
|
|
+ virtual string writeInfos()
|
|
|
{
|
|
|
- cout << "Only1: " << endl;
|
|
|
+ return "Only1";
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -125,9 +128,9 @@ public:
|
|
|
return new ContextMinus();
|
|
|
};
|
|
|
|
|
|
- virtual void writeInfos()
|
|
|
+ virtual string writeInfos()
|
|
|
{
|
|
|
- cout << "ContextMinus: " << endl;
|
|
|
+ return "ContextMinus";
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -148,9 +151,9 @@ public:
|
|
|
return new ContextMinusAbs();
|
|
|
};
|
|
|
|
|
|
- virtual void writeInfos()
|
|
|
+ virtual string writeInfos()
|
|
|
{
|
|
|
- cout << "ContextMinusAbs: " << endl;
|
|
|
+ return "ContextMinusAbs";
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -171,9 +174,9 @@ public:
|
|
|
return new ContextAddition();
|
|
|
};
|
|
|
|
|
|
- virtual void writeInfos()
|
|
|
+ virtual string writeInfos()
|
|
|
{
|
|
|
- cout << "ContextAddition: " << endl;
|
|
|
+ return "ContextAddition";
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -193,9 +196,9 @@ public:
|
|
|
return new ContextOnly1();
|
|
|
};
|
|
|
|
|
|
- virtual void writeInfos()
|
|
|
+ virtual string writeInfos()
|
|
|
{
|
|
|
- cout << "ContextOnly1: " << endl;
|
|
|
+ return "ContextOnly1";
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -220,6 +223,18 @@ SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md
|
|
|
featsPerSplit = conf->gI(section, "feats_per_split", 200);
|
|
|
|
|
|
useShannonEntropy = conf->gB(section, "use_shannon_entropy", true);
|
|
|
+
|
|
|
+ string segmentationtype = conf->gS(section, "segmentation_type", "meanshift");
|
|
|
+
|
|
|
+ pixelWiseLabeling = conf->gB(section, "use_pixelwise_labeling", false);
|
|
|
+
|
|
|
+ if(segmentationtype == "meanshift")
|
|
|
+ segmentation = new RSMeanShift(conf);
|
|
|
+ else if (segmentationtype == "felzenszwalb")
|
|
|
+ segmentation = new RSGraphBased(conf);
|
|
|
+ else
|
|
|
+ throw("no valid segmenation_type\n please choose between meanshift and felzenswalb\n");
|
|
|
+
|
|
|
|
|
|
|
|
|
ftypes = conf->gI(section, "features", 2);;
|
|
@@ -250,7 +265,7 @@ SemSegContextTree::~SemSegContextTree()
|
|
|
void SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> > &feats, vector<vector<vector<int> > > ¤tfeats,const vector<vector<vector<int> > > &labels, int node, Operation *&splitop, double &splitval)
|
|
|
{
|
|
|
|
|
|
- int imgCount, featdim;
|
|
|
+ int imgCount = 0, featdim = 0;
|
|
|
try
|
|
|
{
|
|
|
imgCount = (int)feats.size();
|
|
@@ -469,8 +484,8 @@ void SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> > &
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- splitop->writeInfos();
|
|
|
- cout<< "ig: " << bestig << endl;
|
|
|
+ //splitop->writeInfos();
|
|
|
+ //cout<< "ig: " << bestig << endl;
|
|
|
|
|
|
/*for(int i = 0; i < featsPerSplit; i++)
|
|
|
{
|
|
@@ -639,6 +654,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
int t = (int) tree.size();
|
|
|
int s = startnode;
|
|
|
startnode = t;
|
|
|
+ vector<vector<vector<int> > > lastfeats = currentfeats;
|
|
|
//#pragma omp parallel for
|
|
|
for(int i = s; i < t; i++)
|
|
|
{
|
|
@@ -646,7 +662,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
{
|
|
|
Operation *splitfeat = NULL;
|
|
|
double splitval;
|
|
|
- getBestSplit(allfeats, currentfeats,labels, i, splitfeat, splitval);
|
|
|
+ getBestSplit(allfeats, lastfeats,labels, i, splitfeat, splitval);
|
|
|
tree[i].feat = splitfeat;
|
|
|
|
|
|
tree[i].decision = splitval;
|
|
@@ -675,8 +691,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
{
|
|
|
if(currentfeats[iCounter][x][y] == i)
|
|
|
{
|
|
|
- double val = splitfeat->getVal(allfeats[iCounter],currentfeats[iCounter],tree,x,y);
|
|
|
-
|
|
|
+ double val = splitfeat->getVal(allfeats[iCounter],lastfeats[iCounter],tree,x,y);
|
|
|
if(val < splitval)
|
|
|
{
|
|
|
currentfeats[iCounter][x][y] = left;
|
|
@@ -691,7 +706,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
double lcounter = 0.0, rcounter = 0.0;
|
|
|
for(uint d = 0; d < tree[left].dist.size(); d++)
|
|
|
{
|
|
@@ -708,6 +723,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
rcounter +=tree[right].dist[d];
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
if(lcounter <= 0 || rcounter <= 0)
|
|
|
{
|
|
|
cout << "lcounter : " << lcounter << " rcounter: " << rcounter << endl;
|
|
@@ -724,7 +740,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
{
|
|
|
tree[i].isleaf = true;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
//TODO: features neu berechnen!
|
|
@@ -739,7 +754,9 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
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);
|
|
|
+ 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++)
|
|
|
{
|
|
|
cout << " " << tree[i].dist[d];
|
|
@@ -801,27 +818,24 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
allleaf = true;
|
|
|
//TODO vielleicht parallel wenn nächste schleife auch noch parallelsiert würde, die hat mehr gewicht
|
|
|
//#pragma omp parallel for
|
|
|
- int t = (int) tree.size();
|
|
|
- for(int i = 0; i < t; i++)
|
|
|
+ vector<vector<int> > lastfeats = currentfeats;
|
|
|
+ for(int x = 0; x < xsize; x++)
|
|
|
{
|
|
|
- for(int x = 0; x < xsize; x++)
|
|
|
+ for(int y = 0; y < ysize; y++)
|
|
|
{
|
|
|
- for(int y = 0; y < ysize; y++)
|
|
|
+ int t = currentfeats[x][y];
|
|
|
+ if(tree[t].left > 0)
|
|
|
{
|
|
|
- int t = currentfeats[x][y];
|
|
|
- if(tree[t].left > 0)
|
|
|
+ allleaf = false;
|
|
|
+ double val = tree[t].feat->getVal(feats,lastfeats,tree,x,y);
|
|
|
+
|
|
|
+ if(val < tree[t].decision)
|
|
|
{
|
|
|
- allleaf = false;
|
|
|
- double val = tree[t].feat->getVal(feats,currentfeats,tree,x,y);
|
|
|
-
|
|
|
- if(val < tree[t].decision)
|
|
|
- {
|
|
|
- currentfeats[x][y] = tree[t].left;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- currentfeats[x][y] = tree[t].right;
|
|
|
- }
|
|
|
+ currentfeats[x][y] = tree[t].left;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ currentfeats[x][y] = tree[t].right;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -832,24 +846,73 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
depth++;
|
|
|
}
|
|
|
|
|
|
- //finales labeln:
|
|
|
- long int offset = 0;
|
|
|
- for(int x = 0; x < xsize; x++)
|
|
|
+ if(pixelWiseLabeling)
|
|
|
+ {
|
|
|
+ //finales labeln:
|
|
|
+ long int offset = 0;
|
|
|
+ for(int x = 0; x < xsize; x++)
|
|
|
+ {
|
|
|
+ for(int y = 0; y < ysize; y++,offset++)
|
|
|
+ {
|
|
|
+ int t = currentfeats[x][y];
|
|
|
+ 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++)
|
|
|
+ {
|
|
|
+ probabilities.data[labelmapback[i]][offset] = tree[t].dist[i];
|
|
|
+ if(tree[t].dist[i] > maxvalue)
|
|
|
+ {
|
|
|
+ maxvalue = tree[t].dist[i];
|
|
|
+ maxindex = labelmapback[i];
|
|
|
+ }
|
|
|
+ segresult.setPixel(x,y,maxindex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- for(int y = 0; y < ysize; y++,offset++)
|
|
|
+ //final labeling using segmentation
|
|
|
+ //TODO: segmentation
|
|
|
+ Matrix regions;
|
|
|
+ int regionNumber = segmentation->segRegions(img,regions);
|
|
|
+ cout << "regions: " << regionNumber << endl;
|
|
|
+ int dSize = (int)labelmap.size();
|
|
|
+ vector<vector<double> > regionProbs(regionNumber, vector<double>(dSize,0.0));
|
|
|
+ vector<int> bestlabels(regionNumber, 0);
|
|
|
+
|
|
|
+ for(int y = 0; y < img.height(); y++)
|
|
|
{
|
|
|
- int t = currentfeats[x][y];
|
|
|
- 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++)
|
|
|
+ for(int x = 0; x < img.width(); x++)
|
|
|
{
|
|
|
- probabilities.data[labelmapback[i]][offset] = tree[t].dist[i];
|
|
|
- if(tree[t].dist[i] > maxvalue)
|
|
|
+ int cnode = currentfeats[x][y];
|
|
|
+ int cregion = regions(x,y);
|
|
|
+ for(int d = 0; d < dSize; d++)
|
|
|
{
|
|
|
- maxvalue = tree[t].dist[i];
|
|
|
- maxindex = labelmapback[i];
|
|
|
+ regionProbs[cregion][d]+=tree[cnode].dist[d];
|
|
|
}
|
|
|
- segresult.setPixel(x,y,maxindex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int r = 0; r < regionNumber; r++)
|
|
|
+ {
|
|
|
+ double maxval = regionProbs[r][0];
|
|
|
+ for(int d = 1; d < dSize; d++)
|
|
|
+ {
|
|
|
+ if(maxval < regionProbs[r][d])
|
|
|
+ {
|
|
|
+ maxval = regionProbs[r][d];
|
|
|
+ bestlabels[r] = d;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ bestlabels[r] = labelmapback[bestlabels[r]];
|
|
|
+ }
|
|
|
+
|
|
|
+ for(int y = 0; y < img.height(); y++)
|
|
|
+ {
|
|
|
+ for(int x = 0; x < img.width(); x++)
|
|
|
+ {
|
|
|
+ segresult.setPixel(x,y,bestlabels[regions(x,y)]);
|
|
|
}
|
|
|
}
|
|
|
}
|