瀏覽代碼

added variance map computation

Sven Sickert 12 年之前
父節點
當前提交
d18547df7d
共有 4 個文件被更改,包括 319 次插入239 次删除
  1. 8 1
      image/MultiChannelImage3DT.h
  2. 73 27
      image/MultiChannelImage3DT.tcc
  3. 25 2
      semseg/SemSegContextTree.cpp
  4. 213 209
      semseg/SemSegContextTree.h

+ 8 - 1
image/MultiChannelImage3DT.h

@@ -113,7 +113,14 @@ public:
    * @param dis displacement vector
    * @param channel channel
    */
-  void calcGLCM( const std::vector<int> dis, uint channel = 0 );
+  void calcGLCM( std::vector<std::vector<double> > & mat, const std::vector<int> dis, uint channel = 0 );
+  
+  /** 
+   * @brief calculate the variance image map of a channel
+   * @param srcchan source channel with raw data
+   * @param tarchan target channel for the variance map
+   */
+  void calcVariance( uint srcchan = 0, uint tarchan = 1 );
   
   /**
    * @brief calculate the integral value in the volume given by upper left front corner and lower right back corner, including out of boundary check

+ 73 - 27
image/MultiChannelImage3DT.tcc

@@ -623,7 +623,7 @@ void MultiChannelImage3DT<P>::calcIntegral( uint channel )
 }
 
 template<class P>
-void MultiChannelImage3DT<P>::calcGLCM( const std::vector<int> dis, uint channel )
+void MultiChannelImage3DT<P>::calcGLCM( std::vector<std::vector<double> > & mat, const std::vector<int> dis, uint channel )
 {
   assert( channel < numChannels );
   assert( data[channel] != NULL );
@@ -633,10 +633,8 @@ void MultiChannelImage3DT<P>::calcGLCM( const std::vector<int> dis, uint channel
   statistics( min, max, channel );
   
   long k = 0;
-  int wsize = 2;    // window size = 2*wsize + 1
   
   int tmp[xsize][ysize][zsize];
-  std::vector<std::vector<double> > mat;
   
   for (int z = 0; z < zsize; z++ )
   {
@@ -645,45 +643,93 @@ void MultiChannelImage3DT<P>::calcGLCM( const std::vector<int> dis, uint channel
       for (int x = 0; x < xsize; x++)
       {
         mat = std::vector<std::vector<double> > ( max+1, std::vector<double> ( max+1, 0.0 ) );
-        for (int u=-wsize; u<=wsize; u++)
+        if ( (x+dis[0]>=0) && (x+dis[0]<xsize)
+          && (y+dis[1]>=0) && (y+dis[1]<ysize)
+          && (z+dis[2]>=0) && (z+dis[2]<zsize) )
         {
-          for (int v=-wsize; v<=wsize; v++)
-          {
-            for (int w=-wsize; w<=wsize; w++)
-            {
-              if ( (u+x+dis[0]>=0) && (u+x+dis[0]<xsize)
-                && (v+y+dis[1]>=0) && (v+y+dis[1]<ysize)
-                && (w+z+dis[2]>=0) && (w+z+dis[2]<zsize) )
-              {
-                P val = get( x+u, y+v, z+w, channel );
-                P dval = get( x+u+dis[0], y+v+dis[1], z+w+dis[2], channel );
-                mat[val][dval]++;
-                mat[dval][val]++;   // symmetry
-                k += 2;
-              }
-            }
-          }
+          P val = get( x, y, z, channel );
+          P dval = get( x+dis[0], y+dis[1], z+dis[2], channel );
+          mat[val][dval]++;
+          mat[dval][val]++;   // symmetry
+          k += 2;
         }
-        double ASM = 0.0;
+        
         for (int i = 0; i <= max; i++)
         {
           for (int j = 0; j <= max; j++)
           {
             mat[i][j] /= k;
-            ASM += mat[i][j]*mat[i][j];
           }
         }
-        tmp[x][y][z] = (int) (ASM * get(x,y,z,channel) );
       }
     }
   }
-  for (int z = 0; z < zsize; z++ )
+
+}
+
+template<class P>
+void MultiChannelImage3DT<P>::calcVariance( uint srcchan, uint tarchan )
+{
+  assert( srcchan < tarchan );
+  assert( tarchan < numChannels );
+  assert( data[srcchan] != NULL );
+  assert( data[tarchan] != NULL );
+  
+  uint windowsize = 3;
+  uint win = (windowsize-1)/2;
+  
+  for ( int z = 0; z < zsize; z++ )
   {
-    for (int y = 0; y < ysize; y++ )
+    for ( int y = 0; y < ysize; y++ )
     {
-      for (int x = 0; x < xsize; x++)
+      for ( int x = 0; x < xsize; x++ )
       {
-        set(x,y,z, tmp[x][y][z], channel);
+        int meansum = 0;
+          for ( int u = -win; u <= win; u++ ) 
+          {
+            for ( int v = -win; v <= win; v++ )
+            {
+              for ( int w = -win; w <= win; w++)
+              {
+                int u_tmp = u;
+                int v_tmp = v;
+                int w_tmp = w;
+                if ( (x+u<0) || (x+u>=xsize) )
+                  u_tmp = -u_tmp;
+                if ( (y+v<0) || (y+v>=ysize) )
+                  v_tmp = -v_tmp;
+                if ( (z+w<0) || (z+w>=zsize) )
+                  w_tmp = -w_tmp;
+                meansum += get( x+u_tmp, y+v_tmp, z+w_tmp, srcchan );
+              }
+            }
+          }
+        meansum /= (windowsize*windowsize*windowsize);
+        
+        unsigned long varsum = 0;
+        for ( int u = -win; u <= win; u++ ) 
+        {
+          for ( int v = -win; v <= win; v++ )
+          {
+            for ( int w = -win; w <= win; w++)
+            {
+              int u_tmp = u;
+              int v_tmp = v;
+              int w_tmp = w;
+              if ( (x+u<0) || (x+u>=xsize) )
+                u_tmp = -u_tmp;
+              if ( (y+v<0) || (y+v>=ysize) )
+                v_tmp = -v_tmp;
+              if ( (z+w<0) || (z+w>=zsize) )
+                  w_tmp = -w_tmp;
+              
+              long sdev = (get( x+u_tmp, y+v_tmp, z+w_tmp, srcchan ) - meansum );
+              varsum += (sdev*sdev);
+            }
+          }
+        }
+        varsum /= (windowsize*windowsize+windowsize)-1;
+        set( x, y, z, varsum, tarchan );
       }
     }
   }

+ 25 - 2
semseg/SemSegContextTree.cpp

@@ -169,6 +169,8 @@ SemSegContextTree::SemSegContextTree ( const Config *conf, const MultiDataset *m
   useWeijer = conf->gB ( featsec, "use_weijer", true );
 
   useGaussian = conf->gB ( featsec, "use_diff_gaussian", false );
+  
+  useVariance = conf->gB ( featsec, "use_variance", false );
 
   // geometric features of hoiem
   useHoiemFeatures = conf->gB ( featsec, "use_hoiem_features", false );
@@ -330,7 +332,7 @@ double SemSegContextTree::getBestSplit ( std::vector<NICE::MultiChannelImage3DT<
     if ( ft > 1 )
     {
       //use larger window size for context features
-      tmpws *= 3;
+      tmpws *= 2;
     }
 
     if ( ft == 1 )
@@ -715,6 +717,9 @@ void SemSegContextTree::train ( const MultiDataset *md )
 
   if ( useGaussian )
     rawChannels += 1;
+  
+  if ( useVariance )
+    rawChannels += 1; 
 
   // gray value images
   for ( int i = 0; i < rawChannels; i++ )
@@ -1502,7 +1507,7 @@ void SemSegContextTree::extractBasicFeatures ( NICE::MultiChannelImage3DT<double
       feats_tmp.addChannel ( gauss );
       //cout << "Added file " << gaussPath << " to feature stack " << endl;
     }
-
+    
     // read the geometric cues produced by Hoiem et al.
     if ( useHoiemFeatures )
     {
@@ -1594,6 +1599,24 @@ void SemSegContextTree::extractBasicFeatures ( NICE::MultiChannelImage3DT<double
       }
     }
   }
+  
+  if ( useVariance )
+  {
+    int cchannel = feats.channels();
+    if (imagetype = IMAGETYPE_RGB)
+    {
+      feats.addChannel( 3 );
+      for (int c = 0; c < 3; c++)
+      {
+        feats.calcVariance( c, cchannel+c );
+      }
+    }
+    else
+    {
+      feats.addChannel( 1 );
+      feats.calcVariance( 0, cchannel );
+    }
+  }
 
 }
 

+ 213 - 209
semseg/SemSegContextTree.h

@@ -18,223 +18,227 @@
 
 #include "gp-hik-exp/GPHIKClassifierNICE.h"
 
-namespace OBJREC {
+namespace OBJREC
+{
 
 /** Localization system */
 
 class SemSegContextTree : public SemanticSegmentation, public NICE::Persistent
 {
-    /** Segmentation Method */
-    RegionSegmentationMethod *segmentation;
+  /** Segmentation Method */
+  RegionSegmentationMethod *segmentation;
+
+  /** tree -> saved as vector of nodes */
+  std::vector<std::vector<TreeNode> > forest;
+
+  /** local features */
+  LFColorWeijer *lfcw;
+
+  /** number of featuretype -> currently: local and context features = 2 */
+  int ftypes;
+
+  /** maximum samples for tree  */
+  int maxSamples;
+
+  /** size for neighbourhood */
+  int windowSize;
+
+  /** how many feats should be considered for a split */
+  int featsPerSplit;
+
+  /** count samples per label */
+  std::map<int, int> labelcounter;
+
+  /** map of labels */
+  std::map<int, int> labelmap;
+
+  /** map of labels inverse*/
+  std::map<int, int> labelmapback;
+
+  /** scalefactor for balancing for each class */
+  std::vector<double> a;
+
+  /** counter for used operations */
+  std::vector<int> opOverview;
+
+  /** relative use of context vs raw features per tree level*/
+  std::vector<std::vector<double> > contextOverview;
+
+  /** the minimum number of features allowed in a leaf */
+  int minFeats;
+
+  /** maximal depth of tree */
+  int maxDepth;
+
+  /** current depth for training */
+  int depth;
+
+  /** how many splittests */
+  int randomTests;
+
+  /** operations for pairwise features */
+  std::vector<std::vector<Operation*> > ops;
+
+  std::vector<ValueAccess*> calcVal;
+
+  /** use alternative calculation for information gain */
+  bool useShannonEntropy;
+
+  /** Classnames */
+  ClassNames classnames;
+
+  /** train selection */
+  std::set<int> forbidden_classes;
+
+  /** Configfile */
+  const NICE::Config *conf;
+
+  /** use pixelwise labeling or regionlabeling with additional segmenation */
+  bool pixelWiseLabeling;
+
+  /** Number of trees used for the forest */
+  int nbTrees;
+
+  /** use Gradient image or not */
+  bool useGradient;
+
+  /** use Color features from van de Weijer or not */
+  bool useWeijer;
+
+  /** use Edge features from Difference of Gaussian preprocessing or not */
+  bool useGaussian;
+
+  /** use Variance map features or not */
+  bool useVariance;
+  
+  /** use Regions as extra feature channel or not */
+  bool useRegionFeature;
 
-    /** tree -> saved as vector of nodes */
-    std::vector<std::vector<TreeNode> > forest;
+  /** use external image categorization to avoid some classes */
+  bool useCategorization;
 
-    /** local features */
-    LFColorWeijer *lfcw;
+  /** categorization information for external categorization */
+  std::string cndir;
 
-    /** number of featuretype -> currently: local and context features = 2 */
-    int ftypes;
-
-    /** maximum samples for tree  */
-    int maxSamples;
-
-    /** size for neighbourhood */
-    int windowSize;
-    
-    /** how many feats should be considered for a split */
-    int featsPerSplit;
-
-    /** count samples per label */
-    std::map<int, int> labelcounter;
-
-    /** map of labels */
-    std::map<int, int> labelmap;
-
-    /** map of labels inverse*/
-    std::map<int, int> labelmapback;
-
-    /** scalefactor for balancing for each class */
-    std::vector<double> a;
-
-    /** counter for used operations */
-    std::vector<int> opOverview;
-
-    /** relative use of context vs raw features per tree level*/
-    std::vector<std::vector<double> > contextOverview;
-
-    /** the minimum number of features allowed in a leaf */
-    int minFeats;
-
-    /** maximal depth of tree */
-    int maxDepth;
-
-    /** current depth for training */
-    int depth;
-
-    /** how many splittests */
-    int randomTests;
-
-    /** operations for pairwise features */
-    std::vector<std::vector<Operation*> > ops;
-
-    std::vector<ValueAccess*> calcVal;
-
-    /** use alternative calculation for information gain */
-    bool useShannonEntropy;
-
-    /** Classnames */
-    ClassNames classnames;
-
-    /** train selection */
-    std::set<int> forbidden_classes;
-
-    /** Configfile */
-    const NICE::Config *conf;
-
-    /** use pixelwise labeling or regionlabeling with additional segmenation */
-    bool pixelWiseLabeling;
-
-    /** Number of trees used for the forest */
-    int nbTrees;
-    
-    /** use Gradient image or not */
-    bool useGradient;
-    
-    /** use Color features from van de Weijer or not */
-    bool useWeijer;
-
-		/** use Edge features from Difference of Gaussian preprocessing or not */
-    bool useGaussian;
-    
-    /** use Regions as extra feature channel or not */
-    bool useRegionFeature;
-    
-    /** use external image categorization to avoid some classes */
-    bool useCategorization;
-    
-    /** categorization information for external categorization */
-    std::string cndir;
-
-    /** how to handle each channel
-     * 0: simple grayvalue features
-     * 1: which pixel belongs to which region
-     * 2: graycolor integral images
-     * 3: context integral images
-     * 4: context features (not in MultiChannelImageT encoded)
-     */
-    std::vector<int> channelType;
-
-    /** list of channels per feature type */
-    std::vector<std::vector<int> > channelsPerType;
-    
-    /** whether we should use the geometric features of Hoeim (only offline computation with MATLAB supported) */
-    bool useHoiemFeatures;
-
-    /** directory of the geometric features */
-    std::string hoiemDirectory;
-    
-    /** first iteration or not */
-    bool firstiteration;
-    
-    /** which IntegralImage channel belongs to which raw value channel */
-    std::vector<std::pair<int, int> > integralMap;
-    
-    /** amount of grayvalue Channels */
-    int rawChannels;
-    
-    /** classifier for categorization */
-    OBJREC::GPHIKClassifierNICE *fasthik;
-    
-    /** unique numbers for nodes */
-    int uniquenumber;
-
-  public:
-    /** simple constructor */
-    SemSegContextTree ( const NICE::Config *conf, const MultiDataset *md );
-
-    /** simple destructor */
-    virtual ~SemSegContextTree();
-
-		/**
-     * test a single 3d image
-     * @param imgData input data
-     * @param segresult segmentation results
-     * @param probabilities probabilities for each pixel
-     */
-		void semanticseg ( NICE::MultiChannelImage3DT<double> & imgData, NICE::MultiChannelImageT<double> & segresult, NICE::MultiChannelImage3DT<double> & probabilities, const std::vector<std::string> & filelist );
-
-		/**
-     * the main training method
-     * @param md training data
-     */
-    void train ( const MultiDataset *md );
-
-    /**
-     * @brief computes integral image of given feats
-     *
-     * @param currentfeats input features
-     * @param integralImage output image (must be initilized)
-     * @return void
-     **/
-    void computeIntegralImage ( const NICE::MultiChannelImage3DT<unsigned short int> &currentfeats, NICE::MultiChannelImage3DT<double> &lfeats, int firstChannel );
-
-    /**
-     * @brief reads image and does some simple convertions
-     *
-     * @param feats output image
-     * @param currentFile image filename
-     * @return void
-     **/
-    void extractBasicFeatures ( NICE::MultiChannelImage3DT<double> &feats, const NICE::MultiChannelImage3DT<double> &imgData, const std::vector<std::string> &filelist, int &amountRegions);
-
-    /**
-     * compute best split for current settings
-     * @param feats features
-     * @param currentfeats matrix with current node for each feature
-     * @param labels labels for each feature
-     * @param node current node
-     * @param splitfeat output feature position
-     * @param splitval
-     * @return best information gain
-     */
-    double getBestSplit ( std::vector<NICE::MultiChannelImage3DT<double> > &feats, std::vector<NICE::MultiChannelImage3DT<unsigned short int> > &currentfeats, const std::vector<NICE::MultiChannelImageT<int> > &labels, int node, Operation *&splitop, double &splitval, const int &tree, std::vector<std::vector<std::vector<double> > > &regionProbs );
-
-    /**
-     * @brief computes the mean probability for a given class over all trees
-     * @param x x position
-     * @param y y position
-		 * @param z z 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 &z, const int &channel, const NICE::MultiChannelImage3DT<unsigned short int> &currentfeats );
-
-    /**
-     * @brief load all data to is stream
-     *
-     * @param is input stream
-     * @param format has no influence
-     * @return void
-     **/
-    virtual void restore ( std::istream & is, int format = 0 );
-
-    /**
-     * @brief save all data to is stream
-     *
-     * @param os output stream
-     * @param format has no influence
-     * @return void
-     **/
-    virtual void store ( std::ostream & os, int format = 0 ) const;
-
-    /**
-     * @brief clean up
-     *
-     * @return void
-     **/
-    virtual void clear () {}
+  /** how to handle each channel
+   * 0: simple grayvalue features
+   * 1: which pixel belongs to which region
+   * 2: graycolor integral images
+   * 3: context integral images
+   * 4: context features (not in MultiChannelImageT encoded)
+   */
+  std::vector<int> channelType;
+
+  /** list of channels per feature type */
+  std::vector<std::vector<int> > channelsPerType;
+
+  /** whether we should use the geometric features of Hoeim (only offline computation with MATLAB supported) */
+  bool useHoiemFeatures;
+
+  /** directory of the geometric features */
+  std::string hoiemDirectory;
+
+  /** first iteration or not */
+  bool firstiteration;
+
+  /** which IntegralImage channel belongs to which raw value channel */
+  std::vector<std::pair<int, int> > integralMap;
+
+  /** amount of grayvalue Channels */
+  int rawChannels;
+
+  /** classifier for categorization */
+  OBJREC::GPHIKClassifierNICE *fasthik;
+
+  /** unique numbers for nodes */
+  int uniquenumber;
+
+public:
+  /** simple constructor */
+  SemSegContextTree ( const NICE::Config *conf, const MultiDataset *md );
+
+  /** simple destructor */
+  virtual ~SemSegContextTree();
+
+  /**
+   * test a single 3d image
+   * @param imgData input data
+   * @param segresult segmentation results
+   * @param probabilities probabilities for each pixel
+   */
+  void semanticseg ( NICE::MultiChannelImage3DT<double> & imgData, NICE::MultiChannelImageT<double> & segresult, NICE::MultiChannelImage3DT<double> & probabilities, const std::vector<std::string> & filelist );
+
+  /**
+   * the main training method
+   * @param md training data
+   */
+  void train ( const MultiDataset *md );
+
+  /**
+   * @brief computes integral image of given feats
+   *
+   * @param currentfeats input features
+   * @param integralImage output image (must be initilized)
+   * @return void
+   **/
+  void computeIntegralImage ( const NICE::MultiChannelImage3DT<unsigned short int> &currentfeats, NICE::MultiChannelImage3DT<double> &lfeats, int firstChannel );
+
+  /**
+   * @brief reads image and does some simple convertions
+   *
+   * @param feats output image
+   * @param currentFile image filename
+   * @return void
+   **/
+  void extractBasicFeatures ( NICE::MultiChannelImage3DT<double> &feats, const NICE::MultiChannelImage3DT<double> &imgData, const std::vector<std::string> &filelist, int &amountRegions );
+
+  /**
+   * compute best split for current settings
+   * @param feats features
+   * @param currentfeats matrix with current node for each feature
+   * @param labels labels for each feature
+   * @param node current node
+   * @param splitfeat output feature position
+   * @param splitval
+   * @return best information gain
+   */
+  double getBestSplit ( std::vector<NICE::MultiChannelImage3DT<double> > &feats, std::vector<NICE::MultiChannelImage3DT<unsigned short int> > &currentfeats, const std::vector<NICE::MultiChannelImageT<int> > &labels, int node, Operation *&splitop, double &splitval, const int &tree, std::vector<std::vector<std::vector<double> > > &regionProbs );
+
+  /**
+   * @brief computes the mean probability for a given class over all trees
+   * @param x x position
+   * @param y y position
+   * @param z z 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 &z, const int &channel, const NICE::MultiChannelImage3DT<unsigned short int> &currentfeats );
+
+  /**
+   * @brief load all data to is stream
+   *
+   * @param is input stream
+   * @param format has no influence
+   * @return void
+   **/
+  virtual void restore ( std::istream & is, int format = 0 );
+
+  /**
+   * @brief save all data to is stream
+   *
+   * @param os output stream
+   * @param format has no influence
+   * @return void
+   **/
+  virtual void store ( std::ostream & os, int format = 0 ) const;
+
+  /**
+   * @brief clean up
+   *
+   * @return void
+   **/
+  virtual void clear () {}
 
 };