Browse Source

newest versions

Bjoern Froehlich 13 years ago
parent
commit
b9a48e9fc6
2 changed files with 141 additions and 197 deletions
  1. 129 197
      semseg/SemSegContextTree.cpp
  2. 12 0
      semseg/SemSegContextTree.h

+ 129 - 197
semseg/SemSegContextTree.cpp

@@ -113,6 +113,8 @@ SemSegContextTree::SemSegContextTree ( const Config *conf, const MultiDataset *m
   if ( conf->gB ( featsec, "glob", true ) )
     cops.push_back ( new GlobalFeats() );
 
+  useGradient = conf->gB ( featsec, "use_gradient", true );
+
   opOverview = vector<int> ( NBOPERATIONS, 0 );
   contextOverview = vector<vector<double> > ( maxDepth, vector<double> ( 2, 0.0 ) );
 
@@ -576,9 +578,9 @@ void SemSegContextTree::computeIntegralImage ( const NICE::MultiChannelImageT<un
   }
 }
 
-inline double computeWeight(const double &d, const double &dim)
+inline double computeWeight ( const double &d, const double &dim )
 {
-    return 1.0/(pow(2,(double)(dim-d+1)));
+  return 1.0 / ( pow ( 2, ( double ) ( dim - d + 1 ) ) );
 }
 
 void SemSegContextTree::train ( const MultiDataset *md )
@@ -642,12 +644,12 @@ void SemSegContextTree::train ( const MultiDataset *md )
     currentfeats.push_back ( MultiChannelImageT<unsigned short int> ( xsize, ysize, nbTrees ) );
     currentfeats[imgcounter].setAll ( 0 );
 #ifdef TEXTONMAP
-    textonMap.push_back ( MultiChannelImageT<SparseVectorInt> ( xsize / grid + 1, ysize / grid + 1, 1 ));
-    integralTexton.push_back ( MultiChannelImageT<SparseVectorInt> ( xsize / grid + 1, ysize / grid + 1, 1 ));
+    textonMap.push_back ( MultiChannelImageT<SparseVectorInt> ( xsize / grid + 1, ysize / grid + 1, 1 ) );
+    integralTexton.push_back ( MultiChannelImageT<SparseVectorInt> ( xsize / grid + 1, ysize / grid + 1, 1 ) );
 #endif
-    
+
     labels.push_back ( tmpMat );
-    
+
     try {
       img = ColorImage ( currentFile );
     } catch ( Exception ) {
@@ -656,53 +658,13 @@ void SemSegContextTree::train ( const MultiDataset *md )
     }
 
     Globals::setCurrentImgFN ( currentFile );
-
+    
     //TODO: resize image?!
     MultiChannelImageT<double> feats;
     allfeats.push_back ( feats );
-#ifdef LOCALFEATS
-    lfcw->getFeats ( img, allfeats[imgcounter] );
-#else
-    allfeats[imgcounter].reInit ( xsize, ysize, 3 );
-
-    for ( int x = 0; x < xsize; x++ )
-    {
-      for ( int y = 0; y < ysize; y++ )
-      {
-        for ( int r = 0; r < 3; r++ )
-        {
-          allfeats[imgcounter].set ( x, y, img.getPixel ( x, y, r ), r );
-        }
-      }
-    }
-
-    allfeats[imgcounter] = ColorSpace::rgbtolab ( allfeats[imgcounter] );
-    
-    allfeats[imgcounter].addChannel(3);
-    
-    ImageT<double> tmp(xsize, ysize);
-    ImageT<double> tmp2(xsize, ysize);
-    
-    for(int c = 0; c < 3; c++)
-    {
-      for(int y = 0; y < ysize; y++)
-      {
-        for(int x = 0; x < xsize; x++)
-        {
-          tmp(x,y) = allfeats[imgcounter](x,y,c);
-        }
-      }
     
-      NICE::FilterT<double>::sobel(tmp, tmp2);
-      for(int y = 0; y < ysize; y++)
-      {
-        for(int x = 0; x < xsize; x++)
-        {
-          allfeats[imgcounter](x,y,c+3) = tmp2(x,y);
-        }
-      }
-    }
-#endif
+    // read image and do some simple transformations
+    extractBasicFeatures (allfeats[imgcounter], img, currentFile);
 
     // getting groundtruth
     NICE::Image pixelLabels ( xsize, ysize );
