|
@@ -72,8 +72,8 @@ SemSegContextTree::SemSegContextTree ( const Config *conf, const MultiDataset *m
|
|
fileLocation = conf->gS ( "debug", "datafile", "tmp.txt" );
|
|
fileLocation = conf->gS ( "debug", "datafile", "tmp.txt" );
|
|
|
|
|
|
useRegionFeature = conf->gB ( section, "use_region_feat", false );
|
|
useRegionFeature = conf->gB ( section, "use_region_feat", false );
|
|
|
|
+ pixelWiseLabeling = conf->gB ( section, "pixelWiseLabeling", false );
|
|
|
|
|
|
- pixelWiseLabeling = false;
|
|
|
|
if ( segmentationtype == "meanshift" )
|
|
if ( segmentationtype == "meanshift" )
|
|
segmentation = new RSMeanShift ( conf );
|
|
segmentation = new RSMeanShift ( conf );
|
|
else if ( segmentationtype == "felzenszwalb" )
|
|
else if ( segmentationtype == "felzenszwalb" )
|
|
@@ -94,75 +94,55 @@ SemSegContextTree::SemSegContextTree ( const Config *conf, const MultiDataset *m
|
|
string featsec = "Features";
|
|
string featsec = "Features";
|
|
|
|
|
|
// feature extraction prototypes
|
|
// feature extraction prototypes
|
|
- vector<Operation*> tops;
|
|
|
|
|
|
+ vector<Operation*> tops0, tops1, tops2;
|
|
|
|
|
|
if ( conf->gB ( featsec, "minus", true ) )
|
|
if ( conf->gB ( featsec, "minus", true ) )
|
|
- tops.push_back ( new Minus() );
|
|
|
|
|
|
+ tops0.push_back ( new Minus() );
|
|
if ( conf->gB ( featsec, "minus_abs", true ) )
|
|
if ( conf->gB ( featsec, "minus_abs", true ) )
|
|
- tops.push_back ( new MinusAbs() );
|
|
|
|
|
|
+ tops0.push_back ( new MinusAbs() );
|
|
if ( conf->gB ( featsec, "addition", true ) )
|
|
if ( conf->gB ( featsec, "addition", true ) )
|
|
- tops.push_back ( new Addition() );
|
|
|
|
|
|
+ tops0.push_back ( new Addition() );
|
|
if ( conf->gB ( featsec, "only1", true ) )
|
|
if ( conf->gB ( featsec, "only1", true ) )
|
|
- tops.push_back ( new Only1() );
|
|
|
|
|
|
+ tops0.push_back ( new Only1() );
|
|
if ( conf->gB ( featsec, "rel_x", true ) )
|
|
if ( conf->gB ( featsec, "rel_x", true ) )
|
|
- tops.push_back ( new RelativeXPosition() );
|
|
|
|
|
|
+ tops0.push_back ( new RelativeXPosition() );
|
|
if ( conf->gB ( featsec, "rel_y", true ) )
|
|
if ( conf->gB ( featsec, "rel_y", true ) )
|
|
- tops.push_back ( new RelativeYPosition() );
|
|
|
|
|
|
+ tops0.push_back ( new RelativeYPosition() );
|
|
if ( conf->gB ( featsec, "rel_z", true ) )
|
|
if ( conf->gB ( featsec, "rel_z", true ) )
|
|
- tops.push_back ( new RelativeZPosition() );
|
|
|
|
|
|
+ tops0.push_back ( new RelativeZPosition() );
|
|
|
|
|
|
- ops.push_back ( tops );
|
|
|
|
|
|
+ tops1.push_back ( new RegionFeat() );
|
|
|
|
|
|
- tops.clear();
|
|
|
|
- tops.push_back ( new RegionFeat() );
|
|
|
|
- ops.push_back ( tops );
|
|
|
|
-
|
|
|
|
- tops.clear();
|
|
|
|
if ( conf->gB ( featsec, "int", true ) )
|
|
if ( conf->gB ( featsec, "int", true ) )
|
|
- tops.push_back ( new IntegralOps() );
|
|
|
|
|
|
+ tops2.push_back ( new IntegralOps() );
|
|
if ( conf->gB ( featsec, "bi_int_cent", true ) )
|
|
if ( conf->gB ( featsec, "bi_int_cent", true ) )
|
|
- tops.push_back ( new BiIntegralCenteredOps() );
|
|
|
|
|
|
+ tops2.push_back ( new BiIntegralCenteredOps() );
|
|
if ( conf->gB ( featsec, "int_cent", true ) )
|
|
if ( conf->gB ( featsec, "int_cent", true ) )
|
|
- tops.push_back ( new IntegralCenteredOps() );
|
|
|
|
|
|
+ tops2.push_back ( new IntegralCenteredOps() );
|
|
if ( conf->gB ( featsec, "haar_horz", true ) )
|
|
if ( conf->gB ( featsec, "haar_horz", true ) )
|
|
- tops.push_back ( new HaarHorizontal() );
|
|
|
|
|
|
+ tops2.push_back ( new HaarHorizontal() );
|
|
if ( conf->gB ( featsec, "haar_vert", true ) )
|
|
if ( conf->gB ( featsec, "haar_vert", true ) )
|
|
- tops.push_back ( new HaarVertical() );
|
|
|
|
|
|
+ tops2.push_back ( new HaarVertical() );
|
|
if ( conf->gB ( featsec, "haar_stack", true ) )
|
|
if ( conf->gB ( featsec, "haar_stack", true ) )
|
|
- tops.push_back ( new HaarStacked() );
|
|
|
|
|
|
+ tops2.push_back ( new HaarStacked() );
|
|
if ( conf->gB ( featsec, "haar_diagxy", true ) )
|
|
if ( conf->gB ( featsec, "haar_diagxy", true ) )
|
|
- tops.push_back ( new HaarDiagXY() );
|
|
|
|
|
|
+ tops2.push_back ( new HaarDiagXY() );
|
|
if ( conf->gB ( featsec, "haar_diagxz", true ) )
|
|
if ( conf->gB ( featsec, "haar_diagxz", true ) )
|
|
- tops.push_back ( new HaarDiagXZ() );
|
|
|
|
|
|
+ tops2.push_back ( new HaarDiagXZ() );
|
|
if ( conf->gB ( featsec, "haar_diagyz", true ) )
|
|
if ( conf->gB ( featsec, "haar_diagyz", true ) )
|
|
- tops.push_back ( new HaarDiagYZ() );
|
|
|
|
|
|
+ tops2.push_back ( new HaarDiagYZ() );
|
|
if ( conf->gB ( featsec, "haar3_horz", true ) )
|
|
if ( conf->gB ( featsec, "haar3_horz", true ) )
|
|
- tops.push_back ( new Haar3Horiz() );
|
|
|
|
|
|
+ tops2.push_back ( new Haar3Horiz() );
|
|
if ( conf->gB ( featsec, "haar3_vert", true ) )
|
|
if ( conf->gB ( featsec, "haar3_vert", true ) )
|
|
- tops.push_back ( new Haar3Vert() );
|
|
|
|
|
|
+ tops2.push_back ( new Haar3Vert() );
|
|
if ( conf->gB ( featsec, "haar3_stack", true ) )
|
|
if ( conf->gB ( featsec, "haar3_stack", true ) )
|
|
- tops.push_back ( new Haar3Stack() );
|
|
|
|
|
|
+ tops2.push_back ( new Haar3Stack() );
|
|
|
|
|
|
- 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() );
|
|
|
|
- if ( conf->gB ( featsec, "rel_z", true ) )
|
|
|
|
- tops.push_back ( new RelativeZPosition() );
|
|
|
|
-
|
|
|
|
- ops.push_back ( tops );
|
|
|
|
|
|
+ ops.push_back ( tops0 );
|
|
|
|
+ ops.push_back ( tops1 );
|
|
|
|
+ ops.push_back ( tops2 );
|
|
|
|
+ ops.push_back ( tops2 );
|
|
|
|
+ ops.push_back ( tops0 );
|
|
|
|
|
|
useGradient = conf->gB ( featsec, "use_gradient", true );
|
|
useGradient = conf->gB ( featsec, "use_gradient", true );
|
|
|
|
|
|
@@ -363,7 +343,6 @@ double SemSegContextTree::getBestSplit (
|
|
|
|
|
|
Operation *op = ops[ft][o]->clone();
|
|
Operation *op = ops[ft][o]->clone();
|
|
op->set ( x1, y1, z1, x2, y2, z2, f1, f2, ft );
|
|
op->set ( x1, y1, z1, x2, y2, z2, f1, f2, ft );
|
|
-// op->setFeatType ( ft );
|
|
|
|
|
|
|
|
if ( ft == 3 || ft == 4 )
|
|
if ( ft == 3 || ft == 4 )
|
|
op->setContext ( true );
|
|
op->setContext ( true );
|
|
@@ -501,12 +480,13 @@ inline double SemSegContextTree::getMeanProb ( const int &x, const int &y, const
|
|
return val / ( double ) nbTrees;
|
|
return val / ( double ) nbTrees;
|
|
}
|
|
}
|
|
|
|
|
|
-void SemSegContextTree::computeIntegralImage ( const NICE::MultiChannelImage3DT<unsigned short int> &nodeIndices, NICE::MultiChannelImage3DT<double> &integralImage, int firstChannel )
|
|
|
|
|
|
+void SemSegContextTree::computeIntegralImage ( const NICE::MultiChannelImage3DT<unsigned short int> &nodeIndices, NICE::MultiChannelImage3DT<double> &feats, int firstChannel )
|
|
{
|
|
{
|
|
- int xsize = integralImage.width();
|
|
|
|
- int ysize = integralImage.height();
|
|
|
|
- int zsize = integralImage.depth();
|
|
|
|
|
|
+ int xsize = feats.width();
|
|
|
|
+ int ysize = feats.height();
|
|
|
|
+ int zsize = feats.depth();
|
|
|
|
|
|
|
|
+ // integral images for raw channels
|
|
if ( firstiteration )
|
|
if ( firstiteration )
|
|
{
|
|
{
|
|
#pragma omp parallel for
|
|
#pragma omp parallel for
|
|
@@ -521,97 +501,33 @@ void SemSegContextTree::computeIntegralImage ( const NICE::MultiChannelImage3DT<
|
|
{
|
|
{
|
|
for ( int x = 0; x < xsize; x++ )
|
|
for ( int x = 0; x < xsize; x++ )
|
|
{
|
|
{
|
|
- integralImage ( x, y, z, cint ) = integralImage ( x, y, z, corg );
|
|
|
|
|
|
+ feats ( x, y, z, cint ) = feats ( x, y, z, corg );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- integralImage.calcIntegral ( cint );
|
|
|
|
|
|
+ feats.calcIntegral ( cint );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- int channels = ( int ) forest[0][0].dist.size();
|
|
|
|
|
|
+ int channels = ( int ) forest[0][0].dist.size(); // channels = classes
|
|
|
|
|
|
|
|
+ // integral images for context channels (probability maps for each class)
|
|
#pragma omp parallel for
|
|
#pragma omp parallel for
|
|
for ( int c = 0; c < channels; c++ )
|
|
for ( int c = 0; c < channels; c++ )
|
|
{
|
|
{
|
|
-
|
|
|
|
- integralImage ( 0, 0, 0, firstChannel + c ) = getMeanProb ( 0, 0, 0, c, nodeIndices );
|
|
|
|
-
|
|
|
|
- //first column
|
|
|
|
- for ( int y = 1; y < ysize; y++ )
|
|
|
|
- {
|
|
|
|
- integralImage ( 0, y, 0, firstChannel + c ) = getMeanProb ( 0, y, 0, c, nodeIndices )
|
|
|
|
- + integralImage ( 0, y - 1, 0, firstChannel + c );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //first row
|
|
|
|
- for ( int x = 1; x < xsize; x++ )
|
|
|
|
- {
|
|
|
|
- integralImage ( x, 0, 0, firstChannel + c ) = getMeanProb ( x, 0, 0, c, nodeIndices )
|
|
|
|
- + integralImage ( x - 1, 0, 0, firstChannel + c );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //first stack
|
|
|
|
- for ( int z = 1; z < zsize; z++ )
|
|
|
|
- {
|
|
|
|
- integralImage ( 0, 0, z, firstChannel + c ) = getMeanProb ( 0, 0, z, c, nodeIndices )
|
|
|
|
- + integralImage ( 0, 0, z - 1, firstChannel + c );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //x-y plane
|
|
|
|
- for ( int y = 1; y < ysize; y++ )
|
|
|
|
- {
|
|
|
|
- for ( int x = 1; x < xsize; x++ )
|
|
|
|
- {
|
|
|
|
- integralImage ( x, y, 0, firstChannel + c ) = getMeanProb ( x, y, 0, c, nodeIndices )
|
|
|
|
- + integralImage ( x, y - 1, 0, firstChannel + c )
|
|
|
|
- + integralImage ( x - 1, y, 0, firstChannel + c )
|
|
|
|
- - integralImage ( x - 1, y - 1, 0, firstChannel + c );
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //y-z plane
|
|
|
|
- for ( int z = 1; z < zsize; z++ )
|
|
|
|
- {
|
|
|
|
- for ( int y = 1; y < ysize; y++ )
|
|
|
|
- {
|
|
|
|
- integralImage ( 0, y, z, firstChannel + c ) = getMeanProb ( 0, y, z, c, nodeIndices )
|
|
|
|
- + integralImage ( 0, y - 1, z, firstChannel + c )
|
|
|
|
- + integralImage ( 0, y, z - 1, firstChannel + c )
|
|
|
|
- - integralImage ( 0, y - 1, z - 1, firstChannel + c );
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //x-z plane
|
|
|
|
- for ( int z = 1; z < zsize; z++ )
|
|
|
|
- {
|
|
|
|
- for ( int x = 1; x < xsize; x++ )
|
|
|
|
- {
|
|
|
|
- integralImage ( x, 0, z, firstChannel + c ) = getMeanProb ( x, 0, z, c, nodeIndices )
|
|
|
|
- + integralImage ( x - 1, 0, z, firstChannel + c )
|
|
|
|
- + integralImage ( x, 0, z - 1, firstChannel + c )
|
|
|
|
- - integralImage ( x - 1, 0, z - 1, firstChannel + c );
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //rest
|
|
|
|
- for ( int z = 1; z < zsize; z++ )
|
|
|
|
|
|
+ for ( int z = 0; z < zsize; z++ )
|
|
{
|
|
{
|
|
- for ( int y = 1; y < ysize; y++ )
|
|
|
|
|
|
+ for ( int y = 0; y < ysize; y++ )
|
|
{
|
|
{
|
|
- for ( int x = 1; x < xsize; x++ )
|
|
|
|
|
|
+ for ( int x = 0; x < xsize; x++ )
|
|
{
|
|
{
|
|
- integralImage ( x, y, z, firstChannel + c ) = getMeanProb ( x, y, z, c, nodeIndices )
|
|
|
|
- + integralImage ( x - 1, y, z, firstChannel + c )
|
|
|
|
- + integralImage ( x, y - 1, z, firstChannel + c )
|
|
|
|
- + integralImage ( x, y, z - 1, firstChannel + c )
|
|
|
|
- + integralImage ( x - 1, y - 1, z - 1, firstChannel + c )
|
|
|
|
- - integralImage ( x - 1, y - 1, z, firstChannel + c )
|
|
|
|
- - integralImage ( x - 1, y, z - 1, firstChannel + c )
|
|
|
|
- - integralImage ( x, y - 1, z - 1, firstChannel + c );
|
|
|
|
|
|
+ double val = getMeanProb ( x, y, z, c, nodeIndices );
|
|
|
|
+ feats ( x, y, z, firstChannel + c ) = val;
|
|
|
|
+ feats ( x, y, z, firstChannel + channels + c ) = val;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ feats.calcIntegral ( firstChannel + c );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -826,13 +742,13 @@ void SemSegContextTree::train ( const LabeledSet * trainp )
|
|
////////////////////////// channel type configuration /////////////////////////
|
|
////////////////////////// channel type configuration /////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
- // Type 0: gray value channels
|
|
|
|
|
|
+ // Type 0: single pixel & pixel-comparison features on gray value channels
|
|
for ( int i = 0; i < rawChannels; i++ )
|
|
for ( int i = 0; i < rawChannels; i++ )
|
|
{
|
|
{
|
|
channelType.push_back ( 0 );
|
|
channelType.push_back ( 0 );
|
|
}
|
|
}
|
|
|
|
|
|
- // Type 1: region channels
|
|
|
|
|
|
+ // Type 1: region channel with unsupervised segmentation
|
|
int shift = 0;
|
|
int shift = 0;
|
|
if ( useRegionFeature )
|
|
if ( useRegionFeature )
|
|
{
|
|
{
|
|
@@ -840,7 +756,7 @@ void SemSegContextTree::train ( const LabeledSet * trainp )
|
|
shift++;
|
|
shift++;
|
|
}
|
|
}
|
|
|
|
|
|
- // Type 2: gray value integral channels
|
|
|
|
|
|
+ // Type 2: rectangutar and Haar-like features on gray value integral channels
|
|
integralMap.clear();
|
|
integralMap.clear();
|
|
for ( int i = 0; i < rawChannels; i++ )
|
|
for ( int i = 0; i < rawChannels; i++ )
|
|
{
|
|
{
|
|
@@ -848,17 +764,17 @@ void SemSegContextTree::train ( const LabeledSet * trainp )
|
|
integralMap.push_back ( pair<int, int> ( i, i + rawChannels + shift ) );
|
|
integralMap.push_back ( pair<int, int> ( i, i + rawChannels + shift ) );
|
|
}
|
|
}
|
|
|
|
|
|
- // Type 3: label integral channels (context)
|
|
|
|
|
|
+ // Type 3: type 2 features on context channels
|
|
for ( int i = 0; i < classes; i++ )
|
|
for ( int i = 0; i < classes; i++ )
|
|
{
|
|
{
|
|
channelType.push_back ( 3 );
|
|
channelType.push_back ( 3 );
|
|
}
|
|
}
|
|
|
|
|
|
- // Type 4: label value channels (context) --> INFO: creates bad splits
|
|
|
|
-// for ( int i = 0; i < classes; i++ )
|
|
|
|
-// {
|
|
|
|
-// channelType.push_back ( 4 );
|
|
|
|
-// }
|
|
|
|
|
|
+ // Type 4: type 0 features on context channels
|
|
|
|
+ for ( int i = 0; i < classes; i++ )
|
|
|
|
+ {
|
|
|
|
+ channelType.push_back ( 4 );
|
|
|
|
+ }
|
|
|
|
|
|
// configure to include all possible feature types (just a subset
|
|
// configure to include all possible feature types (just a subset
|
|
// defined by ftypes is actually used)
|
|
// defined by ftypes is actually used)
|
|
@@ -1215,13 +1131,13 @@ void SemSegContextTree::train ( const LabeledSet * trainp )
|
|
{
|
|
{
|
|
for ( int i = 0; i < imgCounter; i++ )
|
|
for ( int i = 0; i < imgCounter; i++ )
|
|
{
|
|
{
|
|
- allfeats[i].addChannel ( ( int ) ( classes + rawChannels ) );
|
|
|
|
|
|
+ allfeats[i].addChannel ( (2*classes) + rawChannels );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
for ( int i = 0; i < imgCounter; i++ )
|
|
for ( int i = 0; i < imgCounter; i++ )
|
|
{
|
|
{
|
|
- computeIntegralImage ( nodeIndices[i], allfeats[i], channelType.size() - classes );
|
|
|
|
|
|
+ computeIntegralImage ( nodeIndices[i], allfeats[i], channelType.size() - (2*classes) );
|
|
}
|
|
}
|
|
|
|
|
|
if ( firstiteration )
|
|
if ( firstiteration )
|
|
@@ -1758,9 +1674,9 @@ void SemSegContextTree::classify (
|
|
//compute integral images
|
|
//compute integral images
|
|
if ( firstiteration )
|
|
if ( firstiteration )
|
|
{
|
|
{
|
|
- feats.addChannel ( classes + rawChannels );
|
|
|
|
|
|
+ feats.addChannel ( (2*classes) + rawChannels );
|
|
}
|
|
}
|
|
- computeIntegralImage ( nodeIndices, feats, channelType.size() - classes );
|
|
|
|
|
|
+ computeIntegralImage ( nodeIndices, feats, channelType.size() - (2*classes) );
|
|
if ( firstiteration )
|
|
if ( firstiteration )
|
|
{
|
|
{
|
|
firstiteration = false;
|
|
firstiteration = false;
|