Bjoern Froehlich 13 years ago
parent
commit
2c5125b43d
2 changed files with 162 additions and 18 deletions
  1. 158 17
      semseg/SemSegContextTree.cpp
  2. 4 1
      semseg/SemSegContextTree.h

+ 158 - 17
semseg/SemSegContextTree.cpp

@@ -7,6 +7,7 @@
 #include "vislearning/cbaselib/PascalResults.h"
 #include "objrec/segmentation/RSMeanShift.h"
 #include "objrec/segmentation/RSGraphBased.h"
+#include "core/basics/numerictools.h"
 
 #include <omp.h>
 
@@ -35,7 +36,7 @@ public:
 	virtual Operation* clone()
 	{
 		return new Minus();
-	};
+	}
 	
 	virtual string writeInfos()
 	{
@@ -81,7 +82,7 @@ public:
 	virtual Operation* clone()
 	{
 		return new Addition();
-	};
+	}
 	
 	virtual string writeInfos()
 	{
@@ -103,7 +104,7 @@ public:
 	virtual Operation* clone()
 	{
 		return new Only1();
-	};
+	}
 	
 	virtual string writeInfos()
 	{
@@ -126,7 +127,7 @@ public:
 	virtual Operation* clone()
 	{
 		return new ContextMinus();
-	};
+	}
 	
 	virtual string writeInfos()
 	{
@@ -149,7 +150,7 @@ public:
 	virtual Operation* clone()
 	{
 		return new ContextMinusAbs();
-	};
+	}
 	
 	virtual string writeInfos()
 	{
@@ -172,7 +173,7 @@ public:
 	virtual Operation* clone()
 	{
 		return new ContextAddition();
-	};
+	}
 	
 	virtual string writeInfos()
 	{
@@ -194,14 +195,82 @@ public:
 	virtual Operation* clone()
 	{
 		return new ContextOnly1();
-	};
+	}
 	
 	virtual string writeInfos()
 	{
 		return "ContextOnly1";
 	}
 };
-      
+
+// uses mean of classification in window given by (x1,y1) (x2,y2)
+class IntegralOps:public Operation
+{
+public:
+	virtual void set(int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2)
+	{
+		x1 = min(_x1,_x2);
+		y1 = min(_y1,_y2);
+		x2 = max(_x1,_x2);
+		y2 = max(_y1,_y2);
+		channel1 = _channel1;
+		channel2 = _channel2;
+	}
+	
+	virtual double getVal(const NICE::MultiChannelImageT<double> &feats, const std::vector<std::vector<int> > &cfeats, const std::vector<TreeNode> &tree, const int &x, const int &y)
+	{
+		MultiChannelImageT<double> intImg;
+		return computeMean(intImg,x1,y1,x2,y2,channel1);
+	}
+	
+	virtual Operation* clone()
+	{
+		return new IntegralOps();
+	}
+	
+	virtual string writeInfos()
+	{
+		return "IntegralOps";
+	}
+	
+	inline double computeMean(const NICE::MultiChannelImageT<double> &intImg, int &uLx, int &uLy, int &lRx, int &lRy, int &chan)
+	{
+		double val1 = intImg.get(uLx,uLy, chan);
+		double val2 = intImg.get(lRx,uLy, chan);
+		double val3 = intImg.get(uLx,lRy, chan);
+		double val4 = intImg.get(lRx,lRy, chan);
+		double area = (lRx-uLx)*(lRy-uLy);
+		return (val1+val4-val2-val3)/area;
+	}
+};
+
+//uses mean of Integral image given by x1, y1 with current pixel as center
+class IntegralCenteredOps:public IntegralOps
+{
+public:
+	virtual void set(int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2)
+	{
+		x1 = _x1;
+		y1 = _y1;
+		x2 = -x1;
+		y2 = -y1;
+	}
+	
+	virtual Operation* clone()
+	{
+		return new IntegralCenteredOps();
+	}
+	
+	virtual string writeInfos()
+	{
+		return "IntegralCenteredOps";
+	}
+
+};
+
+//uses different of mean of Integral image given by two windows, where (x1,y1) is the width and height of window1 and (x2,y2) of window 2
+//TODO von Integral ops ableiten
+
 
 SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md )
     : SemanticSegmentation ( conf, &(md->getClassNames("train")) )
