|
|
@@ -40,7 +40,6 @@ using namespace NICE;
|
|
|
|
|
|
SemSegContextTree3D::SemSegContextTree3D () : SemanticSegmentation ()
|
|
|
{
|
|
|
- this->lfcw = NULL;
|
|
|
this->firstiteration = true;
|
|
|
this->run3Dseg = false;
|
|
|
this->maxSamples = 2000;
|
|
|
@@ -53,9 +52,8 @@ SemSegContextTree3D::SemSegContextTree3D () : SemanticSegmentation ()
|
|
|
this->randomTests = 10;
|
|
|
this->useAltTristimulus = false;
|
|
|
this->useGradient = true;
|
|
|
- this->useWeijer = false;
|
|
|
this->useAdditionalLayer = false;
|
|
|
- this->useHoiemFeatures = false;
|
|
|
+ this->numAdditionalLayer = 0;
|
|
|
this->useCategorization = false;
|
|
|
this->cndir = "";
|
|
|
this->fasthik = NULL;
|
|
|
@@ -87,7 +85,6 @@ SemSegContextTree3D::SemSegContextTree3D (
|
|
|
string section = "SSContextTree";
|
|
|
string featsec = "Features";
|
|
|
|
|
|
- this->lfcw = NULL;
|
|
|
this->firstiteration = true;
|
|
|
this->maxSamples = conf->gI ( section, "max_samples", 2000 );
|
|
|
this->minFeats = conf->gI ( section, "min_feats", 50 );
|
|
|
@@ -100,9 +97,11 @@ SemSegContextTree3D::SemSegContextTree3D (
|
|
|
|
|
|
this->useAltTristimulus = conf->gB ( featsec, "use_alt_trist", false );
|
|
|
this->useGradient = conf->gB ( featsec, "use_gradient", true );
|
|
|
- this->useWeijer = conf->gB ( featsec, "use_weijer", true );
|
|
|
this->useAdditionalLayer = conf->gB ( featsec, "use_additional_layer", false );
|
|
|
- this->useHoiemFeatures = conf->gB ( featsec, "use_hoiem_features", false );
|
|
|
+ if (useAdditionalLayer)
|
|
|
+ this->numAdditionalLayer = conf->gI ( featsec, "num_additional_layer", 1 );
|
|
|
+ else
|
|
|
+ this->numAdditionalLayer = 0;
|
|
|
|
|
|
this->useCategorization = conf->gB ( section, "use_categorization", false );
|
|
|
this->cndir = conf->gS ( "SSContextTree", "cndir", "" );
|
|
|
@@ -122,9 +121,6 @@ SemSegContextTree3D::SemSegContextTree3D (
|
|
|
else
|
|
|
this->fasthik = NULL;
|
|
|
|
|
|
- if ( useWeijer )
|
|
|
- this->lfcw = new LocalFeatureColorWeijer ( conf );
|
|
|
-
|
|
|
this->classnames = (*classNames);
|
|
|
|
|
|
string forbidden_classes_s = conf->gS ( "analysis", "forbidden_classes", "" );
|
|
|
@@ -280,9 +276,7 @@ double SemSegContextTree3D::getBestSplit (
|
|
|
if ( globent < 0.5 )
|
|
|
return 0.0;
|
|
|
|
|
|
- // pointers to all randomly chosen features
|
|
|
- std::vector<Operation3D*> featsel;
|
|
|
- for ( int i = 0; i < featsPerSplit; i++ )
|
|
|
+ for ( int f = 0; f < featsPerSplit; f++ )
|
|
|
{
|
|
|
int x1, x2, y1, y2, z1, z2, ft;
|
|
|
|
|
|
@@ -312,12 +306,7 @@ double SemSegContextTree3D::getBestSplit (
|
|
|
op->set ( x1, y1, z1, x2, y2, z2, f1, f2, ft );
|
|
|
op->setWSize( windowSize );
|
|
|
|
|
|
- featsel.push_back ( op );
|
|
|
- }
|
|
|
-
|
|
|
- // do actual split tests
|
|
|
- for ( int f = 0; f < featsPerSplit; f++ )
|
|
|
- {
|
|
|
+ /* do actual split tests */
|
|
|
double l_bestig = -numeric_limits< double >::max();
|
|
|
double l_splitval = -1.0;
|
|
|
vector<double> vals;
|
|
|
@@ -336,12 +325,12 @@ double SemSegContextTree3D::getBestSplit (
|
|
|
assert ( forest[tree][0].dist.size() > 0 );
|
|
|
|
|
|
double val = 0.0;
|
|
|
- val = featsel[f]->getVal ( feat, ( *it ).second, ( *it ).third, ( *it ).fourth );
|
|
|
+ val = op->getVal ( feat, ( *it ).second, ( *it ).third, ( *it ).fourth );
|
|
|
if ( !isfinite ( val ) )
|
|
|
{
|
|
|
#ifdef DEBUG
|
|
|
cerr << "feat " << feat.feats->width() << " " << feat.feats->height() << " " << feat.feats->depth() << endl;
|
|
|
- cerr << "non finite value " << val << " for " << featsel[f]->writeInfos() << endl << (*it).second << " " << (*it).third << " " << (*it).fourth << endl;
|
|
|
+ cerr << "non finite value " << val << " for " << op->writeInfos() << endl << (*it).second << " " << (*it).third << " " << (*it).fourth << endl;
|
|
|
#endif
|
|
|
val = 0.0;
|
|
|
}
|
|
|
@@ -423,7 +412,7 @@ double SemSegContextTree3D::getBestSplit (
|
|
|
if ( l_bestig > bestig )
|
|
|
{
|
|
|
bestig = l_bestig;
|
|
|
- splitop = featsel[f];
|
|
|
+ splitop = op;
|
|
|
splitval = l_splitval;
|
|
|
}
|
|
|
}
|
|
|
@@ -506,6 +495,10 @@ void SemSegContextTree3D::train ( const MultiDataset *md )
|
|
|
{
|
|
|
train ( trainp );
|
|
|
}
|
|
|
+
|
|
|
+#ifdef VERBOSE
|
|
|
+ printFeatureStatistics();
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
void SemSegContextTree3D::train ( const LabeledSet * trainp )
|
|
|
@@ -548,14 +541,8 @@ void SemSegContextTree3D::train ( const LabeledSet * trainp )
|
|
|
rawChannels *= 3; // gx, gy
|
|
|
}
|
|
|
|
|
|
- if ( useWeijer ) // Weijer Colornames
|
|
|
- rawChannels += 11;
|
|
|
-
|
|
|
- if ( useHoiemFeatures ) // geometrische Kontextmerkmale
|
|
|
- rawChannels += 8;
|
|
|
-
|
|
|
if ( useAdditionalLayer ) // beliebige Merkmale in extra Bilddateien
|
|
|
- rawChannels += 1;
|
|
|
+ rawChannels += numAdditionalLayer;
|
|
|
|
|
|
|
|
|
///////////////////////////// read input data /////////////////////////////////
|
|
|
@@ -1046,7 +1033,11 @@ void SemSegContextTree3D::train ( const LabeledSet * trainp )
|
|
|
cerr << "Time for Categorization: " << timer.getLastAbsolute() << " seconds\n" << endl;
|
|
|
}
|
|
|
|
|
|
-#ifdef VERBOSE
|
|
|
+}
|
|
|
+
|
|
|
+void SemSegContextTree3D::printFeatureStatistics ()
|
|
|
+{
|
|
|
+
|
|
|
cout << "\nFEATURE USAGE" << endl;
|
|
|
cout << "#############\n" << endl;
|
|
|
|
|
|
@@ -1120,7 +1111,6 @@ void SemSegContextTree3D::train ( const LabeledSet * trainp )
|
|
|
|
|
|
cout << "Depth [" << d+1 << "] Normal: " << contextOverview[d][0] << " Context: " << contextOverview[d][1] << endl;
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
@@ -1216,87 +1206,28 @@ void SemSegContextTree3D::addFeatureMaps (
|
|
|
|
|
|
}
|
|
|
|
|
|
- // Weijer color names
|
|
|
- if ( useWeijer )
|
|
|
+ // arbitrary amount of additional layers as feature maps
|
|
|
+ if ( useAdditionalLayer )
|
|
|
{
|
|
|
- if ( imagetype == IMAGETYPE_RGB )
|
|
|
+ for ( int a = 0; a < numAdditionalLayer; a++ )
|
|
|
{
|
|
|
+ ostringstream convert;
|
|
|
+ convert << a;
|
|
|
+#ifdef DEBUG
|
|
|
+ cout << "Using additional layer #" << a << endl;
|
|
|
+#endif
|
|
|
int currentsize = imgData.channels();
|
|
|
- imgData.addChannel ( 11 );
|
|
|
+ imgData.addChannel ( 1 );
|
|
|
for ( int z = 0; z < zsize; z++ )
|
|
|
{
|
|
|
- NICE::ColorImage img = imgData.getColor ( z );
|
|
|
- NICE::MultiChannelImageT<double> cfeats;
|
|
|
- lfcw->getFeats ( img, cfeats );
|
|
|
- for ( int c = 0; c < cfeats.channels(); c++)
|
|
|
- for ( int y = 0; y < ysize; y++ )
|
|
|
- for ( int x = 0; x < xsize; x++ )
|
|
|
- imgData.set(x, y, z, cfeats.get(x,y,(uint)c), c+currentsize);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- cerr << "Can't compute weijer features of a grayscale image." << endl;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // arbitrary additional layer as image
|
|
|
- if ( useAdditionalLayer )
|
|
|
- {
|
|
|
- int currentsize = imgData.channels();
|
|
|
- imgData.addChannel ( 1 );
|
|
|
- for ( int z = 0; z < zsize; z++ )
|
|
|
- {
|
|
|
- vector<string> list;
|
|
|
- StringTools::split ( filelist[z], '/', list );
|
|
|
- string layerPath = StringTools::trim ( filelist[z], list.back() ) + "addlayer/" + list.back();
|
|
|
- NICE::Image layer ( layerPath );
|
|
|
- for ( int y = 0; y < ysize; y++ )
|
|
|
- for ( int x = 0; x < xsize; x++ )
|
|
|
- imgData.set(x, y, z, layer.getPixelQuick(x,y), currentsize);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // read the geometric cues produced by Hoiem et al.
|
|
|
- if ( useHoiemFeatures )
|
|
|
- {
|
|
|
- string hoiemDirectory = conf->gS ( "Features", "hoiem_directory" );
|
|
|
- // we could also give the following set as a config option
|
|
|
- string hoiemClasses_s = "sky 000 090-045 090-090 090-135 090 090-por 090-sol";
|
|
|
- vector<string> hoiemClasses;
|
|
|
- StringTools::split ( hoiemClasses_s, ' ', hoiemClasses );
|
|
|
-
|
|
|
- int currentsize = imgData.channels();
|
|
|
- imgData.addChannel ( hoiemClasses.size() );
|
|
|
- for ( int z = 0; z < zsize; z++ )
|
|
|
- {
|
|
|
- FileName fn ( filelist[z] );
|
|
|
- fn.removeExtension();
|
|
|
- FileName fnBase = fn.extractFileName();
|
|
|
-
|
|
|
- for ( vector<string>::const_iterator i = hoiemClasses.begin(); i != hoiemClasses.end(); i++, currentsize++ )
|
|
|
- {
|
|
|
- string hoiemClass = *i;
|
|
|
- FileName fnConfidenceImage ( hoiemDirectory + fnBase.str() + "_c_" + hoiemClass + ".png" );
|
|
|
- if ( ! fnConfidenceImage.fileExists() )
|
|
|
- {
|
|
|
- fthrow ( Exception, "Unable to read the Hoiem geometric confidence image: " << fnConfidenceImage.str() << " (original image is " << filelist[z] << ")" );
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Image confidenceImage ( fnConfidenceImage.str() );
|
|
|
- if ( confidenceImage.width() != xsize || confidenceImage.height() != ysize )
|
|
|
- {
|
|
|
- fthrow ( Exception, "The size of the geometric confidence image does not match with the original image size: " << fnConfidenceImage.str() );
|
|
|
- }
|
|
|
-
|
|
|
- // copy standard image to double image
|
|
|
- for ( int y = 0 ; y < confidenceImage.height(); y++ )
|
|
|
- for ( int x = 0 ; x < confidenceImage.width(); x++ )
|
|
|
- imgData ( x, y, z, currentsize ) = ( double ) confidenceImage ( x, y );
|
|
|
-
|
|
|
- currentsize++;
|
|
|
- }
|
|
|
+ vector<string> list;
|
|
|
+ StringTools::split ( filelist[z], '/', list );
|
|
|
+ string layerPath = StringTools::trim ( filelist[z], list.back() )
|
|
|
+ + "addlayer" + convert.str() + "/" + list.back();
|
|
|
+ NICE::Image layer ( layerPath );
|
|
|
+ for ( int y = 0; y < ysize; y++ )
|
|
|
+ for ( int x = 0; x < xsize; x++ )
|
|
|
+ imgData.set(x, y, z, layer.getPixelQuick(x,y), currentsize);
|
|
|
}
|
|
|
}
|
|
|
}
|