16 Комити 73a0e2141d ... 9e03d98750

Аутор SHA1 Порука Датум
  Sven Sickert 9e03d98750 removed dependencies on deprecated Filter.h пре 8 година
  Sven Sickert 5d712edde4 minor name change пре 8 година
  Sven Sickert 447307e38d fixed wrong call for preprocessing 3D image channels пре 8 година
  Sven Sickert 118fb5a5c7 minor пре 9 година
  Sven Sickert dde54ede0f added missing variable initialization пре 9 година
  Sven Sickert 5918dcaa77 modified SemSegObliqueTree according CachedExample change пре 9 година
  Sven Sickert f1bafd4965 adding zsize configuration for 2D scenarios in SemSegTools пре 9 година
  Sven Sickert 5b88c97373 revised performance statistics пре 9 година
  Sven Sickert a7f2f20e8f first running version of 3D oblique forests пре 9 година
  Sven Sickert 067c5cf547 modified testSemSegObliqueTrees for the use of 3d images пре 10 година
  Sven Sickert 72428f2f60 implemented function semanticseg for 3d images for oblique forests пре 10 година
  Sven Sickert dc0c0bbf7b removed unused variable пре 10 година
  Sven Sickert 33bbac6231 moved run3Dseg boolean to abstract class пре 10 година
  Sven Sickert c1ed3f1f23 added function semanticseg() for 3d cached examples пре 10 година
  Sven Sickert 863b38046c modified SemSegObliqueTree for the use of 3d images пре 10 година
  Sven Sickert 07f8b63ad2 moved function getDepthVector() to SemSegTools пре 10 година

+ 56 - 17
progs/testSemSegObliqueTrees.cpp

@@ -66,6 +66,14 @@ int main ( int argc, char **argv )
     NICE::Timer timer;
     std::cout << "\nCLASSIFICATION" << std::endl;
     std::cout << "##############\n" << std::endl;
