/** * @file ConvolutionFeature.cpp * @brief convolutional feature * @author Sven Sickert * @date 10/13/2008 */ #include #include #include "ConvolutionFeature.h" #include "vislearning/cbaselib/FeaturePool.h" using namespace OBJREC; using namespace NICE; /* Convolutional feature consists of shift parameter params[0] and the convolutional mask, which is stored in the rest of the parameter vector params */ /** simple constructor */ ConvolutionFeature::ConvolutionFeature ( ) { window_size_x = 15; window_size_y = 15; window_size_z = 15; isColor = false; useSpatialPriors = false; initializeParameterVector(); } /** alternative constructor */ ConvolutionFeature::ConvolutionFeature ( const int wsize_x, const int wsize_y, const bool color, const bool prior ) { window_size_x = wsize_x; window_size_y = wsize_y; window_size_z = 1; isColor = color; useSpatialPriors = prior; initializeParameterVector(); } /** alternative 3d constructor */ ConvolutionFeature::ConvolutionFeature ( const int wsize_x, const int wsize_y, const int wsize_z, const bool color, const bool prior ) { window_size_x = wsize_x; window_size_y = wsize_y; window_size_z = wsize_z; isColor = color; useSpatialPriors = prior; initializeParameterVector(); } /** default constructor */ ConvolutionFeature::ConvolutionFeature ( const Config *conf ) { std::string section = "ConvolutionFeature"; window_size_x = conf->gI ( section, "window_size_x", 15 ); window_size_y = conf->gI ( section, "window_size_y", 15 ); window_size_z = conf->gI ( section, "window_size_z", 15 ); isColor = conf->gB ( section, "is_color", false ); useSpatialPriors = conf->gB ( section, "use_spatial_priors", false ); initializeParameterVector(); } /** copy constructor */ ConvolutionFeature::ConvolutionFeature ( const ConvolutionFeature *confFeat ) { window_size_x = confFeat->window_size_x; window_size_y = confFeat->window_size_y; window_size_z = confFeat->window_size_z; paramsLength = confFeat->paramsLength; isColor = confFeat->isColor; useSpatialPriors = confFeat->useSpatialPriors; numChannels = confFeat->numChannels; params = new NICE::Vector( paramsLength, 0.0 ); int i = 0; for ( NICE::Vector::iterator it = confFeat->params->begin(); it != confFeat->params->end(); ++it, i++ ) { params[i] = *it; } } /** simple destructor */ ConvolutionFeature::~ConvolutionFeature ( ) { if ( params != NULL) delete params; } /** (re)initialize parameter vector */ void ConvolutionFeature::initializeParameterVector() { if (window_size_x > 0 && window_size_y > 0 && window_size_z > 0) { if (isColor) numChannels = 3; else numChannels = 1; paramsLength = numChannels*window_size_x*window_size_y*window_size_z + 1; if (useSpatialPriors) paramsLength += 2; params = new NICE::Vector( paramsLength, (1.0/(double)(paramsLength-1) ) ); params[0] = 1; } else std::cerr << "ConvolutionFeature::initializeVector: Size of window is Zero! Could not initialize..." << std::endl; } bool ConvolutionFeature::isColorMode() const { return isColor; } /** return parameter vector */ NICE::Vector ConvolutionFeature::getParameterVector() const { NICE::Vector res = (*this->params); return res; } /** return feature vector */ void ConvolutionFeature::getFeatureVector( const Example *example, NICE::Vector & vec ) const { NICE::MultiChannelImage3DT * imgD = NULL; imgD = & example->ce->getDChannel3( CachedExample::D_EOH ); std::vector data = imgD->getDataPointer(); int xsize, ysize, zsize; example->ce->getImageSize3( xsize, ysize, zsize ); const int x = example->x; const int y = example->y; const int z = example->z; const int halfwsx = std::floor ( window_size_x / 2 ); const int halfwsy = std::floor ( window_size_y / 2 ); const int halfwsz = std::floor ( window_size_z / 2 ); //const int step = window_size_x*window_size_y; int k = 1; for ( int c = 0; c < numChannels; c++) for ( int w = -halfwsz; w <= halfwsz; w++ ) for ( int v = -halfwsy; v <= halfwsy; v++ ) for ( int u = -halfwsx; u <= halfwsx; u++, k++ ) { int uu = u; int vv = v; int ww = w; if (x+u < 0 || x+u >= xsize) uu=-u; if (y+v < 0 || y+v >= ysize) vv=-v; if (z+v < 0 || z+v >= zsize) ww=-w; //vec[k] = imgD->get(x+uu,y+vv,c); vec[k] = data[c][(x+uu)+(y+vv)*xsize+(z+ww)*xsize*ysize]; } if (useSpatialPriors) { vec[paramsLength-2] = (double)x/(double)xsize; vec[paramsLength-1] = (double)y/(double)ysize; } } /** return length of parameter vector */ int ConvolutionFeature::getParameterLength() const { return paramsLength; } void ConvolutionFeature::setRandomParameterVector ( ) { srand (time(NULL)); for ( NICE::Vector::iterator it = params->begin(); it != params->end(); ++it ) { double b = (double) rand() / (double) RAND_MAX; *it = b; } params->normalizeL2(); } /** set parameter vector */ void ConvolutionFeature::setParameterVector( const Vector & vec ) { if ( params->size() == vec.size() ) { int i = 0; for ( NICE::Vector::iterator it = params->begin(); it != params->end(); ++it, i++ ) { *it = vec[i]; } params->normalizeL2(); } else std::cerr << "ConvolutionFeature::setParameterVector: Vector sizes do not match!" << " expected: " << params->size() << ", got: " << vec.size() << std::endl; } /** return feature value */ double ConvolutionFeature::val ( const Example *example ) const { double val1 = 0.0; // is parameter vector and image data available? if (params == NULL) { std::cerr << "ConvolutionalFeature::val: Missing parameter vector!" << std::endl; return val1; } NICE::Vector featVec (paramsLength, 1.0); getFeatureVector ( example, featVec ); // for ( int i = 0; i < featVec.size(); i++ ) // val1 += featVec[i] * params->operator [](i); val1 = params->scalarProduct ( featVec ); return val1; } /** creature feature pool */ void ConvolutionFeature::explode ( FeaturePool &featurePool, bool variableWindow ) const { ConvolutionFeature *f = new ConvolutionFeature ( this->window_size_x, this->window_size_y, this->window_size_z, this->isColor, this->useSpatialPriors ); featurePool.addFeature(f); } /** clone current feature */ Feature *ConvolutionFeature::clone ( ) const { ConvolutionFeature *f = new ConvolutionFeature ( this->window_size_x, this->window_size_y, this->window_size_z, this->isColor, this->useSpatialPriors ); f->setParameterVector( *params ); return f; } Feature *ConvolutionFeature::generateFirstParameter () const { return clone(); } void ConvolutionFeature::restore ( std::istream & is, int format ) { if ( format == 1 ) { is >> window_size_x; is >> window_size_y; is >> window_size_z; } else { is >> window_size_x; is >> window_size_y; window_size_z = 1; } is >> paramsLength; isColor = false; useSpatialPriors = false; numChannels = 1; if ( paramsLength == (window_size_x*window_size_y*window_size_z+3) ) { useSpatialPriors = true; } else if ( paramsLength == (3*window_size_x*window_size_y*window_size_z+1) ) { isColor = true; numChannels = 3; } else if ( paramsLength == (3*window_size_x*window_size_y*window_size_z+3) ) { isColor = true; numChannels = 3; useSpatialPriors = true; } params = new NICE::Vector( paramsLength, 1.0 ); for ( NICE::Vector::iterator it = params->begin(); it != params->end(); ++it ) is >> *it; } void ConvolutionFeature::store ( std::ostream & os, int format ) const { if ( format == 1 ) { os << "ConvolutionFeature " << window_size_x << " " << window_size_y << " " << window_size_z << " " << paramsLength; } else { os << "ConvolutionFeature " << window_size_x << " " << window_size_y << " " << paramsLength; } for ( NICE::Vector::const_iterator it = params->begin(); it != params->end(); ++it ) os << ' ' << *it; } void ConvolutionFeature::clear () { params->clear(); }