LocalizationResult.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. /**
  2. * @file LocalizationResult.cpp
  3. * @brief Localization result, what else?
  4. * @author Erik Rodner
  5. * @date 02/13/2008
  6. */
  7. #include "core/image/ImageT.h"
  8. #include "core/vector/VectorT.h"
  9. #include "core/vector/MatrixT.h"
  10. #include <iostream>
  11. #include <core/image/LineT.h>
  12. #include "vislearning/cbaselib/LocalizationResult.h"
  13. #include "ImageInfo.h"
  14. #include "core/basics/StringTools.h"
  15. // use this macro to show labeled images
  16. #undef DEBUG_LOCALIZATIONREAD
  17. #ifdef DEBUG_LOCALIZATIONREAD
  18. #include <core/imagedisplay/ImageDisplay.h>
  19. #endif
  20. using namespace OBJREC;
  21. using namespace std;
  22. using namespace NICE;
  23. /******** SingleLocalizationResult ********/
  24. SingleLocalizationResult::SingleLocalizationResult ( ClassificationResult *_r, const NICE::Region & _reg, int _controlPoints )
  25. : controlPoints(_controlPoints), hasRegionInformation_bool(true), reg(_reg), r(_r)
  26. {
  27. objectid = -1;
  28. reg.getRect(xi,yi,xa,ya);
  29. }
  30. SingleLocalizationResult::SingleLocalizationResult ( ClassificationResult *_r, int _xi, int _yi, int _xa, int _ya )
  31. : controlPoints(4), xi(_xi), yi(_yi), xa(_xa), ya(_ya), hasRegionInformation_bool(true), r(_r)
  32. {
  33. objectid = -1;
  34. // reg.add (xi,yi,xa,ya);
  35. // this might lead to problems...in general the current Region representation is awful !
  36. }
  37. double SingleLocalizationResult::getBBOverlapMeasureMin ( const SingleLocalizationResult & y ) const
  38. {
  39. double measure = 0.0;
  40. int xxi, xyi, xxa, xya;
  41. int yxi, yyi, yxa, yya;
  42. getBoundingBox ( xxi, xyi, xxa, xya );
  43. y.getBoundingBox ( yxi, yyi, yxa, yya );
  44. int mxi = ( xxi > yxi ) ? xxi : yxi;
  45. int myi = ( xyi > yyi ) ? xyi : yyi;
  46. int mxa = ( xxa < yxa ) ? xxa : yxa;
  47. int mya = ( xya < yya ) ? xya : yya;
  48. int iw = mxa - mxi + 1;
  49. int ih = mya - myi + 1;
  50. if ( (iw > 0) && (ih > 0) )
  51. {
  52. // if iw>0 & ih>0
  53. double A = (xxa - xxi + 1)*(xya - xyi + 1);
  54. double B = (yxa - yxi + 1)*(yya - yyi + 1);
  55. double overlap = A < B ? A : B;
  56. measure = iw*ih / overlap;
  57. }
  58. return measure;
  59. }
  60. double SingleLocalizationResult::getBBOverlapMeasure ( const SingleLocalizationResult & y ) const
  61. {
  62. double measure = 0.0;
  63. int xxi, xyi, xxa, xya;
  64. int yxi, yyi, yxa, yya;
  65. getBoundingBox ( xxi, xyi, xxa, xya );
  66. y.getBoundingBox ( yxi, yyi, yxa, yya );
  67. int mxi = ( xxi > yxi ) ? xxi : yxi;
  68. int myi = ( xyi > yyi ) ? xyi : yyi;
  69. int mxa = ( xxa < yxa ) ? xxa : yxa;
  70. int mya = ( xya < yya ) ? xya : yya;
  71. int iw = mxa - mxi + 1;
  72. int ih = mya - myi + 1;
  73. if ( (iw > 0) && (ih > 0) )
  74. {
  75. // if iw>0 & ih>0
  76. double overlap = (xxa - xxi + 1)*(xya - xyi + 1) +
  77. (yxa - yxi + 1)*(yya - yyi + 1) -
  78. iw*ih;
  79. measure = iw*ih / overlap;
  80. }
  81. return measure;
  82. }
  83. void SingleLocalizationResult::getBoundingBox ( int & _xi, int & _yi, int & _xa, int & _ya ) const
  84. {
  85. _xi = xi;
  86. _yi = yi;
  87. _xa = xa;
  88. _ya = ya;
  89. }
  90. void SingleLocalizationResult::getBoundingBox ( RectT<int> & rectangle ) const
  91. {
  92. rectangle = RectT<int> ( CoordT<int> ( xi, yi ), CoordT<int> ( xa, ya ) );
  93. }
  94. void SingleLocalizationResult::getCentroid ( double & x, double & y ) const
  95. {
  96. reg.getCentroid ( x, y );
  97. }
  98. SingleLocalizationResult::~SingleLocalizationResult ()
  99. {
  100. if ( r != NULL )
  101. delete r;
  102. }
  103. /******** LocalizationResult *********/
  104. LocalizationResult::LocalizationResult ( int xsize, int ysize ) : cn(NULL)
  105. {
  106. hasLabeledImage = false;
  107. this->xsize = xsize;
  108. this->ysize = ysize;
  109. }
  110. LocalizationResult::LocalizationResult ( const ClassNames *_cn, int xsize, int ysize ) : cn(_cn)
  111. {
  112. hasLabeledImage = false;
  113. this->xsize = xsize;
  114. this->ysize = ysize;
  115. }
  116. LocalizationResult::~LocalizationResult ()
  117. {
  118. for ( iterator k = begin(); k != end() ; k++ )
  119. {
  120. SingleLocalizationResult *slr = *k;
  121. delete slr;
  122. }
  123. }
  124. LocalizationResult::LocalizationResult ( const ClassNames *_cn, const NICE::Image & img, int classno ) : cn(_cn)
  125. {
  126. // FIXME: just a bad predefined threshold !
  127. const int t = 200;
  128. NICE::Region reg;
  129. #ifdef DEBUG_LOCALIZATIONREAD
  130. NICE::Image imgo (img);
  131. imgo.set(0);
  132. #endif
  133. this->xsize = img.width();
  134. this->ysize = img.height();
  135. for ( int y = 0 ; y < img.height(); y++ )
  136. for ( int x = 0 ; x < img.width(); x++ )
  137. {
  138. if ( img.getPixel(x,y) < t )
  139. {
  140. #ifdef DEBUG_LOCALIZATIONREAD
  141. imgo.setPixel(x,y,1);
  142. #endif
  143. reg.add ( x, y );
  144. }
  145. }
  146. #ifdef DEBUG_LOCALIZATIONREAD
  147. NICE::showImageOverlay ( imgo, imgo );
  148. #endif
  149. ClassificationResult *r = new ClassificationResult (classno, 1.0, _cn->getMaxClassno());
  150. push_back ( new SingleLocalizationResult ( r, reg ) );
  151. hasLabeledImage = false;
  152. }
  153. LocalizationResult::LocalizationResult ( const ClassNames *_cn, const NICE::ColorImage & img) : cn(_cn)
  154. {
  155. map<int, NICE::Region> regions;
  156. xsize = img.width();
  157. ysize = img.height();
  158. #ifdef DEBUG_LOCALIZATIONREAD
  159. NICE::showImage ( img );
  160. NICE::Image imgo (xsize,ysize);
  161. imgo.set(0);
  162. #endif
  163. for ( int y = 0 ; y < ysize ; y++ )
  164. {
  165. int xstart = 0;
  166. // RGB values of the current pixel
  167. int r = img.getPixel(0,y,0);
  168. int g = img.getPixel(0,y,1);
  169. int b = img.getPixel(0,y,2);
  170. for ( int x = 0 ; x < xsize ; x++ )
  171. {
  172. int r_next, g_next, b_next;
  173. if ( x != xsize - 1 ) {
  174. r_next = img.getPixel(x,y,0);
  175. g_next = img.getPixel(x,y,1);
  176. b_next = img.getPixel(x,y,2);
  177. } else {
  178. // at the border of the image, we should
  179. // always have a color change to add the last
  180. // line segment
  181. r_next = -1;
  182. g_next = -1;
  183. b_next = -1;
  184. }
  185. // now the RGB color changes and we have an object boundary
  186. // therefore we have to add a line segment
  187. if ( r != r_next || g != g_next || b != b_next )
  188. {
  189. int classno;
  190. // look up class number for the label color
  191. _cn->getClassnoFromColor ( classno, r, g, b );
  192. if ( classno >= 0 ) {
  193. // add line segment as an rectangular region
  194. regions[classno].add( xstart, y, x, y );
  195. #ifdef DEBUG_LOCALIZATIONREAD
  196. for ( int z = xstart ; z <= x ; z++ )
  197. imgo.setPixel(z,y,classno);
  198. #endif
  199. xstart = x+1;
  200. }
  201. }
  202. r = r_next;
  203. g = g_next;
  204. b = b_next;
  205. }
  206. }
  207. #ifdef DEBUG_LOCALIZATIONREAD
  208. showImageOverlay(imgo, imgo);
  209. #endif
  210. for ( map<int, NICE::Region>::const_iterator j = regions.begin();
  211. j != regions.end();
  212. j++ )
  213. {
  214. int classno = j->first;
  215. ClassificationResult *r = new ClassificationResult (classno, 1.0, _cn->getMaxClassno());
  216. push_back ( new SingleLocalizationResult ( r, j->second ) );
  217. }
  218. hasLabeledImage = false;
  219. }
  220. void LocalizationResult::restore (istream & is, int format)
  221. {
  222. if ( format == FILEFORMAT_PASCAL2006_RESULT )
  223. {
  224. while ( ! is.eof() )
  225. {
  226. double score;
  227. int xi, yi, xa, ya;
  228. // refactor-nice.pl: check this substitution
  229. // old: string classname;
  230. std::string classname;
  231. if ( ! (is >> classname) ) break;
  232. if ( ! (is >> score) ) break;
  233. if ( ! (is >> xi) ) break;
  234. if ( ! (is >> yi) ) break;
  235. if ( ! (is >> xa) ) break;
  236. if ( ! (is >> ya) ) break;
  237. ClassificationResult *r = new ClassificationResult ( cn->classno(classname), score, cn->getMaxClassno() );
  238. SingleLocalizationResult *sr = new SingleLocalizationResult ( r, xi, yi, xa, ya );
  239. push_back ( sr );
  240. }
  241. } else if ( format == FILEFORMAT_PASCAL2006_GROUNDTRUTH ) {
  242. #if 0
  243. /* # Details for object 1 ("PAScat")
  244. Original label for object 1 "PAScat" : "PAScat"
  245. Bounding box for object 1 "PAScat" (Xmin, Ymin) - (Xmax, Ymax) : (11, 135) - (333, 410) */
  246. // refactor-nice.pl: check this substitution
  247. // old: string word;
  248. std::string word;
  249. while ( ! is.eof() )
  250. {
  251. if ( ! (is >> word) ) break;
  252. if ( word != "Bounding" ) continue;
  253. char line[1024];
  254. is.getline (line, 1024);
  255. vector<string> submatches;
  256. bool result = StringTools::regexMatch ( line, "box for object ([:digit]+) \"([:alpha:]+)\" (Xmin, Ymin) - (Xmax, Ymax) : (([:digit:]+) *, *([:digit:]+)) *: *(([:digit:]+) *, *([:digit:]+))", submatches );
  257. cerr << "string: " << line << endl;
  258. for ( vector<string>::const_iterator i = submatches.begin(); i != submatches.end(); i++ )
  259. cerr << "submatch " << *i << endl;
  260. exit(-1);
  261. }
  262. #endif
  263. } else if ( format == FILEFORMAT_POLYGON ) {
  264. // This is limited to bounding boxes ...sorry
  265. while (! is.eof()) {
  266. #define USE_CALTECH101_POLYGON_FORMAT
  267. #ifdef USE_CALTECH101_POLYGON_FORMAT
  268. std::string filename;
  269. if ( !(is >> filename) ) break;
  270. #endif
  271. std::string classname;
  272. if ( !(is >> classname) ) break;
  273. const double score = 1.0;
  274. int classno = cn->classnoFromText(classname);
  275. uint polygon_points;
  276. if ( !(is >> polygon_points) ) break;
  277. int xi = std::numeric_limits<int>::max();
  278. int xa = - std::numeric_limits<int>::max();
  279. int yi = std::numeric_limits<int>::max();
  280. int ya = - std::numeric_limits<int>::max();
  281. for ( uint i = 0 ; i < polygon_points ; i++ )
  282. {
  283. double x,y;
  284. if ( !(is >> x) ) break;
  285. if ( !(is >> y) ) break;
  286. if ( x < xi ) xi = x;
  287. if ( x > xa ) xa = x;
  288. if ( y < yi ) yi = y;
  289. if ( y > ya ) ya = y;
  290. }
  291. if ( classno >= 0 ) {
  292. ClassificationResult *r = new ClassificationResult ( classno, score, cn->getMaxClassno() );
  293. SingleLocalizationResult *sr = new SingleLocalizationResult ( r, xi, yi, xa, ya );
  294. push_back ( sr );
  295. }
  296. }
  297. //sortEmpricalDepth();
  298. } else if ( format == FILEFORMAT_POLYGON_SIFTFLOW ) {
  299. // parser for xml annotations of SIFTFlow dataset
  300. if ( is.good() )
  301. {
  302. std::string tmp;
  303. is >> tmp; // annotation tag
  304. bool b_endOfBlock = false;
  305. while ( !b_endOfBlock )
  306. {
  307. is >> tmp; // get current line
  308. // reached end of file properly
  309. if ( this->isEndTag ( tmp, "annotation") )
  310. {
  311. b_endOfBlock = true;
  312. continue;
  313. }
  314. StringTools::normalize_string( tmp );
  315. tmp = this->removeStartTag ( tmp );
  316. // found new single localization result
  317. if ( tmp.compare("object") == 0 )
  318. {
  319. std::string classname;
  320. is >> classname;
  321. classname = classname.substr( 6, classname.length()-13 ); //remove tags
  322. int classno = cn->classnoFromText(classname);
  323. bool foundPolygonBlock = false;
  324. while ( !foundPolygonBlock )
  325. {
  326. is >> tmp;
  327. StringTools::normalize_string( tmp );
  328. tmp = this->removeStartTag ( tmp );
  329. if ( tmp.compare("polygon") == 0 )
  330. foundPolygonBlock = true;
  331. }
  332. is >> tmp; // 'username' line
  333. NICE::Region newPolygon;
  334. bool endOfPolyBlock = false;
  335. while ( !endOfPolyBlock )
  336. {
  337. is >> tmp; // <pt> or </polygon> ?
  338. if ( this->isEndTag ( tmp, "polygon" ) )
  339. {
  340. endOfPolyBlock = true;
  341. continue;
  342. }
  343. int x, y;
  344. is >> tmp; // <x> ... </x>
  345. StringTools::normalize_string( tmp );
  346. tmp = tmp.substr( 3, tmp.length()-7 ); //remove tags
  347. x = atoi ( tmp.c_str() );
  348. is >> tmp; // <y> ... </y>
  349. StringTools::normalize_string( tmp );
  350. tmp = tmp.substr( 3, tmp.length()-7 ); //remove tags
  351. y = atoi ( tmp.c_str() );
  352. newPolygon.add( x, y );
  353. is >> tmp; // </pt>
  354. }
  355. if ( classno >= 0 ) {
  356. ClassificationResult *r = new ClassificationResult ( classno, 1.0, cn->getMaxClassno() );
  357. SingleLocalizationResult *sr = new SingleLocalizationResult ( r, newPolygon );
  358. push_back ( sr );
  359. }
  360. }
  361. }
  362. }
  363. else
  364. {
  365. fthrow(IOException, "LocalizationResult::restore: InStream not initialized !");
  366. }
  367. }
  368. else {
  369. fthrow(IOException, "LocalizationResult::restore: file format not yet supported !");
  370. }
  371. }
  372. void LocalizationResult::loadImageInfo(std::string sFilename, int selectObjectWithUniqueId)
  373. {
  374. ImageInfo info;
  375. info.loadImageInfo(sFilename);
  376. this->loadImageInfo(info, selectObjectWithUniqueId);
  377. }
  378. void LocalizationResult::loadImageInfo(ImageInfo &p_ImageInfo, int selectObjectWithUniqueId)
  379. {
  380. try
  381. {
  382. const std::list< OBJREC::BoundingBox > *listBBoxes = p_ImageInfo.bboxes();
  383. const double score = 1.0;
  384. OBJREC::BoundingBox box;
  385. std::list< OBJREC::BoundingBox >::const_iterator itBBoxes = listBBoxes->begin();
  386. for(;itBBoxes != listBBoxes->end(); itBBoxes++)
  387. {
  388. box = *itBBoxes;
  389. int id = box.id();
  390. if( selectObjectWithUniqueId != -1 && selectObjectWithUniqueId != box.unique_id_ )
  391. //only extract bounding boxes with a specific unique id. for why, see @
  392. continue;
  393. std::stringstream ss;
  394. ss << id;
  395. std::string classname = ss.str();
  396. int classno = cn->classno(classname);
  397. if(classno == -1)
  398. {
  399. fprintf (stderr, "LocalizationResult::loadImageInfo: no classno found for classname %s (using classno=-1)\n", classname.c_str());
  400. }
  401. ClassificationResult *r = new ClassificationResult ( classno, score, cn->getMaxClassno() );
  402. r->classname = cn->text( classno );
  403. SingleLocalizationResult *sr = new SingleLocalizationResult ( r, box.topLeft().x,
  404. box.topLeft().y,
  405. box.width(),
  406. box.height() );
  407. sr->objectid = box.unique_id_;
  408. this->push_back ( sr );
  409. }
  410. }
  411. catch(Exception e)
  412. {
  413. fthrow( Exception, "LocalizationResult::loadImageInfo: error loading image info (ImageLabeler xml format)");
  414. }
  415. }
  416. void LocalizationResult::store (ostream & os, int format) const
  417. {
  418. if ( format == FILEFORMAT_PASCAL2006_RESULT )
  419. {
  420. for ( const_iterator i = begin(); i != end(); i++ )
  421. {
  422. const SingleLocalizationResult *sr = *i;
  423. const ClassificationResult *r = sr->r;
  424. int classno = r->classno;
  425. double score = r->scores.get(classno);
  426. int xi, yi, xa, ya;
  427. sr->getBoundingBox ( xi, yi, xa, ya );
  428. os << cn->text(r->classno) << " " << score << " "
  429. << xi << " "
  430. << yi << " "
  431. << xa << " "
  432. << ya << " " << endl;
  433. }
  434. } else {
  435. fprintf (stderr, "LocalizationResult::store: file format not yet supported !\n");
  436. exit(-1);
  437. }
  438. }
  439. void LocalizationResult::clear ()
  440. {
  441. for ( iterator k = begin(); k != end() ; k++ )
  442. {
  443. SingleLocalizationResult *slr = *k;
  444. delete slr;
  445. }
  446. vector<SingleLocalizationResult *>::clear();
  447. hasLabeledImage = false;
  448. }
  449. /** returns whether the depth of x is smaller than that of y
  450. !!! no transitivity !!! */
  451. bool depthCompare ( const SingleLocalizationResult *x, const SingleLocalizationResult *y )
  452. {
  453. /** According to the LabelMe paper of Torralba et al., Murphy */
  454. const NICE::Region & rx = x->getRegion();
  455. const NICE::Region & ry = y->getRegion();
  456. NICE::Region intersect;
  457. intersect.setIntersection ( rx, ry );
  458. int ax = rx.size();
  459. int ay = ry.size();
  460. int is = intersect.size();
  461. if ( is == 0 )
  462. {
  463. int nx = x->getControlPoints();
  464. int ny = y->getControlPoints();
  465. return ( nx > ny );
  466. } else {
  467. double ratx = (double)is / ax;
  468. double raty = (double)is / ay;
  469. return ( ratx > raty );
  470. }
  471. }
  472. bool confidenceCompare ( const SingleLocalizationResult *x, const SingleLocalizationResult *y )
  473. {
  474. return ( x->r->confidence() > y->r->confidence() );
  475. }
  476. void LocalizationResult::sortDescendingConfidence()
  477. {
  478. sort ( begin(), end(), confidenceCompare );
  479. }
  480. void LocalizationResult::sortEmpricalDepth()
  481. {
  482. sort ( begin(), end(), depthCompare );
  483. }
  484. void LocalizationResult::calcLabeledImage (
  485. NICE::ImageT<int> & mark,
  486. int backgroundClassNo ) const
  487. {
  488. mark.set(backgroundClassNo);
  489. fprintf (stderr, "LocalizationResult: calcLabeledImage %zd\n", size() );
  490. for ( int y = 0 ; y < mark.height(); y++ )
  491. for ( int x = 0 ; x < mark.width(); x++ )
  492. for ( LocalizationResult::const_iterator k = begin(); k != end() ; k++ )
  493. {
  494. SingleLocalizationResult *slr = *k;
  495. const NICE::Region & r = slr->getRegion();
  496. if ( r.inside(x,y) ) {
  497. mark.setPixel(x,y,slr->r->classno);
  498. break;
  499. }
  500. }
  501. }
  502. void LocalizationResult::calcLabeledImage (
  503. NICE::Image & mark,
  504. int backgroundClassNo ) const
  505. {
  506. NICE::ImageT<int> markInt;
  507. markInt.resize ( mark.width(), mark.height() );
  508. calcLabeledImage( markInt, backgroundClassNo );
  509. for ( int y = 0; y < markInt.height(); y++ )
  510. for ( int x = 0; x < markInt.width(); x++ )
  511. {
  512. int cLabel = markInt.getPixelQuick( x, y );
  513. if ( cLabel > std::numeric_limits<unsigned char>::max() )
  514. std::cerr << "LocalizationResult::calcLabeledImage: To many classes! Labeled image with UCHAR is not sufficient!"
  515. << std::endl;
  516. mark.setPixelQuick( x, y, (unsigned char) cLabel );
  517. }
  518. }
  519. void LocalizationResult::getLabeledImageCache ( NICE::Image & mark ) const
  520. {
  521. assert ( hasLabeledImage );
  522. labeledImage->copyFrom ( mark );
  523. }
  524. void LocalizationResult::setMap ( const NICE::Image & _labeledImage )
  525. {
  526. labeledImage = new Image( _labeledImage );
  527. hasLabeledImage = true;
  528. }
  529. void drawOrthoLine ( NICE::ColorImage & img,
  530. int x1, int y1, int x2, int y2,
  531. int width, int sign,
  532. int r,
  533. int g,
  534. int b )
  535. {
  536. int xi = x1; int yi = y1;
  537. int xa = x2; int ya = y2;
  538. for ( int i = 0 ; i < width; i++ )
  539. {
  540. if ( yi == ya ) {
  541. yi = yi + sign;
  542. ya = ya + sign;
  543. } else if ( xi == xa ) {
  544. xi = xi + sign;
  545. xa = xa + sign;
  546. } else {
  547. assert ( 0 == 1 );
  548. }
  549. if ( (xi>=0) && (yi>=0) && (xa<=img.width())
  550. && (ya<=img.height()) )
  551. {
  552. NICE::Line l ( Coord(xi, yi), Coord(xa, ya) );
  553. img.draw( l, NICE::Color(r, g, b) );
  554. }
  555. }
  556. }
  557. void LocalizationResult::displayBoxes ( NICE::ColorImage & img, const ClassNames *cn,
  558. bool display_confidence, bool invert, int width ) const
  559. {
  560. for ( LocalizationResult::const_iterator k = begin(); k != end() ; k++ )
  561. {
  562. SingleLocalizationResult *slr = *k;
  563. int xi, yi, xa, ya;
  564. slr->getBoundingBox ( xi, yi, xa, ya );
  565. int classno = (slr->r == NULL ) ? 0 : slr->r->classno;
  566. int r,g,b;
  567. if ( cn != NULL ) {
  568. cn->getRGBColor ( classno, r, g, b );
  569. } else {
  570. r = 255;
  571. g = 0;
  572. b = 0;
  573. }
  574. if ( invert ) {
  575. r = 255 - r;
  576. g = 255 - g;
  577. b = 255 - b;
  578. }
  579. if ( display_confidence && (cn != NULL)) {
  580. std::string name = cn->text(classno);
  581. char caption[1024];
  582. sprintf ( caption, "%3.2lf %s", slr->r->confidence(), name.c_str() );
  583. // refactor-nice.pl: check this substitution
  584. // old: Text(caption, xi, yi, r, 0, img.RedImage());
  585. // REFACTOR-FIXME Unable to map this statement
  586. // refactor-nice.pl: check this substitution
  587. // old: Text(caption, xi, yi, g, 0, img.GreenImage());
  588. // REFACTOR-FIXME Unable to map this statement
  589. // refactor-nice.pl: check this substitution
  590. // old: Text(caption, xi, yi, b, 0, img.BlueImage());
  591. // REFACTOR-FIXME Unable to map this statement
  592. }
  593. drawOrthoLine ( img, xi-width, yi, xa+width, yi, width, -1, r, g, b );
  594. drawOrthoLine ( img, xa, yi, xa, ya, width, +1, r, g, b );
  595. drawOrthoLine ( img, xa+width, ya, xi-width, ya, width, +1, r, g, b );
  596. drawOrthoLine ( img, xi, ya, xi, yi, width, -1, r, g, b );
  597. }
  598. }