+
+    std::vector<int> zsizeVec;
+    bool run3Dseg = semseg->isMode3D();
+    SemSegTools::getDepthVector ( testFiles, zsizeVec, run3Dseg );
+    int depthCount = 0, idx = 0;
+    std::vector<std::string> filelist;
+    NICE::MultiChannelImageT<int> segresult, gt;
+
     for (LabeledSet::const_iterator it = testFiles->begin(); it != testFiles->end(); it++)
     {
         for (std::vector<ImageInfo *>::const_iterator jt = it->second.begin();
@@ -73,8 +81,10 @@ int main ( int argc, char **argv )
         {
             ImageInfo & info = *(*jt);
             std::string file = info.img();
+            filelist.push_back(file);
+            depthCount++;
 
-            NICE::ImageT<int> segresult, gtruth;
+            NICE::ImageT<int> gtruth, res;
             if ( info.hasLocalizationInfo() )
             {
                 const LocalizationResult *l_gt = info.localization();
@@ -86,31 +96,60 @@ int main ( int argc, char **argv )
                 std::cerr << "testSemSegConvTrees: WARNING: NO localization info found for "
                           << file << std::endl;
             }
-            segresult = gtruth;
+            segresult.addChannel(gtruth);
+            gt.addChannel(gtruth);
+
+            int depthBoundary = 1;
+            if ( run3Dseg )
+                depthBoundary = zsizeVec[idx];
+
+            std::cout << "Slice " << depthCount << "/"
+                      << depthBoundary << std::endl;
+            if ( depthCount < depthBoundary )
+                continue;
 
             // actual testing
-            NICE::MultiChannelImageT<double> probabilities;
+            NICE::MultiChannelImage3DT<double> probabilities;
 
             timer.start();
-            semseg->semanticseg( file, segresult, probabilities );
+            semseg->semanticseg( filelist, segresult, probabilities );
             timer.stop();
             std::cout << "Time for Classification: " << timer.getLastAbsolute()
                       << "\n\n";
 
             // updating confusion matrix
-            SemSegTools::updateConfusionMatrix ( segresult, gtruth, M,
-                forbiddenClasses, classMapping );
-
-            // saving results to image file
-            NICE::ColorImage rgb;
-            NICE::ColorImage rgb_gt;
-            NICE::ColorImage orig ( file );
-            classNames.labelToRGB( segresult, rgb);
-            classNames.labelToRGB( gtruth, rgb_gt);
-            std::string fname = NICE::StringTools::baseName ( file, false );
-            std::string outStr;
-            SemSegTools::saveResultsToImageFile( &conf, "analysis", orig,
-                        rgb_gt, rgb, fname, outStr );
+            res = gtruth;
+            for ( int z = 0; z < segresult.channels(); z++ )
+            {
+                for ( int y = 0; y < res.height(); y++ )
+                    for ( int x = 0; x < res.width(); x++)
+                    {
+                        res.setPixel ( x, y, segresult.get(x,y,(unsigned int)z) );
+                        if ( run3Dseg )
+                            gtruth.setPixel ( x, y, gt.get(x,y,(unsigned int)z) );
+                    }
+
+                SemSegTools::updateConfusionMatrix ( res, gtruth, M,
+                    forbiddenClasses, classMapping );
+
+                // saving results to image file
+                NICE::ColorImage rgb;
+                NICE::ColorImage rgb_gt;
+                NICE::ColorImage orig ( filelist[z] );
+                classNames.labelToRGB( res, rgb);
+                classNames.labelToRGB( gtruth, rgb_gt);
+                std::string fname = NICE::StringTools::baseName ( filelist[z], false );
+                std::string outStr;
+                SemSegTools::saveResultsToImageFile( &conf, "analysis", orig,
+                            rgb_gt, rgb, fname, outStr );
+            }
+
+            // prepare for new 3d image
+            filelist.clear();
+            segresult.reInit(0,0,0);
+            gt.reInit(0,0,0);
+            depthCount = 0;
+            idx++;
         }
     }
 

+ 3 - 2
progs/testSemanticSegmentation3D.cpp

@@ -46,11 +46,11 @@ void startClassification (SemanticSegmentation *semseg,
     if (cvRuns > 1)
         write_results = false;
 
-    bool run_3Dseg = conf.gB( "SSContextTree", "run_3dseg", false);
+    bool run_3Dseg = semseg->isMode3D();
     string output_type = conf.gS ( "debug", "output_type", "ppm" );
 
     vector< int > zsizeVec;
-    semseg->getDepthVector ( testFiles, zsizeVec, run_3Dseg );
+    SemSegTools::getDepthVector ( testFiles, zsizeVec, run_3Dseg );
     int depthCount = 0, idx = 0;
     vector< string > filelist;
     NICE::MultiChannelImageT<int> segresult;
@@ -87,6 +87,7 @@ void startClassification (SemanticSegmentation *semseg,
                 depthBoundary = zsizeVec[idx];
             }
 
+//            std::cout << depthCount << " " << depthBoundary << std::endl;
             if ( depthCount < depthBoundary ) continue;
 
             NICE::MultiChannelImage3DT<double> probabilities;

+ 5 - 0
semseg/SemSegContextTree.h

@@ -168,6 +168,11 @@ class SemSegContextTree : public SemanticSegmentation
      */
     void semanticseg ( CachedExample *ce,   NICE::ImageT<int> & segresult,  NICE::MultiChannelImageT<double> & probabilities );
 
+    void semanticseg ( CachedExample *ce,
+                       NICE::MultiChannelImageT<int> & segresult,
+                       NICE::MultiChannelImage3DT<double> & probabilities )
+    {}
+
     /**
      * the main training method
      * @param md training data

+ 3 - 3
semseg/SemSegContextTree3D.cpp

@@ -1,4 +1,5 @@
 #include "SemSegContextTree3D.h"
+#include "SemSegTools.h"
 
 #include <core/basics/FileName.h>
 #include <core/basics/numerictools.h>
@@ -88,7 +89,6 @@ SemSegContextTree3D::SemSegContextTree3D (
 
     this->lfcw                = NULL;
     this->firstiteration      = true;
-    this->run3Dseg            = conf->gB ( section, "run_3dseg", false );
     this->maxSamples          = conf->gI ( section, "max_samples", 2000 );
     this->minFeats            = conf->gI ( section, "min_feats", 50 );
     this->maxDepth            = conf->gI ( section, "max_depth", 10 );
@@ -516,7 +516,7 @@ void SemSegContextTree3D::train ( const LabeledSet * trainp )
     timer.start();
 
     vector<int> zsizeVec;
-    getDepthVector ( trainp, zsizeVec, run3Dseg );
+    SemSegTools::getDepthVector ( trainp, zsizeVec, run3Dseg );
 
     //FIXME: memory usage
     vector<MultiChannelImage3DT<double> > allfeats;   // Feature Werte
@@ -1597,7 +1597,7 @@ void SemSegContextTree3D::classify (
                 }
 
 #ifdef VISUALIZE
-        getProbabilityMap( probabilities );
+        saveProbabilityMapAsImage( probabilities );
 #endif
     }
     else

+ 8 - 6
semseg/SemSegContextTree3D.h

@@ -41,9 +41,6 @@ private:
   /** local features */
   LocalFeatureColorWeijer *lfcw;
 
-  /** whether to run in 3D mode or not */
-  bool run3Dseg;
-
   /** whether to use a particular feature type or not */
   bool useFeat0, useFeat1, useFeat2, useFeat3, useFeat4;
 
@@ -233,9 +230,14 @@ public:
   void train ( const MultiDataset *md );
 
   // deprecated stuff
-  virtual void semanticseg ( OBJREC::CachedExample *ce,
-                             NICE::ImageT<int> & segresult,
-                             NICE::MultiChannelImageT<double> & probabilities )
+  void semanticseg ( CachedExample *ce,
+                     NICE::ImageT<int> & segresult,
+                     NICE::MultiChannelImageT<double> & probabilities )
+  {}
+
+  void semanticseg ( CachedExample *ce,
+                     NICE::MultiChannelImageT<int> & segresult,
+                     NICE::MultiChannelImage3DT<double> & probabilities )
   {}
 
   bool active3DMode ()

+ 5 - 0
semseg/SemSegCsurka.h

@@ -235,6 +235,11 @@ class SemSegCsurka : public SemanticSegmentation
                        NICE::ImageT<int> & segresult,
                        NICE::MultiChannelImageT<double> & probabilities );
 
+    void semanticseg ( CachedExample *ce,
+                       NICE::MultiChannelImageT<int> & segresult,
+                       NICE::MultiChannelImage3DT<double> & probabilities )
+    {}
+
     /** this procedure is equal semanticseg, if there is no post process
     * @param ce image data
     * @param segresult result of the semantic segmentation with a label for each pixel

+ 5 - 0
semseg/SemSegLocal.h

@@ -40,6 +40,11 @@ class SemSegLocal : public SemanticSegmentation
                        NICE::ImageT<int> & segresult,
                        NICE::MultiChannelImageT<double> & probabilities );
 
+    void semanticseg ( CachedExample *ce,
+                       NICE::MultiChannelImageT<int> & segresult,
+                       NICE::MultiChannelImage3DT<double> & probabilities )
+    {}
+
 };
 
 

+ 5 - 0
semseg/SemSegNovelty.h

@@ -245,6 +245,11 @@ class SemSegNovelty : public SemanticSegmentation
                        NICE::ImageT<int> & segresult,
                        NICE::MultiChannelImageT<double> & probabilities );
 
+    void semanticseg ( CachedExample *ce,
+                       NICE::MultiChannelImageT<int> & segresult,
+                       NICE::MultiChannelImage3DT<double> & probabilities )
+    {}
+
     /**
      * @brief visualize a specific region in the original image
      *

+ 5 - 0
semseg/SemSegNoveltyBinary.h

@@ -197,6 +197,11 @@ class SemSegNoveltyBinary : public SemanticSegmentation
                        NICE::ImageT<int> & segresult,
                        NICE::MultiChannelImageT<double> & probabilities );
     
+    void semanticseg ( CachedExample *ce,
+                       NICE::MultiChannelImageT<int> & segresult,
+                       NICE::MultiChannelImage3DT<double> & probabilities )
+    {}
+
     /**
      * @brief visualize a specific region in the original image
      *

+ 94 - 57
semseg/SemSegObliqueTree.cpp

@@ -55,52 +55,53 @@ void SemSegObliqueTree::preprocessChannels (
         CachedExample *ce,
         bool isColor ) const
 {
-    NICE::MultiChannelImageT<int> * img = NULL;
-    NICE::MultiChannelImageT<double> * imgD = NULL;
+    NICE::MultiChannelImage3DT<int> * img = NULL;
+    NICE::MultiChannelImage3DT<double> * imgD = NULL;
 
-    imgD    = & ce->getDChannel( CachedExample::D_EOH );
+    imgD = & ce->getDChannel( CachedExample::D_EOH );
     assert( imgD->channels() == 0 );
 
     if ( isColor )
     {
         img = & ce->getIChannel( CachedExample::I_COLOR );
 
-        imgD->reInit ( img->width(), img->height(), 3 );
+        imgD->reInit ( img->width(), img->height(), img->depth(), 3 );
 
-        for ( int y = 0; y < img->height(); y++ )
-            for ( int x = 0; x < img->width(); x++ )
-            {
-                double r = (double)img->get( x, y, 0);
-                double g = (double)img->get( x, y, 1);
-                double b = (double)img->get( x, y, 2);
-
-                if ( colorMode == 1 )
-                {
-                    double h,s,v;
-                    ColorConversion::ccRGBtoHSV(r, g, b, &h, &s, &v);
-                    imgD->set( x, y, h, 0);
-                    imgD->set( x, y, s, 1);
-                    imgD->set( x, y, v, 2);
-                }
-                else if ( colorMode == 2 )
+        for ( int z = 0; z < img->depth(); z++ )
+            for ( int y = 0; y < img->height(); y++ )
+                for ( int x = 0; x < img->width(); x++ )
                 {
-                    double cX, cY, cZ, cL, ca, cb;
-                    r /= 255.0;
-                    g /= 255.0;
-                    b /= 255.0;
-                    ColorConversion::ccRGBtoXYZ( r, g, b, &cX, &cY, &cZ, 0 );
-                    ColorConversion::ccXYZtoCIE_Lab( cX, cY, cZ, &cL, &ca, &cb, 0 );
-                    imgD->set( x, y, cL, 0);
-                    imgD->set( x, y, ca, 1);
-                    imgD->set( x, y, cb, 2);
+                    double r = (double)img->get( x, y, z, 0);
+                    double g = (double)img->get( x, y, z, 1);
+                    double b = (double)img->get( x, y, z, 2);
+
+                    if ( colorMode == 1 )
+                    {
+                        double h,s,v;
+                        ColorConversion::ccRGBtoHSV(r, g, b, &h, &s, &v);
+                        imgD->set( x, y, z, h, 0);
+                        imgD->set( x, y, z, s, 1);
+                        imgD->set( x, y, z, v, 2);
+                    }
+                    else if ( colorMode == 2 )
+                    {
+                        double cX, cY, cZ, cL, ca, cb;
+                        r /= 255.0;
+                        g /= 255.0;
+                        b /= 255.0;
+                        ColorConversion::ccRGBtoXYZ( r, g, b, &cX, &cY, &cZ, 0 );
+                        ColorConversion::ccXYZtoCIE_Lab( cX, cY, cZ, &cL, &ca, &cb, 0 );
+                        imgD->set( x, y, z, cL, 0);
+                        imgD->set( x, y, z, ca, 1);
+                        imgD->set( x, y, z, cb, 2);
+                    }
+                    else
+                    {
+                        imgD->set( x, y, z, r/255.0, 0 );
+                        imgD->set( x, y, z, g/255.0, 1 );
+                        imgD->set( x, y, z, b/255.0, 2 );
+                    }
                 }
-                else
-                {
-                    imgD->set( x, y, r/255.0, 0 );
-                    imgD->set( x, y, g/255.0, 1 );
-                    imgD->set( x, y, b/255.0, 2 );
-                }
-            }
 
         // remove integer channels
         img->freeData();
@@ -110,18 +111,18 @@ void SemSegObliqueTree::preprocessChannels (
         img = & ce->getIChannel( CachedExample::I_GRAYVALUES );
 
         // gray values to range [0,1]
-        imgD->reInit ( img->width(), img->height(), 1 );
+        imgD->reInit ( img->width(), img->height(), img->depth(), 1 );
 
-        for ( int y = 0; y < img->height(); y++ )
-            for ( int x = 0; x < img->width(); x++ )
-            {
-                double g = (double)img->get( x, y, 0) / 255.0;
-                imgD->set( x, y, g, 0);
-            }
+        for ( int z = 0; z < img->depth(); z++ )
+            for ( int y = 0; y < img->height(); y++ )
+                for ( int x = 0; x < img->width(); x++ )
+                {
+                    double g = (double)img->get( x, y, z, 0) / 255.0;
+                    imgD->set( x, y, z, g, 0);
+                }
 
         // remove integer channel
         img->freeData();
-
     }
 
     img = NULL;
@@ -130,7 +131,7 @@ void SemSegObliqueTree::preprocessChannels (
 
 
 void SemSegObliqueTree::initFromConfig( const Config *_conf,
-                                         const string &s_confSection )
+                                        const string &s_confSection )
 {
     conf = _conf;
     saveLoadData = conf->gB ( s_confSection, "save_load_data", false );
@@ -146,7 +147,7 @@ void SemSegObliqueTree::train ( const MultiDataset *md )
 {
     if ( saveLoadData && FileMgt::fileExists( fileLocation ) )
     {
-        read( fileLocation );
+        read( fileLocation, 1 );
     }
     else
     {
@@ -162,7 +163,8 @@ void SemSegObliqueTree::train ( const MultiDataset *md )
           * ( ( *md ) ["train"] ),
           *classNames,
           examples,
-          imgexamples );
+          imgexamples,
+          run3Dseg );
 
         assert ( examples.size() > 0 );
 
@@ -178,7 +180,7 @@ void SemSegObliqueTree::train ( const MultiDataset *md )
         fpc->train( fp, examples);
 
         // save trained classifier to file
-        if (saveLoadData) save( fileLocation );
+        if (saveLoadData) save( fileLocation, 1 );
 
         // Cleaning up
         for ( vector<CachedExample *>::iterator i = imgexamples.begin();
@@ -212,15 +214,50 @@ void SemSegObliqueTree::semanticseg(
 
     Example pce ( ce, 0, 0 );
     for ( int y = 0 ; y < ysize ; y++ )
-      for ( int x = 0 ; x < xsize ; x++ )
-      {
-        pce.x = x ;
-        pce.y = y;
-        ClassificationResult r = fpcrf->classify ( pce );
-        segresult.setPixel ( x, y, r.classno );
-        for ( int i = 0 ; i < ( int ) probabilities.channels(); i++ )
-          probabilities[i](x,y) = r.scores[i];
-      }
+        for ( int x = 0 ; x < xsize ; x++ )
+        {
+            pce.x = x;
+            pce.y = y;
+            ClassificationResult r = fpcrf->classify ( pce );
+            segresult.setPixel ( x, y, r.classno );
+            for ( int i = 0 ; i < ( int ) probabilities.channels(); i++ )
+                probabilities[i](x,y) = r.scores[i];
+        }
+}
+
+/** classification function 3d */
+void SemSegObliqueTree::semanticseg(
+        OBJREC::CachedExample *ce,
+        NICE::MultiChannelImageT<int> &segresult,
+        NICE::MultiChannelImage3DT<double> &probabilities )
+{
+    // for speed optimization
+    FPCRandomForests *fpcrf = dynamic_cast<FPCRandomForests *> ( fpc );
+
+    int xsize, ysize, zsize;
+    ce->getImageSize3 ( xsize, ysize, zsize );
+    probabilities.reInit ( xsize, ysize, zsize, classNames->getMaxClassno() + 1 );
+    segresult.reInit ( xsize, ysize, (unsigned int)zsize );
+
+    vector<DecisionTree *> forest = fpcrf->getForest ();
+    DecisionNode *root = forest[0]->getRoot ();
+    ConvolutionFeature* cf = dynamic_cast<ConvolutionFeature*> (root->f);
+
+    preprocessChannels( ce, cf->isColorMode() ); //FIXME!!!
+
+    Example pce ( ce, 0, 0, 0 );
+    for ( int z = 0 ; z < zsize; z++ )
+        for ( int y = 0 ; y < ysize ; y++ )
+            for ( int x = 0 ; x < xsize ; x++ )
+            {
+                pce.x = x;
+                pce.y = y;
+                pce.z = z;
+                ClassificationResult r = fpcrf->classify ( pce );
+                segresult.set ( x, y, r.classno, (unsigned int)z );
+                for ( int i = 0 ; i < ( int ) probabilities.channels(); i++ )
+                    probabilities.set ( x, y, z, r.scores[i], i );
+            }
 }
 
 ///////////////////// INTERFACE PERSISTENT /////////////////////

+ 13 - 2
semseg/SemSegObliqueTree.h

@@ -52,8 +52,9 @@ class SemSegObliqueTree : public SemanticSegmentation
         SemSegObliqueTree ();
 
         /** config constructor */
-        SemSegObliqueTree ( const NICE::Config *conf,
-                                  const ClassNames *classNames );
+        SemSegObliqueTree (
+                const NICE::Config *conf,
+                const ClassNames *classNames );
 
         /** simple destructor */
         virtual ~SemSegObliqueTree();
@@ -85,6 +86,16 @@ class SemSegObliqueTree : public SemanticSegmentation
                            NICE::ImageT<int> &segresult,
                            NICE::MultiChannelImageT<double> &probabilities );
 
