// STL includes #include #include #include #include /* used for getenv */ // nice-vislearning includes #include "vislearning/baselib/ColorSpace.h" // #include "vislearning/features/localfeatures/LocalFeatureColorWeijer.h" using namespace OBJREC; using namespace std; using namespace NICE; //! color representation for visualization const int colors[11][3] = { {0, 0, 0}, // black {0, 0, 255}, // blue {165, 42, 42}, // brown {190, 190, 190}, // grey { 0, 255, 0}, // green {255, 165, 0}, // orange {255, 192, 203}, // pink {160, 32, 240}, // purple {255, 0, 0}, // red {255, 255, 255}, // white {255, 255, 0}, // yellow }; OBJREC::LocalFeatureColorWeijer::LocalFeatureColorWeijer() { this->tfile = ""; } LocalFeatureColorWeijer::LocalFeatureColorWeijer( const NICE::Config *_conf ) { this->initFromConfig ( _conf ); } LocalFeatureColorWeijer::~LocalFeatureColorWeijer() { } void LocalFeatureColorWeijer::initFromConfig ( const NICE::Config * _conf, const std::string & _confSection ) { this->tfile = _conf->gS( "LocalFeatureColorWeijer", "table", ""); // If no destination to the LUT was given, we try to use the file shipped with this library // Therefore, we try to catch the NICEHOME and if possible, append the location where the LUT file is stored // NOTE This will only work if NICEHOME is set in your environment (e.g., by exporting it in your bashrc or sourcing the setenv.sh) if ( this->tfile.compare("") == 0 ) { char* pNICEHOME; pNICEHOME = getenv ("NICEHOME"); if ( pNICEHOME != NULL ) { this->tfile = std::string ( pNICEHOME ); this->tfile += "/vislearning/features/localfeatures/input/colorWeijer/w2c.txt"; } } this->restoreLUT(); } int LocalFeatureColorWeijer::getDescSize() const { return LASTCOLOR; } void LocalFeatureColorWeijer::restoreLUT() { ifstream fin( this->tfile.c_str() ); if( !fin.is_open() ) { fthrow(Exception,"ColorWeijer: could not find lookup table file. Specify the path in the config, e.g., YOURNICEHOME/vislearning/features/localfeatures/input/colorWeijer/w2c.txt"); } while( !fin.eof() ) { double rd,gd,bd; int r,g,b; fin >> rd; fin >> gd; fin >> bd; r = rd/8; g = gd/8; b = bd/8; // read LUT values for all 11 colornames for( int i = 0; i < 11; i++ ) { fin >> hist[r][g][b][i]; } } /* for(int r = 0; r < 32; r++) { for(int g = 0; g < 32; g++) { for(int b = 0; b < 32; b++) { for(int i = 0; i < 11; i++) { fin >> hist[r][g][b][i]; } } } } */ } int LocalFeatureColorWeijer::getDescriptors( const NICE::Image & img, VVector & positions, VVector & features ) const { throw NICE::Exception ( "LocalFeatureColorWeijer extracts COLOR Features, it won't work on gray value images"); } int LocalFeatureColorWeijer::getDescriptors( const NICE::ColorImage & img, VVector & positions, VVector & features ) const { for ( int j = 0; j < ( int )positions.size(); j++ ) { int x = positions[j][0]; int y = positions[j][1]; int r = img(x,y,0)/8; int g = img(x,y,1)/8; int b = img(x,y,2)/8; NICE::Vector feat( 11 ); for ( uint i = 0; i < 11; i++ ) { feat[i] = hist[r][g][b][i]; } features.push_back( feat ); } return 1; } void LocalFeatureColorWeijer::visualizeFeatures( NICE::Image & mark, const VVector & positions, size_t color ) const { } int LocalFeatureColorWeijer::findColor( string &fn ) { if ( fn.find( "black" ) != string::npos ) return BLACK; if ( fn.find( "blue" ) != string::npos ) return BLUE; if ( fn.find( "brown" ) != string::npos ) return BROWN; if ( fn.find( "grey" ) != string::npos ) return GREY; if ( fn.find( "green" ) != string::npos ) return GREEN; if ( fn.find( "orange" ) != string::npos ) return ORANGE; if ( fn.find( "pink" ) != string::npos ) return PINK; if ( fn.find( "purple" ) != string::npos ) return PURPLE; if ( fn.find( "red" ) != string::npos ) return RED; if ( fn.find( "white" ) != string::npos ) return WHITE; if ( fn.find( "yellow" ) != string::npos ) return YELLOW; return -1; } void LocalFeatureColorWeijer::visualizeFeatures( NICE::ColorImage & out, const VVector & features, const VVector & position ) const { for ( int i = 0; i < ( int )position.size(); i++ ) { int maxpos = 0; double maxval = 0.0; for ( int j = 0; j < ( int )features[i].size(); j++ ) { if ( maxval < features[i][j] ) { maxval = features[i][j]; maxpos = j; } } out.setPixel( position[i][0], position[i][1], colors[maxpos][0], colors[maxpos][1], colors[maxpos][2] ); } } void LocalFeatureColorWeijer::visualizeFeatures( const NICE::ColorImage & cimg ) const { NICE::ColorImage out; this->visualizeFeatures( cimg, out ); } void LocalFeatureColorWeijer::visualizeFeatures( const NICE::ColorImage & cimg, NICE::ColorImage &out ) const { NICE::VVector pos, feats; for ( int y = 0; y < cimg.height(); y++ ) { for ( int x = 0; x < cimg.width(); x++ ) { Vector vec( 2 ); vec[0] = x; vec[1] = y; pos.push_back( vec ); } } this->getDescriptors( cimg, pos, feats ); //heatmap for a special class /*ofstream fout("out.txt"); int counter = 0; for ( int y = 0; y < cimg.height(); y++ ) { for ( int x = 0; x < cimg.width(); x++, counter++ ) { fout << feats[counter][8] << " "; } } cout << "counter: " << counter << " feats.size(): " << feats.size() << endl; fout.close();*/ out.resize( cimg.width(), cimg.height() ); out.set( 0, 0, 0 ); this->visualizeFeatures( out, feats, pos ); NICE::ColorImage combinedout( cimg.width()*2, cimg.height() ); int width = ( int )cimg.width(); for ( int y = 0; y < ( int )cimg.height(); y++ ) { for ( int x = 0; x < width; x++ ) { combinedout.setPixel( x, y, cimg.getPixel( x, y, 0 ), cimg.getPixel( x, y, 1 ), cimg.getPixel( x, y, 2 ) ); combinedout.setPixel( x + width, y, out.getPixel( x, y, 0 ), out.getPixel( x, y, 1 ), out.getPixel( x, y, 2 ) ); } } showImage( combinedout, "result" ); } void LocalFeatureColorWeijer::getFeats( const NICE::ColorImage &img, MultiChannelImageT &feats ) { int width = ( int )img.width(); int height = ( int )img.height(); feats.reInit( width, height, 11); for ( int y = 0; y < height; y++ ) { for ( int x = 0; x < width; x++ ) { int r = img(x,y,0)/8; int g = img(x,y,1)/8; int b = img(x,y,2)/8; for ( uint i = 0; i < 11; i++ ) { feats.set( x, y, hist[r][g][b][i], i ); } } } return; } ///////////////////// INTERFACE PERSISTENT ///////////////////// // interface specific methods for store and restore ///////////////////// INTERFACE PERSISTENT ///////////////////// void LocalFeatureColorWeijer::restore ( std::istream & is, int format ) { //delete everything we knew so far... this->clear(); bool b_restoreVerbose ( false ); #ifdef B_RESTOREVERBOSE b_restoreVerbose = true; #endif if ( is.good() ) { if ( b_restoreVerbose ) std::cerr << " restore LocalFeatureColorWeijer" << std::endl; std::string tmp; is >> tmp; //class name if ( ! this->isStartTag( tmp, "LocalFeatureColorWeijer" ) ) { std::cerr << " WARNING - attempt to restore LocalFeatureColorWeijer, but start flag " << tmp << " does not match! Aborting... " << std::endl; throw; } bool b_endOfBlock ( false ) ; while ( !b_endOfBlock ) { is >> tmp; // start of block if ( this->isEndTag( tmp, "LocalFeatureColorWeijer" ) ) { b_endOfBlock = true; continue; } tmp = this->removeStartTag ( tmp ); if ( b_restoreVerbose ) std::cerr << " currently restore section " << tmp << " in LocalFeatureColorWeijer" << std::endl; if ( tmp.compare("tfile") == 0 ) { is >> this->tfile; is >> tmp; // end of block tmp = this->removeEndTag ( tmp ); } else { std::cerr << "WARNING -- unexpected LocalFeatureColorWeijer object -- " << tmp << " -- for restoration... aborting" << std::endl; throw; } } } else { std::cerr << "LocalFeatureColorWeijer::restore -- InStream not initialized - restoring not possible!" << std::endl; throw; } // try to load the LUT from a separate external file //NOTE we could also think about adding the LUT into the store/restore process. However, the table is BIG, so it would // blow up whole outfile this->restoreLUT ( ) ; } void LocalFeatureColorWeijer::store ( std::ostream & os, int format ) const { if (os.good()) { // show starting point os << this->createStartTag( "LocalFeatureColorWeijer" ) << std::endl; os << this->createStartTag( "tfile" ) << std::endl; os << this->tfile << std::endl; os << this->createEndTag( "tfile" ) << std::endl; // done os << this->createEndTag( "LocalFeatureColorWeijer" ) << std::endl; } else { std::cerr << "OutStream not initialized - storing not possible!" << std::endl; } } void LocalFeatureColorWeijer::clear () { //TODO }