ImageInfo.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. /**
  2. * @file ImageInfo.cpp
  3. * @brief localization info + image filename + ?
  4. * @author Erik Rodner
  5. * @date 04/16/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 "vislearning/cbaselib/ImageInfo.h"
  12. /* Qt */
  13. #ifdef NICE_USELIB_QT4_XML
  14. #include <QFile>
  15. #include <QString>
  16. #include <QByteArray>
  17. #include <QDomDocument>
  18. #include <QDomNode>
  19. #include <QDomElement>
  20. #include <QPoint>
  21. #include <QStringList>
  22. #include <QVariant>
  23. #endif //NICE_USELIB_QT4_XML
  24. using namespace OBJREC;
  25. using namespace std;
  26. using namespace NICE;
  27. ImageInfo::~ImageInfo()
  28. {
  29. //if ( lr != NULL )
  30. //delete lr;
  31. }
  32. //! A member loading labeled image from formatted xml file.
  33. /*!
  34. * \param[in] filename a std::string containing a path to the file
  35. * we need to load data from
  36. *
  37. * \see loadLegendFromNode(QDomElement *)
  38. * \see BBoxFromData(QString *aBBoxData, int *ID)
  39. * \see polyFromData(QString *aPolyData, int *labelID)
  40. */
  41. bool
  42. ImageInfo::loadImageInfo(const string &aFilename)
  43. {
  44. #ifdef NICE_USELIB_QT4_XML
  45. QString filename(aFilename.data());
  46. QDomDocument doc("Image Labeler");
  47. QFile file(filename);
  48. if (!file.open(QIODevice::ReadOnly)) {
  49. cout << "loadImageInfo:Can not open such file\n";
  50. return false;
  51. /* NOTREACHED */
  52. }
  53. QString errMsg;
  54. if (!doc.setContent(&file, &errMsg)) {
  55. QByteArray array = errMsg.toAscii();
  56. cout << array.data();
  57. //showWarning(errMsg);
  58. file.close();
  59. return false;
  60. /* NOTREACHED */
  61. }
  62. file.close();
  63. /* getting all info */
  64. QDomElement elements = doc.documentElement();
  65. QDomNode rootNode = elements.firstChild();
  66. QString string_buffer;
  67. int width = -1;
  68. int height = -1;
  69. // cout << "\nlet the parsing begin!\n";
  70. while(!rootNode.isNull()) {
  71. QDomElement element = rootNode.toElement();
  72. if(!element.isNull()) {
  73. /* path to the image */
  74. if (element.tagName() == "image") {
  75. string_buffer = element.text();
  76. if (string_buffer.isEmpty()) {
  77. cout << "loadImageInfo:The file with data"
  78. " doesn't contain path to the image\n";
  79. return false;
  80. /* NOTREACHED */
  81. }
  82. QByteArray array = string_buffer.toAscii();
  83. image_path_ = string(array.data());
  84. }
  85. /* path to the segmented image */
  86. if (element.tagName() == "segmented") {
  87. string_buffer = element.text();
  88. if ( !string_buffer.isEmpty() ) {
  89. QByteArray array = string_buffer.toAscii();
  90. segmented_image_path_ = string(array.data());
  91. }
  92. }
  93. /* image description */
  94. else if (element.tagName() == "description") {
  95. string_buffer = element.text();
  96. if ( !string_buffer.isEmpty()) {
  97. QByteArray array = string_buffer.toAscii();
  98. image_description_ = string(array.data());
  99. }
  100. }
  101. /* tags */
  102. else if (element.tagName() == "tags") {
  103. string_buffer = element.text();
  104. if ( !string_buffer.isEmpty()) {
  105. QByteArray array = string_buffer.toAscii();
  106. //TODO: make parsing into the string list
  107. tags_ = string(array.data());
  108. }
  109. }
  110. /* legend */
  111. else if (element.tagName() == "legend") {
  112. loadLegendFromElement(&element);
  113. }
  114. /* objects */
  115. else if (element.tagName() == "objects") {
  116. QDomNode subNode = element.firstChild();
  117. QDomElement subElement;
  118. while(!subNode.isNull()) {
  119. subElement = subNode.toElement();
  120. if (subElement.isNull() || subElement.text().isEmpty()) {
  121. subNode = subNode.nextSibling();
  122. continue;
  123. }
  124. string_buffer = subElement.attribute("id");
  125. bool ok = 1;
  126. int id = string_buffer.toInt(&ok, 10);
  127. if (!ok) {
  128. cout << "loadImageInfo: "
  129. "poly id format is corrupted\n";
  130. subNode = subNode.nextSibling();
  131. continue;
  132. }
  133. // try reading a unique object/bounding box id, which identifies
  134. // this object against all others (not a label)
  135. string_buffer = subElement.attribute("uniqueObjectId");
  136. ok = 1;
  137. int uniqueObjectId = string_buffer.toInt(&ok, 10);
  138. if(!ok)
  139. uniqueObjectId = -1;
  140. string_buffer = subElement.text();
  141. if (subElement.tagName() == "bbox") {
  142. BoundingBox bbox;
  143. bool bValid = BBoxFromData(&string_buffer, id, bbox);
  144. if( bValid )
  145. {
  146. bbox.unique_id_ = uniqueObjectId;
  147. bboxes_.push_back(bbox);
  148. }
  149. }
  150. if (subElement.tagName() == "poly") {
  151. Polygon poly;
  152. bool bValid = polyFromData(&string_buffer, poly);
  153. if(bValid)
  154. {
  155. poly.setID(id);
  156. poly.unique_id_ = uniqueObjectId;
  157. polys_.push_back(poly);
  158. }
  159. }
  160. subNode = subNode.nextSibling();
  161. }
  162. }
  163. /* image size */
  164. else if (element.tagName() == "image_size") {
  165. string_buffer = element.text();
  166. if (string_buffer.isEmpty()) {
  167. cout << "loadImageInfo: "
  168. "image size format is corrupted\n";
  169. return false;
  170. /* NOTREACHED */
  171. }
  172. QString buffer;
  173. int size = string_buffer.size();
  174. bool ok = 0;
  175. for (int i = 0; i < size; i++) {
  176. /* ";" is a separator */
  177. if (';' != string_buffer.at(i))
  178. continue;
  179. buffer = string_buffer.mid(0, i);
  180. width = buffer.toInt(&ok, 10);
  181. if (!ok) {
  182. cout <<
  183. "loadImageInfo: "
  184. "image size format is corrupted\n";
  185. return false;
  186. /* NOTREACHED */
  187. }
  188. buffer = string_buffer.mid(i + 1, size - (i + 1));
  189. height = buffer.toInt(&ok, 10);
  190. if (!ok) {
  191. cout <<
  192. "loadImageInfo: "
  193. "image size format is corrupted";
  194. return false;
  195. /* NOTREACHED */
  196. }
  197. break;
  198. }
  199. }
  200. else if (element.tagName() == "pure_data") {
  201. string_buffer = element.text();
  202. labeled_image_ = imageTFromData(width, height, &string_buffer);
  203. }
  204. }
  205. rootNode = rootNode.nextSibling();
  206. }
  207. #endif //NICE_USELIB_QT4_XML
  208. return true;
  209. }
  210. #ifdef NICE_USELIB_QT4_XML
  211. //! A member loading legend from xml node
  212. /*!
  213. * \param[in] anElement a pointer to the object containing all the legend
  214. */
  215. void
  216. ImageInfo::loadLegendFromElement(QDomElement *anElement)
  217. {
  218. if (!anElement) {
  219. return;
  220. /* NOTREACHED */
  221. }
  222. QDomNode subNode = anElement->firstChild();
  223. QDomElement subElement;
  224. while(!subNode.isNull()) {
  225. subElement = subNode.toElement();
  226. if (!subElement.isNull() && !subElement.text().isEmpty())
  227. loadCategoryInfo(&subElement);
  228. subNode = subNode.nextSibling();
  229. }
  230. }
  231. //! Loads one category info(label) from xml QDomElement
  232. /*!
  233. * \param[in] anElement an object containing category info data
  234. */
  235. bool
  236. ImageInfo::loadCategoryInfo(QDomElement *anElement)
  237. {
  238. QString string_buffer;
  239. int id = -1;
  240. bool isMain;
  241. uint color = 0xff000000;
  242. /* id attribute */
  243. string_buffer = anElement->attribute("id");
  244. bool ok = 0;
  245. id = string_buffer.toInt(&ok, 10);
  246. if (!ok) {
  247. cout <<
  248. "loadCategoryInfo: "
  249. "label id format is corrupted\n";
  250. return false;
  251. /* NOTREACHED */
  252. }
  253. /* isMain attribute */
  254. string_buffer = anElement->attribute("isMain");
  255. isMain = string_buffer.toInt(&ok, 2);
  256. if (!ok) {
  257. cout <<
  258. "loadCategoryInfo: "
  259. "label isMain flag format is corrupted\n";
  260. return false;
  261. /* NOTREACHED */
  262. }
  263. /* color attribute */
  264. string_buffer = anElement->attribute("color");
  265. color = string_buffer.toUInt(&ok, 16);
  266. if (!ok) {
  267. cout <<
  268. "loadCategoryInfo: "
  269. "label color format is corrupted\n";
  270. return false;
  271. /* NOTREACHED */
  272. }
  273. /* converting label name from QString to std::string*/
  274. string_buffer = anElement->text();
  275. QByteArray array = string_buffer.toAscii();
  276. std::string labelName(array.data());
  277. CategoryInfo label;
  278. label.setID(id);
  279. label.setCategoryName(labelName);
  280. label.setColor(color);
  281. labels_.push_back(label);
  282. return true;
  283. }
  284. //! A protected member parsing string data and returning a BoundingBox from it
  285. /*!
  286. * format is x;y;w;h where w - width and h - height
  287. */
  288. bool ImageInfo::BBoxFromData( QString *aBBoxData, int &id, BoundingBox &p_bbox )
  289. {
  290. p_bbox.setID(id);
  291. QStringList coordsList = aBBoxData->split(";", QString::SkipEmptyParts);
  292. try
  293. {
  294. if( coordsList.size() == 4)
  295. {
  296. int x = QVariant(coordsList[0]).toInt();
  297. int y = QVariant(coordsList[1]).toInt();
  298. int w = QVariant(coordsList[2]).toInt();
  299. int h = QVariant(coordsList[3]).toInt();
  300. p_bbox.setTopLeft(x,y);
  301. p_bbox.setWidth( w );
  302. p_bbox.setHeight( h );
  303. }
  304. else
  305. {
  306. std::cout <<
  307. "BBoxFromData: "
  308. "bbox format is corrupted\n";
  309. return false;
  310. }
  311. }
  312. catch(std::exception &e)
  313. {
  314. std::cout << "BBoxFromData: exception:" << e.what() << std::endl;
  315. return false;
  316. }
  317. if ( !p_bbox.isValid() )
  318. {
  319. std::cout << "BBoxFromData not valid:"<< aBBoxData->toStdString() << std::endl;
  320. p_bbox.setTopLeft(0, 0);
  321. p_bbox.setBottomRight(0, 0);
  322. return false;
  323. }
  324. return true;
  325. }
  326. //! A protected member parsing string data and returning a Polygon from it
  327. /*!
  328. * format is x0;y0;x1;y1;...
  329. */
  330. bool ImageInfo::polyFromData( QString *aPolyData, Polygon &p_Poly)
  331. {
  332. QStringList coordsList = aPolyData->split(";", QString::SkipEmptyParts);
  333. try
  334. {
  335. if( coordsList.size() % 2 == 0)
  336. {
  337. for( int i = 0; i < coordsList.size(); i += 2)
  338. {
  339. p_Poly.push( QVariant(coordsList[i]).toInt(),
  340. QVariant(coordsList[i+1]).toInt() );
  341. }
  342. }
  343. else
  344. {
  345. std::cout << "polyFromData: not valid (coordinates not multiple of two)" << std::endl;
  346. return false;
  347. }
  348. }
  349. catch(std::exception &e)
  350. {
  351. std::cout << "polyFromData: exception:" << e.what() << std::endl;
  352. return false;
  353. }
  354. return true;
  355. }
  356. //!
  357. ImageT< unsigned int >
  358. ImageInfo::imageTFromData(
  359. const int &aWidth,
  360. const int &aHeight,
  361. QString *aPureData
  362. )
  363. {
  364. int startPos = 0;
  365. QString buffer = 0;
  366. ImageT< unsigned int > image(aWidth, aHeight);
  367. int y = 0;
  368. int x = 0;
  369. bool ok = 0;
  370. for (int i = 0; i < aPureData->size(); i++) {
  371. if ('\n' == aPureData->at(i)) {
  372. y++;
  373. x = 0;
  374. startPos = i + 1;
  375. continue;
  376. }
  377. /* ";" is a separator */
  378. if (';' != aPureData->at(i))
  379. continue;
  380. buffer = aPureData->mid(startPos, i - startPos);
  381. int pixel = buffer.toInt(&ok, 10);
  382. if (!ok) {
  383. cout <<
  384. "imageTFromData: "
  385. "pure data format is corrupted\n";
  386. image = 0;
  387. return image;
  388. /* NOTREACHED */
  389. }
  390. image.setPixel(x, y, pixel);
  391. x++;
  392. startPos = i + 1;
  393. }
  394. return image;
  395. }
  396. #endif //NICE_USELIB_QT4_XML
  397. //! returns pointer to labels_ list
  398. const std::list< CategoryInfo > *
  399. ImageInfo::labels() const
  400. {
  401. return &labels_;
  402. }
  403. //! returns pointer to bboxes_ list
  404. const std::list< BoundingBox > *
  405. ImageInfo::bboxes() const
  406. {
  407. return &bboxes_;
  408. }
  409. //! returns pointer to polys_ list
  410. const std::list< Polygon > *
  411. ImageInfo::polys() const
  412. {
  413. return &polys_;
  414. }
  415. //! returns ImageT object labeled_image_
  416. ImageT< unsigned int >
  417. ImageInfo::labeledImage() const
  418. {
  419. return labeled_image_;
  420. }
  421. //! returns tags
  422. std::string
  423. ImageInfo::tags() const
  424. {
  425. return tags_;
  426. }
  427. //! returns path to the original image
  428. std::string
  429. ImageInfo::imagePath() const
  430. {
  431. return image_path_;
  432. }
  433. //! returns string with the image description
  434. std::string
  435. ImageInfo::imageDescription() const
  436. {
  437. return image_description_;
  438. }
  439. //! returns path to the image segmented by ImageLabeler tool
  440. std::string
  441. ImageInfo::segmentedImagePath() const
  442. {
  443. return segmented_image_path_;
  444. }
  445. /*
  446. *
  447. */