@@ -804,7 +766,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
   //int baseFeatSize = allfeats[0].size();
 
   vector<MultiChannelImageT<double> > integralImgs ( imgcounter, MultiChannelImageT<double>() );
-  
+
   while ( !allleaf && depth < maxDepth )
   {
     depth++;
@@ -819,13 +781,13 @@ void SemSegContextTree::train ( const MultiDataset *md )
     timer.start();
 #endif
 
-    double weight = computeWeight(depth,maxDepth) - computeWeight(depth-1,maxDepth);
-    
-    if(depth == 1)
+    double weight = computeWeight ( depth, maxDepth ) - computeWeight ( depth - 1, maxDepth );
+
+    if ( depth == 1 )
     {
-      weight = computeWeight(1,maxDepth);
+      weight = computeWeight ( 1, maxDepth );
     }
-    
+
     for ( int tree = 0; tree < nbTrees; tree++ )
     {
       int t = ( int ) forest[tree].size();
@@ -845,17 +807,17 @@ void SemSegContextTree::train ( const MultiDataset *md )
           Operation *splitfeat = NULL;
           double splitval;
           double bestig = getBestSplit ( allfeats, lastfeats, integralImgs, labels, i, splitfeat, splitval, tree );
-          
-          for(int ii = 0; ii < lastfeats.size(); ii++)
+
+          for ( int ii = 0; ii < lastfeats.size(); ii++ )
           {
-            for(int c = 0; c < lastfeats[ii].channels(); c++)
+            for ( int c = 0; c < lastfeats[ii].channels(); c++ )
             {
               short unsigned int minv, maxv;
-              lastfeats[ii].statistics(minv, maxv, c);
-              cout << "min: " << minv << " max: " << maxv << endl;
-            } 
+              lastfeats[ii].statistics ( minv, maxv, c );
+              //cout << "min: " << minv << " max: " << maxv << endl;
+            }
           }
-          
+
 #if 0
           timer.stop();
           double tl = timer.getLast();
@@ -1040,7 +1002,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
       timer.start();
 #endif
     }
-    
+
     //compute integral image
     int channels = classes + allfeats[0].channels();
 #if 0
@@ -1082,9 +1044,9 @@ void SemSegContextTree::train ( const MultiDataset *md )
   }
 
 #ifdef WRITEGLOB
-  ofstream outstream("globtrain.feat");
-  
-  for(int i = 0; i < textonMap.size(); i++)
+  ofstream outstream ( "globtrain.feat" );
+
+  for ( int i = 0; i < textonMap.size(); i++ )
   {
     set<int> usedclasses;
     for ( uint x = 0; x < labels[i].rows(); x++ )
@@ -1096,29 +1058,29 @@ void SemSegContextTree::train ( const MultiDataset *md )
         if ( forbidden_classes.find ( classno ) != forbidden_classes.end() )
           continue;
 
-        usedclasses.insert(classno);
+        usedclasses.insert ( classno );
       }
     }
-    
+
     cout << "labels.cols: " << labels[i].cols() << " labels.rows " << labels[i].rows() << endl;
     cout << "currentfeats : " << allfeats[i].width() << " allfeats[i].height(); " << allfeats[i].height() << endl;
-    
+
     set<int>::iterator it;
-    for ( it=usedclasses.begin() ; it != usedclasses.end(); it++ )
+    for ( it = usedclasses.begin() ; it != usedclasses.end(); it++ )
       outstream << *it << " ";
     outstream << endl;
-    integralTexton[i](integralTexton[i].width()-1, integralTexton[i].height()-1).store(outstream);
+    integralTexton[i] ( integralTexton[i].width() - 1, integralTexton[i].height() - 1 ).store ( outstream );
   }
-  
+
   outstream.close();
 #endif