+        /**
+         * Classify each voxel of a 3D image (image stack)
+         * @author Sven Sickert
+         * @param ce 3d image data
+         * @param segresult segmentation results (output)
+         * @param probabilities probabilities for each pixel (output)
+         */
+        void semanticseg ( OBJREC::CachedExample *ce,
+                           NICE::MultiChannelImageT<int> & segresult,
+                           NICE::MultiChannelImage3DT<double> & probabilities );
 
         ///////////////////// INTERFACE PERSISTENT /////////////////////
         // interface specific methods for store and restore

+ 174 - 75
semseg/SemSegTools.cpp

@@ -8,6 +8,7 @@
 #include <iostream>
 #include <iomanip>
 
+#include "core/basics/StringTools.h"
 #include "SemSegTools.h"
 
 using namespace OBJREC;
@@ -99,7 +100,7 @@ void SemSegTools::computeClassificationStatistics(
     std::cout << "\nPERFORMANCE" << std::endl;
     std::cout << "###########\n" << std::endl;
 
-    double overallTrue = confMat.trace();
+    double accuracy = confMat.trace();
     double sumAll  = 0.0;
 
     // overall recognition rate
@@ -107,31 +108,48 @@ void SemSegTools::computeClassificationStatistics(
         for ( int c = 0; c < (int) confMat.cols(); c++ )
             sumAll += confMat( r, c );
 
-    overallTrue /= sumAll;
+    accuracy /= sumAll;
 
-    double precision = 0.0, recall = 0.0, f1score = 0.0, iuScore = 0.0;
+    double prec = 0.0, rec = 0.0, f1score = 0.0, iuScore = 0.0;
 
-    // binary classification
+    // classification
+    int normConst = classMappingInv.size();
     for ( int c = 0; c < classMappingInv.size(); c++ )
     {
+        std::cout << "Class " << classNames.text( classMappingInv[c] ) << ":" << std::endl;
+
         double precBase = 0.0, recBase = 0.0;
+        // row-wise sum
         for ( int r = 0; r < classMappingInv.size(); r++ )
             precBase += confMat(r,c);
 
+        // column-wise sum
         for ( int cc = 0; cc < classMappingInv.size(); cc++ )
             recBase += confMat(c,cc);
 
-        precision += confMat(c,c) / precBase;
-        recall += confMat(c,c) / recBase;
-        iuScore += confMat(c,c) / (precBase+recBase-confMat(c,c));
+        double precClass = 0, recClass = 0;
+
+        if (precBase > 0) precClass = confMat(c,c) / precBase;
+
+        if (recBase > 0) recClass = confMat(c,c) / recBase;
+
+        std::cout << "  Precision: " << precClass << std::endl;
+        std::cout << "  Recall:    " << recClass << std::endl;
+        prec += precClass;
+        rec += recClass;
+
+        if (precBase > 0 && recBase > 0)
+            iuScore += confMat(c,c) / (precBase+recBase-confMat(c,c));
+        else
+            normConst--;
     }
 
-    precision /= classMappingInv.size();
-    recall /= classMappingInv.size();
-    iuScore /= classMappingInv.size();
-    f1score = 2.0*(precision*recall)/(precision+recall);
+    prec /= (double)normConst;
+    rec /= (double)normConst;
+    iuScore /= (double)normConst;
+    f1score = 2.0*(prec*rec)/(prec+rec);
 
-    // normalizing confMat using rows
+    // row-wise normalization of confMat
     for ( int r = 0 ; r < (int) confMat.rows() ; r++ )
     {
         double sum = 0.0;
@@ -176,12 +194,12 @@ void SemSegTools::computeClassificationStatistics(
     }
 
     // print classification statistics
-    std::cout << "\nAccuracy: " << overallTrue;
-    std::cout << "\nPrecision: " << precision;
-    std::cout << "\nRecall: " << recall;
+    std::cout << "\nAccuracy: " << accuracy;
+    std::cout << "\nPrecision: " << prec;
+    std::cout << "\nRecall: " << rec;
     std::cout << "\nF1Score: " << f1score;
     std::cout << "\nIU: " << iuScore;
-    std::cout << "\n\nAverage Recognition Rate: " << confMat.trace() / (double)classMappingInv.size();
+    //std::cout << "\n\nAverage Recognition Rate: " << confMat.trace() / (double)classMappingInv.size();
     //std::cout << "\nLower Bound: " << 1.0 /(double)classMappingInv.size();
     std::cout << std::endl;
 }
@@ -235,98 +253,179 @@ void SemSegTools::saveResultsToImageFile(
     outStr = out.str();
 }
 
-void SemSegTools::collectTrainingExamples ( 
+void SemSegTools::getDepthVector (
+        const LabeledSet *Files,
+        std::vector<int> & depthVec,
+        const bool run3Dseg )
+{
+    std::string oldName;
+    int zsize = 0;
+    bool isInit = false;
+
+    for (LabeledSet::const_iterator it = Files->begin(); it != Files->end(); it++)
+    {
+        for (std::vector<ImageInfo *>::const_iterator jt = it->second.begin();
+             jt != it->second.end(); jt++)
+        {
+            ImageInfo & info = *(*jt);
+            std::string file = info.img();
+
+            std::vector< std::string > list;
+            StringTools::split ( file, '/', list );
+            std::string filename = list.back();
+            uint found = filename.find_last_of ( "_" );
+            if (run3Dseg && found < filename.size() && found-3 > 0 )
+            {
+                std::string curName = filename.substr ( found-3,3 );
+                if ( !isInit )
+                {
+                    oldName = curName;
+                    isInit = true;
+                }
+                if ( curName.compare ( oldName ) == 0 ) // if strings match up
+                {
+                    zsize++;
+                }
+                else
+                {
+                    depthVec.push_back ( zsize );
+                    zsize = 1;
+                    oldName = curName;
+                }
+            }
+            else
+            {
+                zsize = 1;
+                depthVec.push_back ( zsize );
+            }
+
+        }
+    }
+    depthVec.push_back ( zsize );
+}
+
+void SemSegTools::collectTrainingExamples (
         const Config * conf,
         const std::string & section,
         const LabeledSet & train,
         const ClassNames & cn,
         Examples & examples,
-        vector<CachedExample *> & imgexamples )
+        vector<CachedExample *> & imgexamples,
+        const bool run3Dseg )
 {
     assert ( train.count() > 0 );
     examples.clear();
     imgexamples.clear();
 
+    vector<int> zsizeVec;
+    SemSegTools::getDepthVector ( &train, zsizeVec, run3Dseg );
+
     int grid_size_x = conf->gI(section, "grid_size_x", 5 );
     int grid_size_y = conf->gI(section, "grid_size_y", 5 );
+    int grid_size_z = conf->gI(section, "grid_size_z", 5 );
     int grid_border_x = conf->gI(section, "grid_border_x", 20 );
     int grid_border_y = conf->gI(section, "grid_border_y", 20 );
+    int grid_border_z = conf->gI(section, "grid_border_z", 20 );
+
+    if (!run3Dseg)
+    {
+        grid_size_z = 1;
+        grid_border_z = 0;
+    }
 
     std::string selection = conf->gS(section, "train_selection" );
 
     set<int> classnoSelection;
     cn.getSelection ( selection, classnoSelection );
-    
+
     bool useExcludedAsBG = conf->gB(section, "use_excluded_as_background", false );
 
     int backgroundClassNo = 0;
-    
+
     if ( useExcludedAsBG )
     {
         backgroundClassNo = cn.classno("various");
         assert ( backgroundClassNo >= 0 );
     }
 
-    LOOP_ALL_S (train)
-    {
-        EACH_INFO(image_classno,imgInfo);
-        std::string imgfn = imgInfo.img();
-
-        if ( ! imgInfo.hasLocalizationInfo() ) {
-            std::cerr << "WARNING: NO localization info found for "
-                      << imgfn << " !" << std::endl;
-            continue;
-        }
-
-        int xsize, ysize;
-        CachedExample *ce = new CachedExample ( imgfn );
-        ce->getImageSize ( xsize, ysize );
-        imgexamples.push_back ( ce );
+    int depthCount = 0;
+    int imgCounter = 0;
+    vector<std::string> filelist;
+    NICE::MultiChannelImageT<int> pixelLabels;
 
-        const LocalizationResult *locResult = imgInfo.localization();
-        if ( locResult->size() <= 0 ) {
-            std::cerr << "WARNING: NO ground truth polygons found for "
-                      << imgfn << " !" << std::endl;
-            continue;
-        }
-
-        std::cerr << "SemSegTools: Collecting pixel examples from localization info: "
-                  << imgfn << std::endl;
+    for (LabeledSet::const_iterator it = train.begin(); it != train.end(); it++)
+    {
+        for (std::vector<ImageInfo *>::const_iterator jt = it->second.begin();
+             jt != it->second.end(); jt++)
+        {
+            ImageInfo & info = *(*jt);
+            std::string file = info.img();
+            filelist.push_back ( file );
+            depthCount++;
+
+            const LocalizationResult *locResult = info.localization();
+
+            // getting groundtruth
+            NICE::ImageT<int> pL;
+            pL.resize ( locResult->xsize, locResult->ysize );
+            pL.set ( 0 );
+            locResult->calcLabeledImage ( pL, cn.getBackgroundClass() );
+            pixelLabels.addChannel ( pL );
+
+            if ( locResult->size() <= 0 ) {
+                std::cerr << "WARNING: NO ground truth polygons found for "
+                          << file << " !" << std::endl;
+                continue;
+            }
 
-        NICE::ImageT<int> pixelLabels (xsize, ysize);
-        pixelLabels.set(0);
-        locResult->calcLabeledImage ( pixelLabels, cn.getBackgroundClass() );
+            std::cerr << "SemSegTools: Collecting pixel examples from localization info: "
+                      << file << std::endl;
 
-#ifdef DEBUG_LOCALIZATION
-        NICE::Image img (imgfn);
-        showImage(img);
-        showImage(pixelLabels);
-#endif
-
-        Example pce ( ce, 0, 0 );
-        for ( int x = 0 ; x < xsize ; x += grid_size_x )
-            for ( int y = 0 ; y < ysize ; y += grid_size_y )
+            int depthBoundary = 0;
+            if ( run3Dseg )
             {
-                if ( (x >= grid_border_x) &&
-                     ( y >= grid_border_y ) && ( x < xsize - grid_border_x ) &&
-                     ( y < ysize - grid_border_x ) )
-                {
-                    pce.x = x; pce.y = y;
-                    int classno = pixelLabels.getPixel(x,y);
-
-                    if ( classnoSelection.find(classno) != classnoSelection.end() ) {
-                        examples.push_back ( pair<int, Example> (
-                                                 classno,
-                                                 pce // FIXME: offset handling
-                                                 ) );
-                    } else if ( useExcludedAsBG ) {
-                        examples.push_back ( pair<int, Example> (
-                                                 backgroundClassNo,
-                                                 pce // FIXME: offset handling
-                                                 ) );
-                    }
-                }
+                depthBoundary = zsizeVec[imgCounter];
             }
+
+            if ( depthCount < depthBoundary ) continue;
+
+            int xsize, ysize, zsize;
+            CachedExample *ce = new CachedExample ( filelist );
+            ce->getImageSize3 ( xsize, ysize, zsize );
+            imgexamples.push_back ( ce );
+
+            // drawing actual examples
+            Example pce ( ce, 0, 0, 0 );
+            for ( int z = 0; z < zsize; z += grid_size_z )
+                for ( int x = 0 ; x < xsize ; x += grid_size_x )
+                    for ( int y = 0 ; y < ysize ; y += grid_size_y )
+                        if ( ( x >= grid_border_x ) &&
+                             ( y >= grid_border_y ) &&
+                             ( z >= grid_border_z ) &&
+                             ( x < xsize - grid_border_x ) &&
+                             ( y < ysize - grid_border_y ) &&
+                             ( z < zsize - grid_border_z ) )
+                        {
+                            pce.x = x; pce.y = y; pce.z = z;
+                            int classno = pixelLabels.get(x,y,(unsigned int)z);
+
+                            if ( classnoSelection.find(classno) != classnoSelection.end() )
+                            {
+                                examples.push_back (
+                                            pair<int, Example> ( classno, pce ) );
+                            } else if ( useExcludedAsBG )
+                            {
+                                examples.push_back (
+                                            pair<int, Example> ( backgroundClassNo, pce ) );
+                            }
+                        }
+
+            // prepare for new 3D image
+            filelist.clear();
+            pixelLabels.reInit ( 0,0,0 );
+            depthCount = 0;
+            imgCounter++;
+        }
     }
 
     std::cerr << "total number of examples: " << (int)examples.size() << std::endl;

+ 15 - 2
semseg/SemSegTools.h

@@ -89,6 +89,18 @@ class SemSegTools
             const std::string & file,
             std::string & outStr );
 
+    /**
+     * @brief Collect information about the depth of 3d images
+     * @author Sven Sickert
+     * @param Files a labeled set of data
+     * @param depthVec output of depth values
+     * @param run3dseg whether slice counting is necessary or not
+     */
+    static void getDepthVector (
+            const LabeledSet *Files,
+            std::vector<int> & depthVec,
+            const bool run3dseg );
+
     /** collect pixel-wise training examples
         from a set of images
         @param conf includes settings about grid size etc.
@@ -97,6 +109,7 @@ class SemSegTools
         @param cn classNames object
         @param examples resulting pixel-wise examples
         @param imgexamples image based caching structure referenced by pixel-wise examples
+        @param run3Dseg whether to run in 3D segmentation mode or not
     */
     static void collectTrainingExamples (
             const NICE::Config * conf,
@@ -104,8 +117,8 @@ class SemSegTools
             const LabeledSet & train,
             const ClassNames & cn,
             Examples & examples,
-            std::vector<CachedExample *> & imgexamples );
-
+            std::vector<CachedExample *> & imgexamples,
+            const bool run3Dseg = false );
 };
 
 

+ 268 - 383
semseg/SemanticSegmentation.cpp

@@ -7,10 +7,8 @@
 */
 #include "SemanticSegmentation.h"
 
-#include <core/basics/StringTools.h>
-
-#include <vislearning/baselib/Preprocess.h>
-#include <vislearning/baselib/Globals.h>
+#include "vislearning/baselib/Preprocess.h"
+#include "vislearning/baselib/Globals.h"
 
 #include <iostream>
 
@@ -25,27 +23,27 @@ using namespace NICE;
 SemanticSegmentation::SemanticSegmentation ( )
     : iterationCountSuffix(1)
 {
-  this->imagetype = IMAGETYPE_RGB;
-  
-  this->classNames = new ClassNames();
-
+    this->imagetype = IMAGETYPE_RGB;
+    this->classNames = new ClassNames();
+    this->run3Dseg = false;
+    this->coarseMode = false;
 }
 
 SemanticSegmentation::SemanticSegmentation ( const Config *conf,
                                              const ClassNames *classNames )
     : iterationCountSuffix(1)
 {
-  ///////////
-  // same code as in empty constructor - duplication can be avoided with C++11 allowing for constructor delegation
-  /////////// 
-  
-  ///////////
-  // here comes the new code part different from the empty constructor
-  /////////// 
-
-  this->classNames = classNames; 
-  
-  this->initFromConfig( conf ); 
+    ///////////
+    // same code as in empty constructor - duplication can be avoided with C++11 allowing for constructor delegation
+    ///////////
+
+    ///////////
+    // here comes the new code part different from the empty constructor
+    ///////////
+
+    this->classNames = classNames;
+
+    this->initFromConfig( conf );
 }
 
 SemanticSegmentation::~SemanticSegmentation()
@@ -54,60 +52,73 @@ SemanticSegmentation::~SemanticSegmentation()
 
 void SemanticSegmentation::initFromConfig(const Config* conf, const string& s_confSection)
 {
-  std::string imagetype_s = conf->gS ( "main", "imagetype", "rgb" );
-  coarseMode = conf->gB( "main", "coarse_mode", false );
-
-  if ( imagetype_s == "rgb" )
-    imagetype = IMAGETYPE_RGB;
-  else if ( imagetype_s == "gray" )
-    imagetype = IMAGETYPE_GRAY;
-  else {
-    fprintf ( stderr, "SemanticSegmentation:: unknown image type option\n" );
-    exit ( -1 );
-  }
-
-  // dangerous!!!
-  Preprocess::Init ( conf );
+    std::string imagetype_s = conf->gS ( "main", "imagetype", "rgb" );
+    coarseMode = conf->gB( "main", "coarse_mode", false );
+    run3Dseg = conf->gB( "main", "run_3dseg", false );
+
+    if ( imagetype_s == "rgb" )
+        imagetype = IMAGETYPE_RGB;
+    else if ( imagetype_s == "gray" )
+        imagetype = IMAGETYPE_GRAY;
+    else {
+        fprintf ( stderr, "SemanticSegmentation:: unknown image type option\n" );
+        exit ( -1 );
+    }
+
+    // dangerous!!!
+    Preprocess::Init ( conf );
 }
 
 ///////////////////// ///////////////////// /////////////////////
 //                      SEGMENTATION STUFF
 ///////////////////// ///////////////////// /////////////////////
 
-void SemanticSegmentation::semanticseg ( const std::string & filename,
-    NICE::ImageT<int> & segresult,
-    NICE::MultiChannelImageT<double> & probabilities )
+void SemanticSegmentation::semanticseg (
+        const std::string & filename,
+        NICE::ImageT<int> & segresult,
+        NICE::MultiChannelImageT<double> & probabilities )
 {
-  Globals::setCurrentImgFN ( filename );
-  CachedExample *ce;
-  if ( imagetype == IMAGETYPE_RGB )
-  {
-    NICE::ColorImage img = Preprocess::ReadImgAdvRGB ( filename );
-    ce = new CachedExample ( img );
-  } else {
-
-    NICE::Image img = Preprocess::ReadImgAdv ( filename );
-    ce = new CachedExample ( img );
-  }
-#ifdef DEBUG_PRINTS
-  fprintf ( stderr, "Starting Semantic Segmentation !\n" );
-#endif
-  this->semanticseg ( ce, segresult, probabilities );
-  delete ce;
+    Globals::setCurrentImgFN ( filename );
+    CachedExample *ce;
+    if ( imagetype == IMAGETYPE_RGB )
+    {
+        NICE::ColorImage img = Preprocess::ReadImgAdvRGB ( filename );
+        ce = new CachedExample ( img );
+    } else {
+
+        NICE::Image img = Preprocess::ReadImgAdv ( filename );
+        ce = new CachedExample ( img );
+    }
+
+    this->semanticseg ( ce, segresult, probabilities );
+    delete ce;
+}
+
+void SemanticSegmentation::semanticseg (
+        const std::vector<std::string> & filelist,
+        NICE::MultiChannelImageT<int> & segresult,
+        NICE::MultiChannelImage3DT<double> & probabilities )
+{
+    //NICE::MultiChannelImage3DT<int> img;
+    //make3DImage( filelist, img );
+    CachedExample *ce = new CachedExample (filelist);
+
+    this->semanticseg ( ce, segresult, probabilities );
+    delete ce;
 }
 
 void SemanticSegmentation::classify ( const std::vector<std::string> & filelist,
                                       NICE::MultiChannelImageT<int> & segresult,
                                       NICE::MultiChannelImage3DT<double> & probabilities )
 {
-  for ( int it = 0; it < ( int ) filelist.size(); it++ )
-  {
-    NICE::MultiChannelImageT<double> probs;
-    NICE::ImageT<int> res ( segresult.width(), segresult.height() );
-    this->semanticseg( filelist[it], res, probs );
-    probabilities.addChannel( probs );
-    segresult.addChannel( res );
-  }
+    for ( int it = 0; it < ( int ) filelist.size(); it++ )
+    {
+        NICE::MultiChannelImageT<double> probs;
+        NICE::ImageT<int> res ( segresult.width(), segresult.height() );
+        this->semanticseg( filelist[it], res, probs );
+        probabilities.addChannel( probs );
+        segresult.addChannel( res );
+    }
 }
 
 ///////////////////// ///////////////////// /////////////////////
@@ -116,298 +127,172 @@ void SemanticSegmentation::classify ( const std::vector<std::string> & filelist,
 void SemanticSegmentation::convertLSetToSparseExamples ( Examples &examples, LabeledSetVector &lvec )
 {
 #ifdef DEBUG_PRINTS
-  cout << "SemSegRegionBased::convertLSetToExamples starts" << endl;
+    cout << "SemSegRegionBased::convertLSetToExamples starts" << endl;
 #endif
-  for ( map< int, vector<NICE::Vector *> >::iterator iter = lvec.begin(); iter != lvec.end(); ++iter )
-  {
-    for ( int j = 0; j < ( int ) iter->second.size(); j++ )
+    for ( map< int, vector<NICE::Vector *> >::iterator iter = lvec.begin(); iter != lvec.end(); ++iter )
     {
-      Vector &tmp = * ( iter->second[j] );
-      int dim = tmp.size();
-      SparseVector *vec = new SparseVector ( dim );
-      for ( int j = 0; j < dim; j++ )
-      {
-        if ( tmp[j] != 0.0 )
+        for ( int j = 0; j < ( int ) iter->second.size(); j++ )
         {
-          ( *vec ) [j] = tmp[j];
+            Vector &tmp = * ( iter->second[j] );
+            int dim = tmp.size();
+            SparseVector *vec = new SparseVector ( dim );
+            for ( int j = 0; j < dim; j++ )
+            {
+                if ( tmp[j] != 0.0 )
+                {
+                    ( *vec ) [j] = tmp[j];
+                }
+            }
+            Example ex;
+            ex.svec = vec;
+            examples.push_back ( pair<int, Example> ( iter->first, ex ) );
         }
-      }
-      Example ex;
-      ex.svec = vec;
-      examples.push_back ( pair<int, Example> ( iter->first, ex ) );
     }
-  }
-  lvec.clear();
+    lvec.clear();
 #ifdef DEBUG_PRINTS
-  cout << "SemSegRegionBased::convertLSetToExamples finished" << endl;
+    cout << "SemSegRegionBased::convertLSetToExamples finished" << endl;
 #endif
 }
 
 void SemanticSegmentation::convertLSetToExamples ( Examples &examples, LabeledSetVector &lvec, const bool & removeOldDataPointer )
 {
 #ifdef DEBUG_PRINTS
-  cout << "SemSegRegionBased::convertLSetToExamples starts" << endl;
+    cout << "SemSegRegionBased::convertLSetToExamples starts" << endl;
 #endif
-  for ( map< int, vector<NICE::Vector *> >::iterator iter = lvec.begin(); iter != lvec.end(); ++iter )
-  {
-    for ( int j = 0; j < (int)iter->second.size(); j++ )
+    for ( map< int, vector<NICE::Vector *> >::iterator iter = lvec.begin(); iter != lvec.end(); ++iter )
     {
-      NICE::Vector *vec = new NICE::Vector ( * ( iter->second[j] ) );
-      Example ex ( vec );
-      examples.push_back ( pair<int, Example> ( iter->first, ex ) );
+        for ( int j = 0; j < (int)iter->second.size(); j++ )
+        {
+            NICE::Vector *vec = new NICE::Vector ( * ( iter->second[j] ) );
+            Example ex ( vec );
+            examples.push_back ( pair<int, Example> ( iter->first, ex ) );
+        }
     }
-  }
 
-  if (!removeOldDataPointer)
-  {
-    //NOTE this is only useful, if our classifier does NOT need the data explicitely
-    lvec.clear();
-  }
-  else
-  {
-    lvec.removePointersToDataWithoutDeletion();
-    //after setting all the pointers to NULL, we can savely clear the LSet without deleting the previously
-    //stored features, which might be needed somewhere else, e.g., in the VCNearestNeighbour
-    lvec.clear();
-  }
+    if (!removeOldDataPointer)
+    {
+        //NOTE this is only useful, if our classifier does NOT need the data explicitely
+        lvec.clear();
+    }
+    else
+    {
+        lvec.removePointersToDataWithoutDeletion();
+        //after setting all the pointers to NULL, we can savely clear the LSet without deleting the previously
+        //stored features, which might be needed somewhere else, e.g., in the VCNearestNeighbour
+        lvec.clear();
+    }
 
 #ifdef DEBUG_PRINTS
-  cout << "SemSegRegionBased::convertLSetToExamples finished" << endl;
+    cout << "SemSegRegionBased::convertLSetToExamples finished" << endl;
 #endif
 }
 
 void SemanticSegmentation::convertExamplesToLSet ( Examples &examples, LabeledSetVector &lvec )
 {
 #ifdef DEBUG_PRINTS
-  cout << "SemSegRegionBased::convertExamplesToLSet starts" << endl;
+    cout << "SemSegRegionBased::convertExamplesToLSet starts" << endl;
 #endif
-  lvec.clear();
-  for ( int i = 0; i < ( int ) examples.size(); i++ )
-  {
-    if ( examples[i].second.vec != NULL )
-    {
-      lvec.add ( examples[i].first, *examples[i].second.vec );
-      delete examples[i].second.vec;
-      examples[i].second.vec = NULL;
-    }
-    else
+    lvec.clear();
+    for ( int i = 0; i < ( int ) examples.size(); i++ )
     {
-      if ( examples[i].second.svec != NULL )
-      {
-        NICE::Vector v;
-        examples[i].second.svec->convertToVectorT(v);
-        lvec.add ( examples[i].first, v );
-        delete examples[i].second.svec;
-        examples[i].second.svec = NULL;        
-      }
-      else
-      {
-        throw ( "no features for LabeledSet" );
-      }
-    }
+        if ( examples[i].second.vec != NULL )
+        {
+            lvec.add ( examples[i].first, *examples[i].second.vec );
+            delete examples[i].second.vec;
+            examples[i].second.vec = NULL;
+        }
+        else
+        {
+            if ( examples[i].second.svec != NULL )
+            {
+                NICE::Vector v;
+                examples[i].second.svec->convertToVectorT(v);
+                lvec.add ( examples[i].first, v );
+                delete examples[i].second.svec;
+                examples[i].second.svec = NULL;
+            }
+            else
+            {
+                throw ( "no features for LabeledSet" );
+            }
+        }
 
-  }
-  examples.clear();  
+    }
+    examples.clear();
 #ifdef DEBUG_PRINTS
-  cout << "SemSegRegionBased::convertExamplesToLSet finished" << endl;
+    cout << "SemSegRegionBased::convertExamplesToLSet finished" << endl;
 #endif
 }
 
 void SemanticSegmentation::convertExamplesToVVector ( VVector &feats, Examples &examples, vector<int> &label )
 {
 #ifdef DEBUG_PRINTS
-  cout << "SemSegRegionBased::convertExamplesToVVector starts" << endl;
+    cout << "SemSegRegionBased::convertExamplesToVVector starts" << endl;
 #endif
-  feats.clear();
-  label.clear();
-  for ( int i = 0; i < ( int ) examples.size(); i++ )
-  {
-    label.push_back ( examples[i].first );
-    feats.push_back ( *examples[i].second.vec );
-    delete examples[i].second.vec;
-    examples[i].second.vec = NULL;
-  }
-  examples.clear();
+    feats.clear();
+    label.clear();
+    for ( int i = 0; i < ( int ) examples.size(); i++ )
+    {
+        label.push_back ( examples[i].first );
+        feats.push_back ( *examples[i].second.vec );
+        delete examples[i].second.vec;
+        examples[i].second.vec = NULL;
+    }
+    examples.clear();
 #ifdef DEBUG_PRINTS
-  cout << "SemSegRegionBased::convertExamplesToVVector finished" << endl;
+    cout << "SemSegRegionBased::convertExamplesToVVector finished" << endl;
 #endif
 }
 
 void SemanticSegmentation::convertVVectorToExamples ( VVector &feats, Examples &examples, vector<int> &label )
 {
 #ifdef DEBUG_PRINTS
-  cout << "SemSegRegionBased::convertVVectorToExamples starts" << endl;
+    cout << "SemSegRegionBased::convertVVectorToExamples starts" << endl;
 #endif
-  for ( int i = 0; i < ( int ) feats.size(); i++ )
-  {
-    NICE::Vector *v = new NICE::Vector ( feats[i] );
-    Example ex ( v );
-    ex.position = 0; //TODO: hier mal was besseres überlegen, damit Klassifikator wieder Bildspezifisch lernt
-    examples.push_back ( pair<int, Example> ( label[i], ex ) );
-    feats[i].clear();
-  }
-  feats.clear();
-  label.clear();
+    for ( int i = 0; i < ( int ) feats.size(); i++ )
+    {
+        NICE::Vector *v = new NICE::Vector ( feats[i] );
+        Example ex ( v );
+        ex.position = 0; //TODO: hier mal was besseres überlegen, damit Klassifikator wieder Bildspezifisch lernt
+        examples.push_back ( pair<int, Example> ( label[i], ex ) );
+        feats[i].clear();
+    }
+    feats.clear();
+    label.clear();
 #ifdef DEBUG_PRINTS
-  cout << "SemSegRegionBased::convertVVectorToExamples finished" << endl;
+    cout << "SemSegRegionBased::convertVVectorToExamples finished" << endl;
 #endif
 }
 
 void SemanticSegmentation::setIterationCountSuffix( const int & _iterationCountSuffix)
 {
-  this->iterationCountSuffix = _iterationCountSuffix;
+    this->iterationCountSuffix = _iterationCountSuffix;
 }
 
 void SemanticSegmentation::setClassNames ( const OBJREC::ClassNames * _classNames )
 {
-  this->classNames = _classNames;
+    this->classNames = _classNames;
 }
 
-void SemanticSegmentation::getDepthVector ( const LabeledSet *Files,
-                                            vector<int> & depthVec,
-                                            const bool run3Dseg )
+void SemanticSegmentation::saveProbabilityMapAsImage ( const NICE::MultiChannelImage3DT<double> & prob )
 {
-  std::string oldName;
-  int zsize = 0;
-  bool isInit = false;
-
-  for (LabeledSet::const_iterator it = Files->begin(); it != Files->end(); it++)
-  {
-    for (std::vector<ImageInfo *>::const_iterator jt = it->second.begin();
-         jt != it->second.end(); jt++)
-    {
-      ImageInfo & info = *(*jt);
-      std::string file = info.img();
-
-      std::vector< std::string > list;
-      StringTools::split ( file, '/', list );
-      std::string filename = list.back();
-      uint found = filename.find_last_of ( "_" );
-      if (run3Dseg && found < filename.size() && found-3 > 0 )
-      {
-        std::string curName = filename.substr ( found-3,3 );
-        if ( !isInit )
-        {
-          oldName = curName;
-          isInit = true;
-        }
-        if ( curName.compare ( oldName ) == 0 ) // if strings match up
-        {
-          zsize++;
-        }
-        else
-        {
-          depthVec.push_back ( zsize );
-          zsize = 1;
-          oldName = curName;
-        }
-      }
-      else
-      {
-        zsize = 1;
-        depthVec.push_back ( zsize );
-      }
+    std::string s;
 
-    }
-  }
-  depthVec.push_back ( zsize );
-}
-
-void SemanticSegmentation::make3DImage ( const std::vector<std::string> & filelist,
-    NICE::MultiChannelImage3DT<double> & imgData )
-{
-  bool isInit = false;
-  for ( int it = 0; it < ( int ) filelist.size(); it++ )
-  {
-    if ( imagetype == IMAGETYPE_RGB )
-    {
-      NICE::ColorImage img;
-      try
-      {
-        img.read ( filelist[it] );
-      }
-      catch ( ImageException iE )
-      {
-        fprintf ( stderr, "Failed to open color image file: %s\n", filelist[it].c_str() );
-        fprintf ( stderr, "%s\n", iE.what() );
-        exit ( -1 );
-      }
-      if ( !isInit )
-      {
-        imgData.reInit ( img.width(),img.height(),filelist.size(),3 );
-        isInit = true;
-      }
-      for ( int y = 0; y < img.height(); y++ )
-      {
-        for ( int x = 0; x < img.width(); x++ )
-        {
-          for ( int r = 0; r < 3; r++ )
-          {
-            imgData.set ( x, y, it, img.getPixel ( x,y,r ), r );
-          }
-        }
-      }
-    }
-    else
-    {
-      NICE::Image img;
-      try
-      {
-        img.read ( filelist[it] );
-      }
-      catch ( ImageException iE )
-      {
-        fprintf ( stderr, "Failed to open image file: %s\n", filelist[it].c_str() );
-        fprintf ( stderr, "%s\n", iE.what() );
-        exit ( -1 );
-      }
-      if ( !isInit )
-      {
-        imgData.reInit ( img.width(),img.height(),filelist.size(),1 );
-        isInit = true;
-      }
-      for ( int y = 0; y < img.height(); y++ )
-      {
-        for ( int x = 0; x < img.width(); x++ )
+    for ( int cl = 0; cl < prob.channels(); cl++ )
+        for ( int z = 0; z < prob.depth(); z++ )
         {
-          imgData.set ( x, y, it, img.getPixel ( x,y ), 0 );
-        }
-      }
-    }
-  }
+            NICE::ColorImage img( prob.width(),prob.height() );
+            NICE::ImageT<double> m = prob.getChannelT(z, cl);
+            imageToPseudoColor(m, img);
 
-  if ( imagetype == IMAGETYPE_GRAY )
-  {
-    imgData.equalizeHistogram( 0 );
-#ifdef DEBUG_PRINTS
-    for (int z = 0; z < imgData.depth(); z++)
-    {
-      NICE::Image im = imgData.getChannel( z, 0);
-      im.write( filelist[z]+"_eq.pgm");
-    }
-#endif
-  }
-}
-
-void SemanticSegmentation::getProbabilityMap ( const NICE::MultiChannelImage3DT<double> & prob )
-{
-  std::string s;
-
-  for ( int cl = 0; cl < prob.channels(); cl++ )
-    for ( int z = 0; z < prob.depth(); z++ )
-    {
-      NICE::ColorImage img( prob.width(),prob.height() );
-      NICE::ImageT<double> m = prob.getChannelT(z, cl);
-      imageToPseudoColor(m, img);
+            std::stringstream out;
+            out << "probmap_s" << z << "_c" << cl << ".ppm";
+            s = out.str();
+            img.write( s );
 
-      std::stringstream out;
-      out << "probmap_s" << z << "_c" << cl << ".ppm";
-      s = out.str();
-      img.write( s );
-
-      //showImage(img, "Probability map");
-      //getchar();
-    }
+            //showImage(img, "Probability map");
+            //getchar();
+        }
 }
 
 ///////////////////// INTERFACE PERSISTENT /////////////////////
