/** * @file BoWFeatureConverter.cpp * @brief Convert a set of features into a Bag of visual Words histogram (either by Vector Quantization, or Hard / Soft Assignment) * @author Alexander Freytag * @date 11-06-2013 (dd-mm-yyyy) */ #include #include #include "vislearning/features/simplefeatures/BoWFeatureConverter.h" using namespace OBJREC; using namespace std; using namespace NICE; BoWFeatureConverter::BoWFeatureConverter( const Config *conf, const Codebook *_codebook, const std::string _section ) : codebook(_codebook) { this->s_section = _section; this->p_conf = conf; std::string normalizationMethod = conf->gS( _section, "normalizationMethod", "sum" ); if ( normalizationMethod == "sum" ) this->n_normalizationMethod = NORMALIZE_SUM; else if ( normalizationMethod == "binzero" ) this->n_normalizationMethod = NORMALIZE_BINZERO; else if ( normalizationMethod == "raw" ) this->n_normalizationMethod = NORMALIZE_RAW; else if ( normalizationMethod == "thresh" ) this->n_normalizationMethod = NORMALIZE_THRESH; else { //default: L1 normalization this->n_normalizationMethod = NORMALIZE_SUM; } std::string n_quantizationMethod = conf->gS( _section, "n_quantizationMethod", "VQ" ); if ( normalizationMethod == "VQ" ) this->n_quantizationMethod = VECTOR_QUANTIZATION; else if ( normalizationMethod == "VA" ) this->n_quantizationMethod = VECTOR_ASSIGNMENT; else { //default: standard vector quantization this->n_quantizationMethod = VECTOR_QUANTIZATION; } } BoWFeatureConverter::~BoWFeatureConverter() { } void BoWFeatureConverter::calcHistogram ( const NICE::VVector & features, NICE::Vector & histogram , const bool & b_resetHistogram ) { if ( b_resetHistogram || (histogram.size() != this->codebook->getCodebookSize() ) ) { histogram.resize( this->codebook->getCodebookSize() ); histogram.set(0); } int cluster_index = 0; double weight = 0; double distance = 0.0; if ( this->n_quantizationMethod == VECTOR_QUANTIZATION ) { for ( NICE::VVector::const_iterator featIt = features.begin(); featIt != features.end(); featIt++ ) { const NICE::Vector & x = *featIt; this->codebook->voteVQ ( x, cluster_index, weight, distance ); histogram[ cluster_index ] ++; } } else // VECTOR_ASSIGNMENT (hard or soft can be set directly in the codebook-object) { NICE::Vector assignment (this->codebook->getCodebookSize() );; for ( NICE::VVector::const_iterator featIt = features.begin(); featIt != features.end(); featIt++ ) { assignment.set(0); const NICE::Vector & x = *featIt; this->codebook->voteVA ( x, assignment ); histogram += assignment; } } } void BoWFeatureConverter::normalizeHistogram ( NICE::Vector & histogram ) { if ( n_normalizationMethod == NORMALIZE_RAW ) { // do nothing } else if ( n_normalizationMethod == NORMALIZE_BINZERO ) { for ( size_t i = 0 ; i < histogram.size() ; i++ ) if ( histogram[i] > 0 ) histogram[i] = 1.0; } else if ( n_normalizationMethod == NORMALIZE_SUM ) { double sum = 0.0; for ( size_t i = 0 ; i < histogram.size() ; i++ ) { assert ( histogram[i] >= 0.0 ); sum += histogram[i]; } if ( sum < 1e-5 ) { fprintf (stderr, "BoWFeatureConverter::normalizeHistogram: WARNING histogram is zero !!\n"); return; } for ( size_t i = 0 ; i < histogram.size() ; i++ ) histogram[i] /= sum; } else if ( n_normalizationMethod == NORMALIZE_THRESH ) { const NICE::Vector & thresholds = codebook->getThresholds(); if ( thresholds.size() <= 0 ) { fprintf (stderr, "BoWFeatureConverter:: This is maybe an OLD codebook ! \n"); exit(-1); } for ( size_t i = 0 ; i < histogram.size() ; i++ ) histogram[i] = (histogram[i] > thresholds[i]) ? 1.0 : 0.0; } } int BoWFeatureConverter::getNormalizationMethod () const { return n_normalizationMethod; } void BoWFeatureConverter::setNormalizationMethod ( int normalizationMethod ) { n_normalizationMethod = normalizationMethod; }