-    cout << "uniquenumber " << uniquenumber << endl;
-    //getchar();
+  cout << "uniquenumber " << uniquenumber << endl;
+  //getchar();
 #ifdef DEBUG
   for ( int tree = 0; tree < nbTrees; tree++ )
   {
     int t = ( int ) forest[tree].size();
-    
+
     for ( int i = 0; i < t; i++ )
     {
       printf ( "tree[%i]: left: %i, right: %i", i, forest[tree][i].left, forest[tree][i].right );
@@ -1162,43 +1124,12 @@ void SemSegContextTree::train ( const MultiDataset *md )
 #endif
 }
 
-void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult, NICE::MultiChannelImageT<double> & probabilities )
+void SemSegContextTree::extractBasicFeatures ( NICE::MultiChannelImageT<double> &feats, const ColorImage &img, const string &currentFile)
 {
-  //int xpos = 8;
-  //int xpos = 15;
-  //int ypos = 78;
-
-  int xsize;
-  int ysize;
-  ce->getImageSize ( xsize, ysize );
-
-  int numClasses = classNames->numClasses();
-
-  fprintf ( stderr, "ContextTree classification !\n" );
-
-  probabilities.reInit ( xsize, ysize, numClasses );
-  probabilities.setAll ( 0 );
-
-  NICE::ColorImage img;
-
-  std::string currentFile = Globals::getCurrentImgFN();
-
-  try {
-    img = ColorImage ( currentFile );
-  } catch ( Exception ) {
-    cerr << "SemSeg: error opening image file <" << currentFile << ">" << endl;
-    return;
-  }
-
+  int xsize = img.width();
+  int ysize = img.height();
   //TODO: resize image?!
 
-  MultiChannelImageT<double> feats;
-  
-#ifdef TEXTONMAP
-  MultiChannelImageT<SparseVectorInt> textonMap ( xsize / grid + 1, ysize / grid + 1, 1 );
-  MultiChannelImageT<SparseVectorInt> integralTexton ( xsize / grid + 1, ysize / grid + 1, 1 );
-#endif
-
 #ifdef LOCALFEATS
   lfcw->getFeats ( img, feats );
 #else
@@ -1216,34 +1147,54 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
   }
 
   feats = ColorSpace::rgbtolab ( feats );
-  
-  feats.addChannel(3);
-  
-  ImageT<double> tmp(xsize, ysize);
-  ImageT<double> tmp2(xsize, ysize);
-  
-  for(int c = 0; c < 3; c++)
+#endif
+
+  if ( useGradient )
   {
-    for(int y = 0; y < ysize; y++)
-    {
-      for(int x = 0; x < xsize; x++)
-      {
-        tmp(x,y) = feats(x,y,c);
-      }
-    }
-  
-    NICE::FilterT<double>::sobel(tmp, tmp2);
-    for(int y = 0; y < ysize; y++)
+    int currentsize = feats.channels();
+    feats.addChannel ( currentsize );
+
+    for ( int c = 0; c < currentsize; c++ )
     {
-      for(int x = 0; x < xsize; x++)
-      {
-        feats(x,y,c+3) = tmp2(x,y);
-      }
+      ImageT<double> tmp = feats[c];
+      ImageT<double> tmp2 = feats[c+currentsize];
+
+      NICE::FilterT<double>::sobel ( tmp, tmp2 );
     }
   }
+}
+
+void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult, NICE::MultiChannelImageT<double> & probabilities )
+{
+  int xsize;
+  int ysize;
+  ce->getImageSize ( xsize, ysize );
+
+  int numClasses = classNames->numClasses();
+
+  fprintf ( stderr, "ContextTree classification !\n" );
+
+  probabilities.reInit ( xsize, ysize, numClasses );
+  probabilities.setAll ( 0 );
+
+#ifdef TEXTONMAP
+  MultiChannelImageT<SparseVectorInt> textonMap ( xsize / grid + 1, ysize / grid + 1, 1 );
+  MultiChannelImageT<SparseVectorInt> integralTexton ( xsize / grid + 1, ysize / grid + 1, 1 );
+#endif
+
+  std::string currentFile = Globals::getCurrentImgFN();
+  MultiChannelImageT<double> feats;
   
+  NICE::ColorImage img;
+
+  try {
+    img = ColorImage ( currentFile );
+  } catch ( Exception ) {
+    cerr << "SemSeg: error opening image file <" << currentFile << ">" << endl;
+    return;
+  }
   
-#endif
+  extractBasicFeatures(feats, img, currentFile); //read image and do some simple transformations
 
   bool allleaf = false;
 
@@ -1258,20 +1209,20 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
   for ( int d = 0; d < maxDepth && !allleaf; d++ )
   {
     depth++;
-    
+
 #ifdef TEXTONMAP
-    double weight = computeWeight(depth,maxDepth) - computeWeight(depth-1,maxDepth);
-    
-    if(depth == 1)
+    double weight = computeWeight ( depth, maxDepth ) - computeWeight ( depth - 1, maxDepth );
+
+    if ( depth == 1 )
     {
-      weight = computeWeight(1,maxDepth);
+      weight = computeWeight ( 1, maxDepth );
     }
 #endif
 
     allleaf = true;
-    
+
     MultiChannelImageT<unsigned short int> lastfeats = currentfeats;
-    
+
     int tree;
 #pragma omp parallel for private(tree)
     for ( tree = 0; tree < nbTrees; tree++ )
@@ -1332,7 +1283,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
         }
       }
 
