ClassNames.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. /**
  2. * @file ClassNames.cpp
  3. * @brief simple interface for class name confusion
  4. * @author Erik Rodner
  5. * @date 02/08/2008
  6. */
  7. #include <vislearning/nice_nonvis.h>
  8. #include <iostream>
  9. #include <algorithm>
  10. #include <string>
  11. #include <functional>
  12. #include <assert.h>
  13. #include "vislearning/cbaselib/ClassNames.h"
  14. #include "core/basics/StringTools.h"
  15. #include "vislearning/baselib/ICETools.h"
  16. using namespace OBJREC;
  17. using namespace std;
  18. using namespace NICE;
  19. ClassNames::ClassNames()
  20. {
  21. maxClassNo = 0;
  22. }
  23. ClassNames::ClassNames ( const ClassNames & cn,
  24. const std::string & classselection )
  25. {
  26. std::set<int> selection;
  27. cn.getSelection ( classselection, selection );
  28. maxClassNo = 0;
  29. store ( cerr );
  30. for ( map<string, string>::const_iterator i = cn.tbl_code_text.begin();
  31. i != cn.tbl_code_text.end();
  32. i++ )
  33. {
  34. const std::string & classname = i->second;
  35. std::string code = i->first;
  36. if ( cn.tbl_code_classno.find(code) == cn.tbl_code_classno.end() )
  37. {
  38. fprintf (stderr, "class %s excluded in base classnames\n", code.c_str() );
  39. continue;
  40. }
  41. int classno = cn.classno(code);
  42. if ( selection.find(classno) != selection.end() )
  43. {
  44. addClass( classno, code, classname );
  45. if ( classno > maxClassNo ) maxClassNo = classno;
  46. #ifdef DEBUG_ClassNames
  47. fprintf (stderr, "class %s (%d) inherited\n", code.c_str(), classno );
  48. #endif
  49. } else {
  50. #ifdef DEBUG_ClassNames
  51. fprintf (stderr, "class %s (%d) excluded in selection\n", code.c_str(), classno );
  52. #endif
  53. }
  54. }
  55. }
  56. ClassNames::ClassNames ( const ClassNames & cn )
  57. : tbl_code_text(cn.tbl_code_text), tbl_text_code(cn.tbl_text_code),
  58. tbl_classno_code(cn.tbl_classno_code), tbl_code_classno(cn.tbl_code_classno),
  59. tbl_color_classno(tbl_color_classno), tbl_classno_color(cn.tbl_classno_color), maxClassNo(cn.maxClassNo)
  60. {
  61. }
  62. ClassNames::~ClassNames()
  63. {
  64. }
  65. int ClassNames::classnoFromText ( std::string text ) const
  66. {
  67. map<string, string>::const_iterator j = tbl_text_code.find(text);
  68. if ( j == tbl_text_code.end() ) return -1;
  69. map<string, int>::const_iterator jj = tbl_code_classno.find(j->second);
  70. if ( jj == tbl_code_classno.end() ) return -1;
  71. return jj->second;
  72. }
  73. void ClassNames::getSelection ( const std::string & classselection,
  74. std::set<int> & classnos ) const
  75. {
  76. if ( classselection.size() <= 0 ) return;
  77. std::vector<string> classlist;
  78. StringTools::split ( classselection, ',', classlist );
  79. if ( classlist.size() <= 0 )
  80. {
  81. fprintf (stderr, "FATAL ERROR: wrong format for classselection\n");
  82. exit(-1);
  83. } else if ( classlist[0] == "*" )
  84. {
  85. map<string, bool> forbidden_classes;
  86. for ( size_t k = 1 ; k < classlist.size() ; k++ )
  87. if ( classlist[k].substr(0,1) == "-" )
  88. {
  89. std::string f_class = classlist[k].substr(1);
  90. #if defined DEBUG_ClassNames
  91. fprintf (stderr, "ClassNames: class %s excluded !\n", f_class.c_str() );
  92. #endif
  93. forbidden_classes[ f_class ] = true;
  94. } else {
  95. fprintf (stderr, "FATAL ERROR: wrong format for classselection: *,-class0,class1,...\n");
  96. exit(-1);
  97. }
  98. for ( map<int, string>::const_iterator i = tbl_classno_code.begin();
  99. i != tbl_classno_code.end();
  100. i++ )
  101. {
  102. int myclassno = i->first;
  103. const std::string & classname = text(myclassno);
  104. if ( forbidden_classes.find(classname) != forbidden_classes.end() )
  105. continue;
  106. classnos.insert ( myclassno );
  107. }
  108. } else {
  109. for ( vector<string>::const_iterator i = classlist.begin();
  110. i != classlist.end();
  111. i++ )
  112. {
  113. const std::string & classname = *i;
  114. map<string, string>::const_iterator j = tbl_text_code.find(classname);
  115. if ( j == tbl_text_code.end() )
  116. {
  117. fprintf (stderr, "ClassNames: FATAL ERROR This is not a selection of a subset: %s [%s]\n",
  118. classname.c_str(), classselection.c_str());
  119. exit(-1);
  120. }
  121. const std::string & code = j->second;
  122. int myclassno = classno (code);
  123. if ( myclassno < 0 ) {
  124. fprintf (stderr, "ClassNames: FATAL ERROR This is not a selection of a subset\n");
  125. exit(-1);
  126. }
  127. classnos.insert ( myclassno );
  128. }
  129. }
  130. }
  131. std::string ClassNames::text ( int classno ) const
  132. {
  133. map<string, string>::const_iterator i =
  134. tbl_code_text.find ( code(classno) );
  135. if ( i == tbl_code_text.end() )
  136. {
  137. fprintf (stderr, "ClassNames: no name found for classno %d\n", classno );
  138. return "unknown";
  139. } else {
  140. return i->second;
  141. }
  142. }
  143. std::string ClassNames::code ( int classno ) const
  144. {
  145. map<int, string>::const_iterator i =
  146. tbl_classno_code.find ( classno );
  147. if ( i == tbl_classno_code.end() )
  148. {
  149. fprintf (stderr, "ClassNames: no code found for classno %d\n", classno );
  150. return "unknown";
  151. } else {
  152. return i->second;
  153. }
  154. }
  155. int ClassNames::classno ( std::string code ) const
  156. {
  157. map<string, int>::const_iterator i =
  158. tbl_code_classno.find ( code );
  159. if ( i == tbl_code_classno.end() )
  160. {
  161. fthrow(Exception, "no classno found for code <" << code << ">" );
  162. } else {
  163. return i->second;
  164. }
  165. }
  166. int ClassNames::numClasses () const
  167. {
  168. return tbl_classno_code.size();
  169. }
  170. void ClassNames::addClass ( int classno, const std::string & code,
  171. const std::string & text )
  172. {
  173. tbl_classno_code[classno] = code;
  174. tbl_text_code[text] = code;
  175. tbl_code_text[code] = text;
  176. tbl_code_classno[code] = classno;
  177. if ( classno > maxClassNo ) maxClassNo = classno;
  178. }
  179. bool ClassNames::existsClassno ( int classno ) const
  180. {
  181. return (tbl_classno_code.find(classno) != tbl_classno_code.end());
  182. }
  183. // refactor-nice.pl: check this substitution
  184. // old: bool ClassNames::existsClassCode ( const string & classcode ) const
  185. bool ClassNames::existsClassCode ( const std::string & classcode ) const
  186. {
  187. return (tbl_code_classno.find(classcode) != tbl_code_classno.end());
  188. }
  189. bool ClassNames::readFromConfig ( const Config & datasetconf,
  190. // refactor-nice.pl: check this substitution
  191. // old: const string & classselection )
  192. const std::string & classselection )
  193. {
  194. datasetconf.getAllS ( "classnames", tbl_code_text );
  195. if ( tbl_code_text.size() <= 0 ) {
  196. fprintf (stderr, "ClassNames: no classnames specified\n");
  197. return false;
  198. }
  199. // reverse map and lower case
  200. for ( map<string, string>::const_iterator i = tbl_code_text.begin();
  201. i != tbl_code_text.end(); i++ )
  202. tbl_text_code [ i->second ] = i->first;
  203. #if defined DEBUG_ClassNames
  204. cerr << "ClassNames::read: selection = " << classselection << endl;
  205. #endif
  206. std::vector<string> classlist;
  207. StringTools::split ( classselection, ',', classlist );
  208. if ( classlist.size() <= 0 )
  209. {
  210. fprintf (stderr, "FATAL ERROR: wrong format for classselection\n");
  211. exit(-1);
  212. } else if ( classlist[0] == "*" )
  213. {
  214. map<string, bool> forbidden_classes;
  215. for ( size_t k = 1 ; k < classlist.size() ; k++ )
  216. if ( classlist[k].substr(0,1) == "-" )
  217. {
  218. // refactor-nice.pl: check this substitution
  219. // old: string f_class = classlist[k].substr(1);
  220. std::string f_class = classlist[k].substr(1);
  221. #if defined DEBUG_ClassNames
  222. fprintf (stderr, "ClassNames: class %s excluded !\n", f_class.c_str() );
  223. #endif
  224. forbidden_classes[ f_class ] = true;
  225. } else {
  226. fprintf (stderr, "FATAL ERROR: wrong format for classselection: *,-class0,class1,...\n");
  227. exit(-1);
  228. }
  229. int classno_seq = 0;
  230. for ( map<string, string>::const_iterator i = tbl_code_text.begin();
  231. i != tbl_code_text.end();
  232. i++,classno_seq++ )
  233. {
  234. const std::string & classname = i->second;
  235. if ( forbidden_classes.find(classname) != forbidden_classes.end() )
  236. continue;
  237. // refactor-nice.pl: check this substitution
  238. // old: string code = tbl_text_code [ i->second ];
  239. std::string code = tbl_text_code [ i->second ];
  240. int classno;
  241. classno = classno_seq;
  242. tbl_classno_code[classno] = code;
  243. tbl_code_classno[code] = classno;
  244. if ( classno > maxClassNo ) maxClassNo = classno;
  245. #if defined DEBUG_ClassNames
  246. fprintf (stderr, "classno %d class code %s class text %s\n", classno, code.c_str(), classname.c_str() );
  247. #endif
  248. }
  249. } else {
  250. #if defined DEBUG_ClassNames
  251. cerr << "list : " << classlist.size() << endl;
  252. #endif
  253. for ( size_t classno_seq = 0 ; classno_seq < classlist.size() ; classno_seq++ )
  254. {
  255. std::string classname = classlist[classno_seq];
  256. if ( tbl_text_code.find ( classname ) != tbl_text_code.end() )
  257. {
  258. std::string code = tbl_text_code [ classname ];
  259. int classno;
  260. classno = classno_seq;
  261. tbl_classno_code[classno] = code;
  262. tbl_code_classno[code] = classno;
  263. if ( classno > maxClassNo ) maxClassNo = classno;
  264. #if defined DEBUG_ClassNames
  265. fprintf (stderr, "classno %d class code %s class text %s\n", (int)classno, code.c_str(), classname.c_str() );
  266. #endif
  267. } else {
  268. fprintf (stderr, "ClassNames::ClassNames: FATAL ERROR class >%s< not found in data set\n", classname.c_str() );
  269. exit(-1);
  270. }
  271. }
  272. }
  273. /****** after all, try to read color coding *******/
  274. map<string, string> list;
  275. datasetconf.getAllS ( "colors", list );
  276. if ( list.size() > 0 ) {
  277. for ( map<string,string>::const_iterator i = list.begin();
  278. i != list.end();
  279. i++ )
  280. {
  281. std::string value = i->second;
  282. std::string classname = i->first;
  283. int _classno = classno(classname);
  284. vector<string> submatches;
  285. if ( StringTools::regexMatch ( value, "^ *([[:digit:]]+) *: *([[:digit:]]+) *: *([[:digit:]]+) *$", submatches )
  286. && ( submatches.size() == 4 ) )
  287. {
  288. int r = StringTools::convert<int> ( submatches[1] );
  289. int g = StringTools::convert<int> ( submatches[2] );
  290. int b = StringTools::convert<int> ( submatches[3] );
  291. long index = 256*(256*r + g) + b;
  292. tbl_color_classno[index] = _classno;
  293. tbl_classno_color[_classno] = index;
  294. } else {
  295. fprintf (stderr, "LabeledFileList: parse error colors >%s<\n", value.c_str() );
  296. exit(-1);
  297. }
  298. }
  299. }
  300. return true;
  301. }
  302. int ClassNames::getMaxClassno () const
  303. {
  304. return maxClassNo;
  305. }
  306. void ClassNames::getRGBColor ( int classno, int & r, int & g, int & b ) const
  307. {
  308. map<int, long>::const_iterator i = tbl_classno_color.find(classno);
  309. if ( i == tbl_classno_color.end() )
  310. {
  311. fprintf (stderr, "ClassNames: no color setting found for class %d\n", classno );
  312. getchar();
  313. double x = classno / (double)numClasses();
  314. double rd, gd, bd;
  315. ICETools::toColor ( x, rd, gd, bd );
  316. r = (int)(255*rd);
  317. g = (int)(255*gd);
  318. b = (int)(255*bd);
  319. } else {
  320. long color = i->second;
  321. b = color % 256;
  322. color /= 256;
  323. g = color % 256;
  324. color /= 256;
  325. r = color % 256;
  326. }
  327. }
  328. void ClassNames::getClassnoFromColor ( int & classno, int r, int g, int b ) const
  329. {
  330. long color = 256*(256*r+g) + b;
  331. map<long, int>::const_iterator i = tbl_color_classno.find(color);
  332. if ( i == tbl_color_classno.end() )
  333. {
  334. classno = -1;
  335. } else {
  336. classno = i->second;
  337. }
  338. }
  339. void ClassNames::labelToRGB ( const NICE::Image & img, NICE::ColorImage & rgb ) const
  340. {
  341. int red, green, blue;
  342. rgb.resize(img.width(), img.height());
  343. for ( int y = 0 ; y < img.height(); y++ )
  344. for ( int x = 0 ; x < img.width(); x++ )
  345. {
  346. int label = img.getPixel(x,y);
  347. getRGBColor ( label, red, green, blue );
  348. rgb.setPixel(x,y,0,red);
  349. rgb.setPixel(x,y,1,green);
  350. rgb.setPixel(x,y,2,blue);
  351. }
  352. }
  353. int ClassNames::getBackgroundClass () const
  354. {
  355. if ( existsClassCode ("various" ) )
  356. return classno("various");
  357. else if ( existsClassCode ("background" ) )
  358. return classno("background");
  359. else if ( existsClassCode ("clutter" ) )
  360. return classno("clutter");
  361. else
  362. return 0;
  363. }
  364. void ClassNames::restore (istream & is, int format)
  365. {
  366. maxClassNo = -1;
  367. while ( ! is.eof() )
  368. {
  369. std::string mytext;
  370. std::string mycode;
  371. int myclassno;
  372. if ( !(is >> mytext) ) break;
  373. if ( !(is >> mycode) ) break;
  374. if ( !(is >> myclassno) ) break;
  375. tbl_code_text.insert ( pair<string, string> ( mycode, mytext ) );
  376. tbl_text_code.insert ( pair<string, string> ( mytext, mycode ) );
  377. tbl_classno_code.insert ( pair<int, string> ( myclassno, mycode ) );
  378. tbl_code_classno.insert ( pair<string, int> ( mycode, myclassno ) );
  379. if ( myclassno > maxClassNo ) maxClassNo = myclassno;
  380. }
  381. }
  382. void ClassNames::store (ostream & os, int format) const
  383. {
  384. assert ( tbl_classno_code.size() == tbl_code_classno.size() );
  385. for ( map<int, string>::const_iterator i = tbl_classno_code.begin() ;
  386. i != tbl_classno_code.end();
  387. i++ )
  388. {
  389. int myclassno = i->first;
  390. std::string mycode = i->second;
  391. std::string mytext = text(myclassno);
  392. os << mytext << "\t" << mycode << "\t" << myclassno << endl;
  393. }
  394. }
  395. void ClassNames::clear ()
  396. {
  397. tbl_code_text.clear();
  398. tbl_text_code.clear();
  399. tbl_classno_code.clear();
  400. tbl_code_classno.clear();
  401. tbl_color_classno.clear();
  402. tbl_classno_color.clear();
  403. }