@@ -416,123 +301,123 @@ void SemanticSegmentation::getProbabilityMap ( const NICE::MultiChannelImage3DT<
 
 void SemanticSegmentation::restore ( std::istream & is, int format )
 {
-  //delete everything we knew so far...
-  this->clear();
+    //delete everything we knew so far...
+    this->clear();
 
-  bool b_restoreVerbose ( false );
+    bool b_restoreVerbose ( false );
 #ifdef B_RESTOREVERBOSE
-  b_restoreVerbose = true;
+    b_restoreVerbose = true;
 #endif
 
-  if ( is.good() )
-  {
-    if ( b_restoreVerbose )
-      std::cerr << " restore SemanticSegmentation" << std::endl;
+    if ( is.good() )
+    {
+        if ( b_restoreVerbose )
+            std::cerr << " restore SemanticSegmentation" << std::endl;
 
-    std::string tmp;
-    is >> tmp; //class name
+        std::string tmp;
+        is >> tmp; //class name
 
-    if ( ! this->isStartTag( tmp, "SemanticSegmentation" ) )
-    {
-      std::cerr << " WARNING - attempt to restore SemanticSegmentation, but start flag " << tmp << " does not match! Aborting... " << std::endl;
-      throw;
-    }
+        if ( ! this->isStartTag( tmp, "SemanticSegmentation" ) )
+        {
+            std::cerr << " WARNING - attempt to restore SemanticSegmentation, but start flag " << tmp << " does not match! Aborting... " << std::endl;
+            throw;
+        }
 
-    is.precision (numeric_limits<double>::digits10 + 1);
+        is.precision (numeric_limits<double>::digits10 + 1);
 
-    bool b_endOfBlock ( false ) ;
+        bool b_endOfBlock ( false ) ;
 
-    while ( !b_endOfBlock )
+        while ( !b_endOfBlock )
+        {
+            is >> tmp; // start of block
+
+            if ( this->isEndTag( tmp, "SemanticSegmentation" ) )
+            {
+                b_endOfBlock = true;
+                continue;
+            }
+
+            tmp = this->removeStartTag ( tmp );
+
+            if ( b_restoreVerbose )
+                std::cerr << " currently restore section " << tmp << " in SemanticSegmentation" << std::endl;
+
+            if ( tmp.compare("classNames") == 0 )
+            {
+                //dirty solution to circumvent the const-flag
+                const_cast<ClassNames*>(this->classNames)->restore ( is, format );
+
+                is >> tmp; // end of block
+                tmp = this->removeEndTag ( tmp );
+            }
+            else if ( tmp.compare("imagetype") == 0 )
+            {
+                unsigned int ui_imagetyp;
+                is >> ui_imagetyp;
+                this->imagetype = static_cast<IMAGETYP> ( ui_imagetyp );
+
+                is >> tmp; // end of block
+                tmp = this->removeEndTag ( tmp );
+            }
+            else if ( tmp.compare("iterationCountSuffix") == 0 )
+            {
+                is >> this->iterationCountSuffix;
+
+                is >> tmp; // end of block
+                tmp = this->removeEndTag ( tmp );
+            }
+            else
+            {
+                std::cerr << "WARNING -- unexpected SemanticSegmentation object -- " << tmp << " -- for restoration... aborting" << std::endl;
+                throw;
+            }
+        }
+    }
+    else
     {
-      is >> tmp; // start of block
-
-      if ( this->isEndTag( tmp, "SemanticSegmentation" ) )
-      {
-        b_endOfBlock = true;
-        continue;
-      }
-
-      tmp = this->removeStartTag ( tmp );
-
-      if ( b_restoreVerbose )
-        std::cerr << " currently restore section " << tmp << " in SemanticSegmentation" << std::endl;
-
-      if ( tmp.compare("classNames") == 0 )
-      {
-  //dirty solution to circumvent the const-flag
-        const_cast<ClassNames*>(this->classNames)->restore ( is, format );
-
-        is >> tmp; // end of block
-        tmp = this->removeEndTag ( tmp );
-      }
-      else if ( tmp.compare("imagetype") == 0 )
-      {
-        unsigned int ui_imagetyp;
-        is >> ui_imagetyp;
-        this->imagetype = static_cast<IMAGETYP> ( ui_imagetyp );
-
-        is >> tmp; // end of block
-        tmp = this->removeEndTag ( tmp );
-      }
-      else if ( tmp.compare("iterationCountSuffix") == 0 )
-      {
-        is >> this->iterationCountSuffix;
-
-        is >> tmp; // end of block
-        tmp = this->removeEndTag ( tmp );
-      }
-      else
-      {
-      std::cerr << "WARNING -- unexpected SemanticSegmentation object -- " << tmp << " -- for restoration... aborting" << std::endl;
-      throw;
-      }
+        std::cerr << "SemanticSegmentation::restore -- InStream not initialized - restoring not possible!" << std::endl;
+        throw;
     }
-  }
-  else
-  {
-    std::cerr << "SemanticSegmentation::restore -- InStream not initialized - restoring not possible!" << std::endl;
-    throw;
-  }
 
 
- //TODO check whether we also have to do something linke Preprocess::Init ( conf );
+    //TODO check whether we also have to do something linke Preprocess::Init ( conf );
 }
 
 void SemanticSegmentation::store ( std::ostream & os, int format ) const
 {
-  if (os.good())
-  {
-    // show starting point
-    os << this->createStartTag( "SemanticSegmentation" ) << std::endl;
+    if (os.good())
+    {
+        // show starting point
+        os << this->createStartTag( "SemanticSegmentation" ) << std::endl;
 
-    os.precision (numeric_limits<double>::digits10 + 1);
+        os.precision (numeric_limits<double>::digits10 + 1);
 
-    os << this->createStartTag( "classNames" ) << std::endl;
-    this->classNames->store ( os, format );
-    os << this->createEndTag( "classNames" ) << std::endl;
+        os << this->createStartTag( "classNames" ) << std::endl;
+        this->classNames->store ( os, format );
+        os << this->createEndTag( "classNames" ) << std::endl;
 
-    //
+        //
 
-    os << this->createStartTag( "imagetype" ) << std::endl;
-    os << imagetype << std::endl;
-    os << this->createEndTag( "imagetype" ) << std::endl;
+        os << this->createStartTag( "imagetype" ) << std::endl;
+        os << imagetype << std::endl;
+        os << this->createEndTag( "imagetype" ) << std::endl;
 
-    //
+        //
 
-    os << this->createStartTag( "iterationCountSuffix" ) << std::endl;
-    os << iterationCountSuffix << std::endl;
-    os << this->createEndTag( "iterationCountSuffix" ) << std::endl;
+        os << this->createStartTag( "iterationCountSuffix" ) << std::endl;
+        os << iterationCountSuffix << std::endl;
+        os << this->createEndTag( "iterationCountSuffix" ) << std::endl;
 
-    // done
-    os << this->createEndTag( "SemanticSegmentation" ) << std::endl;
-  }
-  else
-  {
-    std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
-  }
+        // done
+        os << this->createEndTag( "SemanticSegmentation" ) << std::endl;
+    }
+    else
+    {
+        std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
+    }
 }
 
 void SemanticSegmentation::clear ()
 {
- //TODO
+    //TODO
 }

+ 41 - 14
semseg/SemanticSegmentation.h

@@ -65,6 +65,9 @@ class SemanticSegmentation : public NICE::Persistent
     /** whether to do a coarse segmentation or not */
     bool coarseMode;
 
+    /** whether to run in 3D mode or not */
+    bool run3Dseg;
+
     /////////////////////////
     /////////////////////////
     //  PROTECTED METHODS  //
@@ -105,11 +108,30 @@ class SemanticSegmentation : public NICE::Persistent
     //                      SEGMENTATION STUFF
     ///////////////////// ///////////////////// /////////////////////
 
+    /**
+     * @brief return whether 3D mode is activated or not
+     * @return bool 3d mode status
+     */
+    bool isMode3D ()
+    {
+        return run3Dseg;
+    }
+
     /** load img from file call localize(CachedExample *ce) etc. */
     void semanticseg ( const std::string & filename,
                        NICE::ImageT<int> & segresult,
                        NICE::MultiChannelImageT<double> & probabilities );
 
+    /**
+     * @brief Pre-processing and classification of a 3D image
+     * @param filelist filename list of images that represent slices of a stack
+     * @param segresult segmentation results (output)
+     * @param probabilities probabilities for each pixel (output)
+     */
+    void semanticseg ( const std::vector<std::string> & filelist,
+                       NICE::MultiChannelImageT<int> & segresult,
+                       NICE::MultiChannelImage3DT<double> & probabilities );
+
     /**
      * Classify each voxel of a 3D image (image stack)
      * @author Sven Sickert
@@ -132,6 +154,17 @@ class SemanticSegmentation : public NICE::Persistent
                                NICE::ImageT<int> & segresult,
                                NICE::MultiChannelImageT<double> & probabilities ) = 0;
 
+    /**
+     * Classify each voxel of a 3D image (image stack)
+     * @author Sven Sickert
+     * @param ce 3d image data
+     * @param segresult segmentation results (output)
+     * @param probabilities probabilities for each pixel (output)
+     */
+    virtual void semanticseg ( OBJREC::CachedExample *ce,
+                               NICE::MultiChannelImageT<int> & segresult,
+                               NICE::MultiChannelImage3DT<double> & probabilities ) = 0;
+
 
     /** training function (has to be overloaded by all subclasses)
      * @param md the data set
@@ -150,8 +183,9 @@ class SemanticSegmentation : public NICE::Persistent
      * @param filelist filename list of images that represent slices of a stack
      * @param imgData output
      */
+    template<class SrcP>
     void make3DImage ( const std::vector<std::string> & filelist,
-                       NICE::MultiChannelImage3DT<double> & imgData );
+                       NICE::MultiChannelImage3DT<SrcP> & imgData );
 
 
     ///////////////////// ///////////////////// /////////////////////