@@ -226,16 +295,22 @@ SemSegContextTree::SemSegContextTree( const Config *conf, const MultiDataset *md
 	
 	string segmentationtype = conf->gS(section, "segmentation_type", "meanshift");
 	
-	pixelWiseLabeling = conf->gB(section, "use_pixelwise_labeling", false);
+	useGaussian = conf->gB(section, "use_gaussian", true);
+	
+	pixelWiseLabeling = false;
 	
 	if(segmentationtype == "meanshift")
 		segmentation = new RSMeanShift(conf);
+	else if (segmentationtype == "none")
+	{
+		segmentation = NULL;
+		pixelWiseLabeling = true;
+	}
 	else if (segmentationtype == "felzenszwalb")
 		segmentation = new RSGraphBased(conf);
 	else
-		throw("no valid segmenation_type\n please choose between meanshift and felzenswalb\n");
-		
-
+		throw("no valid segmenation_type\n please choose between none, meanshift and felzenszwalb\n");
+	
 	
 	ftypes = conf->gI(section, "features", 2);;
 	
@@ -370,10 +445,23 @@ void SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> > &
 	featsel.clear();
 	for(int i = 0; i < featsPerSplit; i++)
 	{
-		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 x1, x2, y1, y2;
+		
+		if(useGaussian)
+		{
+			double sigma = (double)windowSize/2.0;
+			x1 = randGaussDouble(sigma)*(double)windowSize;
+			x2 = randGaussDouble(sigma)*(double)windowSize;
+			y1 = randGaussDouble(sigma)*(double)windowSize;
+			y2 = randGaussDouble(sigma)*(double)windowSize;
+		}
+		else
+		{
+			x1 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
+			x2 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
+			y1 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
+			y2 = (int)((double)rand()/(double)RAND_MAX*(double)windowSize)-windowSize/2;
+		}
 		
 		int ft = (int)((double)rand()/(double)RAND_MAX*(double)ftypes);
 		
@@ -436,7 +524,6 @@ void SemSegContextTree::getBestSplit(const vector<MultiChannelImageT<double> > &
 					eR[cn] = eR[cn]+1;
 					counterR++;
 				}
-				
 			}
 			
 			double leftent = 0.0;
@@ -655,6 +742,9 @@ void SemSegContextTree::train ( const MultiDataset *md )
 		int s = startnode;
 		startnode = t;
 		vector<vector<vector<int> > > lastfeats = currentfeats;
+		
+		vector<MultiChannelImageT<double> > integralImgs;
+		
 //#pragma omp parallel for
 		for(int i = s; i < t; i++)
 		{
@@ -743,6 +833,57 @@ void SemSegContextTree::train ( const MultiDataset *md )
 			}
 		}
 		//TODO: features neu berechnen!
+		
+#if 1
+		//compute integral image
+		int channels = (int)labelmap.size();
+		
+		if(integralImgs.size() == 0)
+		{
+			for(int i = 0; i < imgcounter; i++)
+			{
+				int xsize = allfeats[i].width();
+				int ysize = allfeats[i].height();
+				
+				integralImgs.push_back(MultiChannelImageT<double>(xsize, ysize, channels));
+			}
+		}
+		
+		for(int i = 0; i < imgcounter; i++)
+		{
+			int xsize = allfeats[i].width();
+			int ysize = allfeats[i].height();
+			
+			for(int c = 0; c < channels; c++)
+			{
+				integralImgs[i].set(0,0,tree[currentfeats[i][0][0]].dist[c], c);
+				
+				//first column
+				for(int y = 1; y < ysize; y++)
+				{
+					integralImgs[i].set(0,0,tree[currentfeats[i][0][y]].dist[c]+integralImgs[i].get(0,y,c), c);
+				}
+				
+				//first row
+				for(int x = 1; x < xsize; x++)
+				{
+					integralImgs[i].set(0,0,tree[currentfeats[i][x][0]].dist[c]+integralImgs[i].get(x,0,c), c);
+				}
+				
+				//rest
+				for(int y = 1; y < ysize; y++)
+				{
+					for(int x = 1; x < xsize; x++)
+					{
+						double val = tree[currentfeats[i][x][y]].dist[c]+integralImgs[i].get(x,y-1,c)+integralImgs[i].get(x-1,y,c)-integralImgs[i].get(x-1,y-1,c);
+						integralImgs[i].set(0, 0, val, c);
+					}
+				}
+			}
+		}
+#endif
+		
+		
 		depth++;
 #ifdef DEBUG
 		cout << "depth: " << depth << endl;

+ 4 - 1
semseg/SemSegContextTree.h

@@ -56,7 +56,7 @@ class Operation
 protected:
 	int x1, y1, x2, y2, channel1, channel2;
 public:
-	void set(int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2)
+	virtual void set(int _x1, int _y1, int _x2, int _y2, int _channel1, int _channel2)
 	{
 		x1 = _x1;
 		y1 = _y1;
@@ -147,6 +147,9 @@ class SemSegContextTree : public SemanticSegmentation
 	
 	/** use pixelwise labeling or regionlabeling with additional segmenation */
 	bool pixelWiseLabeling;
+	
+	/** use Gaussian distributed features based on the feature position */
+	bool useGaussian;
 
 	
     public: