Browse Source

context fixed

Bjoern Froehlich 13 years ago
parent
commit
48d9073749
2 changed files with 212 additions and 176 deletions
  1. 195 172
      semseg/SemSegContextTree.cpp
  2. 17 4
      semseg/SemSegContextTree.h

+ 195 - 172
semseg/SemSegContextTree.cpp

@@ -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> > > &currentfeats, 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> > &currentfeats, 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> > &currentfeats, MultiChannelImageT<double> &integralImage)
+inline double SemSegContextTree::getMeanProb(const int &x,const int &y,const int &channel, const MultiChannelImageT<int> &currentfeats)
 {
-	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> &currentfeats, 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> > &current
 		{
 			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++)
 				{

+ 17 - 4
semseg/SemSegContextTree.h

@@ -74,7 +74,7 @@ public:
 	 * @param y current y position
 	 * @return double distance
 	 **/
-	virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, NICE::MultiChannelImageT<double> &integralImg, const int &x, const int &y) = 0;
+	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) = 0;
 	virtual Operation* clone() = 0;
 	virtual std::string writeInfos() = 0;
 };
@@ -86,7 +86,7 @@ class SemSegContextTree : public SemanticSegmentation
 	RegionSegmentationMethod *segmentation;
 			
 	/** tree -> saved as vector of nodes */
-	std::vector<TreeNode> tree;
+	std::vector<std::vector<TreeNode> > forest;
 	
 	/** local features */
 	LFColorWeijer *lfcw;
@@ -151,6 +151,9 @@ class SemSegContextTree : public SemanticSegmentation
 	/** use Gaussian distributed features based on the feature position */
 	bool useGaussian;
 	
+	/** Number of trees used for the forest */
+	int nbTrees;
+	
     public:
 	/** simple constructor */
 	SemSegContextTree( const NICE::Config *conf, const MultiDataset *md );
@@ -180,7 +183,7 @@ class SemSegContextTree : public SemanticSegmentation
 	 * @param integralImage output image (must be initilized)
 	 * @return void
 	 **/
-	void computeIntegralImage(const std::vector<std::vector<int> > &currentfeats, MultiChannelImageT<double> &integralImage);
+	void computeIntegralImage(const NICE::MultiChannelImageT<int> &currentfeats, NICE::MultiChannelImageT<double> &integralImage);
 	
 	/**
 	 * compute best split for current settings
@@ -192,7 +195,17 @@ class SemSegContextTree : public SemanticSegmentation
 	 * @param splitval 
 	 * @return best information gain
 	 */
-	double getBestSplit(const std::vector<NICE::MultiChannelImageT<double> > &feats, std::vector<std::vector<std::vector<int> > > &currentfeats, std::vector<NICE::MultiChannelImageT<double> > &integralImgs, const std::vector<std::vector<std::vector<int> > > &labels, int node, Operation *&splitfeat, double &splitval);
+	double getBestSplit(const std::vector<NICE::MultiChannelImageT<double> > &feats, std::vector<NICE::MultiChannelImageT<int> > &currentfeats, std::vector<NICE::MultiChannelImageT<double> > &integralImgs, const std::vector<NICE::MatrixT<int> > &labels, int node, Operation *&splitop, double &splitval, const int &tree);
+	
+	/**
+	 * @brief computes the mean probability for a given class over all trees
+	 * @param x x position
+	 * @param y y position
+	 * @param channel current class
+	 * @param currentfeats information about the nodes
+	 * @return double mean value
+	 **/
+	inline double getMeanProb(const int &x,const int &y,const int &channel, const MultiChannelImageT<int> &currentfeats);
 
 };