@@ -202,29 +236,20 @@ class SemanticSegmentation : public NICE::Persistent
     }
 
     /**
-     * @brief Collect information about the depth of 3d images
-     * @author Sven Sickert
-     * @param Files a labeled set of data
-     * @param depthVec output of depth values
-     * @param run3dseg whether slice counting is necessary or not
-     */
-    void getDepthVector ( const LabeledSet *Files, std::vector<int> & depthVec, const bool run3dseg );
-
-    /**
-     * @brief Save probability maps of all classes to iamge files
+     * @brief Save probability maps of all classes to image files
      * @author Sven Sickert
      * @param prob class probability maps
      */
-    void getProbabilityMap( const NICE::MultiChannelImage3DT<double> & prob );
+    void saveProbabilityMapAsImage( const NICE::MultiChannelImage3DT<double> & prob );
 
     /**
      * @author Alexander Freytag
      * @date 06-02-2014 ( dd-mm-yyyy )
      */
     void setClassNames ( const OBJREC::ClassNames * _classNames  ) ;
-    
+
     void setIterationCountSuffix( const int & _iterationCountSuffix);
-    
+
     ///////////////////// INTERFACE PERSISTENT /////////////////////
     // interface specific methods for store and restore
     ///////////////////// INTERFACE PERSISTENT /////////////////////
