/** * @file ImageInfo.cpp * @brief localization info + image filename + ? * @author Erik Rodner * @date 04/16/2008 */ #include #include #include "vislearning/cbaselib/ImageInfo.h" /* Qt */ #ifdef NICE_USELIB_QT4_XML #include #include #include #include #include #include #include #endif //NICE_USELIB_QT4_XML using namespace OBJREC; using namespace std; using namespace NICE; ImageInfo::~ImageInfo() { //if ( lr != NULL ) //delete lr; } //! A member loading labeled image from formatted xml file. /*! * \param[in] filename a std::string containing a path to the file * we need to load data from * * \see loadLegendFromNode(QDomElement *) * \see BBoxFromData(QString *aBBoxData, int *ID) * \see polyFromData(QString *aPolyData, int *labelID) */ bool ImageInfo::loadImageInfo(const string &aFilename) { #ifdef NICE_USELIB_QT4_XML QString filename(aFilename.data()); QDomDocument doc("Image Labeler"); QFile file(filename); if (!file.open(QIODevice::ReadOnly)) { cout << "loadImageInfo:Can not open such file\n"; return false; /* NOTREACHED */ } QString errMsg; if (!doc.setContent(&file, &errMsg)) { QByteArray array = errMsg.toAscii(); cout << array.data(); //showWarning(errMsg); file.close(); return false; /* NOTREACHED */ } file.close(); /* getting all info */ QDomElement elements = doc.documentElement(); QDomNode rootNode = elements.firstChild(); QString string_buffer; int width = -1; int height = -1; // cout << "\nlet the parsing begin!\n"; while(!rootNode.isNull()) { QDomElement element = rootNode.toElement(); if(!element.isNull()) { /* path to the image */ if (element.tagName() == "image") { string_buffer = element.text(); if (string_buffer.isEmpty()) { cout << "loadImageInfo:The file with data" " doesn't contain path to the image\n"; return false; /* NOTREACHED */ } QByteArray array = string_buffer.toAscii(); image_path_ = string(array.data()); } /* path to the segmented image */ if (element.tagName() == "segmented") { string_buffer = element.text(); if (string_buffer.isEmpty()) { continue; } QByteArray array = string_buffer.toAscii(); segmented_image_path_ = string(array.data()); } /* image description */ else if (element.tagName() == "description") { string_buffer = element.text(); if (string_buffer.isEmpty()) { continue; } QByteArray array = string_buffer.toAscii(); image_description_ = string(array.data()); } /* tags */ else if (element.tagName() == "tags") { string_buffer = element.text(); if (string_buffer.isEmpty()) { rootNode = rootNode.nextSibling(); cout << "tags are empty\n"; continue; } QByteArray array = string_buffer.toAscii(); //TODO: make parsing into the string list tags_ = string(array.data()); } /* legend */ else if (element.tagName() == "legend") { loadLegendFromElement(&element); } /* objects */ else if (element.tagName() == "objects") { QDomNode subNode = element.firstChild(); QDomElement subElement; while(!subNode.isNull()) { subElement = subNode.toElement(); if (subElement.isNull() || subElement.text().isEmpty()) { subNode = subNode.nextSibling(); continue; } string_buffer = subElement.attribute("id"); bool ok = 1; int id = string_buffer.toInt(&ok, 10); if (!ok) { cout << "loadImageInfo: " "poly id format is corrupted\n"; subNode = subNode.nextSibling(); continue; } string_buffer = subElement.text(); if (subElement.tagName() == "bbox") { BoundingBox bbox = BBoxFromData(&string_buffer); bbox.setID(id); bboxes_.push_back(bbox); } if (subElement.tagName() == "poly") { Polygon poly = polyFromData(&string_buffer); poly.setID(id); polys_.push_back(poly); } subNode = subNode.nextSibling(); } } /* image size */ else if (element.tagName() == "image_size") { string_buffer = element.text(); if (string_buffer.isEmpty()) { cout << "loadImageInfo: " "image size format is corrupted\n"; return false; /* NOTREACHED */ } QString buffer; int size = string_buffer.size(); bool ok = 0; for (int i = 0; i < size; i++) { /* ";" is a separator */ if (';' != string_buffer.at(i)) continue; buffer = string_buffer.mid(0, i); width = buffer.toInt(&ok, 10); if (!ok) { cout << "loadImageInfo: " "image size format is corrupted\n"; return false; /* NOTREACHED */ } buffer = string_buffer.mid(i + 1, size - (i + 1)); height = buffer.toInt(&ok, 10); if (!ok) { cout << "loadImageInfo: " "image size format is corrupted"; return false; /* NOTREACHED */ } break; } } else if (element.tagName() == "pure_data") { string_buffer = element.text(); labeled_image_ = imageTFromData(width, height, &string_buffer); } } rootNode = rootNode.nextSibling(); } #endif //NICE_USELIB_QT4_XML return true; } #ifdef NICE_USELIB_QT4_XML //! A member loading legend from xml node /*! * \param[in] anElement a pointer to the object containing all the legend */ void ImageInfo::loadLegendFromElement(QDomElement *anElement) { if (!anElement) { return; /* NOTREACHED */ } QDomNode subNode = anElement->firstChild(); QDomElement subElement; while(!subNode.isNull()) { subElement = subNode.toElement(); if (!subElement.isNull() && !subElement.text().isEmpty()) loadCategoryInfo(&subElement); subNode = subNode.nextSibling(); } } //! Loads one category info(label) from xml QDomElement /*! * \param[in] anElement an object containing category info data */ bool ImageInfo::loadCategoryInfo(QDomElement *anElement) { QString string_buffer; int id = -1; bool isMain; uint color = 0xff000000; /* id attribute */ string_buffer = anElement->attribute("id"); bool ok = 0; id = string_buffer.toInt(&ok, 10); if (!ok) { cout << "loadCategoryInfo: " "label id format is corrupted\n"; return false; /* NOTREACHED */ } /* isMain attribute */ string_buffer = anElement->attribute("isMain"); isMain = string_buffer.toInt(&ok, 2); if (!ok) { cout << "loadCategoryInfo: " "label isMain flag format is corrupted\n"; return false; /* NOTREACHED */ } /* color attribute */ string_buffer = anElement->attribute("color"); color = string_buffer.toUInt(&ok, 16); if (!ok) { cout << "loadCategoryInfo: " "label color format is corrupted\n"; return false; /* NOTREACHED */ } /* converting label name from QString to std::string*/ string_buffer = anElement->text(); QByteArray array = string_buffer.toAscii(); std::string labelName(array.data()); CategoryInfo label; label.setID(id); label.setCategoryName(labelName); label.setColor(color); labels_.push_back(label); } //! A protected member parsing string data and returning a BoundingBox from it /*! * format is x;y;w;h where w - width and h - height */ BoundingBox ImageInfo::BBoxFromData( QString *aBBoxData ) { BoundingBox bbox; QString buffer; int startPos = 0; bool ok = 1; int counter = 0; for (int i = 0; i < aBBoxData->size(); i++) { if (';' != aBBoxData->at(i)) continue; buffer = aBBoxData->mid(startPos, i - startPos); int bboxData = buffer.toInt(&ok, 10); if (!ok) { cout << "BBoxFromData: " "bbox format is corrupted\n"; break; } if (!counter) { bbox.setTopLeft(bboxData, 0); counter++; } else if (1 == counter) { int x = bbox.topLeft().x; bbox.setTopLeft(x, bboxData); counter++; } else if (2 == counter) { bbox.setWidth(bboxData); counter++; } else if (3 == counter) { bbox.setHeight(bboxData); counter++; } startPos = i + 1; } if (!bbox.isValid() || !ok) { cout << "BBoxFromData: " "bbox format is corrupted\n"; bbox.setTopLeft(0, 0); bbox.setBottomRight(0, 0); } return bbox; } //! A protected member parsing string data and returning a Polygon from it /*! * format is x0;y0;x1;y1;... */ Polygon ImageInfo::polyFromData( QString *aPolyData ) { Polygon poly; QPoint point; QString buffer; int startPos = 0; bool ok = 1; /* indicates whether coordinate x or y */ bool evenFlag = 0; for (int i = 0; i < aPolyData->size(); i++) { /* ";" is a separator */ if (';' != aPolyData->at(i)) continue; buffer = aPolyData->mid(startPos, i - startPos); int polyCoor = buffer.toInt(&ok, 10); if (!ok) { cout << "polyFromData: " "poly format is corrupted\n"; break; } if (!evenFlag) { point.setX(polyCoor); evenFlag = 1; } else { point.setY(polyCoor); poly.push(point.x(), point.y()); evenFlag = 0; } startPos = i + 1; } /* last coordinate was Xi what means an error or last converting from string was not successful */ if (evenFlag || !ok) { cout << "polyFromData: " "poly format is corrupted\n"; //poly.clear(); } return poly; } //! ImageT< unsigned int > ImageInfo::imageTFromData( const int &aWidth, const int &aHeight, QString *aPureData ) { int startPos = 0; QString buffer = 0; ImageT< unsigned int > image(aWidth, aHeight); int y = 0; int x = 0; bool ok = 0; for (int i = 0; i < aPureData->size(); i++) { if ('\n' == aPureData->at(i)) { y++; x = 0; startPos = i + 1; continue; } /* ";" is a separator */ if (';' != aPureData->at(i)) continue; buffer = aPureData->mid(startPos, i - startPos); int pixel = buffer.toInt(&ok, 10); if (!ok) { cout << "imageTFromData: " "pure data format is corrupted\n"; image = 0; return image; /* NOTREACHED */ } image.setPixel(x, y, pixel); x++; startPos = i + 1; } return image; } #endif //NICE_USELIB_QT4_XML //! returns pointer to labels_ list const std::list< CategoryInfo > * ImageInfo::labels() const { return &labels_; } //! returns pointer to bboxes_ list const std::list< BoundingBox > * ImageInfo::bboxes() const { return &bboxes_; } //! returns pointer to polys_ list const std::list< Polygon > * ImageInfo::polys() const { return &polys_; } //! returns ImageT object labeled_image_ ImageT< unsigned int > ImageInfo::labeledImage() const { return labeled_image_; } //! returns tags std::string ImageInfo::tags() const { return tags_; } //! returns path to the original image std::string ImageInfo::imagePath() const { return image_path_; } //! returns string with the image description std::string ImageInfo::imageDescription() const { return image_description_; } //! returns path to the image segmented by ImageLabeler tool std::string ImageInfo::segmentedImagePath() const { return segmented_image_path_; } /* * */