123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- /**
- * @file ClassNames.cpp
- * @brief simple interface for class name confusion
- * @author Erik Rodner
- * @date 02/08/2008
- */
- #include "core/image/ImageT.h"
- #include "core/vector/VectorT.h"
- #include "core/vector/MatrixT.h"
- #include <iostream>
- #include <algorithm>
- #include <string>
- #include <functional>
- #include <assert.h>
- #include "vislearning/cbaselib/ClassNames.h"
- #include "core/basics/StringTools.h"
- #include "core/image/ImageTools.h"
- #include "vislearning/baselib/ICETools.h"
- using namespace OBJREC;
- using namespace std;
- using namespace NICE;
- ClassNames::ClassNames()
- {
- maxClassNo = 0;
- }
- ClassNames::ClassNames ( const ClassNames & cn,
- const std::string & classselection )
- {
- std::set<int> selection;
- cn.getSelection ( classselection, selection );
- maxClassNo = 0;
- store ( cerr );
- for ( map<string, string>::const_iterator i = cn.tbl_code_text.begin();
- i != cn.tbl_code_text.end();
- i++ )
- {
- const std::string & classname = i->second;
- std::string code = i->first;
- if ( cn.tbl_code_classno.find ( code ) == cn.tbl_code_classno.end() )
- {
- fprintf ( stderr, "class %s excluded in base classnames\n", code.c_str() );
- continue;
- }
- int classno = cn.classno ( code );
- if ( selection.find ( classno ) != selection.end() )
- {
- addClass ( classno, code, classname );
- if ( classno > maxClassNo ) maxClassNo = classno;
- #ifdef DEBUG_ClassNames
- fprintf ( stderr, "class %s (%d) inherited\n", code.c_str(), classno );
- #endif
- } else {
- #ifdef DEBUG_ClassNames
- fprintf ( stderr, "class %s (%d) excluded in selection\n", code.c_str(), classno );
- #endif
- }
- }
- }
- ClassNames::ClassNames ( const ClassNames & cn )
- : tbl_code_text ( cn.tbl_code_text ), tbl_text_code ( cn.tbl_text_code ),
- tbl_classno_code ( cn.tbl_classno_code ), tbl_code_classno ( cn.tbl_code_classno ),
- tbl_color_classno ( cn.tbl_color_classno ), tbl_classno_color ( cn.tbl_classno_color ), maxClassNo ( cn.maxClassNo )
- {
- }
- ClassNames::~ClassNames()
- {
- }
- int ClassNames::classnoFromText ( std::string text ) const
- {
- map<string, string>::const_iterator j = tbl_text_code.find ( text );
- if ( j == tbl_text_code.end() ) return -1;
- map<string, int>::const_iterator jj = tbl_code_classno.find ( j->second );
- if ( jj == tbl_code_classno.end() ) return -1;
- return jj->second;
- }
- void ClassNames::getSelection ( const std::string & classselection,
- std::set<int> & classnos ) const
- {
- if ( classselection.size() <= 0 ) return;
- std::vector<string> classlist;
- StringTools::split ( classselection, ',', classlist );
- if ( classlist.size() <= 0 )
- {
- fprintf ( stderr, "FATAL ERROR: wrong format for classselection\n" );
- exit ( -1 );
- } else if ( classlist[0] == "*" )
- {
- map<string, bool> forbidden_classes;
- for ( size_t k = 1 ; k < classlist.size() ; k++ )
- if ( classlist[k].substr ( 0, 1 ) == "-" )
- {
- std::string f_class = classlist[k].substr ( 1 );
- #if defined DEBUG_ClassNames
- fprintf ( stderr, "ClassNames: class %s excluded !\n", f_class.c_str() );
- #endif
- forbidden_classes[ f_class ] = true;
- } else {
- fprintf ( stderr, "FATAL ERROR: wrong format for classselection: *,-class0,class1,...\n" );
- exit ( -1 );
- }
- for ( map<int, string>::const_iterator i = tbl_classno_code.begin();
- i != tbl_classno_code.end();
- i++ )
- {
- int myclassno = i->first;
- const std::string & classname = text ( myclassno );
- if ( forbidden_classes.find ( classname ) != forbidden_classes.end() )
- continue;
- classnos.insert ( myclassno );
- }
- } else {
- for ( vector<string>::const_iterator i = classlist.begin();
- i != classlist.end();
- i++ )
- {
- const std::string & classname = *i;
- map<string, string>::const_iterator j = tbl_text_code.find ( classname );
- if ( j == tbl_text_code.end() )
- {
- fprintf ( stderr, "ClassNames: FATAL ERROR This is not a selection of a subset: %s [%s]\n",
- classname.c_str(), classselection.c_str() );
- exit ( -1 );
- }
- const std::string & code = j->second;
- int myclassno = classno ( code );
- if ( myclassno < 0 ) {
- fprintf ( stderr, "ClassNames: FATAL ERROR This is not a selection of a subset\n" );
- exit ( -1 );
- }
- classnos.insert ( myclassno );
- }
- }
- }
- std::string ClassNames::text ( int classno ) const
- {
- map<string, string>::const_iterator i =
- tbl_code_text.find ( code ( classno ) );
- if ( i == tbl_code_text.end() )
- {
- fprintf ( stderr, "ClassNames: no name found for classno %d\n", classno );
- return "unknown";
- } else {
- return i->second;
- }
- }
- std::string ClassNames::code ( int classno ) const
- {
- map<int, string>::const_iterator i =
- tbl_classno_code.find ( classno );
- if ( i == tbl_classno_code.end() )
- {
- fprintf ( stderr, "ClassNames: no code found for classno %d\n", classno );
- return "unknown";
- } else {
- return i->second;
- }
- }
- int ClassNames::classno ( std::string code ) const
- {
- map<string, int>::const_iterator i =
- tbl_code_classno.find ( code );
- if ( i == tbl_code_classno.end() )
- {
- fthrow ( Exception, "no classno found for code <" << code << ">" );
- } else {
- return i->second;
- }
- }
- int ClassNames::numClasses () const
- {
- return tbl_classno_code.size();
- }
- void ClassNames::addClass ( int classno, const std::string & code,
- const std::string & text )
- {
- tbl_classno_code[classno] = code;
- tbl_text_code[text] = code;
- tbl_code_text[code] = text;
- tbl_code_classno[code] = classno;
- if ( classno > maxClassNo ) maxClassNo = classno;
- }
- bool ClassNames::existsClassno ( int classno ) const
- {
- return ( tbl_classno_code.find ( classno ) != tbl_classno_code.end() );
- }
- // refactor-nice.pl: check this substitution
- // old: bool ClassNames::existsClassCode ( const string & classcode ) const
- bool ClassNames::existsClassCode ( const std::string & classcode ) const
- {
- return ( tbl_code_classno.find ( classcode ) != tbl_code_classno.end() );
- }
- bool ClassNames::readFromConfig ( const Config & datasetconf,
- // refactor-nice.pl: check this substitution
- // old: const string & classselection )
- const std::string & classselection )
- {
- datasetconf.getAllS ( "classnames", tbl_code_text );
- if ( tbl_code_text.size() <= 0 ) {
- fprintf ( stderr, "ClassNames: no classnames specified\n" );
- return false;
- }
- // reverse map and lower case
- for ( map<string, string>::const_iterator i = tbl_code_text.begin();
- i != tbl_code_text.end(); i++ )
- tbl_text_code [ i->second ] = i->first;
- #if defined DEBUG_ClassNames
- cerr << "ClassNames::read: selection = " << classselection << endl;
- #endif
- std::vector<string> classlist;
- StringTools::split ( classselection, ',', classlist );
- if ( classlist.size() <= 0 )
- {
- fprintf ( stderr, "FATAL ERROR: wrong format for classselection\n" );
- exit ( -1 );
- } else if ( classlist[0] == "*" )
- {
- map<string, bool> forbidden_classes;
- for ( size_t k = 1 ; k < classlist.size() ; k++ )
- if ( classlist[k].substr ( 0, 1 ) == "-" )
- {
- // refactor-nice.pl: check this substitution
- // old: string f_class = classlist[k].substr(1);
- std::string f_class = classlist[k].substr ( 1 );
- #if defined DEBUG_ClassNames
- fprintf ( stderr, "ClassNames: class %s excluded !\n", f_class.c_str() );
- #endif
- forbidden_classes[ f_class ] = true;
- } else {
- fprintf ( stderr, "FATAL ERROR: wrong format for classselection: *,-class0,class1,...\n" );
- exit ( -1 );
- }
- int classno_seq = 0;
- for ( map<string, string>::const_iterator i = tbl_code_text.begin();
- i != tbl_code_text.end();
- i++, classno_seq++ )
- {
- const std::string & classname = i->second;
- if ( forbidden_classes.find ( classname ) != forbidden_classes.end() )
- continue;
- // refactor-nice.pl: check this substitution
- // old: string code = tbl_text_code [ i->second ];
- std::string code = tbl_text_code [ i->second ];
- int classno;
- classno = classno_seq;
- tbl_classno_code[classno] = code;
- tbl_code_classno[code] = classno;
- if ( classno > maxClassNo ) maxClassNo = classno;
- #if defined DEBUG_ClassNames
- fprintf ( stderr, "classno %d class code %s class text %s\n", classno, code.c_str(), classname.c_str() );
- #endif
- }
- } else {
- #if defined DEBUG_ClassNames
- cerr << "list : " << classlist.size() << endl;
- #endif
- for ( size_t classno_seq = 0 ; classno_seq < classlist.size() ; classno_seq++ )
- {
- std::string classname = classlist[classno_seq];
- if ( tbl_text_code.find ( classname ) != tbl_text_code.end() )
- {
- std::string code = tbl_text_code [ classname ];
- int classno;
- classno = classno_seq;
- tbl_classno_code[classno] = code;
- tbl_code_classno[code] = classno;
- if ( classno > maxClassNo ) maxClassNo = classno;
- #if defined DEBUG_ClassNames
- fprintf ( stderr, "classno %d class code %s class text %s\n", ( int ) classno, code.c_str(), classname.c_str() );
- #endif
- } else {
- fprintf ( stderr, "ClassNames::ClassNames: FATAL ERROR class >%s< not found in data set\n", classname.c_str() );
- exit ( -1 );
- }
- }
- }
- /****** after all, try to read color coding *******/
- map<string, string> list;
- datasetconf.getAllS ( "colors", list );
- if ( list.size() > 0 ) {
- for ( map<string, string>::const_iterator i = list.begin();
- i != list.end();
- i++ )
- {
- std::string value = i->second;
- std::string classname = i->first;
- int _classno = classno ( classname );
- vector<string> submatches;
- if ( StringTools::regexMatch ( value, "^ *([[:digit:]]+) *: *([[:digit:]]+) *: *([[:digit:]]+) *$", submatches )
- && ( submatches.size() == 4 ) )
- {
- int r = StringTools::convert<int> ( submatches[1] );
- int g = StringTools::convert<int> ( submatches[2] );
- int b = StringTools::convert<int> ( submatches[3] );
- long index = 256 * ( 256 * r + g ) + b;
- tbl_color_classno[index] = _classno;
- tbl_classno_color[_classno] = index;
- } else {
- fprintf ( stderr, "LabeledFileList: parse error colors >%s<\n", value.c_str() );
- exit ( -1 );
- }
- }
- }
- return true;
- }
- int ClassNames::getMaxClassno () const
- {
- return maxClassNo;
- }
- void ClassNames::getRGBColor ( int classno, int & r, int & g, int & b ) const
- {
- map<int, long>::const_iterator i = tbl_classno_color.find ( classno );
- if ( i == tbl_classno_color.end() )
- {
- fprintf ( stderr, "ClassNames: no color setting found for class %d\n", classno );
- getchar();
- double x = classno / ( double ) numClasses();
- double rd, gd, bd;
- convertToPseudoColor ( x, rd, gd, bd );
- r = ( int ) ( 255 * rd );
- g = ( int ) ( 255 * gd );
- b = ( int ) ( 255 * bd );
- } else {
- long color = i->second;
- b = color % 256;
- color /= 256;
- g = color % 256;
- color /= 256;
- r = color % 256;
- }
- }
- void ClassNames::getClassnoFromColor ( int & classno, int r, int g, int b ) const
- {
- long color = 256 * ( 256 * r + g ) + b;
- #if defined WIN32 && defined NICE_USELIB_BOOST
- boost::unordered_map<long, int>::const_iterator i = tbl_color_classno.find ( color );
- #else
- // __gnu_cxx::hash_map<long, int>::const_iterator i = tbl_color_classno.find ( color );
- #ifdef __clang__
- std::unordered_map<long, int>::const_iterator i = tbl_color_classno.find(color);
- #else
- std::tr1::unordered_map<long, int>::const_iterator i = tbl_color_classno.find ( color );
- #endif
- #endif
- if ( i == tbl_color_classno.end() )
- {
- classno = -1;
- } else {
- classno = i->second;
- }
- }
- void ClassNames::labelToRGB ( const NICE::Image & img, NICE::ColorImage & rgb ) const
- {
- int red, green, blue;
- rgb.resize ( img.width(), img.height() );
- for ( int y = 0 ; y < img.height(); y++ )
- for ( int x = 0 ; x < img.width(); x++ )
- {
- int label = img.getPixel ( x, y );
- getRGBColor ( label, red, green, blue );
- rgb.setPixel ( x, y, 0, red );
- rgb.setPixel ( x, y, 1, green );
- rgb.setPixel ( x, y, 2, blue );
- }
- }
- int ClassNames::getBackgroundClass () const
- {
- if ( existsClassCode ( "various" ) )
- return classno ( "various" );
- else if ( existsClassCode ( "background" ) )
- return classno ( "background" );
- else if ( existsClassCode ( "clutter" ) )
- return classno ( "clutter" );
- else
- return 0;
- }
- void ClassNames::restore ( istream & is, int format )
- {
- this->maxClassNo = -1;
-
- if ( is.good() )
- {
-
- std::string tmp;
- is >> tmp; //class name
-
- bool b_endOfBlock ( false ) ;
-
- while ( !b_endOfBlock )
- {
- is >> tmp; // start of block
-
- if ( this->isEndTag( tmp, "ClassNames" ) )
- {
- b_endOfBlock = true;
- continue;
- }
-
- tmp = this->removeStartTag ( tmp );
- if ( tmp.compare("content") == 0 )
- {
- is >> tmp; // size:
- int mySize ( 0 );
- is >> mySize;
- this->tbl_code_text.clear();
- this->tbl_text_code.clear();
- this->tbl_classno_code.clear();
- this->tbl_code_classno.clear();
-
- for ( int i = 0; i < mySize; i++ )
- {
- std::string mytext;
- is >> mytext;
- std::string mycode;
- is >> mycode;
- int myclassno;
- is >> myclassno;
-
- this->tbl_code_text.insert ( std::pair<std::string, std::string> ( mycode, mytext ) );
- this->tbl_text_code.insert ( std::pair<std::string, std::string> ( mytext, mycode ) );
- this->tbl_classno_code.insert ( std::pair<int, std::string> ( myclassno, mycode ) );
- this->tbl_code_classno.insert ( std::pair<std::string, int> ( mycode, myclassno ) );
-
- if ( myclassno > this->maxClassNo )
- this->maxClassNo = myclassno;
- }
-
- is >> tmp; // end of block
- tmp = this->removeEndTag ( tmp );
- }
- else
- {
- std::cerr << "WARNING -- unexpected ClassNames object -- " << tmp << " -- for restoration... aborting" << std::endl;
- throw;
- }
- }
- }
- else
- {
- std::cerr << "ClassNames::restore -- InStream not initialized - restoring not possible!" << std::endl;
- throw;
- }
- }
- void ClassNames::store ( ostream & os, int format ) const
- {
- assert ( tbl_classno_code.size() == tbl_code_classno.size() );
-
- if (os.good())
- {
- // show starting point
- os << this->createStartTag( "ClassNames" ) << std::endl;
-
- os.precision (numeric_limits<double>::digits10 + 1);
-
- os << this->createStartTag( "content" ) << std::endl;
- os << "size: " << this->tbl_classno_code.size() << std::endl;
-
- for ( std::map< int, std::string >::const_iterator iIt = this->tbl_classno_code.begin();
- iIt != this->tbl_classno_code.end();
- iIt++
- )
- {
- int myclassno = iIt->first;
- std::string mycode = iIt->second;
- std::string mytext = text ( myclassno );
-
- os << mytext << " " << mycode << " " << myclassno << endl;
- }
- os << this->createEndTag( "content" ) << std::endl;
-
- // done
- os << this->createEndTag( "ClassNames" ) << std::endl;
- }
- else
- {
- std::cerr << "OutStream not initialized - storing not possible!" << std::endl;
- }
- }
- void ClassNames::clear ()
- {
- tbl_code_text.clear();
- tbl_text_code.clear();
- tbl_classno_code.clear();
- tbl_code_classno.clear();
- tbl_color_classno.clear();
- tbl_classno_color.clear();
- }
|