@@ -252,4 +277,6 @@ class SemanticSegmentation : public NICE::Persistent
 
 } // namespace
 
+#include "SemanticSegmentation.tcc"
+
 #endif

+ 77 - 0
semseg/SemanticSegmentation.tcc

@@ -0,0 +1,77 @@
+#include <stdio.h>
+#include <vector>
+
+namespace OBJREC {
+
+template<class SrcP>
+void SemanticSegmentation::make3DImage ( const std::vector<std::string> & filelist,
+                                         NICE::MultiChannelImage3DT<SrcP> & imgData )
+{
+    bool isInit = false;
+    for ( int it = 0; it < ( int ) filelist.size(); it++ )
+    {
+        if ( imagetype == IMAGETYPE_RGB )
+        {
+            NICE::ColorImage img;
+            try
+            {
+                img.read ( filelist[it] );
+            }
+            catch ( NICE::ImageException iE )
+            {
+                fprintf ( stderr, "Failed to open color image file: %s\n", filelist[it].c_str() );
+                fprintf ( stderr, "%s\n", iE.what() );
+                exit ( -1 );
+            }
+            if ( !isInit )
+            {
+                imgData.reInit ( img.width(),img.height(),filelist.size(),3 );
+                isInit = true;
+            }
+            for ( int y = 0; y < img.height(); y++ )
+            {
+                for ( int x = 0; x < img.width(); x++ )
+                {
+                    for ( int r = 0; r < 3; r++ )
+                    {
+                        imgData.set ( x, y, it, (SrcP)img.getPixel ( x,y,r ), r );
+                    }
+                }
+            }
+        }
+        else
+        {
+            NICE::Image img;
+            try
+            {
+                img.read ( filelist[it] );
+            }
+            catch ( NICE::ImageException iE )
+            {
+                fprintf ( stderr, "Failed to open image file: %s\n", filelist[it].c_str() );
+                fprintf ( stderr, "%s\n", iE.what() );
+                exit ( -1 );
+            }
+            if ( !isInit )
+            {
+                imgData.reInit ( img.width(),img.height(),filelist.size(),1 );
+                isInit = true;
+            }
+            for ( int y = 0; y < img.height(); y++ )
+            {
+                for ( int x = 0; x < img.width(); x++ )
+                {
+                    imgData.set ( x, y, it, (SrcP)img.getPixel ( x,y ), 0 );
+                }
+            }
+        }
+    }
+
+    if ( imagetype == IMAGETYPE_GRAY )
+    {
+        imgData.equalizeHistogram( 0 );
+    }
+
+}
+
+}