-      if(depth < maxDepth)
+      if ( depth < maxDepth )
       {
         //compute integral image
         int channels = ( int ) labelmap.size() + feats.channels();
@@ -1348,7 +1299,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
       }
     }
 
-    if(depth < maxDepth)
+    if ( depth < maxDepth )
     {
       computeIntegralImage ( currentfeats, feats, integralImg );
 #ifdef TEXTONMAP
@@ -1360,9 +1311,9 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
 //  cout << forest[0][currentfeats.get ( xpos, ypos, 0 ) ].dist << endl;
 
 #ifdef WRITEGLOB
-  ofstream outstream("globtest.feat",ofstream::app);
+  ofstream outstream ( "globtest.feat", ofstream::app );
   outstream << 0 << endl;
-  integralTexton(integralTexton.width()-1, integralTexton.height()-1).store(outstream);
+  integralTexton ( integralTexton.width() - 1, integralTexton.height() - 1 ).store ( outstream );
   outstream.close();
 #endif
 
@@ -1370,14 +1321,14 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
   int classes = ( int ) probabilities.channels();
   vector<int> useclass ( classes, 1 );
 #ifdef WRITEGLOB
-  
-  
+
+
   std::vector< std::string > list;
   StringTools::split ( currentFile, '/', list );
 
   string orgname = list.back();
 
-  ofstream ostream("filelist.txt",ofstream::app);
+  ofstream ostream ( "filelist.txt", ofstream::app );
   ostream << orgname << ".dat" << endl;
   ostream.close();
 
@@ -1385,55 +1336,55 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
   {
     useclass = vector<int> ( classes, 0 );
     ifstream infile ( ( cndir + "/" + orgname + ".dat" ).c_str() );
-    
+
 #undef OLD
 #ifdef OLD
     while ( !infile.eof() && infile.good() )
     {
       int tmp;
       infile >> tmp;
-      assert(tmp >= 0 && tmp < classes);
+      assert ( tmp >= 0 && tmp < classes );
       useclass[tmp] = 1;
     }
 #else
     int c = 0;
-    vector<double> probs(classes, 0.0);
-    
+    vector<double> probs ( classes, 0.0 );
+
     while ( !infile.eof() && infile.good() )
     {
       infile >> probs[c];
       c++;
     }
-    
+
     vector<double> sorted = probs;
-    sort (sorted.begin(), sorted.end());
-    
+    sort ( sorted.begin(), sorted.end() );
+
     double thr = sorted[10];
-    
-    if(thr < 0.0)
+
+    if ( thr < 0.0 )
       thr = 0.0;
-    
-    for(int c = 0; c < classes; c++)
+
+    for ( int c = 0; c < classes; c++ )
     {
-      if(probs[c] < thr)
+      if ( probs[c] < thr )
       {
         useclass[c] = 1;
       }
     }
-    
-    
+
+
 #endif
-    
-    for(int c = 0; c < classes; c++)
+
+    for ( int c = 0; c < classes; c++ )
     {
-      if(useclass[c] == 0)
+      if ( useclass[c] == 0 )
       {
-        probabilities.set(-numeric_limits< double >::max(), c);
+        probabilities.set ( -numeric_limits< double >::max(), c );
       }
     }
   }
 #endif
-  
+
   if ( pixelWiseLabeling )
   {
     //finales labeln:
@@ -1450,13 +1401,13 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
         for ( uint i = 0; i < s; i++ )
         {
           int currentclass = labelmapback[i];
-          if(useclass[currentclass])
+          if ( useclass[currentclass] )
           {
-            probabilities(x,y,currentclass) = getMeanProb ( x, y, i, currentfeats );
+            probabilities ( x, y, currentclass ) = getMeanProb ( x, y, i, currentfeats );
 
-            if ( probabilities(x,y,currentclass) > maxvalue )
+            if ( probabilities ( x, y, currentclass ) > maxvalue )
             {
-              maxvalue = probabilities(x,y,currentclass);
+              maxvalue = probabilities ( x, y, currentclass );
               maxindex = currentclass;
             }
           }
@@ -1475,29 +1426,29 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
       NICE::Matrix tmp ( probabilities.height(), probabilities.width() );
       double maxval = -numeric_limits<double>::max();
       double minval = numeric_limits<double>::max();
-      
-      
+
+
       for ( int y = 0; y < probabilities.height(); y++ )
         for ( int x = 0; x < probabilities.width(); x++ )
         {
-          double val = probabilities( x, y, j );
+          double val = probabilities ( x, y, j );
           tmp ( y, x ) = val;
           maxval = std::max ( val, maxval );
           minval = std::min ( val, minval );
         }
-      tmp(0,0) = 1.0;
-      tmp(0,1) = 0.0;
-        
+      tmp ( 0, 0 ) = 1.0;
+      tmp ( 0, 1 ) = 0.0;
+
       NICE::ColorImage imgrgb ( probabilities.width(), probabilities.height() );
       ICETools::convertToRGB ( tmp, imgrgb );
 
       cout << "maxval = " << maxval << " minval: " << minval << " for class " << j << endl; //cn.text ( j ) << endl;
-      
+
       std::string s;
       std::stringstream out;
       out << "tmpprebmap" << j << ".ppm";
       s = out.str();
-      imgrgb.write( s );
+      imgrgb.write ( s );
       //showImage(imgrgb, "Ergebnis");
       //getchar();
     }
@@ -1518,25 +1469,6 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
     vector<vector<double> > regionProbs ( regionNumber, vector<double> ( dSize, 0.0 ) );
     vector<int> bestlabels ( regionNumber, 0 );
 
-    /*
-    for(int r = 0; r < regionNumber; r++)
-    {
-     Image over(img.width(), img.height());
-     for(int y = 0; y < img.height(); y++)
-     {
-      for(int x = 0; x < img.width(); x++)
-      {
-       if(((int)regions(x,y)) == r)
-        over.setPixel(x,y,1);
-       else
-        over.setPixel(x,y,0);
-      }
-     }
-     cout << "r: " << r << endl;
-     showImageOverlay(img, over);
-    }
-    */
-
     for ( int y = 0; y < img.height(); y++ )
     {
       for ( int x = 0; x < img.width(); x++ )
@@ -1575,11 +1507,11 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
         segresult.setPixel ( x, y, bestlabels[regions ( x,y ) ] );
       }
     }
-    
+
 #define WRITEREGIONS
 #ifdef WRITEREGIONS
     RegionGraph rg;
-    segmentation->getGraphRepresentation ( img, regions,  rg);
+    segmentation->getGraphRepresentation ( img, regions,  rg );
     for ( uint pos = 0; pos < regionProbs.size(); pos++ )
     {
       rg[pos]->setProbs ( regionProbs[pos] );

+ 12 - 0
semseg/SemSegContextTree.h

@@ -106,6 +106,9 @@ class SemSegContextTree : public SemanticSegmentation, public NICE::Persistent
 
     /** Number of trees used for the forest */
     int nbTrees;
+    
+    /** use Gradient image or not */
+    bool useGradient;
 
   public:
     /** simple constructor */
@@ -138,6 +141,15 @@ class SemSegContextTree : public SemanticSegmentation, public NICE::Persistent
      **/
     void computeIntegralImage ( const NICE::MultiChannelImageT<unsigned short int> &currentfeats, const NICE::MultiChannelImageT<double> &lfeats, NICE::MultiChannelImageT<double> &integralImage );
 
+    /**
+     * @brief reads image and does some simple convertions
+     *
+     * @param feats output image
+     * @param currentFile image filename
+     * @return void
+     **/
+    void extractBasicFeatures ( NICE::MultiChannelImageT<double> &feats, const NICE::ColorImage &img, const std::string &currentFile);
+    
     /**
      * @brief computes integral image for Sparse Multichannel Image
      *