|
@@ -36,6 +36,7 @@ SemSegContextTree::SemSegContextTree ( const Config *conf, const MultiDataset *m
|
|
|
this->conf = conf;
|
|
|
string section = "SSContextTree";
|
|
|
lfcw = new LFColorWeijer ( conf );
|
|
|
+ firstiteration = true;
|
|
|
|
|
|
grid = conf->gI ( section, "grid", 10 );
|
|
|
|
|
@@ -62,12 +63,14 @@ SemSegContextTree::SemSegContextTree ( const Config *conf, const MultiDataset *m
|
|
|
|
|
|
pixelWiseLabeling = false;
|
|
|
|
|
|
+ useRegionFeature = true;
|
|
|
if ( segmentationtype == "meanshift" )
|
|
|
segmentation = new RSMeanShift ( conf );
|
|
|
else if ( segmentationtype == "none" )
|
|
|
{
|
|
|
segmentation = NULL;
|
|
|
pixelWiseLabeling = true;
|
|
|
+ useRegionFeature = false;
|
|
|
}
|
|
|
else if ( segmentationtype == "felzenszwalb" )
|
|
|
segmentation = new RSGraphBased ( conf );
|
|
@@ -78,53 +81,85 @@ SemSegContextTree::SemSegContextTree ( const Config *conf, const MultiDataset *m
|
|
|
|
|
|
string featsec = "Features";
|
|
|
|
|
|
+ vector<Operation*> tops;
|
|
|
+
|
|
|
if ( conf->gB ( featsec, "minus", true ) )
|
|
|
- ops.push_back ( new Minus() );
|
|
|
+ tops.push_back ( new Minus() );
|
|
|
if ( conf->gB ( featsec, "minus_abs", true ) )
|
|
|
- ops.push_back ( new MinusAbs() );
|
|
|
+ tops.push_back ( new MinusAbs() );
|
|
|
if ( conf->gB ( featsec, "addition", true ) )
|
|
|
- ops.push_back ( new Addition() );
|
|
|
+ tops.push_back ( new Addition() );
|
|
|
if ( conf->gB ( featsec, "only1", true ) )
|
|
|
- ops.push_back ( new Only1() );
|
|
|
+ tops.push_back ( new Only1() );
|
|
|
if ( conf->gB ( featsec, "rel_x", true ) )
|
|
|
- ops.push_back ( new RelativeXPosition() );
|
|
|
+ tops.push_back ( new RelativeXPosition() );
|
|
|
if ( conf->gB ( featsec, "rel_y", true ) )
|
|
|
- ops.push_back ( new RelativeYPosition() );
|
|
|
+ tops.push_back ( new RelativeYPosition() );
|
|
|
+
|
|
|
+ ops.push_back ( tops );
|
|
|
+
|
|
|
+ tops.clear();
|
|
|
+ tops.push_back ( new Equality() );
|
|
|
+ ops.push_back ( tops );
|
|
|
|
|
|
+ tops.clear();
|
|
|
if ( conf->gB ( featsec, "bi_int_cent", true ) )
|
|
|
- cops.push_back ( new BiIntegralCenteredOps() );
|
|
|
+ tops.push_back ( new BiIntegralCenteredOps() );
|
|
|
if ( conf->gB ( featsec, "int_cent", true ) )
|
|
|
- cops.push_back ( new IntegralCenteredOps() );
|
|
|
+ tops.push_back ( new IntegralCenteredOps() );
|
|
|
if ( conf->gB ( featsec, "int", true ) )
|
|
|
- cops.push_back ( new IntegralOps() );
|
|
|
+ tops.push_back ( new IntegralOps() );
|
|
|
if ( conf->gB ( featsec, "haar_horz", true ) )
|
|
|
- cops.push_back ( new HaarHorizontal() );
|
|
|
+ tops.push_back ( new HaarHorizontal() );
|
|
|
if ( conf->gB ( featsec, "haar_vert", true ) )
|
|
|
- cops.push_back ( new HaarVertical() );
|
|
|
+ tops.push_back ( new HaarVertical() );
|
|
|
if ( conf->gB ( featsec, "haar_diag", true ) )
|
|
|
- cops.push_back ( new HaarDiag() );
|
|
|
+ tops.push_back ( new HaarDiag() );
|
|
|
if ( conf->gB ( featsec, "haar3_horz", true ) )
|
|
|
- cops.push_back ( new Haar3Horiz() );
|
|
|
+ tops.push_back ( new Haar3Horiz() );
|
|
|
if ( conf->gB ( featsec, "haar3_vert", true ) )
|
|
|
- cops.push_back ( new Haar3Vert() );
|
|
|
+ tops.push_back ( new Haar3Vert() );
|
|
|
if ( conf->gB ( featsec, "glob", true ) )
|
|
|
- cops.push_back ( new GlobalFeats() );
|
|
|
+ tops.push_back ( new GlobalFeats() );
|
|
|
+
|
|
|
+ ops.push_back ( tops );
|
|
|
+ ops.push_back ( tops );
|
|
|
+
|
|
|
+ tops.clear();
|
|
|
+ if ( conf->gB ( featsec, "minus", true ) )
|
|
|
+ tops.push_back ( new Minus() );
|
|
|
+ if ( conf->gB ( featsec, "minus_abs", true ) )
|
|
|
+ tops.push_back ( new MinusAbs() );
|
|
|
+ if ( conf->gB ( featsec, "addition", true ) )
|
|
|
+ tops.push_back ( new Addition() );
|
|
|
+ if ( conf->gB ( featsec, "only1", true ) )
|
|
|
+ tops.push_back ( new Only1() );
|
|
|
+ if ( conf->gB ( featsec, "rel_x", true ) )
|
|
|
+ tops.push_back ( new RelativeXPosition() );
|
|
|
+ if ( conf->gB ( featsec, "rel_y", true ) )
|
|
|
+ tops.push_back ( new RelativeYPosition() );
|
|
|
+
|
|
|
+ ops.push_back ( tops );
|
|
|
+
|
|
|
useGradient = conf->gB ( featsec, "use_gradient", true );
|
|
|
- useRegionFeature = conf->gB ( featsec, "use_region", true );
|
|
|
-
|
|
|
+
|
|
|
// geometric features of hoiem
|
|
|
- useHoiemFeatures = conf->gB( featsec, "use_hoiem_features", false );
|
|
|
+ useHoiemFeatures = conf->gB ( featsec, "use_hoiem_features", false );
|
|
|
if ( useHoiemFeatures )
|
|
|
{
|
|
|
- hoiemDirectory = conf->gS( featsec, "hoiem_directory" );
|
|
|
+ hoiemDirectory = conf->gS ( featsec, "hoiem_directory" );
|
|
|
}
|
|
|
|
|
|
opOverview = vector<int> ( NBOPERATIONS, 0 );
|
|
|
contextOverview = vector<vector<double> > ( maxDepth, vector<double> ( 2, 0.0 ) );
|
|
|
|
|
|
+ calcVal.push_back ( new MCImageAccess() );
|
|
|
+ calcVal.push_back ( new MCImageAccess() );
|
|
|
+ calcVal.push_back ( new MCImageAccess() );
|
|
|
calcVal.push_back ( new MCImageAccess() );
|
|
|
calcVal.push_back ( new ClassificationResultAccess() );
|
|
|
|
|
|
+
|
|
|
classnames = md->getClassNames ( "train" );
|
|
|
|
|
|
///////////////////////////////////
|
|
@@ -151,7 +186,7 @@ SemSegContextTree::~SemSegContextTree()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
-double SemSegContextTree::getBestSplit ( std::vector<NICE::MultiChannelImageT<double> > &feats, std::vector<NICE::MultiChannelImageT<unsigned short int> > ¤tfeats, std::vector<NICE::MultiChannelImageT<double> > &integralImgs, const std::vector<NICE::MatrixT<int> > &labels, int node, Operation *&splitop, double &splitval, const int &tree )
|
|
|
+double SemSegContextTree::getBestSplit ( std::vector<NICE::MultiChannelImageT<double> > &feats, std::vector<NICE::MultiChannelImageT<unsigned short int> > ¤tfeats, const std::vector<NICE::MatrixT<int> > &labels, int node, Operation *&splitop, double &splitval, const int &tree )
|
|
|
{
|
|
|
Timer t;
|
|
|
t.start();
|
|
@@ -252,11 +287,17 @@ double SemSegContextTree::getBestSplit ( std::vector<NICE::MultiChannelImageT<do
|
|
|
|
|
|
int tmpws = windowSize;
|
|
|
|
|
|
- if ( integralImgs[0].width() == 0 )
|
|
|
+ if ( ft > 1 && firstiteration )
|
|
|
ft = 0;
|
|
|
|
|
|
- if ( ft > 0 )
|
|
|
+ if ( channelsPerType[ft].size() == 0 )
|
|
|
{
|
|
|
+ ft = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ft > 1 )
|
|
|
+ {
|
|
|
+ //use larger window size for context features
|
|
|
tmpws *= 4;
|
|
|
}
|
|
|
|
|
@@ -265,50 +306,26 @@ double SemSegContextTree::getBestSplit ( std::vector<NICE::MultiChannelImageT<do
|
|
|
y1 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) tmpws ) - tmpws / 2;
|
|
|
y2 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) tmpws ) - tmpws / 2;
|
|
|
|
|
|
- if ( ft == 0 )
|
|
|
- {
|
|
|
- int f1 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) featdim );
|
|
|
- int f2 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) featdim );
|
|
|
- int o = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) ops.size() );
|
|
|
- Operation *op = ops[o]->clone();
|
|
|
- op->set ( x1, y1, x2, y2, f1, f2, calcVal[ft] );
|
|
|
- op->setContext ( false );
|
|
|
- featsel.push_back ( op );
|
|
|
- }
|
|
|
- else if ( ft == 1 )
|
|
|
- {
|
|
|
- int opssize = ( int ) ops.size();
|
|
|
- //opssize = 0;
|
|
|
- int o = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( ( ( double ) cops.size() ) + ( double ) opssize ) );
|
|
|
+ int f1 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) channelsPerType[ft].size() );
|
|
|
+ int f2 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) channelsPerType[ft].size() );
|
|
|
+ int o = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) ops[ft].size() );
|
|
|
|
|
|
- Operation *op;
|
|
|
+ Operation *op = ops[ft][o]->clone();
|
|
|
|
|
|
- if ( o < opssize )
|
|
|
- {
|
|
|
- int chans = ( int ) forest[0][0].dist.size();
|
|
|
- int f1 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) chans );
|
|
|
- int f2 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) chans );
|
|
|
- op = ops[o]->clone();
|
|
|
- op->set ( x1, y1, x2, y2, f1, f2, calcVal[ft] );
|
|
|
- op->setContext ( true );
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- int chans = integralImgs[0].channels();
|
|
|
- int f1 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) chans );
|
|
|
- int f2 = ( int ) ( ( double ) rand() / ( double ) RAND_MAX * ( double ) chans );
|
|
|
-
|
|
|
- o -= opssize;
|
|
|
- op = cops[o]->clone();
|
|
|
- op->set ( x1, y1, x2, y2, f1, f2, calcVal[ft] );
|
|
|
- if ( f1 < (int)forest[0][0].dist.size() )
|
|
|
- op->setContext ( true );
|
|
|
- else
|
|
|
- op->setContext ( false );
|
|
|
- }
|
|
|
+ op->set ( x1, y1, x2, y2, channelsPerType[ft][f1], channelsPerType[ft][f2], calcVal[ft] );
|
|
|
|
|
|
- featsel.push_back ( op );
|
|
|
- }
|
|
|
+ //if( i < 10)
|
|
|
+ //cerr << "type: " << ft << " features: " << op->writeInfos() << endl;
|
|
|
+
|
|
|
+ if ( ft == 3 || ft == 4 )
|
|
|
+ op->setContext ( true );
|
|
|
+ else
|
|
|
+ op->setContext ( false );
|
|
|
+
|
|
|
+ //if(ft == 4)
|
|
|
+ //cerr << "type: " << ft << " features: " << op->writeInfos() << endl;
|
|
|
+
|
|
|
+ featsel.push_back ( op );
|
|
|
}
|
|
|
|
|
|
#pragma omp parallel for private(mapit)
|
|
@@ -328,7 +345,6 @@ double SemSegContextTree::getBestSplit ( std::vector<NICE::MultiChannelImageT<do
|
|
|
feat.cfeats = ¤tfeats[ ( *it ) [0]];
|
|
|
feat.cTree = tree;
|
|
|
feat.tree = &forest[tree];
|
|
|
- feat.integralImg = &integralImgs[ ( *it ) [0]];
|
|
|
double val = featsel[f]->getVal ( feat, ( *it ) [1], ( *it ) [2] );
|
|
|
vals.push_back ( val );
|
|
|
maxval = std::max ( val, maxval );
|
|
@@ -489,65 +505,38 @@ void SemSegContextTree::computeIntegralImage ( const NICE::MultiChannelImageT<Sp
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void SemSegContextTree::computeIntegralImage ( const NICE::MultiChannelImageT<unsigned short int> ¤tfeats, const NICE::MultiChannelImageT<double> &lfeats, NICE::MultiChannelImageT<double> &integralImage )
|
|
|
+void SemSegContextTree::computeIntegralImage ( const NICE::MultiChannelImageT<unsigned short int> ¤tfeats, NICE::MultiChannelImageT<double> &feats, int firstChannel )
|
|
|
{
|
|
|
+
|
|
|
int xsize = currentfeats.width();
|
|
|
int ysize = currentfeats.height();
|
|
|
|
|
|
- int channels = ( int ) forest[0][0].dist.size();
|
|
|
-#pragma omp parallel for
|
|
|
- for ( int c = 0; c < channels; c++ )
|
|
|
- {
|
|
|
- integralImage.set ( 0, 0, getMeanProb ( 0, 0, c, currentfeats ), c );
|
|
|
-
|
|
|
- //first column
|
|
|
+ xsize = feats.width();
|
|
|
+ ysize = feats.height();
|
|
|
|
|
|
- for ( int y = 1; y < ysize; y++ )
|
|
|
- {
|
|
|
- integralImage.set ( 0, y, getMeanProb ( 0, y, c, currentfeats ) + integralImage.get ( 0, y - 1, c ), c );
|
|
|
- }
|
|
|
-
|
|
|
- //first row
|
|
|
- for ( int x = 1; x < xsize; x++ )
|
|
|
- {
|
|
|
- integralImage.set ( x, 0, getMeanProb ( x, 0, c, currentfeats ) + integralImage.get ( x - 1, 0, c ), c );
|
|
|
- }
|
|
|
-
|
|
|
- //rest
|
|
|
- for ( int y = 1; y < ysize; y++ )
|
|
|
- {
|
|
|
- for ( int x = 1; x < xsize; x++ )
|
|
|
- {
|
|
|
- double val = getMeanProb ( x, y, c, currentfeats ) + integralImage.get ( x, y - 1, c ) + integralImage.get ( x - 1, y, c ) - integralImage.get ( x - 1, y - 1, c );
|
|
|
- integralImage.set ( x, y, val, c );
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- int channels2 = ( int ) lfeats.channels();
|
|
|
-
|
|
|
- xsize = lfeats.width();
|
|
|
- ysize = lfeats.height();
|
|
|
-
|
|
|
- if ( integralImage.get ( xsize - 1, ysize - 1, channels ) == 0.0 )
|
|
|
+ if ( firstiteration )
|
|
|
{
|
|
|
+ firstiteration = false;
|
|
|
#pragma omp parallel for
|
|
|
- for ( int c1 = 0; c1 < channels2; c1++ )
|
|
|
+ for ( int it = 0; it < integralMap.size(); it++ )
|
|
|
{
|
|
|
- int c = channels + c1;
|
|
|
- integralImage.set ( 0, 0, lfeats.get ( 0, 0, c1 ), c );
|
|
|
+ int c1 = integralMap[it].first;
|
|
|
+ int c = integralMap[it].second;
|
|
|
|
|
|
- //first column
|
|
|
+ feats( 0, 0, c ) = feats( 0, 0, c1 );
|
|
|
|
|
|
+ //first column
|
|
|
for ( int y = 1; y < ysize; y++ )
|
|
|
{
|
|
|
- integralImage.set ( 0, y, lfeats.get ( 0, y, c1 ) + integralImage.get ( 0, y, c ), c );
|
|
|
+ feats( 0, y, c ) = feats.get ( 0, y, c1 )
|
|
|
+ + feats.get ( 0, y-1, c );
|
|
|
}
|
|
|
|
|
|
//first row
|
|
|
for ( int x = 1; x < xsize; x++ )
|
|
|
{
|
|
|
- integralImage.set ( x, 0, lfeats.get ( x, 0, c1 ) + integralImage.get ( x, 0, c ), c );
|
|
|
+ feats( x, 0, c ) = feats.get ( x, 0, c1 )
|
|
|
+ + feats.get ( x-1, 0, c );
|
|
|
}
|
|
|
|
|
|
//rest
|
|
@@ -555,12 +544,48 @@ void SemSegContextTree::computeIntegralImage ( const NICE::MultiChannelImageT<un
|
|
|
{
|
|
|
for ( int x = 1; x < xsize; x++ )
|
|
|
{
|
|
|
- double val = lfeats.get ( x, y, c1 ) + integralImage.get ( x, y - 1, c ) + integralImage.get ( x - 1, y, c ) - integralImage.get ( x - 1, y - 1, c );
|
|
|
- integralImage.set ( x, y, val, c );
|
|
|
+ feats ( x, y, c ) = feats ( x, y, c1 )
|
|
|
+ + feats ( x, y - 1, c )
|
|
|
+ + feats ( x - 1, y, c )
|
|
|
+ - feats ( x - 1, y - 1, c );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ int channels = ( int ) forest[0][0].dist.size();
|
|
|
+
|
|
|
+#pragma omp parallel for
|
|
|
+ for ( int c = 0; c < channels; c++ )
|
|
|
+ {
|
|
|
+ feats ( 0, 0, firstChannel + c ) = getMeanProb ( 0, 0, c, currentfeats );
|
|
|
+
|
|
|
+ //first column
|
|
|
+ for ( int y = 1; y < ysize; y++ )
|
|
|
+ {
|
|
|
+ feats ( 0, y, firstChannel + c ) = getMeanProb ( 0, y, c, currentfeats )
|
|
|
+ + feats ( 0, y - 1, firstChannel + c );
|
|
|
+ }
|
|
|
+
|
|
|
+ //first row
|
|
|
+ for ( int x = 1; x < xsize; x++ )
|
|
|
+ {
|
|
|
+ feats ( x, 0, firstChannel + c ) = getMeanProb ( x, 0, c, currentfeats )
|
|
|
+ + feats ( x - 1, 0, firstChannel + c );
|
|
|
+ }
|
|
|
+
|
|
|
+ //rest
|
|
|
+ for ( int y = 1; y < ysize; y++ )
|
|
|
+ {
|
|
|
+ for ( int x = 1; x < xsize; x++ )
|
|
|
+ {
|
|
|
+ feats ( x, y, firstChannel + c ) = getMeanProb ( x, y, c, currentfeats )
|
|
|
+ + feats ( x, y - 1, firstChannel + c )
|
|
|
+ + feats ( x - 1, y, firstChannel + c )
|
|
|
+ - feats ( x - 1, y - 1, firstChannel + c );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
inline double computeWeight ( const double &d, const double &dim )
|
|
@@ -642,13 +667,13 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
|
|
|
Globals::setCurrentImgFN ( currentFile );
|
|
|
-
|
|
|
+
|
|
|
//TODO: resize image?!
|
|
|
MultiChannelImageT<double> feats;
|
|
|
allfeats.push_back ( feats );
|
|
|
-
|
|
|
+
|
|
|
// read image and do some simple transformations
|
|
|
- extractBasicFeatures (allfeats[imgcounter], img, currentFile);
|
|
|
+ extractBasicFeatures ( allfeats[imgcounter], img, currentFile );
|
|
|
|
|
|
// getting groundtruth
|
|
|
NICE::Image pixelLabels ( xsize, ysize );
|
|
@@ -693,41 +718,67 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
////////////////////////////////////////////////////
|
|
|
//define which featurextraction methods should be used for each channel
|
|
|
#ifdef LOCALFEATS
|
|
|
- int colorchannels = 9;
|
|
|
+ rawChannels = 9;
|
|
|
#else
|
|
|
- int colorchannels = 3;
|
|
|
+ rawChannels = 3;
|
|
|
#endif
|
|
|
-
|
|
|
- if(useGradient)
|
|
|
- colorchannels *= 2;
|
|
|
-
|
|
|
- // gray value images
|
|
|
- for(int i = 0; i < colorchannels; i++)
|
|
|
+
|
|
|
+ // how many channels without integral image
|
|
|
+ int shift = 0;
|
|
|
+
|
|
|
+ if ( useGradient )
|
|
|
+ rawChannels *= 2;
|
|
|
+
|
|
|
+ if ( useHoiemFeatures )
|
|
|
+ rawChannels += 8;
|
|
|
+
|
|
|
+ // gray value images
|
|
|
+ for ( int i = 0; i < rawChannels; i++ )
|
|
|
{
|
|
|
- channelType.push_back(0);
|
|
|
+ channelType.push_back ( 0 );
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// regions
|
|
|
- if(useRegionFeature)
|
|
|
- channelType.push_back(2);
|
|
|
-
|
|
|
+ if ( useRegionFeature )
|
|
|
+ {
|
|
|
+ channelType.push_back ( 1 );
|
|
|
+ shift++;
|
|
|
+ }
|
|
|
+
|
|
|
+ for ( int i = 0; i < rawChannels; i++ )
|
|
|
+ {
|
|
|
+ channelType.push_back ( 2 );
|
|
|
+ }
|
|
|
+
|
|
|
// integral images
|
|
|
- for(int i = 0; i < colorchannels+classes; i++)
|
|
|
+ for ( int i = 0; i < classes; i++ )
|
|
|
{
|
|
|
- channelType.push_back(1);
|
|
|
+ channelType.push_back ( 3 );
|
|
|
}
|
|
|
-
|
|
|
- int amountTypes = 3;
|
|
|
-
|
|
|
- channelsPerType = vector<vector<int> >(amountTypes, vector<int>());
|
|
|
-
|
|
|
- for(int i = 0; i < channelType.size(); i++)
|
|
|
+
|
|
|
+ integralMap.clear();
|
|
|
+ int integralImageAmount = rawChannels;
|
|
|
+ for ( int ii = 0; ii < integralImageAmount; ii++ )
|
|
|
{
|
|
|
- channelsPerType[channelType[i]].push_back(i);
|
|
|
+ integralMap.push_back ( pair<int, int> ( ii, ii + integralImageAmount + shift ) );
|
|
|
}
|
|
|
-
|
|
|
- ftypes = std::min(amountTypes,ftypes);
|
|
|
-
|
|
|
+
|
|
|
+ int amountTypes = 5;
|
|
|
+
|
|
|
+ channelsPerType = vector<vector<int> > ( amountTypes, vector<int>() );
|
|
|
+
|
|
|
+ for ( int i = 0; i < channelType.size(); i++ )
|
|
|
+ {
|
|
|
+ channelsPerType[channelType[i]].push_back ( i );
|
|
|
+ }
|
|
|
+
|
|
|
+ for ( int i = 0; i < classes; i++ )
|
|
|
+ {
|
|
|
+ channelsPerType[channelsPerType.size()-1].push_back ( i );
|
|
|
+ }
|
|
|
+
|
|
|
+ ftypes = std::min ( amountTypes, ftypes );
|
|
|
+
|
|
|
////////////////////////////////////////////////////
|
|
|
|
|
|
//balancing
|
|
@@ -789,8 +840,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
bool allleaf = false;
|
|
|
//int baseFeatSize = allfeats[0].size();
|
|
|
|
|
|
- vector<MultiChannelImageT<double> > integralImgs ( imgcounter, MultiChannelImageT<double>() );
|
|
|
-
|
|
|
while ( !allleaf && depth < maxDepth )
|
|
|
{
|
|
|
depth++;
|
|
@@ -823,14 +872,9 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
{
|
|
|
if ( !forest[tree][i].isleaf && forest[tree][i].left < 0 )
|
|
|
{
|
|
|
-#if 0
|
|
|
- timer.stop();
|
|
|
- cout << "time 1: " << timer.getLast() << endl;
|
|
|
- timer.start();
|
|
|
-#endif
|
|
|
Operation *splitfeat = NULL;
|
|
|
double splitval;
|
|
|
- double bestig = getBestSplit ( allfeats, lastfeats, integralImgs, labels, i, splitfeat, splitval, tree );
|
|
|
+ double bestig = getBestSplit ( allfeats, lastfeats, labels, i, splitfeat, splitval, tree );
|
|
|
|
|
|
for ( int ii = 0; ii < lastfeats.size(); ii++ )
|
|
|
{
|
|
@@ -838,22 +882,9 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
{
|
|
|
short unsigned int minv, maxv;
|
|
|
lastfeats[ii].statistics ( minv, maxv, c );
|
|
|
- //cout << "min: " << minv << " max: " << maxv << endl;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#if 0
|
|
|
- timer.stop();
|
|
|
- double tl = timer.getLast();
|
|
|
-
|
|
|
- if ( tl > 10.0 )
|
|
|
- {
|
|
|
- cout << "time 2: " << tl << endl;
|
|
|
- cout << "slow split: " << splitfeat->writeInfos() << endl;
|
|
|
- getchar();
|
|
|
- }
|
|
|
- timer.start();
|
|
|
-#endif
|
|
|
forest[tree][i].feat = splitfeat;
|
|
|
forest[tree][i].decision = splitval;
|
|
|
|
|
@@ -880,12 +911,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
uniquenumber++;
|
|
|
forest[tree][right].featcounter = 0;
|
|
|
|
|
|
-#if 0
|
|
|
- timer.stop();
|
|
|
- cout << "time 3: " << timer.getLast() << endl;
|
|
|
- timer.start();
|
|
|
-#endif
|
|
|
-
|
|
|
#pragma omp parallel for
|
|
|
for ( int iCounter = 0; iCounter < imgcounter; iCounter++ )
|
|
|
{
|
|
@@ -903,7 +928,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
feat.cfeats = &lastfeats[iCounter];
|
|
|
feat.cTree = tree;
|
|
|
feat.tree = &forest[tree];
|
|
|
- feat.integralImg = &integralImgs[iCounter];
|
|
|
double val = splitfeat->getVal ( feat, x, y );
|
|
|
|
|
|
int subx = x / grid;
|
|
@@ -939,12 +963,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-#if 0
|
|
|
- timer.stop();
|
|
|
- cout << "time 4: " << timer.getLast() << endl;
|
|
|
- timer.start();
|
|
|
-#endif
|
|
|
-// forest[tree][right].featcounter = forest[tree][i].featcounter - forest[tree][left].featcounter;
|
|
|
|
|
|
double lcounter = 0.0, rcounter = 0.0;
|
|
|
|
|
@@ -963,11 +981,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
rcounter += forest[tree][right].dist[d];
|
|
|
}
|
|
|
}
|
|
|
-#if 0
|
|
|
- timer.stop();
|
|
|
- cout << "time 5: " << timer.getLast() << endl;
|
|
|
- timer.start();
|
|
|
-#endif
|
|
|
+
|
|
|
if ( lcounter <= 0 || rcounter <= 0 )
|
|
|
{
|
|
|
cout << "lcounter : " << lcounter << " rcounter: " << rcounter << endl;
|
|
@@ -995,7 +1009,6 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
feat.cfeats = &lastfeats[iCounter];
|
|
|
feat.cTree = tree;
|
|
|
feat.tree = &forest[tree];
|
|
|
- feat.integralImg = &integralImgs[iCounter];
|
|
|
|
|
|
double val = splitfeat->getVal ( feat, x, y );
|
|
|
|
|
@@ -1020,36 +1033,22 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-#if 0
|
|
|
- timer.stop();
|
|
|
- cout << "time after tree: " << timer.getLast() << endl;
|
|
|
- timer.start();
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
//compute integral images
|
|
|
- int channels = classes + allfeats[0].channels();
|
|
|
-
|
|
|
- if ( integralImgs[0].width() == 0 )
|
|
|
+ if ( firstiteration )
|
|
|
{
|
|
|
for ( int i = 0; i < imgcounter; i++ )
|
|
|
{
|
|
|
- int xsize = allfeats[i].width();
|
|
|
- int ysize = allfeats[i].height();
|
|
|
- integralImgs[i].reInit ( xsize, ysize, channels );
|
|
|
- integralImgs[i].setAll ( 0.0 );
|
|
|
+ int pos = allfeats.size();
|
|
|
+ allfeats[i].addChannel ( ( int ) ( classes + rawChannels ) );
|
|
|
}
|
|
|
}
|
|
|
-#if 0
|
|
|
- timer.stop();
|
|
|
- cout << "time for part1: " << timer.getLast() << endl;
|
|
|
- timer.start();
|
|
|
-#endif
|
|
|
|
|
|
#pragma omp parallel for
|
|
|
for ( int i = 0; i < imgcounter; i++ )
|
|
|
{
|
|
|
- computeIntegralImage ( currentfeats[i], allfeats[i], integralImgs[i] );
|
|
|
+ computeIntegralImage ( currentfeats[i], allfeats[i], channelType.size() - classes );
|
|
|
#ifdef TEXTONMAP
|
|
|
computeIntegralImage ( textonMap[i], integralTexton[i] );
|
|
|
#endif
|
|
@@ -1122,12 +1121,10 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
|
|
|
for ( uint c = 0; c < ops.size(); c++ )
|
|
|
{
|
|
|
- cout << ops[c]->writeInfos() << ": " << opOverview[ops[c]->getOps() ] << endl;
|
|
|
- }
|
|
|
-
|
|
|
- for ( uint c = 0; c < cops.size(); c++ )
|
|
|
- {
|
|
|
- cout << cops[c]->writeInfos() << ": " << opOverview[cops[c]->getOps() ] << endl;
|
|
|
+ for ( int t = 0; t < ops[c].size(); t++ )
|
|
|
+ {
|
|
|
+ cout << ops[c][t]->writeInfos() << ": " << opOverview[ops[c][t]->getOps() ] << endl;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
for ( int d = 0; d < maxDepth; d++ )
|
|
@@ -1143,7 +1140,7 @@ void SemSegContextTree::train ( const MultiDataset *md )
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-void SemSegContextTree::extractBasicFeatures ( NICE::MultiChannelImageT<double> &feats, const ColorImage &img, const string ¤tFile)
|
|
|
+void SemSegContextTree::extractBasicFeatures ( NICE::MultiChannelImageT<double> &feats, const ColorImage &img, const string ¤tFile )
|
|
|
{
|
|
|
int xsize = img.width();
|
|
|
int ysize = img.height();
|
|
@@ -1182,7 +1179,7 @@ void SemSegContextTree::extractBasicFeatures ( NICE::MultiChannelImageT<double>
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // read the geometric cues produced by Hoiem et al.
|
|
|
+ // read the geometric cues produced by Hoiem et al.
|
|
|
if ( useHoiemFeatures )
|
|
|
{
|
|
|
// we could also give the following set as a config option
|
|
@@ -1212,20 +1209,20 @@ void SemSegContextTree::extractBasicFeatures ( NICE::MultiChannelImageT<double>
|
|
|
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 " << currentFile << ")" );
|
|
|
+ fthrow ( Exception, "Unable to read the Hoiem geometric confidence image: " << fnConfidenceImage.str() << " (original image is " << currentFile << ")" );
|
|
|
} else {
|
|
|
Image confidenceImage ( fnConfidenceImage.str() );
|
|
|
// check whether the image size is consistent
|
|
|
if ( confidenceImage.width() != feats.width() || confidenceImage.height() != feats.height() )
|
|
|
{
|
|
|
- fthrow(Exception, "The size of the geometric confidence image does not match with the original image size: " << fnConfidenceImage.str());
|
|
|
+ fthrow ( Exception, "The size of the geometric confidence image does not match with the original image size: " << fnConfidenceImage.str() );
|
|
|
}
|
|
|
ImageT<double> dst = feats[currentChannel];
|
|
|
-
|
|
|
+
|
|
|
// copy standard image to double image
|
|
|
for ( uint y = 0 ; y < confidenceImage.height(); y++ )
|
|
|
for ( uint x = 0 ; x < confidenceImage.width(); x++ )
|
|
|
- feats(x, y, currentChannel) = (double)confidenceImage(x,y);
|
|
|
+ feats ( x, y, currentChannel ) = ( double ) confidenceImage ( x, y );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1236,6 +1233,9 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
int xsize;
|
|
|
int ysize;
|
|
|
ce->getImageSize ( xsize, ysize );
|
|
|
+ firstiteration = true;
|
|
|
+
|
|
|
+ int classes = labelmapback.size();
|
|
|
|
|
|
int numClasses = classNames->numClasses();
|
|
|
|
|
@@ -1251,7 +1251,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
|
|
|
std::string currentFile = Globals::getCurrentImgFN();
|
|
|
MultiChannelImageT<double> feats;
|
|
|
-
|
|
|
+
|
|
|
NICE::ColorImage img;
|
|
|
|
|
|
try {
|
|
@@ -1260,12 +1260,10 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
cerr << "SemSeg: error opening image file <" << currentFile << ">" << endl;
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
- extractBasicFeatures(feats, img, currentFile); //read image and do some simple transformations
|
|
|
|
|
|
- bool allleaf = false;
|
|
|
+ extractBasicFeatures ( feats, img, currentFile ); //read image and do some simple transformations
|
|
|
|
|
|
- MultiChannelImageT<double> integralImg;
|
|
|
+ bool allleaf = false;
|
|
|
|
|
|
MultiChannelImageT<unsigned short int> currentfeats ( xsize, ysize, nbTrees );
|
|
|
|
|
@@ -1308,7 +1306,6 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
feat.cfeats = &lastfeats;
|
|
|
feat.cTree = tree;
|
|
|
feat.tree = &forest[tree];
|
|
|
- feat.integralImg = &integralImg;
|
|
|
|
|
|
double val = forest[tree][t].feat->getVal ( feat, x, y );
|
|
|
|
|
@@ -1340,43 +1337,29 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
}
|
|
|
#endif
|
|
|
}
|
|
|
-
|
|
|
- /*if ( x == xpos && y == ypos )
|
|
|
- {
|
|
|
- cout << "val: " << val << " decision: " << forest[tree][t].decision << " details: " << forest[tree][t].feat->writeInfos() << endl;
|
|
|
-
|
|
|
- }*/
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ( depth < maxDepth )
|
|
|
{
|
|
|
- //compute integral image
|
|
|
- int channels = ( int ) labelmap.size() + feats.channels();
|
|
|
-
|
|
|
- if ( integralImg.width() == 0 )
|
|
|
+ //compute integral images
|
|
|
+ if ( firstiteration )
|
|
|
{
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
-
|
|
|
- integralImg.reInit ( xsize, ysize, channels );
|
|
|
- integralImg.setAll ( 0.0 );
|
|
|
+ feats.addChannel ( classes + rawChannels );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if ( depth < maxDepth )
|
|
|
{
|
|
|
- computeIntegralImage ( currentfeats, feats, integralImg );
|
|
|
+ computeIntegralImage ( currentfeats, feats, channelType.size() - classes );
|
|
|
#ifdef TEXTONMAP
|
|
|
computeIntegralImage ( textonMap, integralTexton );
|
|
|
#endif
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// cout << forest[0][currentfeats.get ( xpos, ypos, 0 ) ].dist << endl;
|
|
|
-
|
|
|
#ifdef WRITEGLOB
|
|
|
ofstream outstream ( "globtest.feat", ofstream::app );
|
|
|
outstream << 0 << endl;
|
|
@@ -1385,8 +1368,8 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
#endif
|
|
|
|
|
|
string cndir = conf->gS ( "SSContextTree", "cndir", "" );
|
|
|
- int classes = ( int ) probabilities.channels();
|
|
|
- vector<int> useclass ( classes, 1 );
|
|
|
+ int allClasses = ( int ) probabilities.channels();
|
|
|
+ vector<int> useclass ( allClasses, 1 );
|
|
|
#ifdef WRITEGLOB
|
|
|
|
|
|
|
|
@@ -1401,7 +1384,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
|
|
|
if ( cndir != "" )
|
|
|
{
|
|
|
- useclass = vector<int> ( classes, 0 );
|
|
|
+ useclass = vector<int> ( allClasses, 0 );
|
|
|
ifstream infile ( ( cndir + "/" + orgname + ".dat" ).c_str() );
|
|
|
|
|
|
#undef OLD
|
|
@@ -1410,12 +1393,12 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
{
|
|
|
int tmp;
|
|
|
infile >> tmp;
|
|
|
- assert ( tmp >= 0 && tmp < classes );
|
|
|
+ assert ( tmp >= 0 && tmp < allClasses );
|
|
|
useclass[tmp] = 1;
|
|
|
}
|
|
|
#else
|
|
|
int c = 0;
|
|
|
- vector<double> probs ( classes, 0.0 );
|
|
|
+ vector<double> probs ( allClasses, 0.0 );
|
|
|
|
|
|
while ( !infile.eof() && infile.good() )
|
|
|
{
|
|
@@ -1431,7 +1414,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
if ( thr < 0.0 )
|
|
|
thr = 0.0;
|
|
|
|
|
|
- for ( int c = 0; c < classes; c++ )
|
|
|
+ for ( int c = 0; c < allClasses; c++ )
|
|
|
{
|
|
|
if ( probs[c] < thr )
|
|
|
{
|
|
@@ -1441,7 +1424,7 @@ void SemSegContextTree::semanticseg ( CachedExample *ce, NICE::Image & segresult
|
|
|
|
|
|
#endif
|
|
|
|
|
|
- for ( int c = 0; c < classes; c++ )
|
|
|
+ for ( int c = 0; c < allClasses; c++ )
|
|
|
{
|
|
|
if ( useclass[c] == 0 )
|
|
|
{
|
|
@@ -1633,13 +1616,21 @@ void SemSegContextTree::store ( std::ostream & os, int format ) const
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
os << channelType.size() << endl;
|
|
|
- for(int i = 0; i < channelType.size(); i++)
|
|
|
+ for ( int i = 0; i < channelType.size(); i++ )
|
|
|
{
|
|
|
os << channelType[i] << " ";
|
|
|
}
|
|
|
os << endl;
|
|
|
+
|
|
|
+ os << integralMap.size() << endl;
|
|
|
+ for ( int i = 0; i < integralMap.size(); i++ )
|
|
|
+ {
|
|
|
+ os << integralMap[i].first << " " << integralMap[i].second << endl;
|
|
|
+ }
|
|
|
+
|
|
|
+ os << rawChannels << endl;
|
|
|
}
|
|
|
|
|
|
void SemSegContextTree::restore ( std::istream & is, int format )
|
|
@@ -1703,39 +1694,51 @@ void SemSegContextTree::restore ( std::istream & is, int format )
|
|
|
{
|
|
|
for ( uint o = 0; o < ops.size(); o++ )
|
|
|
{
|
|
|
- if ( ops[o]->getOps() == feattype )
|
|
|
- {
|
|
|
- forest[t][n].feat = ops[o]->clone();
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if ( forest[t][n].feat == NULL )
|
|
|
- {
|
|
|
- for ( uint o = 0; o < cops.size(); o++ )
|
|
|
+ for ( uint o2 = 0; o2 < ops[o].size(); o2++ )
|
|
|
{
|
|
|
- if ( cops[o]->getOps() == feattype )
|
|
|
+ if ( forest[t][n].feat == NULL )
|
|
|
{
|
|
|
- forest[t][n].feat = cops[o]->clone();
|
|
|
- break;
|
|
|
+ for ( uint c = 0; c < ops[o].size(); c++ )
|
|
|
+ {
|
|
|
+ if ( ops[o][o2]->getOps() == feattype )
|
|
|
+ {
|
|
|
+ forest[t][n].feat = ops[o][o2]->clone();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
assert ( forest[t][n].feat != NULL );
|
|
|
forest[t][n].feat->restore ( is );
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
channelType.clear();
|
|
|
int ctsize;
|
|
|
is >> ctsize;
|
|
|
- for(int i = 0; i < ctsize; i++)
|
|
|
+ for ( int i = 0; i < ctsize; i++ )
|
|
|
{
|
|
|
int tmp;
|
|
|
is >> tmp;
|
|
|
- channelType.push_back(tmp);
|
|
|
+ channelType.push_back ( tmp );
|
|
|
}
|
|
|
+
|
|
|
+ integralMap.clear();
|
|
|
+ int iMapSize;
|
|
|
+ is >> iMapSize;
|
|
|
+ for ( int i = 0; i < iMapSize; i++ )
|
|
|
+ {
|
|
|
+ int first;
|
|
|
+ int second;
|
|
|
+ is >> first;
|
|
|
+ is >> second;
|
|
|
+ integralMap.push_back ( pair<int, int> ( first, second ) );
|
|
|
+ }
|
|
|
+
|
|
|
+ is >> rawChannels;
|
|
|
}
|
|
|
|
|
|
|