+ 14 - 14
semseg/postsegmentation/RelativeLocationPrior.cpp

@@ -1,6 +1,6 @@
 #include "RelativeLocationPrior.h"
 
-#include "core/image/Filter.h"
+#include "core/image/FilterT.h"
 
 using namespace std;
 using namespace NICE;
@@ -104,9 +104,9 @@ void RelativeLocationPrior::finishPriorsMaps ( ClassNames &cn )
     }
   }
 
-  double sigma = 0.1 * ( double ) mapsize; // 10% der Breite/Höhe der Maps
+  double sigma = 0.1 * ( double ) mapsize; // 10 percent of the maps height/width
 
-  // alle Priormaps weichzeichnen
+  // Smoothing the maps
   for ( int j = 0; j < classno; j++ )
   {
     for ( int i = 0; i < classno; i++ )
@@ -122,8 +122,8 @@ void RelativeLocationPrior::finishPriorsMaps ( ClassNames &cn )
       }
 
       NICE::FloatImage out;
-      //FourierLibrary::gaussFilterD(tmp, out, sigma);
-      NICE::filterGaussSigmaApproximate<float, float, float> ( tmp, sigma, &out );
+      NICE::FilterT<float,float,float> filter;
+      filter.filterGaussSigmaApproximate( tmp, sigma, &out );
 
       for ( int x = 0; x < mapsize; x++ )
       {
@@ -135,7 +135,7 @@ void RelativeLocationPrior::finishPriorsMaps ( ClassNames &cn )
     }
   }
 
