diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 149f201f..e8de3fc0 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -12,18 +12,6 @@ SET(LIBRARIES ${OpenCV_LIBS} ) -IF(JSONCPP_FOUND) - SET(INCLUDE_DIRS - ${INCLUDE_DIRS} - ${JSONCPP_INCLUDE_DIRS} - ) - SET(LIBRARIES - ${LIBRARIES} - ${JSONCPP_LIBRARIES} - ) - ADD_DEFINITIONS("-DWITH_JSONCPP") -ENDIF(JSONCPP_FOUND) - #include files INCLUDE_DIRECTORIES(${INCLUDE_DIRS}) diff --git a/app/main.cpp b/app/main.cpp index d2d18c22..dfb1908e 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -6,12 +6,9 @@ #include "find_object/FindObject.h" #include "find_object/Camera.h" #include "find_object/TcpServer.h" +#include "find_object/JsonWriter.h" #include "find_object/utilite/ULogger.h" -#ifdef WITH_JSONCPP -#include -#endif - bool running = true; #ifdef WIN32 @@ -76,89 +73,12 @@ void showUsage() " --objects \"path\" Directory of the objects to detect.\n" " --config \"path\" Path to configuration file (default: %s).\n" " --scene \"path\" Path to a scene image file.\n" -#ifdef WITH_JSONCPP - " --json \"path\" Path to an output JSON file (only in --console mode with --scene).\n" -#endif " --help Show usage.\n", Settings::iniDefaultPath().toStdString().c_str()); - exit(-1); -} - -void writeJSON(const FindObject & findObject, const QString & path) -{ -#ifdef WITH_JSONCPP - if(!path.isEmpty()) + if(JsonWriter::available()) { - Json::Value root; - Json::Value detections; - Json::Value matchesValues; - - if(findObject.objectsDetected().size()) - { - Q_ASSERT(objectsDetected.size() == findObject.inliers().size() && - objectsDetected.size() == findObject.outliers().size()); - - const QMultiMap > & objectsDetected = findObject.objectsDetected(); - QMultiMap >::const_iterator iterInliers = findObject.inliers().constBegin(); - QMultiMap >::const_iterator iterOutliers = findObject.outliers().constBegin(); - for(QMultiMap >::const_iterator iter = objectsDetected.constBegin(); - iter!= objectsDetected.end();) - { - char index = 'a'; - QMultiMap >::const_iterator jter = iter; - for(;jter != objectsDetected.constEnd() && jter.key() == iter.key(); ++jter) - { - QString name = QString("object_%1%2").arg(jter.key()).arg(objectsDetected.count(jter.key())>1?QString(index++):""); - detections.append(name.toStdString()); - - Json::Value homography; - homography.append(jter.value().second.m11()); - homography.append(jter.value().second.m12()); - homography.append(jter.value().second.m13()); - homography.append(jter.value().second.m21()); - homography.append(jter.value().second.m22()); - homography.append(jter.value().second.m23()); - homography.append(jter.value().second.m31()); // dx - homography.append(jter.value().second.m32()); // dy - homography.append(jter.value().second.m33()); - root[name.toStdString()]["width"] = jter.value().first.width(); - root[name.toStdString()]["height"] = jter.value().first.height(); - root[name.toStdString()]["homography"] = homography; - root[name.toStdString()]["inliers"] = iterInliers.value().size(); - root[name.toStdString()]["outliers"] = iterOutliers.value().size(); - - ++iterInliers; - ++iterOutliers; - } - iter = jter; - } - } - - const QMap > & matches = findObject.matches(); - for(QMap >::const_iterator iter = matches.constBegin(); - iter != matches.end(); - ++iter) - { - QString name = QString("matches_%1").arg(iter.key()); - root[name.toStdString()] = iter.value().size(); - matchesValues.append(name.toStdString()); - } - - root["objects"] = detections; - root["matches"] = matchesValues; - - // write in a nice readible way - Json::StyledWriter styledWriter; - //std::cout << styledWriter.write(root); - QFile file(path); - file.open(QIODevice::WriteOnly | QIODevice::Text); - QTextStream out(&file); - out << styledWriter.write(root).c_str(); - file.close(); - UINFO("JSON written to \"%s\"", path.toStdString().c_str()); + printf(" --json \"path\" Path to an output JSON file (only in --console mode with --scene).\n"); } -#else - UERROR("Not built with JSON support!"); -#endif + exit(-1); } int main(int argc, char* argv[]) @@ -249,26 +169,6 @@ int main(int argc, char* argv[]) } continue; } -#ifdef WITH_JSONCPP - if(strcmp(argv[i], "-json") == 0 || - strcmp(argv[i], "--json") == 0) - { - ++i; - if(i < argc) - { - jsonPath = argv[i]; - if(jsonPath.contains('~')) - { - jsonPath.replace('~', QDir::homePath()); - } - } - else - { - showUsage(); - } - continue; - } -#endif if(strcmp(argv[i], "-console") == 0 || strcmp(argv[i], "--console") == 0) { @@ -280,6 +180,27 @@ int main(int argc, char* argv[]) { showUsage(); } + if(JsonWriter::available()) + { + if(strcmp(argv[i], "-json") == 0 || + strcmp(argv[i], "--json") == 0) + { + ++i; + if(i < argc) + { + jsonPath = argv[i]; + if(jsonPath.contains('~')) + { + jsonPath.replace('~', QDir::homePath()); + } + } + else + { + showUsage(); + } + continue; + } + } UERROR("Unrecognized option : %s", argv[i]); showUsage(); @@ -290,9 +211,10 @@ int main(int argc, char* argv[]) UINFO(" Objects path: \"%s\"", objectsPath.toStdString().c_str()); UINFO(" Scene path: \"%s\"", scenePath.toStdString().c_str()); UINFO(" Settings path: \"%s\"", configPath.toStdString().c_str()); -#ifdef WITH_JSONCPP - UINFO(" JSON path: \"%s\"", jsonPath.toStdString().c_str()); -#endif + if(JsonWriter::available()) + { + UINFO(" JSON path: \"%s\"", jsonPath.toStdString().c_str()); + } ////////////////////////// // parse options END @@ -353,26 +275,42 @@ int main(int argc, char* argv[]) QCoreApplication app(argc, argv); - TcpServer tcpServer(Settings::getGeneral_port()); - UINFO("Detection sent on port: %d (IP=%s)", tcpServer.getPort(), tcpServer.getHostAddress().toString().toStdString().c_str()); - - // connect stuff: - // [FindObject] ---ObjectsDetected---> [TcpServer] - QObject::connect(findObject, SIGNAL(objectsFound(QMultiMap >)), &tcpServer, SLOT(publishObjects(QMultiMap >))); - if(!scene.empty()) { // process the scene and exit - findObject->detect(scene); // this will automatically emit objectsFound() + QTime time; + time.start(); + DetectionInfo info; + findObject->detect(scene, info); - if(!jsonPath.isEmpty()) + if(info.objDetected_.size() > 1) { - writeJSON(*findObject, jsonPath); + UINFO("%d objects detected! (%d ms)", (int)info.objDetected_.size(), time.elapsed()); + } + else if(info.objDetected_.size() == 1) + { + UINFO("Object %d detected! (%d ms)", (int)info.objDetected_.begin().key(), time.elapsed()); + } + else if(Settings::getGeneral_sendNoObjDetectedEvents()) + { + UINFO("No objects detected. (%d ms)", time.elapsed()); + } + + if(!jsonPath.isEmpty() && JsonWriter::available()) + { + JsonWriter::write(info, jsonPath); + UINFO("JSON written to \"%s\"", jsonPath.toStdString().c_str()); } } else { Camera camera; + TcpServer tcpServer(Settings::getGeneral_port()); + UINFO("Detection sent on port: %d (IP=%s)", tcpServer.getPort(), tcpServer.getHostAddress().toString().toStdString().c_str()); + + // connect stuff: + // [FindObject] ---ObjectsDetected---> [TcpServer] + QObject::connect(findObject, SIGNAL(objectsFound(DetectionInfo)), &tcpServer, SLOT(publishDetectionInfo(DetectionInfo))); // [Camera] ---Image---> [FindObject] QObject::connect(&camera, SIGNAL(imageReceived(const cv::Mat &)), findObject, SLOT(detect(const cv::Mat &))); @@ -394,9 +332,9 @@ int main(int argc, char* argv[]) // cleanup camera.stop(); + tcpServer.close(); } delete findObject; - tcpServer.close(); } } diff --git a/include/find_object/DetectionInfo.h b/include/find_object/DetectionInfo.h new file mode 100644 index 00000000..eb5c6fb3 --- /dev/null +++ b/include/find_object/DetectionInfo.h @@ -0,0 +1,118 @@ +/* + * DetectionInfo.h + * + * Created on: 2014-08-03 + * Author: mathieu + */ + +#ifndef DETECTIONINFO_H_ +#define DETECTIONINFO_H_ + +#include +#include +#include +#include +#include +#include + +class DetectionInfo +{ +public: + enum TimeStamp{kTimeKeypointDetection, kTimeDescriptorExtraction, kTimeIndexing, kTimeMatching, kTimeHomography, kTimeTotal}; + +public: + DetectionInfo() : + minMatchedDistance_(-1), + maxMatchedDistance_(-1) + {} + +public: + QMultiMap objDetected_; + QMultiMap objDetectedSizes_; // Object ID match the number of detected objects + QMultiMap objDetectedFilenames_; // Object ID match the number of detected objects + QMultiMap objDetectedInliersCount_; // ObjectID match the number of detected objects + QMultiMap objDetectedOutliersCount_; // ObjectID match the number of detected objects + QMultiMap > objDetectedInliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of detected objects + QMultiMap > objDetectedOutliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of detected objects + + QMap timeStamps_; + std::vector sceneKeypoints_; + cv::Mat sceneDescriptors_; + QMultiMap sceneWords_; + QMap > matches_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of objects + QMultiMap > rejectedInliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex > + QMultiMap > rejectedOutliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex > + float minMatchedDistance_; + float maxMatchedDistance_; +}; + +inline QDataStream & operator<<(QDataStream &out, const DetectionInfo & info) +{ + out << quint32(info.objDetected_.size()); + + QMultiMap::const_iterator iterInliers = info.objDetectedInliersCount_.constBegin(); + QMultiMap::const_iterator iterOutliers = info.objDetectedOutliersCount_.constBegin(); + QMultiMap::const_iterator iterSizes = info.objDetectedSizes_.constBegin(); + QMultiMap::const_iterator iterFilenames = info.objDetectedFilenames_.constBegin(); + for(QMultiMap::const_iterator iter=info.objDetected_.constBegin(); + iter!=info.objDetected_.constEnd(); + ++iter) + { + // ID + out << iter.key(); + + // Size + out << iterSizes.value(); + + // Transform + out << iter.value(); + + // Filename + out << iterFilenames.value(); + + // inliers and outliers count + out << iterInliers.value(); + out << iterOutliers.value(); + + ++iterInliers; + ++iterOutliers; + ++iterSizes; + ++iterFilenames; + } + return out; +} + +inline QDataStream & operator>>(QDataStream &in, DetectionInfo & info) +{ + QDataStream::Status oldStatus = in.status(); + in.resetStatus(); + info = DetectionInfo(); + + quint32 n; + in >> n; + + for (quint32 i = 0; i < n; ++i) { + if (in.status() != QDataStream::Ok) + break; + + int id; + QSize size; + QTransform homography; + QString filename; + int inliers, outliers; + in >> id >> size >> homography >> filename >> inliers >> outliers; + info.objDetected_.insert(id, homography); + info.objDetectedSizes_.insert(id, size); + info.objDetectedFilenames_.insert(id, filename); + info.objDetectedInliersCount_.insert(id, inliers); + info.objDetectedOutliersCount_.insert(id, outliers); + } + if (in.status() != QDataStream::Ok) + info = DetectionInfo(); + if (oldStatus != QDataStream::Ok) + in.setStatus(oldStatus); + return in; +} + + +#endif /* DETECTIONINFO_H_ */ diff --git a/include/find_object/FindObject.h b/include/find_object/FindObject.h index e4f2ee25..fe8103e1 100644 --- a/include/find_object/FindObject.h +++ b/include/find_object/FindObject.h @@ -10,6 +10,8 @@ #include "find_object/FindObjectExp.h" // DLL export/import defines +#include "find_object/DetectionInfo.h" + #include #include #include @@ -30,21 +32,18 @@ class FINDOBJECT_EXP FindObject : public QObject { Q_OBJECT; -public: - enum TimeStamp{kTimeKeypointDetection, kTimeDescriptorExtraction, kTimeIndexing, kTimeMatching, kTimeHomography, kTimeTotal}; - public: FindObject(QObject * parent = 0); virtual ~FindObject(); int loadObjects(const QString & dirPath); // call updateObjects() const ObjSignature * addObject(const QString & filePath); - const ObjSignature * addObject(const cv::Mat & image, int id=0); + const ObjSignature * addObject(const cv::Mat & image, int id=0, const QString & filename = QString()); bool addObject(ObjSignature * obj); // take ownership when true is returned void removeObject(int id); void removeAllObjects(); - bool detect(const cv::Mat & image, QMultiMap > & objectsDetected); + bool detect(const cv::Mat & image, DetectionInfo & info); void updateDetectorExtractor(); void updateObjects(); @@ -53,24 +52,11 @@ public: const QMap & objects() const {return objects_;} const Vocabulary * vocabulary() const {return vocabulary_;} - const QMultiMap > & objectsDetected() const {return objectsDetected_;} - const QMap & timeStamps() const {return timeStamps_;} - const std::vector & sceneKeypoints() const {return sceneKeypoints_;} - const cv::Mat & sceneDescriptors() const {return sceneDescriptors_;} - const QMultiMap & sceneWords() const {return sceneWords_;} - const QMap > & matches() const {return matches_;} - const QMultiMap > & inliers() const {return inliers_;} - const QMultiMap > & outliers() const {return outliers_;} - const QMultiMap > & rejectedInliers() const {return rejectedInliers_;} - const QMultiMap > & rejectedOutliers() const {return rejectedOutliers_;} - float minMatchedDistance() const {return minMatchedDistance_;} - float maxMatchedDistance() const {return maxMatchedDistance_;} - public Q_SLOTS: - void detect(const cv::Mat & image); // emit objectsfound() + void detect(const cv::Mat & image); // emit objectsFound() Q_SIGNALS: - void objectsFound(const QMultiMap > &); + void objectsFound(const DetectionInfo &); private: void clearVocabulary(); @@ -82,19 +68,6 @@ private: QMap dataRange_; // KeypointDetector * detector_; DescriptorExtractor * extractor_; - - QMultiMap > objectsDetected_; - QMap timeStamps_; - std::vector sceneKeypoints_; - cv::Mat sceneDescriptors_; - QMultiMap sceneWords_; - QMap > matches_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of objects - QMultiMap > inliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of detected objects - QMultiMap > outliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of detected objects - QMultiMap > rejectedInliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex > - QMultiMap > rejectedOutliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex > - float minMatchedDistance_; - float maxMatchedDistance_; }; #endif /* FINDOBJECT_H_ */ diff --git a/include/find_object/JsonWriter.h b/include/find_object/JsonWriter.h new file mode 100644 index 00000000..eebcac07 --- /dev/null +++ b/include/find_object/JsonWriter.h @@ -0,0 +1,21 @@ +/* + * JsonWriter.h + * + * Created on: 2014-08-03 + * Author: mathieu + */ + +#ifndef JSONWRITER_H_ +#define JSONWRITER_H_ + +#include "find_object/DetectionInfo.h" + +class JsonWriter +{ +public: + static bool available(); + static void write(const DetectionInfo & info, const QString & path); +}; + + +#endif /* JSONWRITER_H_ */ diff --git a/include/find_object/MainWindow.h b/include/find_object/MainWindow.h index 385a3442..b137e6cb 100644 --- a/include/find_object/MainWindow.h +++ b/include/find_object/MainWindow.h @@ -7,6 +7,8 @@ #include "find_object/FindObjectExp.h" // DLL export/import defines +#include "find_object/DetectionInfo.h" + #include #include #include @@ -74,7 +76,7 @@ private Q_SLOTS: void rectHovered(int objId); Q_SIGNALS: - void objectsFound(const QMultiMap > &); + void objectsFound(const DetectionInfo &); private: bool loadSettings(const QString & path); diff --git a/include/find_object/TcpServer.h b/include/find_object/TcpServer.h index 65be488b..f6cd21ce 100644 --- a/include/find_object/TcpServer.h +++ b/include/find_object/TcpServer.h @@ -10,6 +10,8 @@ #include "find_object/FindObjectExp.h" // DLL export/import defines +#include "find_object/DetectionInfo.h" + #include class QNetworkSession; @@ -25,7 +27,7 @@ public: quint16 getPort() const; public Q_SLOTS: - void publishObjects(const QMultiMap > & objects); + void publishDetectionInfo(const DetectionInfo & info); private Q_SLOTS: void addClient(); diff --git a/src/AddObjectDialog.cpp b/src/AddObjectDialog.cpp index 69e619c0..fd09b9c4 100644 --- a/src/AddObjectDialog.cpp +++ b/src/AddObjectDialog.cpp @@ -332,7 +332,7 @@ void AddObjectDialog::setState(int state) delete objSignature_; objSignature_ = 0; } - objSignature_ = new ObjSignature(0, imgRoi.clone()); + objSignature_ = new ObjSignature(0, imgRoi.clone(), ""); objSignature_->setData(keypoints, descriptors, Settings::currentDetectorType(), Settings::currentDescriptorType()); objWidget_ = new ObjWidget(0, keypoints, cvtCvMat2QImage(imgRoi.clone())); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6994900c..d2c100ac 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,9 +36,6 @@ QT4_WRAP_UI(moc_uis ${uis}) QT4_WRAP_CPP(moc_srcs ${headers_ui}) ### Qt Gui stuff end### - - - SET(SRC_FILES ./MainWindow.cpp ./AddObjectDialog.cpp @@ -54,6 +51,7 @@ SET(SRC_FILES ./AboutDialog.cpp ./TcpServer.cpp ./Vocabulary.cpp + ./JsonWriter.cpp ./utilite/ULogger.cpp ./utilite/UPlot.cpp ./utilite/UDirectory.cpp @@ -79,6 +77,18 @@ SET(LIBRARIES ${OpenCV_LIBS} ) +IF(JSONCPP_FOUND) + SET(INCLUDE_DIRS + ${INCLUDE_DIRS} + ${JSONCPP_INCLUDE_DIRS} + ) + SET(LIBRARIES + ${LIBRARIES} + ${JSONCPP_LIBRARIES} + ) + ADD_DEFINITIONS("-DWITH_JSONCPP") +ENDIF(JSONCPP_FOUND) + #include files INCLUDE_DIRECTORIES(${INCLUDE_DIRS}) diff --git a/src/FindObject.cpp b/src/FindObject.cpp index 1f3d0905..f6926d32 100644 --- a/src/FindObject.cpp +++ b/src/FindObject.cpp @@ -23,10 +23,9 @@ FindObject::FindObject(QObject * parent) : QObject(parent), vocabulary_(new Vocabulary()), detector_(Settings::createKeypointDetector()), - extractor_(Settings::createDescriptorExtractor()), - minMatchedDistance_(-1), - maxMatchedDistance_(-1) + extractor_(Settings::createDescriptorExtractor()) { + qRegisterMetaType("DetectionInfo"); Q_ASSERT(detector_ != 0 && extractor_ != 0); } @@ -87,16 +86,16 @@ const ObjSignature * FindObject::addObject(const QString & filePath) id = 0; } } - return this->addObject(img, id); + return this->addObject(img, id, file.fileName()); } } return 0; } -const ObjSignature * FindObject::addObject(const cv::Mat & image, int id) +const ObjSignature * FindObject::addObject(const cv::Mat & image, int id, const QString & filename) { Q_ASSERT(id >= 0); - ObjSignature * s = new ObjSignature(id, image); + ObjSignature * s = new ObjSignature(id, image, filename); if(!this->addObject(s)) { delete s; @@ -596,25 +595,25 @@ void FindObject::detect(const cv::Mat & image) { QTime time; time.start(); - QMultiMap > objects; - this->detect(image, objects); - if(objects.size() > 0 || Settings::getGeneral_sendNoObjDetectedEvents()) + DetectionInfo info; + this->detect(image, info); + if(info.objDetected_.size() > 0 || Settings::getGeneral_sendNoObjDetectedEvents()) { - Q_EMIT objectsFound(objects); + Q_EMIT objectsFound(info); } - if(objects.size() > 1) + if(info.objDetected_.size() > 1) { UINFO("(%s) %d objects detected! (%d ms)", QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(), - (int)objects.size(), + (int)info.objDetected_.size(), time.elapsed()); } - else if(objects.size() == 1) + else if(info.objDetected_.size() == 1) { UINFO("(%s) Object %d detected! (%d ms)", QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(), - (int)objects.begin().key(), + (int)info.objDetected_.begin().key(), time.elapsed()); } else if(Settings::getGeneral_sendNoObjDetectedEvents()) @@ -625,22 +624,13 @@ void FindObject::detect(const cv::Mat & image) } } -bool FindObject::detect(const cv::Mat & image, QMultiMap > & objectsDetected) +bool FindObject::detect(const cv::Mat & image, DetectionInfo & info) { QTime totalTime; totalTime.start(); // reset statistics - objectsDetected_.clear(); - timeStamps_.clear(); - sceneKeypoints_.clear(); - sceneDescriptors_ = cv::Mat(); - sceneWords_.clear(); - matches_.clear(); - inliers_.clear(); - outliers_.clear(); - minMatchedDistance_ = -1.0f; - maxMatchedDistance_ = -1.0f; + info = DetectionInfo(); bool success = false; if(!image.empty()) @@ -660,36 +650,36 @@ bool FindObject::detect(const cv::Mat & image, QMultiMapdetect(grayscaleImg, sceneKeypoints_); - timeStamps_.insert(kTimeKeypointDetection, time.restart()); + detector_->detect(grayscaleImg, info.sceneKeypoints_); + info.timeStamps_.insert(DetectionInfo::kTimeKeypointDetection, time.restart()); - bool emptyScene = sceneKeypoints_.size() == 0; - if(sceneKeypoints_.size()) + bool emptyScene = info.sceneKeypoints_.size() == 0; + if(info.sceneKeypoints_.size()) { int maxFeatures = Settings::getFeature2D_3MaxFeatures(); - if(maxFeatures > 0 && (int)sceneKeypoints_.size() > maxFeatures) + if(maxFeatures > 0 && (int)info.sceneKeypoints_.size() > maxFeatures) { - sceneKeypoints_ = limitKeypoints(sceneKeypoints_, maxFeatures); + info.sceneKeypoints_ = limitKeypoints(info.sceneKeypoints_, maxFeatures); } // EXTRACT DESCRIPTORS - extractor_->compute(grayscaleImg, sceneKeypoints_, sceneDescriptors_); - if((int)sceneKeypoints_.size() != sceneDescriptors_.rows) + extractor_->compute(grayscaleImg, info.sceneKeypoints_, info.sceneDescriptors_); + if((int)info.sceneKeypoints_.size() != info.sceneDescriptors_.rows) { - UERROR("kpt=%d != descriptors=%d", (int)sceneKeypoints_.size(), sceneDescriptors_.rows); + UERROR("kpt=%d != descriptors=%d", (int)info.sceneKeypoints_.size(), info.sceneDescriptors_.rows); } } - timeStamps_.insert(kTimeDescriptorExtraction, time.restart()); + info.timeStamps_.insert(DetectionInfo::kTimeDescriptorExtraction, time.restart()); bool consistentNNData = (vocabulary_->size()!=0 && vocabulary_->wordToObjects().begin().value()!=-1 && Settings::getGeneral_invertedSearch()) || ((vocabulary_->size()==0 || vocabulary_->wordToObjects().begin().value()==-1) && !Settings::getGeneral_invertedSearch()); // COMPARE if(!objectsDescriptors_.empty() && - sceneKeypoints_.size() && + info.sceneKeypoints_.size() && consistentNNData && - objectsDescriptors_.begin().value().cols == sceneDescriptors_.cols && - objectsDescriptors_.begin().value().type() == sceneDescriptors_.type()) // binary descriptor issue, if the dataTree is not yet updated with modified settings + objectsDescriptors_.begin().value().cols == info.sceneDescriptors_.cols && + objectsDescriptors_.begin().value().type() == info.sceneDescriptors_.type()) // binary descriptor issue, if the dataTree is not yet updated with modified settings { success = true; @@ -699,17 +689,17 @@ bool FindObject::detect(const cv::Mat & image, QMultiMapclear(); - words = vocabulary_->addWords(sceneDescriptors_, -1, Settings::getGeneral_vocabularyIncremental()); + words = vocabulary_->addWords(info.sceneDescriptors_, -1, Settings::getGeneral_vocabularyIncremental()); if(!Settings::getGeneral_vocabularyIncremental()) { vocabulary_->update(); } - timeStamps_.insert(kTimeIndexing, time.restart()); + info.timeStamps_.insert(DetectionInfo::kTimeIndexing, time.restart()); } for(QMap::iterator iter=objects_.begin(); iter!=objects_.end(); ++iter) { - matches_.insert(iter.key(), QMultiMap()); + info.matches_.insert(iter.key(), QMultiMap()); } if(Settings::getGeneral_invertedSearch() || Settings::getGeneral_threads() == 1) @@ -728,9 +718,9 @@ bool FindObject::detect(const cv::Mat & image, QMultiMapsearch(sceneDescriptors_, results, dists, k); + results = cv::Mat(info.sceneDescriptors_.rows, k, CV_32SC1); // results index + dists = cv::Mat(info.sceneDescriptors_.rows, k, CV_32FC1); // Distance results are CV_32FC1 + vocabulary_->search(info.sceneDescriptors_, results, dists, k); } // PROCESS RESULTS @@ -761,13 +751,13 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap dists.at(i,0)) + if(info.minMatchedDistance_ == -1 || info.minMatchedDistance_ > dists.at(i,0)) { - minMatchedDistance_ = dists.at(i,0); + info.minMatchedDistance_ = dists.at(i,0); } - if(maxMatchedDistance_ == -1 || maxMatchedDistance_ < dists.at(i,0)) + if(info.maxMatchedDistance_ == -1 || info.maxMatchedDistance_ < dists.at(i,0)) { - maxMatchedDistance_ = dists.at(i,0); + info.maxMatchedDistance_ = dists.at(i,0); } if(matched) @@ -781,7 +771,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMapwordToObjects().count(wordId, objIds[j]) == 1) { - matches_.find(objIds[j]).value().insert(objects_.value(objIds[j])->words().value(wordId), i); + info.matches_.find(objIds[j]).value().insert(objects_.value(objIds[j])->words().value(wordId), i); } } } @@ -795,7 +785,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap(i,0); if(words.count(wordId) == 1) { - matches_.find(objectId).value().insert(objectDescriptorIndex, words.value(wordId)); + info.matches_.find(objectId).value().insert(objectDescriptorIndex, words.value(wordId)); } } } @@ -825,15 +815,15 @@ bool FindObject::detect(const cv::Mat & image, QMultiMapwait(); - matches_[threads[k]->getObjectId()] = threads[k]->getMatches(); + info.matches_[threads[k]->getObjectId()] = threads[k]->getMatches(); - if(minMatchedDistance_ == -1 || minMatchedDistance_ > threads[k]->getMinMatchedDistance()) + if(info.minMatchedDistance_ == -1 || info.minMatchedDistance_ > threads[k]->getMinMatchedDistance()) { - minMatchedDistance_ = threads[k]->getMinMatchedDistance(); + info.minMatchedDistance_ = threads[k]->getMinMatchedDistance(); } - if(maxMatchedDistance_ == -1 || maxMatchedDistance_ < threads[k]->getMaxMatchedDistance()) + if(info.maxMatchedDistance_ == -1 || info.maxMatchedDistance_ < threads[k]->getMaxMatchedDistance()) { - maxMatchedDistance_ = threads[k]->getMaxMatchedDistance(); + info.maxMatchedDistance_ = threads[k]->getMaxMatchedDistance(); } delete threads[k]; } @@ -841,7 +831,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap matchesId = matches_.keys(); - QList > matchesList = matches_.values(); + QList matchesId = info.matches_.keys(); + QList > matchesList = info.matches_.values(); for(int i=0; i threads; @@ -861,7 +851,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMapkeypoints(), &sceneKeypoints_)); + threads.push_back(new HomographyThread(&matchesList[k], objectId, &objects_.value(objectId)->keypoints(), &info.sceneKeypoints_)); threads.back()->start(); } @@ -889,11 +879,11 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap >::iterator objIter = objectsDetected.find(id); - for(;objIter!=objectsDetected.end() && objIter.key() == id; ++objIter) + QMultiMap::iterator objIter = info.objDetected_.find(id); + for(;objIter!=info.objDetected_.end() && objIter.key() == id; ++objIter) { - qreal dx = objIter.value().second.m31() - hTransform.m31(); - qreal dy = objIter.value().second.m32() - hTransform.m32(); + qreal dx = objIter.value().m31() - hTransform.m31(); + qreal dy = objIter.value().m32() - hTransform.m32(); int d = (int)sqrt(dx*dx + dy*dy); if(d < distance) { @@ -905,33 +895,37 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap= Settings::getGeneral_multiDetectionRadius()) { QRect rect = objects_.value(id)->rect(); - objectsDetected.insert(id, QPair(rect, hTransform)); - inliers_.insert(id, threads[j]->getInliers()); - outliers_.insert(id, threads[j]->getOutliers()); + info.objDetected_.insert(id, hTransform); + info.objDetectedSizes_.insert(id, rect.size()); + info.objDetectedInliers_.insert(id, threads[j]->getInliers()); + info.objDetectedOutliers_.insert(id, threads[j]->getOutliers()); + info.objDetectedInliersCount_.insert(id, threads[j]->getInliers().size()); + info.objDetectedOutliersCount_.insert(id, threads[j]->getOutliers().size()); + info.objDetectedFilenames_.insert(id, objects_.value(id)->filename()); } else { - rejectedInliers_.insert(id, threads[j]->getInliers()); - rejectedOutliers_.insert(id, threads[j]->getOutliers()); + info.rejectedInliers_.insert(id, threads[j]->getInliers()); + info.rejectedOutliers_.insert(id, threads[j]->getOutliers()); } } else { - rejectedInliers_.insert(id, threads[j]->getInliers()); - rejectedOutliers_.insert(id, threads[j]->getOutliers()); + info.rejectedInliers_.insert(id, threads[j]->getInliers()); + info.rejectedOutliers_.insert(id, threads[j]->getOutliers()); } } else { - rejectedInliers_.insert(id, threads[j]->getInliers()); - rejectedOutliers_.insert(id, threads[j]->getOutliers()); + info.rejectedInliers_.insert(id, threads[j]->getInliers()); + info.rejectedOutliers_.insert(id, threads[j]->getOutliers()); } } } - timeStamps_.insert(kTimeHomography, time.restart()); + info.timeStamps_.insert(DetectionInfo::kTimeHomography, time.restart()); } } - else if(!objectsDescriptors_.empty() && sceneKeypoints_.size()) + else if(!objectsDescriptors_.empty() && info.sceneKeypoints_.size()) { UWARN("Cannot search, objects must be updated"); } @@ -943,8 +937,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap +#include + +#ifdef WITH_JSONCPP +#include +#endif + +bool JsonWriter::available() +{ +#ifdef WITH_JSONCPP + return true; +#else + return false; +#endif +} + +void JsonWriter::write(const DetectionInfo & info, const QString & path) +{ +#ifdef WITH_JSONCPP + if(!path.isEmpty()) + { + Json::Value root; + + if(info.objDetected_.size()) + { + Json::Value detections; + + QMultiMap::const_iterator iterInliers = info.objDetectedInliersCount_.constBegin(); + QMultiMap::const_iterator iterOutliers = info.objDetectedOutliersCount_.constBegin(); + QMultiMap::const_iterator iterSizes = info.objDetectedSizes_.constBegin(); + QMultiMap::const_iterator iterFilenames = info.objDetectedFilenames_.constBegin(); + for(QMultiMap::const_iterator iter = info.objDetected_.constBegin(); iter!= info.objDetected_.end();) + { + char index = 'a'; + int id = iter.key(); + while(iter != info.objDetected_.constEnd() && id == iter.key()) + { + QString name = QString("object_%1%2").arg(id).arg(info.objDetected_.count(id)>1?QString(index++):""); + detections.append(name.toStdString()); + + Json::Value homography; + homography.append(iter.value().m11()); + homography.append(iter.value().m12()); + homography.append(iter.value().m13()); + homography.append(iter.value().m21()); + homography.append(iter.value().m22()); + homography.append(iter.value().m23()); + homography.append(iter.value().m31()); // dx + homography.append(iter.value().m32()); // dy + homography.append(iter.value().m33()); + root[name.toStdString()]["width"] = iterSizes.value().width(); + root[name.toStdString()]["height"] = iterSizes.value().height(); + root[name.toStdString()]["homography"] = homography; + root[name.toStdString()]["inliers"] = iterInliers.value(); + root[name.toStdString()]["outliers"] = iterOutliers.value(); + root[name.toStdString()]["filename"] = iterFilenames.value().toStdString(); + + ++iter; + ++iterInliers; + ++iterOutliers; + ++iterSizes; + ++iterFilenames; + } + } + root["objects"] = detections; + } + + if(info.matches_.size()) + { + Json::Value matchesValues; + const QMap > & matches = info.matches_; + for(QMap >::const_iterator iter = matches.constBegin(); + iter != matches.end(); + ++iter) + { + QString name = QString("matches_%1").arg(iter.key()); + root[name.toStdString()] = iter.value().size(); + matchesValues.append(name.toStdString()); + } + root["matches"] = matchesValues; + } + + // write in a nice readible way + Json::StyledWriter styledWriter; + //std::cout << styledWriter.write(root); + QFile file(path); + file.open(QIODevice::WriteOnly | QIODevice::Text); + QTextStream out(&file); + out << styledWriter.write(root).c_str(); + file.close(); + } +#else + UERROR("Not built with JSON support!"); +#endif +} diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index eceac0b1..b0eb97cb 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -268,7 +268,7 @@ void MainWindow::setupTCPServer() delete tcpServer_; } tcpServer_ = new TcpServer(Settings::getGeneral_port(), this); - connect(this, SIGNAL(objectsFound(QMultiMap >)), tcpServer_, SLOT(publishObjects(QMultiMap >))); + connect(this, SIGNAL(objectsFound(DetectionInfo)), tcpServer_, SLOT(publishDetectionInfo(DetectionInfo))); ui_->label_ipAddress->setText(tcpServer_->getHostAddress().toString()); ui_->label_port->setNum(tcpServer_->getPort()); UINFO("Detection sent on port: %d (IP=%s)", tcpServer_->getPort(), tcpServer_->getHostAddress().toString().toStdString().c_str()); @@ -916,19 +916,20 @@ void MainWindow::update(const cv::Mat & image) iter.value()->resetKptsColor(); } - QMultiMap > objectsDetected; - if(findObject_->detect(sceneImage_, objectsDetected)) + DetectionInfo info; + if(findObject_->detect(sceneImage_, info)) { - ui_->label_timeDetection->setNum(findObject_->timeStamps().value(FindObject::kTimeKeypointDetection, 0)); - ui_->label_timeExtraction->setNum(findObject_->timeStamps().value(FindObject::kTimeDescriptorExtraction, 0)); - ui_->imageView_source->setData(findObject_->sceneKeypoints(), cvtCvMat2QImage(sceneImage_)); - ui_->label_timeIndexing->setNum(findObject_->timeStamps().value(FindObject::kTimeIndexing, 0)); + ui_->label_timeDetection->setNum(info.timeStamps_.value(DetectionInfo::kTimeKeypointDetection, 0)); + ui_->label_timeExtraction->setNum(info.timeStamps_.value(DetectionInfo::kTimeDescriptorExtraction, 0)); + ui_->imageView_source->setData(info.sceneKeypoints_, cvtCvMat2QImage(sceneImage_)); + ui_->label_timeIndexing->setNum(info.timeStamps_.value(DetectionInfo::kTimeIndexing, 0)); + ui_->label_timeMatching->setNum(info.timeStamps_.value(DetectionInfo::kTimeMatching, 0)); + ui_->label_timeHomographies->setNum(info.timeStamps_.value(DetectionInfo::kTimeHomography, 0)); + ui_->label_vocabularySize->setNum(findObject_->vocabulary()->size()); - ui_->label_timeMatching->setNum(findObject_->timeStamps().value(FindObject::kTimeMatching, 0)); - ui_->label_timeHomographies->setNum(findObject_->timeStamps().value(FindObject::kTimeHomography, 0)); // Colorize features matched - const QMap > & matches = findObject_->matches(); + const QMap > & matches = info.matches_; QMap scores; int maxScoreId = -1; int maxScore = 0; @@ -956,12 +957,12 @@ void MainWindow::update(const cv::Mat & image) ui_->imageView_source->setKptColor(iter.value(), obj->color()); } } - else if(!objectsDetected.contains(id)) + else if(!info.objDetected_.contains(id)) { // Homography could not be computed... QLabel * label = ui_->dockWidget_objects->findChild(QString("%1detection").arg(id)); - QMultiMap rejectedInliers = findObject_->rejectedInliers().value(id); - QMultiMap rejectedOutliers = findObject_->rejectedOutliers().value(id); + QMultiMap rejectedInliers = info.rejectedInliers_.value(id); + QMultiMap rejectedOutliers = info.rejectedOutliers_.value(id); if(jter.value().size() < Settings::getHomography_minimumInliers()) { label->setText(QString("Too low matches (%1)").arg(jter.value().size())); @@ -979,18 +980,18 @@ void MainWindow::update(const cv::Mat & image) } // Add homography rectangles when homographies are computed - QMultiMap >::const_iterator inliersIter = findObject_->inliers().constBegin(); - QMultiMap >::const_iterator outliersIter = findObject_->outliers().constBegin(); - for(QMultiMap >::iterator iter = objectsDetected.begin(); - iter!=objectsDetected.end() && inliersIter!=findObject_->inliers().constEnd(); - ++iter, ++inliersIter) + QMultiMap >::const_iterator inliersIter = info.objDetectedInliers_.constBegin(); + QMultiMap >::const_iterator outliersIter = info.objDetectedOutliers_.constBegin(); + for(QMultiMap::iterator iter = info.objDetected_.begin(); + iter!=info.objDetected_.end(); + ++iter, ++inliersIter, ++outliersIter) { int id = iter.key(); ObjWidget * obj = objWidgets_.value(id); Q_ASSERT(obj != 0); // COLORIZE (should be done in the GUI thread) - QTransform hTransform = iter.value().second; + QTransform hTransform = iter.value(); QRect rect = obj->pixmap().rect(); // add rectangle @@ -1013,10 +1014,10 @@ void MainWindow::update(const cv::Mat & image) } QLabel * label = ui_->dockWidget_objects->findChild(QString("%1detection").arg(id)); - if(objectsDetected.count(id) > 1) + if(info.objDetected_.count(id) > 1) { // if a homography is already found, set the objects count - label->setText(QString("%1 objects found").arg(objectsDetected.count(id))); + label->setText(QString("%1 objects found").arg(info.objDetected_.count(id))); } else { @@ -1030,7 +1031,7 @@ void MainWindow::update(const cv::Mat & image) QMap inlierScores; for(QMap::iterator iter=scores.begin(); iter!=scores.end(); ++iter) { - QList > values = findObject_->inliers().values(iter.key()); + QList > values = info.objDetectedInliers_.values(iter.key()); int maxValue = 0; if(values.size()) { @@ -1051,8 +1052,8 @@ void MainWindow::update(const cv::Mat & image) ui_->likelihoodPlot->update(); } - ui_->label_minMatchedDistance->setNum(findObject_->minMatchedDistance()); - ui_->label_maxMatchedDistance->setNum(findObject_->maxMatchedDistance()); + ui_->label_minMatchedDistance->setNum(info.minMatchedDistance_); + ui_->label_maxMatchedDistance->setNum(info.maxMatchedDistance_); //Scroll objects slider to the best score if(maxScoreId>=0 && Settings::getGeneral_autoScroll()) @@ -1065,17 +1066,17 @@ void MainWindow::update(const cv::Mat & image) } // Emit homographies - if(objectsDetected.size() > 1) + if(info.objDetected_.size() > 1) { UINFO("(%s) %d objects detected!", QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(), - (int)objectsDetected.size()); + (int)info.objDetected_.size()); } - else if(objectsDetected.size() == 1) + else if(info.objDetected_.size() == 1) { UINFO("(%s) Object %d detected!", QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(), - (int)objectsDetected.begin().key()); + (int)info.objDetected_.begin().key()); } else if(Settings::getGeneral_sendNoObjDetectedEvents()) { @@ -1083,16 +1084,16 @@ void MainWindow::update(const cv::Mat & image) QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str()); } - if(objectsDetected.size() > 0 || Settings::getGeneral_sendNoObjDetectedEvents()) + if(info.objDetected_.size() > 0 || Settings::getGeneral_sendNoObjDetectedEvents()) { - Q_EMIT objectsFound(objectsDetected); + Q_EMIT objectsFound(info); } - ui_->label_objectsDetected->setNum(objectsDetected.size()); + ui_->label_objectsDetected->setNum(info.objDetected_.size()); } else { this->statusBar()->showMessage(tr("Cannot search, objects must be updated!")); - ui_->imageView_source->setData(findObject_->sceneKeypoints(), cvtCvMat2QImage(sceneImage_)); + ui_->imageView_source->setData(info.sceneKeypoints_, cvtCvMat2QImage(sceneImage_)); } @@ -1102,7 +1103,7 @@ void MainWindow::update(const cv::Mat & image) iter.value()->update(); } - ui_->label_nfeatures->setNum((int)findObject_->sceneKeypoints().size()); + ui_->label_nfeatures->setNum((int)info.sceneKeypoints_.size()); ui_->imageView_source->update(); ui_->label_detectorDescriptorType->setText(QString("%1/%2").arg(Settings::currentDetectorType()).arg(Settings::currentDescriptorType())); @@ -1116,7 +1117,7 @@ void MainWindow::update(const cv::Mat & image) ui_->horizontalSlider_frames->blockSignals(false); } - ui_->label_timeTotal->setNum(findObject_->timeStamps().value(FindObject::kTimeTotal, 0)); + ui_->label_timeTotal->setNum(info.timeStamps_.value(DetectionInfo::kTimeTotal, 0)); int refreshRate = qRound(1000.0f/float(updateRate_.restart())); if(refreshRate > 0 && refreshRate < lowestRefreshRate_) { @@ -1200,7 +1201,7 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged) ui_->label_timeRefreshRate->setVisible(false); } - ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !UDirectory::exists(Settings::getCamera_5mediaPath().toStdString())); - ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && UDirectory::exists(Settings::getCamera_5mediaPath().toStdString())); + ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()) && !Settings::getCamera_6useTcpCamera()); + ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()) && !Settings::getCamera_6useTcpCamera()); ui_->actionCamera_from_TCP_IP->setChecked(Settings::getCamera_6useTcpCamera()); } diff --git a/src/ObjSignature.h b/src/ObjSignature.h index b9ab6bb3..2817cbfe 100644 --- a/src/ObjSignature.h +++ b/src/ObjSignature.h @@ -15,9 +15,10 @@ class ObjSignature { public: - ObjSignature(int id, const cv::Mat & image) : + ObjSignature(int id, const cv::Mat & image, const QString & filename) : id_(id), - image_(image) + image_(image), + filename_(filename) {} virtual ~ObjSignature() {} @@ -37,6 +38,7 @@ public: QRect rect() const {return QRect(0,0,image_.cols, image_.rows);} int id() const {return id_;} + const QString & filename() const {return filename_;} const cv::Mat & image() const {return image_;} const std::vector & keypoints() const {return keypoints_;} const cv::Mat & descriptors() const {return descriptors_;} @@ -47,6 +49,7 @@ public: private: int id_; cv::Mat image_; + QString filename_; std::vector keypoints_; cv::Mat descriptors_; QMultiMap words_; // diff --git a/src/TcpServer.cpp b/src/TcpServer.cpp index 4a960e8d..281dbd10 100644 --- a/src/TcpServer.cpp +++ b/src/TcpServer.cpp @@ -53,38 +53,23 @@ quint16 TcpServer::getPort() const return this->serverPort(); } -void TcpServer::publishObjects(const QMultiMap > & objects) +void TcpServer::publishDetectionInfo(const DetectionInfo & info) { QList clients = this->findChildren(); if(clients.size()) { - QVector data(objects.size()*12); - int i=0; - for(QMultiMap >::const_iterator iter=objects.constBegin(); iter!=objects.constEnd(); ++iter) - { - data[i++] = iter.key(); - data[i++] = iter.value().first.width(); - data[i++] = iter.value().first.height(); - data[i++] = iter.value().second.m11(); - data[i++] = iter.value().second.m12(); - data[i++] = iter.value().second.m13(); - data[i++] = iter.value().second.m21(); - data[i++] = iter.value().second.m22(); - data[i++] = iter.value().second.m23(); - data[i++] = iter.value().second.m31(); // dx - data[i++] = iter.value().second.m32(); // dy - data[i++] = iter.value().second.m33(); - } + QByteArray block; + QDataStream out(&block, QIODevice::WriteOnly); + out.setVersion(QDataStream::Qt_4_0); + out << (quint16)0; + + out << info; + + out.device()->seek(0); + out << (quint16)(block.size() - sizeof(quint16)); for(QList::iterator iter = clients.begin(); iter!=clients.end(); ++iter) { - QByteArray block; - QDataStream out(&block, QIODevice::WriteOnly); - out.setVersion(QDataStream::Qt_4_0); - out << (quint16)0; - out << data; - out.device()->seek(0); - out << (quint16)(block.size() - sizeof(quint16)); (*iter)->write(block); } } diff --git a/src/utilite/ULogger.cpp b/src/utilite/ULogger.cpp index 06fb2981..984e47c4 100644 --- a/src/utilite/ULogger.cpp +++ b/src/utilite/ULogger.cpp @@ -53,13 +53,13 @@ bool ULogger::printWhereFullPath_ = false; bool ULogger::limitWhereLength_ = false; bool ULogger::buffered_ = false; bool ULogger::exitingState_ = false; -ULogger::Level ULogger::level_ = kInfo; // By default, we show all info msgs + upper level (Warning, Error) +ULogger::Level ULogger::level_ = kWarning; ULogger::Level ULogger::exitLevel_ = kFatal; ULogger::Level ULogger::eventLevel_ = kFatal; const char * ULogger::levelName_[5] = {"DEBUG", " INFO", " WARN", "ERROR", "FATAL"}; ULogger* ULogger::instance_ = 0; UDestroyer ULogger::destroyer_; -ULogger::Type ULogger::type_ = ULogger::kTypeNoLog; // Default nothing +ULogger::Type ULogger::type_ = ULogger::kTypeConsole; UMutex ULogger::loggerMutex_; const std::string ULogger::kDefaultLogFileName = "./ULog.txt"; std::string ULogger::logFileName_; diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index e7550ff8..7e401f1c 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,4 +1,4 @@ -ADD_SUBDIRECTORY( tcpObjectsClient ) +ADD_SUBDIRECTORY( tcpClient ) ADD_SUBDIRECTORY( tcpImagesServer ) ADD_SUBDIRECTORY( tcpRequest ) ADD_SUBDIRECTORY( similarity ) \ No newline at end of file diff --git a/tools/tcpObjectsClient/CMakeLists.txt b/tools/tcpClient/CMakeLists.txt similarity index 100% rename from tools/tcpObjectsClient/CMakeLists.txt rename to tools/tcpClient/CMakeLists.txt diff --git a/tools/tcpObjectsClient/TcpClient.cpp b/tools/tcpClient/TcpClient.cpp similarity index 100% rename from tools/tcpObjectsClient/TcpClient.cpp rename to tools/tcpClient/TcpClient.cpp diff --git a/tools/tcpObjectsClient/TcpClient.h b/tools/tcpClient/TcpClient.h similarity index 100% rename from tools/tcpObjectsClient/TcpClient.h rename to tools/tcpClient/TcpClient.h diff --git a/tools/tcpObjectsClient/main.cpp b/tools/tcpClient/main.cpp similarity index 100% rename from tools/tcpObjectsClient/main.cpp rename to tools/tcpClient/main.cpp diff --git a/tools/tcpRequest/CMakeLists.txt b/tools/tcpRequest/CMakeLists.txt index fe92405b..35e10bbd 100644 --- a/tools/tcpRequest/CMakeLists.txt +++ b/tools/tcpRequest/CMakeLists.txt @@ -25,18 +25,6 @@ SET(LIBRARIES ${QT_LIBRARIES} ) -IF(JSONCPP_FOUND) - SET(INCLUDE_DIRS - ${INCLUDE_DIRS} - ${JSONCPP_INCLUDE_DIRS} - ) - SET(LIBRARIES - ${LIBRARIES} - ${JSONCPP_LIBRARIES} - ) - ADD_DEFINITIONS("-DWITH_JSONCPP") -ENDIF(JSONCPP_FOUND) - # Make sure the compiler can find include files from our library. INCLUDE_DIRECTORIES(${INCLUDE_DIRS}) diff --git a/tools/tcpRequest/TcpResponse.cpp b/tools/tcpRequest/TcpResponse.cpp index 06c5718f..574a9503 100644 --- a/tools/tcpRequest/TcpResponse.cpp +++ b/tools/tcpRequest/TcpResponse.cpp @@ -44,24 +44,7 @@ void TcpResponse::readReceivedData() blockSize_ = 0; - QVector data; - in >> data; - - objectsDetected_.clear(); - for(int i=0; i(QRect(0,0,width, height), homography)); - } + in >> info_; dataReceived_ = true; Q_EMIT detectionReceived(); diff --git a/tools/tcpRequest/TcpResponse.h b/tools/tcpRequest/TcpResponse.h index f60711f4..cc590635 100644 --- a/tools/tcpRequest/TcpResponse.h +++ b/tools/tcpRequest/TcpResponse.h @@ -8,6 +8,8 @@ #ifndef TCPRESPONSE_H_ #define TCPRESPONSE_H_ +#include "find_object/DetectionInfo.h" + #include #include #include @@ -18,7 +20,7 @@ class TcpResponse : public QTcpSocket Q_OBJECT; public: TcpResponse(QObject * parent = 0); - const QMultiMap > & objectsDetected() const {return objectsDetected_;} + const DetectionInfo & info() const {return info_;} bool dataReceived() const {return dataReceived_;} private Q_SLOTS: @@ -31,7 +33,7 @@ Q_SIGNALS: private: quint16 blockSize_; - QMultiMap > objectsDetected_; + DetectionInfo info_; bool dataReceived_; }; diff --git a/tools/tcpRequest/main.cpp b/tools/tcpRequest/main.cpp index d72602a9..debf81fc 100644 --- a/tools/tcpRequest/main.cpp +++ b/tools/tcpRequest/main.cpp @@ -11,10 +11,7 @@ #include #include #include "TcpResponse.h" - -#ifdef WITH_JSONCPP -#include -#endif +#include "find_object/JsonWriter.h" void showUsage() { @@ -22,67 +19,12 @@ void showUsage() " \"out\" is the port to which the image is sent.\n" " \"in\" is the port from which the detection is received.\n" " Options:\n" - " --host #.#.#.# Set host address.\n" -#ifdef WITH_JSONCPP - " --json \"path\" Path to an output JSON file.\n" -#endif - ); - exit(-1); -} - -void writeJSON(const QMultiMap > & objectsDetected, const QString & path) -{ -#ifdef WITH_JSONCPP - if(!path.isEmpty()) + " --host #.#.#.# Set host address.\n"); + if(JsonWriter::available()) { - Json::Value root; - Json::Value detections; - - if(objectsDetected.size()) - { - for(QMultiMap >::const_iterator iter = objectsDetected.constBegin(); - iter!= objectsDetected.end();) - { - char index = 'a'; - QMultiMap >::const_iterator jter = iter; - for(;jter != objectsDetected.constEnd() && jter.key() == iter.key(); ++jter) - { - QString name = QString("object_%1%2").arg(jter.key()).arg(objectsDetected.count(jter.key())>1?QString(index++):""); - detections.append(name.toStdString()); - - Json::Value homography; - homography.append(jter.value().second.m11()); - homography.append(jter.value().second.m12()); - homography.append(jter.value().second.m13()); - homography.append(jter.value().second.m21()); - homography.append(jter.value().second.m22()); - homography.append(jter.value().second.m23()); - homography.append(jter.value().second.m31()); // dx - homography.append(jter.value().second.m32()); // dy - homography.append(jter.value().second.m33()); - root[name.toStdString()]["width"] = jter.value().first.width(); - root[name.toStdString()]["height"] = jter.value().first.height(); - root[name.toStdString()]["homography"] = homography; - } - iter = jter; - } - } - - root["objects"] = detections; - - // write in a nice readible way - Json::StyledWriter styledWriter; - //std::cout << styledWriter.write(root); - QFile file(path); - file.open(QIODevice::WriteOnly | QIODevice::Text); - QTextStream out(&file); - out << styledWriter.write(root).c_str(); - file.close(); - printf("JSON written to \"%s\"\n", path.toStdString().c_str()); + printf(" --json \"path\" Path to an output JSON file.\n"); } -#else - printf("Not built with JSON support!\n"); -#endif + exit(-1); } int main(int argc, char * argv[]) @@ -123,20 +65,6 @@ int main(int argc, char * argv[]) } continue; } - if(strcmp(argv[i], "--json") == 0 || strcmp(argv[i], "-json") == 0) - { - ++i; - if(i < argc) - { - jsonPath = argv[i]; - } - else - { - printf("error parsing --json\n"); - showUsage(); - } - continue; - } if(strcmp(argv[i], "--out") == 0 || strcmp(argv[i], "-out") == 0) { ++i; @@ -166,6 +94,24 @@ int main(int argc, char * argv[]) continue; } + if(JsonWriter::available()) + { + if(strcmp(argv[i], "--json") == 0 || strcmp(argv[i], "-json") == 0) + { + ++i; + if(i < argc) + { + jsonPath = argv[i]; + } + else + { + printf("error parsing --json\n"); + showUsage(); + } + continue; + } + } + printf("Unrecognized option: %s\n", argv[i]); showUsage(); } @@ -242,12 +188,12 @@ int main(int argc, char * argv[]) { printf("Response received! (%d ms)\n", time.elapsed()); // print detected objects - if(response.objectsDetected().size()) + if(response.info().objDetected_.size()) { - QList ids = response.objectsDetected().uniqueKeys(); + QList ids = response.info().objDetected_.uniqueKeys(); for(int i=0; i