Added DetectionInfo object for easier serialization/deserialization of the detection results.
Added filename property in json files Added JsonWritter class for convenience git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@369 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
parent
cd8368f0de
commit
e6fcc961b8
@ -12,18 +12,6 @@ SET(LIBRARIES
|
|||||||
${OpenCV_LIBS}
|
${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 files
|
||||||
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
||||||
|
|
||||||
|
|||||||
174
app/main.cpp
174
app/main.cpp
@ -6,12 +6,9 @@
|
|||||||
#include "find_object/FindObject.h"
|
#include "find_object/FindObject.h"
|
||||||
#include "find_object/Camera.h"
|
#include "find_object/Camera.h"
|
||||||
#include "find_object/TcpServer.h"
|
#include "find_object/TcpServer.h"
|
||||||
|
#include "find_object/JsonWriter.h"
|
||||||
#include "find_object/utilite/ULogger.h"
|
#include "find_object/utilite/ULogger.h"
|
||||||
|
|
||||||
#ifdef WITH_JSONCPP
|
|
||||||
#include <jsoncpp/json/writer.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool running = true;
|
bool running = true;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -76,89 +73,12 @@ void showUsage()
|
|||||||
" --objects \"path\" Directory of the objects to detect.\n"
|
" --objects \"path\" Directory of the objects to detect.\n"
|
||||||
" --config \"path\" Path to configuration file (default: %s).\n"
|
" --config \"path\" Path to configuration file (default: %s).\n"
|
||||||
" --scene \"path\" Path to a scene image file.\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());
|
" --help Show usage.\n", Settings::iniDefaultPath().toStdString().c_str());
|
||||||
exit(-1);
|
if(JsonWriter::available())
|
||||||
}
|
|
||||||
|
|
||||||
void writeJSON(const FindObject & findObject, const QString & path)
|
|
||||||
{
|
|
||||||
#ifdef WITH_JSONCPP
|
|
||||||
if(!path.isEmpty())
|
|
||||||
{
|
{
|
||||||
Json::Value root;
|
printf(" --json \"path\" Path to an output JSON file (only in --console mode with --scene).\n");
|
||||||
Json::Value detections;
|
|
||||||
Json::Value matchesValues;
|
|
||||||
|
|
||||||
if(findObject.objectsDetected().size())
|
|
||||||
{
|
|
||||||
Q_ASSERT(objectsDetected.size() == findObject.inliers().size() &&
|
|
||||||
objectsDetected.size() == findObject.outliers().size());
|
|
||||||
|
|
||||||
const QMultiMap<int,QPair<QRect,QTransform> > & objectsDetected = findObject.objectsDetected();
|
|
||||||
QMultiMap<int, QMultiMap<int, int> >::const_iterator iterInliers = findObject.inliers().constBegin();
|
|
||||||
QMultiMap<int, QMultiMap<int, int> >::const_iterator iterOutliers = findObject.outliers().constBegin();
|
|
||||||
for(QMultiMap<int,QPair<QRect,QTransform> >::const_iterator iter = objectsDetected.constBegin();
|
|
||||||
iter!= objectsDetected.end();)
|
|
||||||
{
|
|
||||||
char index = 'a';
|
|
||||||
QMultiMap<int,QPair<QRect,QTransform> >::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<int, QMultiMap<int, int> > & matches = findObject.matches();
|
|
||||||
for(QMap<int, QMultiMap<int, int> >::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());
|
|
||||||
}
|
}
|
||||||
#else
|
exit(-1);
|
||||||
UERROR("Not built with JSON support!");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
@ -249,26 +169,6 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
continue;
|
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 ||
|
if(strcmp(argv[i], "-console") == 0 ||
|
||||||
strcmp(argv[i], "--console") == 0)
|
strcmp(argv[i], "--console") == 0)
|
||||||
{
|
{
|
||||||
@ -280,6 +180,27 @@ int main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
showUsage();
|
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]);
|
UERROR("Unrecognized option : %s", argv[i]);
|
||||||
showUsage();
|
showUsage();
|
||||||
@ -290,9 +211,10 @@ int main(int argc, char* argv[])
|
|||||||
UINFO(" Objects path: \"%s\"", objectsPath.toStdString().c_str());
|
UINFO(" Objects path: \"%s\"", objectsPath.toStdString().c_str());
|
||||||
UINFO(" Scene path: \"%s\"", scenePath.toStdString().c_str());
|
UINFO(" Scene path: \"%s\"", scenePath.toStdString().c_str());
|
||||||
UINFO(" Settings path: \"%s\"", configPath.toStdString().c_str());
|
UINFO(" Settings path: \"%s\"", configPath.toStdString().c_str());
|
||||||
#ifdef WITH_JSONCPP
|
if(JsonWriter::available())
|
||||||
UINFO(" JSON path: \"%s\"", jsonPath.toStdString().c_str());
|
{
|
||||||
#endif
|
UINFO(" JSON path: \"%s\"", jsonPath.toStdString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
// parse options END
|
// parse options END
|
||||||
@ -353,26 +275,42 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
QCoreApplication app(argc, 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<int,QPair<QRect,QTransform> >)), &tcpServer, SLOT(publishObjects(QMultiMap<int,QPair<QRect,QTransform> >)));
|
|
||||||
|
|
||||||
if(!scene.empty())
|
if(!scene.empty())
|
||||||
{
|
{
|
||||||
// process the scene and exit
|
// 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
|
else
|
||||||
{
|
{
|
||||||
Camera camera;
|
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]
|
// [Camera] ---Image---> [FindObject]
|
||||||
QObject::connect(&camera, SIGNAL(imageReceived(const cv::Mat &)), findObject, SLOT(detect(const cv::Mat &)));
|
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
|
// cleanup
|
||||||
camera.stop();
|
camera.stop();
|
||||||
|
tcpServer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete findObject;
|
delete findObject;
|
||||||
tcpServer.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
118
include/find_object/DetectionInfo.h
Normal file
118
include/find_object/DetectionInfo.h
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* DetectionInfo.h
|
||||||
|
*
|
||||||
|
* Created on: 2014-08-03
|
||||||
|
* Author: mathieu
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DETECTIONINFO_H_
|
||||||
|
#define DETECTIONINFO_H_
|
||||||
|
|
||||||
|
#include <QtCore/QMultiMap>
|
||||||
|
#include <QtGui/QTransform>
|
||||||
|
#include <QtCore/QSize>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <opencv2/features2d/features2d.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class DetectionInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum TimeStamp{kTimeKeypointDetection, kTimeDescriptorExtraction, kTimeIndexing, kTimeMatching, kTimeHomography, kTimeTotal};
|
||||||
|
|
||||||
|
public:
|
||||||
|
DetectionInfo() :
|
||||||
|
minMatchedDistance_(-1),
|
||||||
|
maxMatchedDistance_(-1)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
QMultiMap<int, QTransform> objDetected_;
|
||||||
|
QMultiMap<int, QSize> objDetectedSizes_; // Object ID <width, height> match the number of detected objects
|
||||||
|
QMultiMap<int, QString > objDetectedFilenames_; // Object ID <filename> match the number of detected objects
|
||||||
|
QMultiMap<int, int> objDetectedInliersCount_; // ObjectID <count> match the number of detected objects
|
||||||
|
QMultiMap<int, int> objDetectedOutliersCount_; // ObjectID <count> match the number of detected objects
|
||||||
|
QMultiMap<int, QMultiMap<int, int> > objDetectedInliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of detected objects
|
||||||
|
QMultiMap<int, QMultiMap<int, int> > objDetectedOutliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of detected objects
|
||||||
|
|
||||||
|
QMap<TimeStamp, float> timeStamps_;
|
||||||
|
std::vector<cv::KeyPoint> sceneKeypoints_;
|
||||||
|
cv::Mat sceneDescriptors_;
|
||||||
|
QMultiMap<int, int> sceneWords_;
|
||||||
|
QMap<int, QMultiMap<int, int> > matches_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of objects
|
||||||
|
QMultiMap<int, QMultiMap<int, int> > rejectedInliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >
|
||||||
|
QMultiMap<int, QMultiMap<int, int> > rejectedOutliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >
|
||||||
|
float minMatchedDistance_;
|
||||||
|
float maxMatchedDistance_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline QDataStream & operator<<(QDataStream &out, const DetectionInfo & info)
|
||||||
|
{
|
||||||
|
out << quint32(info.objDetected_.size());
|
||||||
|
|
||||||
|
QMultiMap<int, int>::const_iterator iterInliers = info.objDetectedInliersCount_.constBegin();
|
||||||
|
QMultiMap<int, int>::const_iterator iterOutliers = info.objDetectedOutliersCount_.constBegin();
|
||||||
|
QMultiMap<int, QSize>::const_iterator iterSizes = info.objDetectedSizes_.constBegin();
|
||||||
|
QMultiMap<int, QString>::const_iterator iterFilenames = info.objDetectedFilenames_.constBegin();
|
||||||
|
for(QMultiMap<int, QTransform>::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_ */
|
||||||
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include "find_object/FindObjectExp.h" // DLL export/import defines
|
#include "find_object/FindObjectExp.h" // DLL export/import defines
|
||||||
|
|
||||||
|
#include "find_object/DetectionInfo.h"
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
@ -30,21 +32,18 @@ class FINDOBJECT_EXP FindObject : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
|
|
||||||
public:
|
|
||||||
enum TimeStamp{kTimeKeypointDetection, kTimeDescriptorExtraction, kTimeIndexing, kTimeMatching, kTimeHomography, kTimeTotal};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FindObject(QObject * parent = 0);
|
FindObject(QObject * parent = 0);
|
||||||
virtual ~FindObject();
|
virtual ~FindObject();
|
||||||
|
|
||||||
int loadObjects(const QString & dirPath); // call updateObjects()
|
int loadObjects(const QString & dirPath); // call updateObjects()
|
||||||
const ObjSignature * addObject(const QString & filePath);
|
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
|
bool addObject(ObjSignature * obj); // take ownership when true is returned
|
||||||
void removeObject(int id);
|
void removeObject(int id);
|
||||||
void removeAllObjects();
|
void removeAllObjects();
|
||||||
|
|
||||||
bool detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransform> > & objectsDetected);
|
bool detect(const cv::Mat & image, DetectionInfo & info);
|
||||||
|
|
||||||
void updateDetectorExtractor();
|
void updateDetectorExtractor();
|
||||||
void updateObjects();
|
void updateObjects();
|
||||||
@ -53,24 +52,11 @@ public:
|
|||||||
const QMap<int, ObjSignature*> & objects() const {return objects_;}
|
const QMap<int, ObjSignature*> & objects() const {return objects_;}
|
||||||
const Vocabulary * vocabulary() const {return vocabulary_;}
|
const Vocabulary * vocabulary() const {return vocabulary_;}
|
||||||
|
|
||||||
const QMultiMap<int,QPair<QRect,QTransform> > & objectsDetected() const {return objectsDetected_;}
|
|
||||||
const QMap<TimeStamp, float> & timeStamps() const {return timeStamps_;}
|
|
||||||
const std::vector<cv::KeyPoint> & sceneKeypoints() const {return sceneKeypoints_;}
|
|
||||||
const cv::Mat & sceneDescriptors() const {return sceneDescriptors_;}
|
|
||||||
const QMultiMap<int, int> & sceneWords() const {return sceneWords_;}
|
|
||||||
const QMap<int, QMultiMap<int, int> > & matches() const {return matches_;}
|
|
||||||
const QMultiMap<int, QMultiMap<int, int> > & inliers() const {return inliers_;}
|
|
||||||
const QMultiMap<int, QMultiMap<int, int> > & outliers() const {return outliers_;}
|
|
||||||
const QMultiMap<int, QMultiMap<int, int> > & rejectedInliers() const {return rejectedInliers_;}
|
|
||||||
const QMultiMap<int, QMultiMap<int, int> > & rejectedOutliers() const {return rejectedOutliers_;}
|
|
||||||
float minMatchedDistance() const {return minMatchedDistance_;}
|
|
||||||
float maxMatchedDistance() const {return maxMatchedDistance_;}
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void detect(const cv::Mat & image); // emit objectsfound()
|
void detect(const cv::Mat & image); // emit objectsFound()
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void objectsFound(const QMultiMap<int, QPair<QRect, QTransform> > &);
|
void objectsFound(const DetectionInfo &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void clearVocabulary();
|
void clearVocabulary();
|
||||||
@ -82,19 +68,6 @@ private:
|
|||||||
QMap<int, int> dataRange_; // <last id of object's descriptor, id>
|
QMap<int, int> dataRange_; // <last id of object's descriptor, id>
|
||||||
KeypointDetector * detector_;
|
KeypointDetector * detector_;
|
||||||
DescriptorExtractor * extractor_;
|
DescriptorExtractor * extractor_;
|
||||||
|
|
||||||
QMultiMap<int,QPair<QRect,QTransform> > objectsDetected_;
|
|
||||||
QMap<TimeStamp, float> timeStamps_;
|
|
||||||
std::vector<cv::KeyPoint> sceneKeypoints_;
|
|
||||||
cv::Mat sceneDescriptors_;
|
|
||||||
QMultiMap<int, int> sceneWords_;
|
|
||||||
QMap<int, QMultiMap<int, int> > matches_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of objects
|
|
||||||
QMultiMap<int, QMultiMap<int, int> > inliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of detected objects
|
|
||||||
QMultiMap<int, QMultiMap<int, int> > outliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >, match the number of detected objects
|
|
||||||
QMultiMap<int, QMultiMap<int, int> > rejectedInliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >
|
|
||||||
QMultiMap<int, QMultiMap<int, int> > rejectedOutliers_; // ObjectID Map< ObjectDescriptorIndex, SceneDescriptorIndex >
|
|
||||||
float minMatchedDistance_;
|
|
||||||
float maxMatchedDistance_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FINDOBJECT_H_ */
|
#endif /* FINDOBJECT_H_ */
|
||||||
|
|||||||
21
include/find_object/JsonWriter.h
Normal file
21
include/find_object/JsonWriter.h
Normal file
@ -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_ */
|
||||||
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "find_object/FindObjectExp.h" // DLL export/import defines
|
#include "find_object/FindObjectExp.h" // DLL export/import defines
|
||||||
|
|
||||||
|
#include "find_object/DetectionInfo.h"
|
||||||
|
|
||||||
#include <QtGui/QMainWindow>
|
#include <QtGui/QMainWindow>
|
||||||
#include <QtCore/QSet>
|
#include <QtCore/QSet>
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
@ -74,7 +76,7 @@ private Q_SLOTS:
|
|||||||
void rectHovered(int objId);
|
void rectHovered(int objId);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void objectsFound(const QMultiMap<int, QPair<QRect, QTransform> > &);
|
void objectsFound(const DetectionInfo &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool loadSettings(const QString & path);
|
bool loadSettings(const QString & path);
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include "find_object/FindObjectExp.h" // DLL export/import defines
|
#include "find_object/FindObjectExp.h" // DLL export/import defines
|
||||||
|
|
||||||
|
#include "find_object/DetectionInfo.h"
|
||||||
|
|
||||||
#include <QtNetwork/QTcpServer>
|
#include <QtNetwork/QTcpServer>
|
||||||
|
|
||||||
class QNetworkSession;
|
class QNetworkSession;
|
||||||
@ -25,7 +27,7 @@ public:
|
|||||||
quint16 getPort() const;
|
quint16 getPort() const;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void publishObjects(const QMultiMap<int, QPair<QRect, QTransform> > & objects);
|
void publishDetectionInfo(const DetectionInfo & info);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void addClient();
|
void addClient();
|
||||||
|
|||||||
@ -332,7 +332,7 @@ void AddObjectDialog::setState(int state)
|
|||||||
delete objSignature_;
|
delete objSignature_;
|
||||||
objSignature_ = 0;
|
objSignature_ = 0;
|
||||||
}
|
}
|
||||||
objSignature_ = new ObjSignature(0, imgRoi.clone());
|
objSignature_ = new ObjSignature(0, imgRoi.clone(), "");
|
||||||
objSignature_->setData(keypoints, descriptors, Settings::currentDetectorType(), Settings::currentDescriptorType());
|
objSignature_->setData(keypoints, descriptors, Settings::currentDetectorType(), Settings::currentDescriptorType());
|
||||||
objWidget_ = new ObjWidget(0, keypoints, cvtCvMat2QImage(imgRoi.clone()));
|
objWidget_ = new ObjWidget(0, keypoints, cvtCvMat2QImage(imgRoi.clone()));
|
||||||
|
|
||||||
|
|||||||
@ -36,9 +36,6 @@ QT4_WRAP_UI(moc_uis ${uis})
|
|||||||
QT4_WRAP_CPP(moc_srcs ${headers_ui})
|
QT4_WRAP_CPP(moc_srcs ${headers_ui})
|
||||||
### Qt Gui stuff end###
|
### Qt Gui stuff end###
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SET(SRC_FILES
|
SET(SRC_FILES
|
||||||
./MainWindow.cpp
|
./MainWindow.cpp
|
||||||
./AddObjectDialog.cpp
|
./AddObjectDialog.cpp
|
||||||
@ -54,6 +51,7 @@ SET(SRC_FILES
|
|||||||
./AboutDialog.cpp
|
./AboutDialog.cpp
|
||||||
./TcpServer.cpp
|
./TcpServer.cpp
|
||||||
./Vocabulary.cpp
|
./Vocabulary.cpp
|
||||||
|
./JsonWriter.cpp
|
||||||
./utilite/ULogger.cpp
|
./utilite/ULogger.cpp
|
||||||
./utilite/UPlot.cpp
|
./utilite/UPlot.cpp
|
||||||
./utilite/UDirectory.cpp
|
./utilite/UDirectory.cpp
|
||||||
@ -79,6 +77,18 @@ SET(LIBRARIES
|
|||||||
${OpenCV_LIBS}
|
${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 files
|
||||||
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
||||||
|
|
||||||
|
|||||||
@ -23,10 +23,9 @@ FindObject::FindObject(QObject * parent) :
|
|||||||
QObject(parent),
|
QObject(parent),
|
||||||
vocabulary_(new Vocabulary()),
|
vocabulary_(new Vocabulary()),
|
||||||
detector_(Settings::createKeypointDetector()),
|
detector_(Settings::createKeypointDetector()),
|
||||||
extractor_(Settings::createDescriptorExtractor()),
|
extractor_(Settings::createDescriptorExtractor())
|
||||||
minMatchedDistance_(-1),
|
|
||||||
maxMatchedDistance_(-1)
|
|
||||||
{
|
{
|
||||||
|
qRegisterMetaType<DetectionInfo>("DetectionInfo");
|
||||||
Q_ASSERT(detector_ != 0 && extractor_ != 0);
|
Q_ASSERT(detector_ != 0 && extractor_ != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,16 +86,16 @@ const ObjSignature * FindObject::addObject(const QString & filePath)
|
|||||||
id = 0;
|
id = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this->addObject(img, id);
|
return this->addObject(img, id, file.fileName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
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);
|
Q_ASSERT(id >= 0);
|
||||||
ObjSignature * s = new ObjSignature(id, image);
|
ObjSignature * s = new ObjSignature(id, image, filename);
|
||||||
if(!this->addObject(s))
|
if(!this->addObject(s))
|
||||||
{
|
{
|
||||||
delete s;
|
delete s;
|
||||||
@ -596,25 +595,25 @@ void FindObject::detect(const cv::Mat & image)
|
|||||||
{
|
{
|
||||||
QTime time;
|
QTime time;
|
||||||
time.start();
|
time.start();
|
||||||
QMultiMap<int,QPair<QRect,QTransform> > objects;
|
DetectionInfo info;
|
||||||
this->detect(image, objects);
|
this->detect(image, info);
|
||||||
if(objects.size() > 0 || Settings::getGeneral_sendNoObjDetectedEvents())
|
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)",
|
UINFO("(%s) %d objects detected! (%d ms)",
|
||||||
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
||||||
(int)objects.size(),
|
(int)info.objDetected_.size(),
|
||||||
time.elapsed());
|
time.elapsed());
|
||||||
}
|
}
|
||||||
else if(objects.size() == 1)
|
else if(info.objDetected_.size() == 1)
|
||||||
{
|
{
|
||||||
UINFO("(%s) Object %d detected! (%d ms)",
|
UINFO("(%s) Object %d detected! (%d ms)",
|
||||||
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
||||||
(int)objects.begin().key(),
|
(int)info.objDetected_.begin().key(),
|
||||||
time.elapsed());
|
time.elapsed());
|
||||||
}
|
}
|
||||||
else if(Settings::getGeneral_sendNoObjDetectedEvents())
|
else if(Settings::getGeneral_sendNoObjDetectedEvents())
|
||||||
@ -625,22 +624,13 @@ void FindObject::detect(const cv::Mat & image)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransform> > & objectsDetected)
|
bool FindObject::detect(const cv::Mat & image, DetectionInfo & info)
|
||||||
{
|
{
|
||||||
QTime totalTime;
|
QTime totalTime;
|
||||||
totalTime.start();
|
totalTime.start();
|
||||||
|
|
||||||
// reset statistics
|
// reset statistics
|
||||||
objectsDetected_.clear();
|
info = DetectionInfo();
|
||||||
timeStamps_.clear();
|
|
||||||
sceneKeypoints_.clear();
|
|
||||||
sceneDescriptors_ = cv::Mat();
|
|
||||||
sceneWords_.clear();
|
|
||||||
matches_.clear();
|
|
||||||
inliers_.clear();
|
|
||||||
outliers_.clear();
|
|
||||||
minMatchedDistance_ = -1.0f;
|
|
||||||
maxMatchedDistance_ = -1.0f;
|
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if(!image.empty())
|
if(!image.empty())
|
||||||
@ -660,36 +650,36 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
time.start();
|
time.start();
|
||||||
|
|
||||||
// EXTRACT KEYPOINTS
|
// EXTRACT KEYPOINTS
|
||||||
detector_->detect(grayscaleImg, sceneKeypoints_);
|
detector_->detect(grayscaleImg, info.sceneKeypoints_);
|
||||||
timeStamps_.insert(kTimeKeypointDetection, time.restart());
|
info.timeStamps_.insert(DetectionInfo::kTimeKeypointDetection, time.restart());
|
||||||
|
|
||||||
bool emptyScene = sceneKeypoints_.size() == 0;
|
bool emptyScene = info.sceneKeypoints_.size() == 0;
|
||||||
if(sceneKeypoints_.size())
|
if(info.sceneKeypoints_.size())
|
||||||
{
|
{
|
||||||
int maxFeatures = Settings::getFeature2D_3MaxFeatures();
|
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
|
// EXTRACT DESCRIPTORS
|
||||||
extractor_->compute(grayscaleImg, sceneKeypoints_, sceneDescriptors_);
|
extractor_->compute(grayscaleImg, info.sceneKeypoints_, info.sceneDescriptors_);
|
||||||
if((int)sceneKeypoints_.size() != sceneDescriptors_.rows)
|
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()) ||
|
bool consistentNNData = (vocabulary_->size()!=0 && vocabulary_->wordToObjects().begin().value()!=-1 && Settings::getGeneral_invertedSearch()) ||
|
||||||
((vocabulary_->size()==0 || vocabulary_->wordToObjects().begin().value()==-1) && !Settings::getGeneral_invertedSearch());
|
((vocabulary_->size()==0 || vocabulary_->wordToObjects().begin().value()==-1) && !Settings::getGeneral_invertedSearch());
|
||||||
|
|
||||||
// COMPARE
|
// COMPARE
|
||||||
if(!objectsDescriptors_.empty() &&
|
if(!objectsDescriptors_.empty() &&
|
||||||
sceneKeypoints_.size() &&
|
info.sceneKeypoints_.size() &&
|
||||||
consistentNNData &&
|
consistentNNData &&
|
||||||
objectsDescriptors_.begin().value().cols == sceneDescriptors_.cols &&
|
objectsDescriptors_.begin().value().cols == info.sceneDescriptors_.cols &&
|
||||||
objectsDescriptors_.begin().value().type() == sceneDescriptors_.type()) // binary descriptor issue, if the dataTree is not yet updated with modified settings
|
objectsDescriptors_.begin().value().type() == info.sceneDescriptors_.type()) // binary descriptor issue, if the dataTree is not yet updated with modified settings
|
||||||
{
|
{
|
||||||
success = true;
|
success = true;
|
||||||
|
|
||||||
@ -699,17 +689,17 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
{
|
{
|
||||||
// CREATE INDEX for the scene
|
// CREATE INDEX for the scene
|
||||||
vocabulary_->clear();
|
vocabulary_->clear();
|
||||||
words = vocabulary_->addWords(sceneDescriptors_, -1, Settings::getGeneral_vocabularyIncremental());
|
words = vocabulary_->addWords(info.sceneDescriptors_, -1, Settings::getGeneral_vocabularyIncremental());
|
||||||
if(!Settings::getGeneral_vocabularyIncremental())
|
if(!Settings::getGeneral_vocabularyIncremental())
|
||||||
{
|
{
|
||||||
vocabulary_->update();
|
vocabulary_->update();
|
||||||
}
|
}
|
||||||
timeStamps_.insert(kTimeIndexing, time.restart());
|
info.timeStamps_.insert(DetectionInfo::kTimeIndexing, time.restart());
|
||||||
}
|
}
|
||||||
|
|
||||||
for(QMap<int, ObjSignature*>::iterator iter=objects_.begin(); iter!=objects_.end(); ++iter)
|
for(QMap<int, ObjSignature*>::iterator iter=objects_.begin(); iter!=objects_.end(); ++iter)
|
||||||
{
|
{
|
||||||
matches_.insert(iter.key(), QMultiMap<int, int>());
|
info.matches_.insert(iter.key(), QMultiMap<int, int>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Settings::getGeneral_invertedSearch() || Settings::getGeneral_threads() == 1)
|
if(Settings::getGeneral_invertedSearch() || Settings::getGeneral_threads() == 1)
|
||||||
@ -728,9 +718,9 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//match scene to objects
|
//match scene to objects
|
||||||
results = cv::Mat(sceneDescriptors_.rows, k, CV_32SC1); // results index
|
results = cv::Mat(info.sceneDescriptors_.rows, k, CV_32SC1); // results index
|
||||||
dists = cv::Mat(sceneDescriptors_.rows, k, CV_32FC1); // Distance results are CV_32FC1
|
dists = cv::Mat(info.sceneDescriptors_.rows, k, CV_32FC1); // Distance results are CV_32FC1
|
||||||
vocabulary_->search(sceneDescriptors_, results, dists, k);
|
vocabulary_->search(info.sceneDescriptors_, results, dists, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
// PROCESS RESULTS
|
// PROCESS RESULTS
|
||||||
@ -761,13 +751,13 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
{
|
{
|
||||||
matched = true; // no criterion, match to the nearest descriptor
|
matched = true; // no criterion, match to the nearest descriptor
|
||||||
}
|
}
|
||||||
if(minMatchedDistance_ == -1 || minMatchedDistance_ > dists.at<float>(i,0))
|
if(info.minMatchedDistance_ == -1 || info.minMatchedDistance_ > dists.at<float>(i,0))
|
||||||
{
|
{
|
||||||
minMatchedDistance_ = dists.at<float>(i,0);
|
info.minMatchedDistance_ = dists.at<float>(i,0);
|
||||||
}
|
}
|
||||||
if(maxMatchedDistance_ == -1 || maxMatchedDistance_ < dists.at<float>(i,0))
|
if(info.maxMatchedDistance_ == -1 || info.maxMatchedDistance_ < dists.at<float>(i,0))
|
||||||
{
|
{
|
||||||
maxMatchedDistance_ = dists.at<float>(i,0);
|
info.maxMatchedDistance_ = dists.at<float>(i,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(matched)
|
if(matched)
|
||||||
@ -781,7 +771,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
// just add unique matches
|
// just add unique matches
|
||||||
if(vocabulary_->wordToObjects().count(wordId, objIds[j]) == 1)
|
if(vocabulary_->wordToObjects().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<int,QPair<QRect,QTransf
|
|||||||
int wordId = results.at<int>(i,0);
|
int wordId = results.at<int>(i,0);
|
||||||
if(words.count(wordId) == 1)
|
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, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
for(int k=0; k<threads.size(); ++k)
|
for(int k=0; k<threads.size(); ++k)
|
||||||
{
|
{
|
||||||
threads[k]->wait();
|
threads[k]->wait();
|
||||||
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];
|
delete threads[k];
|
||||||
}
|
}
|
||||||
@ -841,7 +831,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timeStamps_.insert(kTimeMatching, time.restart());
|
info.timeStamps_.insert(DetectionInfo::kTimeMatching, time.restart());
|
||||||
|
|
||||||
// Homographies
|
// Homographies
|
||||||
if(Settings::getHomography_homographyComputed())
|
if(Settings::getHomography_homographyComputed())
|
||||||
@ -850,10 +840,10 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
int threadCounts = Settings::getGeneral_threads();
|
int threadCounts = Settings::getGeneral_threads();
|
||||||
if(threadCounts == 0)
|
if(threadCounts == 0)
|
||||||
{
|
{
|
||||||
threadCounts = matches_.size();
|
threadCounts = info.matches_.size();
|
||||||
}
|
}
|
||||||
QList<int> matchesId = matches_.keys();
|
QList<int> matchesId = info.matches_.keys();
|
||||||
QList<QMultiMap<int, int> > matchesList = matches_.values();
|
QList<QMultiMap<int, int> > matchesList = info.matches_.values();
|
||||||
for(int i=0; i<matchesList.size(); i+=threadCounts)
|
for(int i=0; i<matchesList.size(); i+=threadCounts)
|
||||||
{
|
{
|
||||||
QVector<HomographyThread*> threads;
|
QVector<HomographyThread*> threads;
|
||||||
@ -861,7 +851,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
for(int k=i; k<i+threadCounts && k<matchesList.size(); ++k)
|
for(int k=i; k<i+threadCounts && k<matchesList.size(); ++k)
|
||||||
{
|
{
|
||||||
int objectId = matchesId[k];
|
int objectId = matchesId[k];
|
||||||
threads.push_back(new HomographyThread(&matchesList[k], objectId, &objects_.value(objectId)->keypoints(), &sceneKeypoints_));
|
threads.push_back(new HomographyThread(&matchesList[k], objectId, &objects_.value(objectId)->keypoints(), &info.sceneKeypoints_));
|
||||||
threads.back()->start();
|
threads.back()->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -889,11 +879,11 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
matchesId.push_back(id);
|
matchesId.push_back(id);
|
||||||
|
|
||||||
// compute distance from previous added same objects...
|
// compute distance from previous added same objects...
|
||||||
QMultiMap<int, QPair<QRect, QTransform> >::iterator objIter = objectsDetected.find(id);
|
QMultiMap<int, QTransform>::iterator objIter = info.objDetected_.find(id);
|
||||||
for(;objIter!=objectsDetected.end() && objIter.key() == id; ++objIter)
|
for(;objIter!=info.objDetected_.end() && objIter.key() == id; ++objIter)
|
||||||
{
|
{
|
||||||
qreal dx = objIter.value().second.m31() - hTransform.m31();
|
qreal dx = objIter.value().m31() - hTransform.m31();
|
||||||
qreal dy = objIter.value().second.m32() - hTransform.m32();
|
qreal dy = objIter.value().m32() - hTransform.m32();
|
||||||
int d = (int)sqrt(dx*dx + dy*dy);
|
int d = (int)sqrt(dx*dx + dy*dy);
|
||||||
if(d < distance)
|
if(d < distance)
|
||||||
{
|
{
|
||||||
@ -905,33 +895,37 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
if(distance >= Settings::getGeneral_multiDetectionRadius())
|
if(distance >= Settings::getGeneral_multiDetectionRadius())
|
||||||
{
|
{
|
||||||
QRect rect = objects_.value(id)->rect();
|
QRect rect = objects_.value(id)->rect();
|
||||||
objectsDetected.insert(id, QPair<QRect, QTransform>(rect, hTransform));
|
info.objDetected_.insert(id, hTransform);
|
||||||
inliers_.insert(id, threads[j]->getInliers());
|
info.objDetectedSizes_.insert(id, rect.size());
|
||||||
outliers_.insert(id, threads[j]->getOutliers());
|
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
|
else
|
||||||
{
|
{
|
||||||
rejectedInliers_.insert(id, threads[j]->getInliers());
|
info.rejectedInliers_.insert(id, threads[j]->getInliers());
|
||||||
rejectedOutliers_.insert(id, threads[j]->getOutliers());
|
info.rejectedOutliers_.insert(id, threads[j]->getOutliers());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rejectedInliers_.insert(id, threads[j]->getInliers());
|
info.rejectedInliers_.insert(id, threads[j]->getInliers());
|
||||||
rejectedOutliers_.insert(id, threads[j]->getOutliers());
|
info.rejectedOutliers_.insert(id, threads[j]->getOutliers());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rejectedInliers_.insert(id, threads[j]->getInliers());
|
info.rejectedInliers_.insert(id, threads[j]->getInliers());
|
||||||
rejectedOutliers_.insert(id, threads[j]->getOutliers());
|
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");
|
UWARN("Cannot search, objects must be updated");
|
||||||
}
|
}
|
||||||
@ -943,8 +937,7 @@ bool FindObject::detect(const cv::Mat & image, QMultiMap<int,QPair<QRect,QTransf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objectsDetected_ = objectsDetected;
|
info.timeStamps_.insert(DetectionInfo::kTimeTotal, totalTime.elapsed());
|
||||||
timeStamps_.insert(kTimeTotal, totalTime.elapsed());
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|||||||
106
src/JsonWriter.cpp
Normal file
106
src/JsonWriter.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* JsonWriter.cpp
|
||||||
|
*
|
||||||
|
* Created on: 2014-08-03
|
||||||
|
* Author: mathieu
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "find_object/JsonWriter.h"
|
||||||
|
#include "find_object/utilite/ULogger.h"
|
||||||
|
|
||||||
|
#include <QtCore/QFile>
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
|
|
||||||
|
#ifdef WITH_JSONCPP
|
||||||
|
#include <jsoncpp/json/writer.h>
|
||||||
|
#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<int, int>::const_iterator iterInliers = info.objDetectedInliersCount_.constBegin();
|
||||||
|
QMultiMap<int, int>::const_iterator iterOutliers = info.objDetectedOutliersCount_.constBegin();
|
||||||
|
QMultiMap<int, QSize>::const_iterator iterSizes = info.objDetectedSizes_.constBegin();
|
||||||
|
QMultiMap<int, QString>::const_iterator iterFilenames = info.objDetectedFilenames_.constBegin();
|
||||||
|
for(QMultiMap<int, QTransform>::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<int, QMultiMap<int, int> > & matches = info.matches_;
|
||||||
|
for(QMap<int, QMultiMap<int, int> >::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
|
||||||
|
}
|
||||||
@ -268,7 +268,7 @@ void MainWindow::setupTCPServer()
|
|||||||
delete tcpServer_;
|
delete tcpServer_;
|
||||||
}
|
}
|
||||||
tcpServer_ = new TcpServer(Settings::getGeneral_port(), this);
|
tcpServer_ = new TcpServer(Settings::getGeneral_port(), this);
|
||||||
connect(this, SIGNAL(objectsFound(QMultiMap<int,QPair<QRect,QTransform> >)), tcpServer_, SLOT(publishObjects(QMultiMap<int,QPair<QRect,QTransform> >)));
|
connect(this, SIGNAL(objectsFound(DetectionInfo)), tcpServer_, SLOT(publishDetectionInfo(DetectionInfo)));
|
||||||
ui_->label_ipAddress->setText(tcpServer_->getHostAddress().toString());
|
ui_->label_ipAddress->setText(tcpServer_->getHostAddress().toString());
|
||||||
ui_->label_port->setNum(tcpServer_->getPort());
|
ui_->label_port->setNum(tcpServer_->getPort());
|
||||||
UINFO("Detection sent on port: %d (IP=%s)", tcpServer_->getPort(), tcpServer_->getHostAddress().toString().toStdString().c_str());
|
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();
|
iter.value()->resetKptsColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
QMultiMap<int,QPair<QRect,QTransform> > objectsDetected;
|
DetectionInfo info;
|
||||||
if(findObject_->detect(sceneImage_, objectsDetected))
|
if(findObject_->detect(sceneImage_, info))
|
||||||
{
|
{
|
||||||
ui_->label_timeDetection->setNum(findObject_->timeStamps().value(FindObject::kTimeKeypointDetection, 0));
|
ui_->label_timeDetection->setNum(info.timeStamps_.value(DetectionInfo::kTimeKeypointDetection, 0));
|
||||||
ui_->label_timeExtraction->setNum(findObject_->timeStamps().value(FindObject::kTimeDescriptorExtraction, 0));
|
ui_->label_timeExtraction->setNum(info.timeStamps_.value(DetectionInfo::kTimeDescriptorExtraction, 0));
|
||||||
ui_->imageView_source->setData(findObject_->sceneKeypoints(), cvtCvMat2QImage(sceneImage_));
|
ui_->imageView_source->setData(info.sceneKeypoints_, cvtCvMat2QImage(sceneImage_));
|
||||||
ui_->label_timeIndexing->setNum(findObject_->timeStamps().value(FindObject::kTimeIndexing, 0));
|
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_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
|
// Colorize features matched
|
||||||
const QMap<int, QMultiMap<int, int> > & matches = findObject_->matches();
|
const QMap<int, QMultiMap<int, int> > & matches = info.matches_;
|
||||||
QMap<int, int> scores;
|
QMap<int, int> scores;
|
||||||
int maxScoreId = -1;
|
int maxScoreId = -1;
|
||||||
int maxScore = 0;
|
int maxScore = 0;
|
||||||
@ -956,12 +957,12 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
ui_->imageView_source->setKptColor(iter.value(), obj->color());
|
ui_->imageView_source->setKptColor(iter.value(), obj->color());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!objectsDetected.contains(id))
|
else if(!info.objDetected_.contains(id))
|
||||||
{
|
{
|
||||||
// Homography could not be computed...
|
// Homography could not be computed...
|
||||||
QLabel * label = ui_->dockWidget_objects->findChild<QLabel*>(QString("%1detection").arg(id));
|
QLabel * label = ui_->dockWidget_objects->findChild<QLabel*>(QString("%1detection").arg(id));
|
||||||
QMultiMap<int, int> rejectedInliers = findObject_->rejectedInliers().value(id);
|
QMultiMap<int, int> rejectedInliers = info.rejectedInliers_.value(id);
|
||||||
QMultiMap<int, int> rejectedOutliers = findObject_->rejectedOutliers().value(id);
|
QMultiMap<int, int> rejectedOutliers = info.rejectedOutliers_.value(id);
|
||||||
if(jter.value().size() < Settings::getHomography_minimumInliers())
|
if(jter.value().size() < Settings::getHomography_minimumInliers())
|
||||||
{
|
{
|
||||||
label->setText(QString("Too low matches (%1)").arg(jter.value().size()));
|
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
|
// Add homography rectangles when homographies are computed
|
||||||
QMultiMap<int, QMultiMap<int,int> >::const_iterator inliersIter = findObject_->inliers().constBegin();
|
QMultiMap<int, QMultiMap<int,int> >::const_iterator inliersIter = info.objDetectedInliers_.constBegin();
|
||||||
QMultiMap<int, QMultiMap<int,int> >::const_iterator outliersIter = findObject_->outliers().constBegin();
|
QMultiMap<int, QMultiMap<int,int> >::const_iterator outliersIter = info.objDetectedOutliers_.constBegin();
|
||||||
for(QMultiMap<int,QPair<QRect,QTransform> >::iterator iter = objectsDetected.begin();
|
for(QMultiMap<int,QTransform>::iterator iter = info.objDetected_.begin();
|
||||||
iter!=objectsDetected.end() && inliersIter!=findObject_->inliers().constEnd();
|
iter!=info.objDetected_.end();
|
||||||
++iter, ++inliersIter)
|
++iter, ++inliersIter, ++outliersIter)
|
||||||
{
|
{
|
||||||
int id = iter.key();
|
int id = iter.key();
|
||||||
ObjWidget * obj = objWidgets_.value(id);
|
ObjWidget * obj = objWidgets_.value(id);
|
||||||
Q_ASSERT(obj != 0);
|
Q_ASSERT(obj != 0);
|
||||||
|
|
||||||
// COLORIZE (should be done in the GUI thread)
|
// COLORIZE (should be done in the GUI thread)
|
||||||
QTransform hTransform = iter.value().second;
|
QTransform hTransform = iter.value();
|
||||||
|
|
||||||
QRect rect = obj->pixmap().rect();
|
QRect rect = obj->pixmap().rect();
|
||||||
// add rectangle
|
// add rectangle
|
||||||
@ -1013,10 +1014,10 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QLabel * label = ui_->dockWidget_objects->findChild<QLabel*>(QString("%1detection").arg(id));
|
QLabel * label = ui_->dockWidget_objects->findChild<QLabel*>(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
|
// 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
|
else
|
||||||
{
|
{
|
||||||
@ -1030,7 +1031,7 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
QMap<int, int> inlierScores;
|
QMap<int, int> inlierScores;
|
||||||
for(QMap<int, int>::iterator iter=scores.begin(); iter!=scores.end(); ++iter)
|
for(QMap<int, int>::iterator iter=scores.begin(); iter!=scores.end(); ++iter)
|
||||||
{
|
{
|
||||||
QList<QMultiMap<int, int> > values = findObject_->inliers().values(iter.key());
|
QList<QMultiMap<int, int> > values = info.objDetectedInliers_.values(iter.key());
|
||||||
int maxValue = 0;
|
int maxValue = 0;
|
||||||
if(values.size())
|
if(values.size())
|
||||||
{
|
{
|
||||||
@ -1051,8 +1052,8 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
ui_->likelihoodPlot->update();
|
ui_->likelihoodPlot->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_->label_minMatchedDistance->setNum(findObject_->minMatchedDistance());
|
ui_->label_minMatchedDistance->setNum(info.minMatchedDistance_);
|
||||||
ui_->label_maxMatchedDistance->setNum(findObject_->maxMatchedDistance());
|
ui_->label_maxMatchedDistance->setNum(info.maxMatchedDistance_);
|
||||||
|
|
||||||
//Scroll objects slider to the best score
|
//Scroll objects slider to the best score
|
||||||
if(maxScoreId>=0 && Settings::getGeneral_autoScroll())
|
if(maxScoreId>=0 && Settings::getGeneral_autoScroll())
|
||||||
@ -1065,17 +1066,17 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit homographies
|
// Emit homographies
|
||||||
if(objectsDetected.size() > 1)
|
if(info.objDetected_.size() > 1)
|
||||||
{
|
{
|
||||||
UINFO("(%s) %d objects detected!",
|
UINFO("(%s) %d objects detected!",
|
||||||
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
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!",
|
UINFO("(%s) Object %d detected!",
|
||||||
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
||||||
(int)objectsDetected.begin().key());
|
(int)info.objDetected_.begin().key());
|
||||||
}
|
}
|
||||||
else if(Settings::getGeneral_sendNoObjDetectedEvents())
|
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());
|
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
|
else
|
||||||
{
|
{
|
||||||
this->statusBar()->showMessage(tr("Cannot search, objects must be updated!"));
|
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();
|
iter.value()->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_->label_nfeatures->setNum((int)findObject_->sceneKeypoints().size());
|
ui_->label_nfeatures->setNum((int)info.sceneKeypoints_.size());
|
||||||
ui_->imageView_source->update();
|
ui_->imageView_source->update();
|
||||||
|
|
||||||
ui_->label_detectorDescriptorType->setText(QString("%1/%2").arg(Settings::currentDetectorType()).arg(Settings::currentDescriptorType()));
|
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_->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()));
|
int refreshRate = qRound(1000.0f/float(updateRate_.restart()));
|
||||||
if(refreshRate > 0 && refreshRate < lowestRefreshRate_)
|
if(refreshRate > 0 && refreshRate < lowestRefreshRate_)
|
||||||
{
|
{
|
||||||
@ -1200,7 +1201,7 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
|
|||||||
ui_->label_timeRefreshRate->setVisible(false);
|
ui_->label_timeRefreshRate->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_->actionCamera_from_video_file->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()));
|
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());
|
ui_->actionCamera_from_TCP_IP->setChecked(Settings::getCamera_6useTcpCamera());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,9 +15,10 @@
|
|||||||
|
|
||||||
class ObjSignature {
|
class ObjSignature {
|
||||||
public:
|
public:
|
||||||
ObjSignature(int id, const cv::Mat & image) :
|
ObjSignature(int id, const cv::Mat & image, const QString & filename) :
|
||||||
id_(id),
|
id_(id),
|
||||||
image_(image)
|
image_(image),
|
||||||
|
filename_(filename)
|
||||||
{}
|
{}
|
||||||
virtual ~ObjSignature() {}
|
virtual ~ObjSignature() {}
|
||||||
|
|
||||||
@ -37,6 +38,7 @@ public:
|
|||||||
QRect rect() const {return QRect(0,0,image_.cols, image_.rows);}
|
QRect rect() const {return QRect(0,0,image_.cols, image_.rows);}
|
||||||
|
|
||||||
int id() const {return id_;}
|
int id() const {return id_;}
|
||||||
|
const QString & filename() const {return filename_;}
|
||||||
const cv::Mat & image() const {return image_;}
|
const cv::Mat & image() const {return image_;}
|
||||||
const std::vector<cv::KeyPoint> & keypoints() const {return keypoints_;}
|
const std::vector<cv::KeyPoint> & keypoints() const {return keypoints_;}
|
||||||
const cv::Mat & descriptors() const {return descriptors_;}
|
const cv::Mat & descriptors() const {return descriptors_;}
|
||||||
@ -47,6 +49,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
int id_;
|
int id_;
|
||||||
cv::Mat image_;
|
cv::Mat image_;
|
||||||
|
QString filename_;
|
||||||
std::vector<cv::KeyPoint> keypoints_;
|
std::vector<cv::KeyPoint> keypoints_;
|
||||||
cv::Mat descriptors_;
|
cv::Mat descriptors_;
|
||||||
QMultiMap<int, int> words_; // <word id, keypoint indexes>
|
QMultiMap<int, int> words_; // <word id, keypoint indexes>
|
||||||
|
|||||||
@ -53,38 +53,23 @@ quint16 TcpServer::getPort() const
|
|||||||
return this->serverPort();
|
return this->serverPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpServer::publishObjects(const QMultiMap<int, QPair<QRect, QTransform> > & objects)
|
void TcpServer::publishDetectionInfo(const DetectionInfo & info)
|
||||||
{
|
{
|
||||||
QList<QTcpSocket*> clients = this->findChildren<QTcpSocket*>();
|
QList<QTcpSocket*> clients = this->findChildren<QTcpSocket*>();
|
||||||
if(clients.size())
|
if(clients.size())
|
||||||
{
|
{
|
||||||
QVector<float> data(objects.size()*12);
|
QByteArray block;
|
||||||
int i=0;
|
QDataStream out(&block, QIODevice::WriteOnly);
|
||||||
for(QMultiMap<int, QPair<QRect, QTransform> >::const_iterator iter=objects.constBegin(); iter!=objects.constEnd(); ++iter)
|
out.setVersion(QDataStream::Qt_4_0);
|
||||||
{
|
out << (quint16)0;
|
||||||
data[i++] = iter.key();
|
|
||||||
data[i++] = iter.value().first.width();
|
out << info;
|
||||||
data[i++] = iter.value().first.height();
|
|
||||||
data[i++] = iter.value().second.m11();
|
out.device()->seek(0);
|
||||||
data[i++] = iter.value().second.m12();
|
out << (quint16)(block.size() - sizeof(quint16));
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(QList<QTcpSocket*>::iterator iter = clients.begin(); iter!=clients.end(); ++iter)
|
for(QList<QTcpSocket*>::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);
|
(*iter)->write(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,13 +53,13 @@ bool ULogger::printWhereFullPath_ = false;
|
|||||||
bool ULogger::limitWhereLength_ = false;
|
bool ULogger::limitWhereLength_ = false;
|
||||||
bool ULogger::buffered_ = false;
|
bool ULogger::buffered_ = false;
|
||||||
bool ULogger::exitingState_ = 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::exitLevel_ = kFatal;
|
||||||
ULogger::Level ULogger::eventLevel_ = kFatal;
|
ULogger::Level ULogger::eventLevel_ = kFatal;
|
||||||
const char * ULogger::levelName_[5] = {"DEBUG", " INFO", " WARN", "ERROR", "FATAL"};
|
const char * ULogger::levelName_[5] = {"DEBUG", " INFO", " WARN", "ERROR", "FATAL"};
|
||||||
ULogger* ULogger::instance_ = 0;
|
ULogger* ULogger::instance_ = 0;
|
||||||
UDestroyer<ULogger> ULogger::destroyer_;
|
UDestroyer<ULogger> ULogger::destroyer_;
|
||||||
ULogger::Type ULogger::type_ = ULogger::kTypeNoLog; // Default nothing
|
ULogger::Type ULogger::type_ = ULogger::kTypeConsole;
|
||||||
UMutex ULogger::loggerMutex_;
|
UMutex ULogger::loggerMutex_;
|
||||||
const std::string ULogger::kDefaultLogFileName = "./ULog.txt";
|
const std::string ULogger::kDefaultLogFileName = "./ULog.txt";
|
||||||
std::string ULogger::logFileName_;
|
std::string ULogger::logFileName_;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
ADD_SUBDIRECTORY( tcpObjectsClient )
|
ADD_SUBDIRECTORY( tcpClient )
|
||||||
ADD_SUBDIRECTORY( tcpImagesServer )
|
ADD_SUBDIRECTORY( tcpImagesServer )
|
||||||
ADD_SUBDIRECTORY( tcpRequest )
|
ADD_SUBDIRECTORY( tcpRequest )
|
||||||
ADD_SUBDIRECTORY( similarity )
|
ADD_SUBDIRECTORY( similarity )
|
||||||
@ -25,18 +25,6 @@ SET(LIBRARIES
|
|||||||
${QT_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.
|
# Make sure the compiler can find include files from our library.
|
||||||
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
||||||
|
|
||||||
|
|||||||
@ -44,24 +44,7 @@ void TcpResponse::readReceivedData()
|
|||||||
|
|
||||||
blockSize_ = 0;
|
blockSize_ = 0;
|
||||||
|
|
||||||
QVector<float> data;
|
in >> info_;
|
||||||
in >> data;
|
|
||||||
|
|
||||||
objectsDetected_.clear();
|
|
||||||
for(int i=0; i<data.size(); i+=12)
|
|
||||||
{
|
|
||||||
// get data
|
|
||||||
int id = (int)data[i];
|
|
||||||
float width = data[i+1];
|
|
||||||
float height = data[i+2];
|
|
||||||
|
|
||||||
// Find corners Qt
|
|
||||||
QTransform homography(data[i+3], data[i+4], data[i+5],
|
|
||||||
data[i+6], data[i+7], data[i+8],
|
|
||||||
data[i+9], data[i+10], data[i+11]);
|
|
||||||
|
|
||||||
objectsDetected_.insert(id, QPair<QRect, QTransform>(QRect(0,0,width, height), homography));
|
|
||||||
}
|
|
||||||
|
|
||||||
dataReceived_ = true;
|
dataReceived_ = true;
|
||||||
Q_EMIT detectionReceived();
|
Q_EMIT detectionReceived();
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
#ifndef TCPRESPONSE_H_
|
#ifndef TCPRESPONSE_H_
|
||||||
#define TCPRESPONSE_H_
|
#define TCPRESPONSE_H_
|
||||||
|
|
||||||
|
#include "find_object/DetectionInfo.h"
|
||||||
|
|
||||||
#include <QtNetwork/QTcpSocket>
|
#include <QtNetwork/QTcpSocket>
|
||||||
#include <QtCore/QMultiMap>
|
#include <QtCore/QMultiMap>
|
||||||
#include <QtGui/QTransform>
|
#include <QtGui/QTransform>
|
||||||
@ -18,7 +20,7 @@ class TcpResponse : public QTcpSocket
|
|||||||
Q_OBJECT;
|
Q_OBJECT;
|
||||||
public:
|
public:
|
||||||
TcpResponse(QObject * parent = 0);
|
TcpResponse(QObject * parent = 0);
|
||||||
const QMultiMap<int, QPair<QRect, QTransform> > & objectsDetected() const {return objectsDetected_;}
|
const DetectionInfo & info() const {return info_;}
|
||||||
bool dataReceived() const {return dataReceived_;}
|
bool dataReceived() const {return dataReceived_;}
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
@ -31,7 +33,7 @@ Q_SIGNALS:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
quint16 blockSize_;
|
quint16 blockSize_;
|
||||||
QMultiMap<int, QPair<QRect, QTransform> > objectsDetected_;
|
DetectionInfo info_;
|
||||||
bool dataReceived_;
|
bool dataReceived_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -11,10 +11,7 @@
|
|||||||
#include <QtCore/QTime>
|
#include <QtCore/QTime>
|
||||||
#include <opencv2/opencv.hpp>
|
#include <opencv2/opencv.hpp>
|
||||||
#include "TcpResponse.h"
|
#include "TcpResponse.h"
|
||||||
|
#include "find_object/JsonWriter.h"
|
||||||
#ifdef WITH_JSONCPP
|
|
||||||
#include <jsoncpp/json/writer.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void showUsage()
|
void showUsage()
|
||||||
{
|
{
|
||||||
@ -22,67 +19,12 @@ void showUsage()
|
|||||||
" \"out\" is the port to which the image is sent.\n"
|
" \"out\" is the port to which the image is sent.\n"
|
||||||
" \"in\" is the port from which the detection is received.\n"
|
" \"in\" is the port from which the detection is received.\n"
|
||||||
" Options:\n"
|
" Options:\n"
|
||||||
" --host #.#.#.# Set host address.\n"
|
" --host #.#.#.# Set host address.\n");
|
||||||
#ifdef WITH_JSONCPP
|
if(JsonWriter::available())
|
||||||
" --json \"path\" Path to an output JSON file.\n"
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeJSON(const QMultiMap<int, QPair<QRect, QTransform> > & objectsDetected, const QString & path)
|
|
||||||
{
|
|
||||||
#ifdef WITH_JSONCPP
|
|
||||||
if(!path.isEmpty())
|
|
||||||
{
|
{
|
||||||
Json::Value root;
|
printf(" --json \"path\" Path to an output JSON file.\n");
|
||||||
Json::Value detections;
|
|
||||||
|
|
||||||
if(objectsDetected.size())
|
|
||||||
{
|
|
||||||
for(QMultiMap<int,QPair<QRect,QTransform> >::const_iterator iter = objectsDetected.constBegin();
|
|
||||||
iter!= objectsDetected.end();)
|
|
||||||
{
|
|
||||||
char index = 'a';
|
|
||||||
QMultiMap<int,QPair<QRect,QTransform> >::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());
|
|
||||||
}
|
}
|
||||||
#else
|
exit(-1);
|
||||||
printf("Not built with JSON support!\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char * argv[])
|
int main(int argc, char * argv[])
|
||||||
@ -123,20 +65,6 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
continue;
|
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)
|
if(strcmp(argv[i], "--out") == 0 || strcmp(argv[i], "-out") == 0)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
@ -166,6 +94,24 @@ int main(int argc, char * argv[])
|
|||||||
continue;
|
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]);
|
printf("Unrecognized option: %s\n", argv[i]);
|
||||||
showUsage();
|
showUsage();
|
||||||
}
|
}
|
||||||
@ -242,12 +188,12 @@ int main(int argc, char * argv[])
|
|||||||
{
|
{
|
||||||
printf("Response received! (%d ms)\n", time.elapsed());
|
printf("Response received! (%d ms)\n", time.elapsed());
|
||||||
// print detected objects
|
// print detected objects
|
||||||
if(response.objectsDetected().size())
|
if(response.info().objDetected_.size())
|
||||||
{
|
{
|
||||||
QList<int> ids = response.objectsDetected().uniqueKeys();
|
QList<int> ids = response.info().objDetected_.uniqueKeys();
|
||||||
for(int i=0; i<ids.size(); ++i)
|
for(int i=0; i<ids.size(); ++i)
|
||||||
{
|
{
|
||||||
int count = response.objectsDetected().count(ids[i]);
|
int count = response.info().objDetected_.count(ids[i]);
|
||||||
if(count == 1)
|
if(count == 1)
|
||||||
{
|
{
|
||||||
printf("Object %d detected.\n", ids[i]);
|
printf("Object %d detected.\n", ids[i]);
|
||||||
@ -263,9 +209,10 @@ int main(int argc, char * argv[])
|
|||||||
printf("No objects detected.\n");
|
printf("No objects detected.\n");
|
||||||
}
|
}
|
||||||
// write json
|
// write json
|
||||||
if(!jsonPath.isEmpty())
|
if(!jsonPath.isEmpty() && JsonWriter::available())
|
||||||
{
|
{
|
||||||
writeJSON(response.objectsDetected(), jsonPath);
|
JsonWriter::write(response.info(), jsonPath);
|
||||||
|
printf("JSON written to \"%s\"\n", jsonPath.toStdString().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user