-  // Summe aller Pixel an einer Position über jede Klasse = 1
+  // Sum of all pixels over all classes at a certain position equals 1
   for ( int i = 0; i < classno; i++ )
   {
     for ( int x = 0; x < mapsize; x++ )
@@ -239,7 +239,7 @@ void RelativeLocationPrior::finishPriorsMaps ( ClassNames &cn )
 
 void RelativeLocationPrior::trainClassifier ( Examples &regions, NICE::MultiChannelImageT<double> & probabilities )
 {
-  // für alle Regionen einen Merkmalsvektor erzeugen und diesen der Trainingsmenge hinzufügen
+  // Creating a feature vector for all regions and adding it to the training set
   getFeature ( regions, probabilities );
 
   for ( int i = 0; i < ( int ) regions.size(); i++ )
@@ -251,9 +251,9 @@ void RelativeLocationPrior::trainClassifier ( Examples &regions, NICE::MultiChan
 
 void RelativeLocationPrior::finishClassifier()
 {
-  //////////////////////////////
-  // Klassifikatoren anlernen //
-  //////////////////////////////
+  //////////////////////
+  // Train Classifier //
+  //////////////////////
   FeaturePool fp;
   Feature *f = new SparseVectorFeature ( featdim );
   f->explode ( fp );
@@ -404,7 +404,7 @@ void RelativeLocationPrior::getFeature ( Examples &regions, NICE::MultiChannelIm
     alpha.push_back ( tmpalpha );
   }
 
-  //erzeuge f_relloc
+  // create f_relloc
   vector<vector<double> > vother;
   vector<vector<double> > vself;
   for ( int i = 0; i < ( int ) regions.size(); i++ )
@@ -430,7 +430,7 @@ void RelativeLocationPrior::getFeature ( Examples &regions, NICE::MultiChannelIm
 
         double val = priormaps[c]->get ( x, y, bestclasses[j] ) * alpha[j]; ;
 
-        if ( bestclasses[j] == bestclasses[i] ) //Objektbestandteile
+        if ( bestclasses[j] == bestclasses[i] ) //parts of the object
         {
           tmp_self += val;
         }
@@ -469,7 +469,7 @@ void RelativeLocationPrior::getFeature ( Examples &regions, NICE::MultiChannelIm
 
     for ( int i = 0; i < classno; i++ )
     {
-      //appearence feature (old probability for each class
+      //appearence feature (old probability for each class)
       double fapp = log ( probabilities.get ( regions[r].second.x, regions[r].second.y, i ) );
 
       if ( fabs ( fapp ) > 10e-7 )
@@ -497,7 +497,7 @@ void RelativeLocationPrior::restore ( istream & is, int format )
   is >> mapsize;
   is >> featdim;
 
-  //Priorsmaps erzeugen
+  // Create prior maps
   for ( int i = 0; i < classno; i++ )
   {
     NICE::MultiChannelImageT<double> *tmp  = new NICE::MultiChannelImageT<double> ( mapsize, mapsize, classno);