|
@@ -68,7 +68,6 @@ SemSegContextTree3D::SemSegContextTree3D () : SemanticSegmentation ()
|
|
|
this->useFeat2 = true;
|
|
|
this->useFeat3 = true;
|
|
|
this->useFeat4 = false;
|
|
|
- this->useFeat5 = false;
|
|
|
this->labelIncrement = 1;
|
|
|
|
|
|
if (coarseMode)
|
|
@@ -128,13 +127,15 @@ SemSegContextTree3D::SemSegContextTree3D (
|
|
|
|
|
|
this->classnames = (*classNames);
|
|
|
|
|
|
+ string forbidden_classes_s = conf->gS ( "analysis", "forbidden_classes", "" );
|
|
|
+ classnames.getSelection ( forbidden_classes_s, forbidden_classes );
|
|
|
+
|
|
|
// feature types
|
|
|
this->useFeat0 = conf->gB ( section, "use_feat_0", true); // pixel pair features
|
|
|
this->useFeat1 = conf->gB ( section, "use_feat_1", false); // region feature
|
|
|
this->useFeat2 = conf->gB ( section, "use_feat_2", true); // integral features
|
|
|
this->useFeat3 = conf->gB ( section, "use_feat_3", true); // integral contex features
|
|
|
this->useFeat4 = conf->gB ( section, "use_feat_4", false); // pixel pair context features
|
|
|
- this->useFeat5 = conf->gB ( section, "use_feat_5", false); // ray features
|
|
|
|
|
|
string segmentationtype = conf->gS ( section, "segmentation_type", "none" );
|
|
|
if ( segmentationtype == "meanshift" )
|
|
@@ -152,9 +153,6 @@ SemSegContextTree3D::SemSegContextTree3D (
|
|
|
else
|
|
|
throw ( "no valid segmenation_type\n please choose between none, meanshift, slic and felzenszwalb\n" );
|
|
|
|
|
|
- if ( !useGradient || imagetype == IMAGETYPE_RGB)
|
|
|
- this->useFeat5 = false;
|
|
|
-
|
|
|
if ( useFeat0 )
|
|
|
this->featTypes.push_back(0);
|
|
|
if ( useFeat1 )
|
|
@@ -165,8 +163,6 @@ SemSegContextTree3D::SemSegContextTree3D (
|
|
|
this->featTypes.push_back(3);
|
|
|
if ( useFeat4 )
|
|
|
this->featTypes.push_back(4);
|
|
|
- if ( useFeat5 )
|
|
|
- this->featTypes.push_back(5);
|
|
|
|
|
|
this->initOperations();
|
|
|
}
|
|
@@ -314,21 +310,11 @@ void SemSegContextTree3D::initOperations()
|
|
|
if ( conf->gB ( featsec, "rel_z", true ) )
|
|
|
tops0.push_back ( new RelativeZPosition3D() );
|
|
|
|
|
|
- if ( conf->gB ( featsec, "ray_diff", false ) )
|
|
|
- tops5.push_back ( new RayDiff3D() );
|
|
|
- if ( conf->gB ( featsec, "ray_dist", false ) )
|
|
|
- tops5.push_back ( new RayDist3D() );
|
|
|
- if ( conf->gB ( featsec, "ray_orient", false ) )
|
|
|
- tops5.push_back ( new RayOrient3D() );
|
|
|
- if ( conf->gB ( featsec, "ray_norm", false ) )
|
|
|
- tops5.push_back ( new RayNorm3D() );
|
|
|
-
|
|
|
this->ops.push_back ( tops0 );
|
|
|
this->ops.push_back ( tops1 );
|
|
|
this->ops.push_back ( tops2 );
|
|
|
this->ops.push_back ( tops3 );
|
|
|
this->ops.push_back ( tops4 );
|
|
|
- this->ops.push_back ( tops5 );
|
|
|
}
|
|
|
|
|
|
double SemSegContextTree3D::getBestSplit (
|
|
@@ -461,13 +447,6 @@ double SemSegContextTree3D::getBestSplit (
|
|
|
z1 = ( int ) ( rand() % tmp_z ) - tmp_z / 2 ;
|
|
|
z2 = ( int ) ( rand() % tmp_z ) - tmp_z / 2 ;
|
|
|
|
|
|
- // use z1/z2 as directions (angles) in ray features
|
|
|
- if ( ft == 5 )
|
|
|
- {
|
|
|
- z1 = ( int ) ( rand() % 8 );
|
|
|
- z2 = ( int ) ( rand() % 8 );
|
|
|
- }
|
|
|
-
|
|
|
if (conf->gB ( "SSContextTree", "z_negative_only", false ))
|
|
|
{
|
|
|
z1 = abs(z1);
|
|
@@ -641,88 +620,6 @@ inline double SemSegContextTree3D::getMeanProb (
|
|
|
return val / ( double ) nbTrees;
|
|
|
}
|
|
|
|
|
|
-void SemSegContextTree3D::computeRayFeatImage (
|
|
|
- NICE::MultiChannelImage3DT<double> &feats,
|
|
|
- int firstChannel )
|
|
|
-{
|
|
|
- int xsize = feats.width();
|
|
|
- int ysize = feats.height();
|
|
|
- int zsize = feats.depth();
|
|
|
-
|
|
|
- const int amountDirs = 8;
|
|
|
-
|
|
|
- // compute ray feature maps from canny image
|
|
|
- for ( int z = 0; z < zsize; z++)
|
|
|
- {
|
|
|
- // canny image from raw channel
|
|
|
- NICE::Image med (xsize,ysize);
|
|
|
- NICE::median ( feats.getChannel( z, 0 ), &med, 2);
|
|
|
- NICE::Image* can = NICE::canny( med, 5, 25);
|
|
|
-
|
|
|
- for ( int dir = 0; dir < amountDirs; dir++)
|
|
|
- {
|
|
|
- NICE::Matrix dist(xsize,ysize,0);
|
|
|
- NICE::Matrix norm(xsize,ysize,0);
|
|
|
- NICE::Matrix orient(xsize,ysize,0);
|
|
|
-
|
|
|
- for (int y = 0; y < ysize; y++)
|
|
|
- for ( int x = 0; x < xsize; x++)
|
|
|
- {
|
|
|
- int xo = 0, yo = 0; // offsets
|
|
|
- int theta = 0;
|
|
|
-
|
|
|
- switch (dir)
|
|
|
- {
|
|
|
- case 0: theta = 0; yo = -1; break;
|
|
|
- case 1: theta = 45; xo = 1; yo = -1; break;
|
|
|
- case 2: theta = 90; xo = 1; x = (xsize-1)-x; break;
|
|
|
- case 3: theta = 135; xo = 1; yo = -1; break;
|
|
|
- case 4: theta = 180; yo = 1; y = (ysize-1)-y; break;
|
|
|
- case 5: theta = 225; xo = -1; yo = 1; y = (ysize-1)-y; break;
|
|
|
- case 6: theta = 270; xo = -1; break;
|
|
|
- case 7: theta = 315; xo = -1; yo = -1; break;
|
|
|
- default: return;
|
|
|
- }
|
|
|
-
|
|
|
- if (can->getPixelQuick(x,y) != 0
|
|
|
- || x+xo < 0
|
|
|
- || x+xo >= xsize
|
|
|
- || y+yo < 0
|
|
|
- || y+yo >= ysize )
|
|
|
- {
|
|
|
- double gx = feats.get(x, y, z, 1);
|
|
|
- double gy = feats.get(x, y, z, 2);
|
|
|
-
|
|
|
- //double go = atan2 (gy, gx);
|
|
|
-
|
|
|
- norm(x, y) = sqrt(gx*gx+gy*gy);
|
|
|
- orient(x, y) = ( gx*cos(theta)+gy*sin(theta) ) / norm(x,y);
|
|
|
- dist(x, y) = 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- orient(x, y) = orient(x+xo,y+yo);
|
|
|
- norm(x, y) = norm(x+xo,y+yo);
|
|
|
- dist(x, y) = dist(x+xo,y+yo) + 1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for (int y = 0; y < ysize; y++)
|
|
|
- for (int x = 0; x < xsize; x++)
|
|
|
- {
|
|
|
- // distance feature maps
|
|
|
- feats.set( x, y, z, dist(x,y), firstChannel + dir );
|
|
|
- // norm feature maps
|
|
|
- feats.set( x, y, z, norm(x,y), firstChannel + amountDirs + dir );
|
|
|
- // orientation feature maps
|
|
|
- feats.set( x, y, z, norm(x,y), firstChannel + (amountDirs*2) + dir );
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- delete can;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
void SemSegContextTree3D::updateProbabilityMaps (
|
|
|
const NICE::MultiChannelImage3DT<unsigned short int> &nodeIndices,
|
|
|
NICE::MultiChannelImage3DT<double> &feats,
|
|
@@ -732,16 +629,14 @@ void SemSegContextTree3D::updateProbabilityMaps (
|
|
|
int ysize = feats.height();
|
|
|
int zsize = feats.depth();
|
|
|
|
|
|
- int classes = ( int ) forest[0][0].dist.size();
|
|
|
+ int classes = ( int ) labelmap.size();
|
|
|
|
|
|
// integral images for context channels (probability maps for each class)
|
|
|
#pragma omp parallel for
|
|
|
for ( int c = 0; c < classes; c++ )
|
|
|
{
|
|
|
for ( int z = 0; z < zsize; z++ )
|
|
|
- {
|
|
|
for ( int y = 0; y < ysize; y++ )
|
|
|
- {
|
|
|
for ( int x = 0; x < xsize; x++ )
|
|
|
{
|
|
|
double val = getMeanProb ( x, y, z, c, nodeIndices );
|
|
@@ -752,17 +647,6 @@ void SemSegContextTree3D::updateProbabilityMaps (
|
|
|
if (useFeat4)
|
|
|
feats ( x, y, z, firstChannel + classes + c ) = val;
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
- // Gaussian filter on probability maps
|
|
|
- // NICE::ImageT<double> img = feats.getChannelT( z, firstChannel+c );
|
|
|
- // NICE::ImageT<double> gF(xsize,ysize);
|
|
|
- // NICE::FilterT<double,double,double> filt;
|
|
|
- // filt.filterGaussSigmaApproximate( img, 2, &gF );
|
|
|
- // for ( int y = 0; y < ysize; y++ )
|
|
|
- // for ( int x = 0; x < xsize; x++ )
|
|
|
- // feats.set(x, y, z, gF.getPixelQuick(x,y), firstChannel+c);
|
|
|
- }
|
|
|
|
|
|
feats.calcIntegral ( firstChannel + c );
|
|
|
}
|
|
@@ -818,9 +702,6 @@ void SemSegContextTree3D::train ( const LabeledSet * trainp )
|
|
|
vector<vector<int> > rSize; // anzahl der pixel je region
|
|
|
vector<int> amountRegionpI; // ANZAHL der regionen pro bild (von unsupervised segmentation)
|
|
|
|
|
|
- std::string forbidden_classes_s = conf->gS ( "analysis", "forbidden_classes", "" );
|
|
|
- classnames.getSelection ( forbidden_classes_s, forbidden_classes );
|
|
|
-
|
|
|
int imgCounter = 0;
|
|
|
int amountPixels = 0;
|
|
|
|
|
@@ -937,7 +818,7 @@ void SemSegContextTree3D::train ( const LabeledSet * trainp )
|
|
|
if ( forbidden_classes.find ( classno ) != forbidden_classes.end() )
|
|
|
continue;
|
|
|
|
|
|
- labelExist[classno] = 1;
|
|
|
+ labelExist[classno] = true;
|
|
|
|
|
|
if ( useCategorization )
|
|
|
classesPerImage[imgCounter][classno] = 1;
|
|
@@ -989,11 +870,6 @@ void SemSegContextTree3D::train ( const LabeledSet * trainp )
|
|
|
for ( int i = 0; i < classes; i++ )
|
|
|
channelType.push_back ( 4 );
|
|
|
|
|
|
- // Type 5: ray features for shape modeling on canny-map
|
|
|
- if ( useFeat5 )
|
|
|
- for ( int i = 0; i < 24; i++ )
|
|
|
- channelType.push_back ( 5 );
|
|
|
-
|
|
|
// 'amountTypes' sets upper bound for usable feature types
|
|
|
int amountTypes = 6;
|
|
|
channelsPerType = vector<vector<int> > ( amountTypes, vector<int>() );
|
|
@@ -1594,7 +1470,7 @@ void SemSegContextTree3D::addFeatureMaps (
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- int classes = classNames->numClasses();
|
|
|
+ int classes = classNames->numClasses() - forbidden_classes.size();
|
|
|
|
|
|
if ( useFeat3 )
|
|
|
imgData.addChannel ( classes );
|
|
@@ -1602,12 +1478,6 @@ void SemSegContextTree3D::addFeatureMaps (
|
|
|
if ( useFeat4 )
|
|
|
imgData.addChannel ( classes );
|
|
|
|
|
|
- if ( useFeat5 )
|
|
|
- {
|
|
|
- imgData.addChannel ( 24 );
|
|
|
- this->computeRayFeatImage( imgData, imgData.channels()-24);
|
|
|
- }
|
|
|
-
|
|
|
}
|
|
|
|
|
|
void SemSegContextTree3D::classify (
|
|
@@ -2230,7 +2100,6 @@ void SemSegContextTree3D::restore ( std::istream & is, int format )
|
|
|
case 2: useFeat2 = true; break;
|
|
|
case 3: useFeat3 = true; break;
|
|
|
case 4: useFeat4 = true; break;
|
|
|
- case 5: useFeat5 = true; break;
|
|
|
}
|
|
|
channelType.push_back ( tmp );
|
|
|
}
|