28 #include <QApplication> 29 #include <QtCore/QDir> 30 #include <QtCore/QFile> 48 if (signal == CTRL_C_EVENT)
50 printf(
"\nCtrl-C caught! Quitting application...\n");
51 QCoreApplication::quit();
60 printf(
"\nCtrl-C caught! Quitting application...\n");
61 QCoreApplication::quit();
64 inline void Sleep(
unsigned int ms)
68 req.tv_sec = ms / 1000;
69 req.tv_nsec = (ms - req.tv_sec * 1000) * 1000 * 1000;
70 nanosleep (&req, &rem);
80 UERROR(
"Could not set control (ctrl-c) handler");
83 struct sigaction sigIntHandler;
85 sigemptyset(&sigIntHandler.sa_mask);
86 sigIntHandler.sa_flags = 0;
87 sigaction(SIGINT, &sigIntHandler,
NULL);
95 " Find-Object.exe [options]\n" 97 " find_object [options]\n" 100 " --console Don't use the GUI (by default the camera will be\n" 101 " started automatically). Option --objects must also be\n" 102 " used with valid objects.\n" 103 " --session \"path\" Path to a session to load (*.bin). Use \"--session_new\" to\n" 104 " create a session instead (will be saved to \"path\" on exit, only\n" 105 " on console mode).\n" 106 " --object \"path\" Path to an object to detect.\n" 107 " --objects \"path\" Directory of the objects to detect (--object is ignored).\n" 108 " --config \"path\" Path to configuration file (default: %s).\n" 109 " If set to \"\", default parameters are used\n" 110 " without saving modified parameters on closing.\n" 111 " --scene \"path\" Path to a scene image file.\n" 112 " --vocabulary \"path\" Path to a vocabulary file (*.yaml *.xml). Parameters \"General/invertedSearch\"\n" 113 " and \"General/vocabularyFixed\" will be also enabled. Ignored if \"--session\" is set.\n" 114 " --images_not_saved Don't keep images in RAM after the features are extracted (only\n" 115 " in console mode). Images won't be saved if an output session is set.\n" 116 " --tcp_threads # Number of TCP threads (default 1, only in --console mode). \"--General/port\" parameter should not be 0.\n" 117 " Port numbers start from \"General/port\" value. \"Detect\" TCP service can be\n" 118 " executed at the same time by multiple threads. \"Add/Remove\" TCP services\n" 119 " cannot be called by multiple threads, so calling these services on a port\n " 120 " will block all other threads on the other ports.\n" 121 " --debug Show debug log.\n" 122 " --log-time Show log with time.\n" 123 " --params Show all parameters.\n" 124 " --defaults Use default parameters (--config is ignored).\n" 125 " --My/Parameter \"value\" Set find-Object's parameter (look --params for parameters' name).\n" 126 " It will override the one in --config. Example to set 4 threads:\n" 127 " $ find_object --General/threads 4\n" 128 " --json \"path\" Path to an output JSON file (only in --console mode with --scene).\n" 129 " --help Show usage.\n" 134 int main(
int argc,
char* argv[])
145 QString sessionPath =
"";
146 bool sessionNew =
false;
147 QString objectsPath =
"";
148 QString objectPath =
"";
149 QString scenePath =
"";
151 QString vocabularyPath =
"";
154 bool imagesSaved =
true;
157 for(
int i=1; i<argc; ++i)
160 if(QString(argv[i]).startsWith(
"-psn"))
166 if(strcmp(argv[i],
"-objs") == 0 ||
167 strcmp(argv[i],
"--objs") == 0 ||
168 strcmp(argv[i],
"-objects") == 0 ||
169 strcmp(argv[i],
"--objects") == 0)
174 objectsPath = argv[i];
175 if(objectsPath.contains(
'~'))
177 objectsPath.replace(
'~', QDir::homePath());
179 if(!QDir(objectsPath).
exists())
181 UERROR(
"Objects path not valid : %s", objectsPath.toStdString().c_str());
191 if(strcmp(argv[i],
"-session") == 0 ||
192 strcmp(argv[i],
"--session") == 0 ||
193 strcmp(argv[i],
"-session_new") == 0 ||
194 strcmp(argv[i],
"--session_new") == 0)
196 if(strcmp(argv[i],
"-session_new") == 0 ||
197 strcmp(argv[i],
"--session_new") == 0)
204 sessionPath = argv[i];
205 if(sessionPath.contains(
'~'))
207 sessionPath.replace(
'~', QDir::homePath());
210 if(!sessionNew && !QFile(sessionPath).
exists())
212 UERROR(
"Session path not valid : %s (if you want to create a new session, use \"--session_new\")", sessionPath.toStdString().c_str());
222 if(strcmp(argv[i],
"-object") == 0 ||
223 strcmp(argv[i],
"--object") == 0)
228 objectPath = argv[i];
229 if(objectPath.contains(
'~'))
231 objectPath.replace(
'~', QDir::homePath());
233 if(!QFile(objectPath).
exists())
235 UERROR(
"Object path not valid : %s", objectPath.toStdString().c_str());
245 if(strcmp(argv[i],
"-scene") == 0 ||
246 strcmp(argv[i],
"--scene") == 0)
252 if(scenePath.contains(
'~'))
254 scenePath.replace(
'~', QDir::homePath());
256 if(!QFile(scenePath).
exists())
258 UERROR(
"Scene path not valid : %s", scenePath.toStdString().c_str());
268 if(strcmp(argv[i],
"-vocabulary") == 0 ||
269 strcmp(argv[i],
"--vocabulary") == 0)
274 vocabularyPath = argv[i];
275 if(vocabularyPath.contains(
'~'))
277 vocabularyPath.replace(
'~', QDir::homePath());
279 if(!QFile(vocabularyPath).
exists())
281 UERROR(
"Vocabulary path not valid : %s", vocabularyPath.toStdString().c_str());
291 if(strcmp(argv[i],
"-config") == 0 ||
292 strcmp(argv[i],
"--config") == 0)
297 configPath = argv[i];
298 if(configPath.contains(
'~'))
300 configPath.replace(
'~', QDir::homePath());
302 if(!configPath.isEmpty() && !QFile::exists(configPath))
304 UWARN(
"Configuration file \"%s\" doesn't exist, it will be created with default values...", configPath.toStdString().c_str());
313 if(strcmp(argv[i],
"-console") == 0 ||
314 strcmp(argv[i],
"--console") == 0)
319 if(strcmp(argv[i],
"-images_not_saved") == 0 ||
320 strcmp(argv[i],
"--images_not_saved") == 0)
325 if(strcmp(argv[i],
"-debug") == 0 ||
326 strcmp(argv[i],
"--debug") == 0)
328 customParameters.insert(find_object::Settings::kGeneral_debug(),
true);
331 if(strcmp(argv[i],
"-log-time") == 0 ||
332 strcmp(argv[i],
"--log-time") == 0)
338 if(strcmp(argv[i],
"-help") == 0 ||
339 strcmp(argv[i],
"--help") == 0)
343 if(strcmp(argv[i],
"-json") == 0 ||
344 strcmp(argv[i],
"--json") == 0)
350 if(jsonPath.contains(
'~'))
352 jsonPath.replace(
'~', QDir::homePath());
361 if(strcmp(argv[i],
"-tcp_threads") == 0 ||
362 strcmp(argv[i],
"--tcp_threads") == 0)
367 tcpThreads = atoi(argv[i]);
370 printf(
"tcp_threads should be >= 1!\n");
380 if(strcmp(argv[i],
"--params") == 0)
383 for(find_object::ParametersMap::iterator iter=parameters.begin(); iter!=parameters.end(); ++iter)
385 std::string str =
"Param: " + iter.key().toStdString() +
" = \"" + iter.value().toString().toStdString() +
"\"";
388 std::setw(60 - str.size()) <<
394 UINFO(
"Node will now exit after showing default Find-Object's parameters because " 395 "argument \"--params\" is detected!");
401 QString name = argv[i];
406 if(parameters.contains(name))
411 customParameters.insert(name, argv[i]);
421 UERROR(
"Unrecognized option : %s", argv[i]);
426 UINFO(
" GUI mode = %s", guiMode?
"true":
"false");
427 if(!sessionPath.isEmpty())
431 UINFO(
" Session path: \"%s\" [NEW]", sessionPath.toStdString().c_str());
435 UINFO(
" Session path: \"%s\"", sessionPath.toStdString().c_str());
438 else if(!objectsPath.isEmpty())
440 UINFO(
" Objects path: \"%s\"", objectsPath.toStdString().c_str());
442 else if(!objectPath.isEmpty())
444 UINFO(
" Object path: \"%s\"", objectPath.toStdString().c_str());
446 UINFO(
" Scene path: \"%s\"", scenePath.toStdString().c_str());
449 UINFO(
" JSON path: \"%s\"", jsonPath.toStdString().c_str());
451 UINFO(
" Settings path: \"%s\"", configPath.toStdString().c_str());
452 UINFO(
" Vocabulary path: \"%s\"", vocabularyPath.toStdString().c_str());
454 if(!vocabularyPath.isEmpty())
456 if(customParameters.contains(find_object::Settings::kGeneral_vocabularyFixed()))
458 UWARN(
"\"General/vocabularyFixed\" custom parameter overwritten as a fixed vocabulary is used.");
460 if(customParameters.contains(find_object::Settings::kGeneral_invertedSearch()))
462 UWARN(
"\"General/invertedSearch\" custom parameter overwritten as a fixed vocabulary is used.");
464 customParameters[find_object::Settings::kGeneral_vocabularyFixed()] =
true;
465 customParameters[find_object::Settings::kGeneral_invertedSearch()] =
true;
468 for(find_object::ParametersMap::iterator iter= customParameters.begin(); iter!=customParameters.end(); ++iter)
470 UINFO(
" Param \"%s\"=\"%s\"", iter.key().toStdString().c_str(), iter.value().toString().toStdString().c_str());
481 for(find_object::ParametersMap::iterator iter= customParameters.begin(); iter!=customParameters.end(); ++iter)
490 int objectsLoaded = 0;
491 if(!sessionPath.isEmpty() && !sessionNew)
493 if(!vocabularyPath.isEmpty() && !findObject->loadVocabulary(vocabularyPath))
495 UWARN(
"Vocabulary \"%s\" is not loaded as a session \"%s\" is already loaded",
496 vocabularyPath.toStdString().c_str(),
497 sessionPath.toStdString().c_str());
499 if(!findObject->loadSession(sessionPath))
501 UERROR(
"Could not load session \"%s\"", sessionPath.toStdString().c_str());
505 objectsLoaded = findObject->objects().size();
508 else if(!objectsPath.isEmpty())
510 if(!vocabularyPath.isEmpty() && !findObject->loadVocabulary(vocabularyPath))
512 UERROR(
"Failed to load vocabulary \"%s\"", vocabularyPath.toStdString().c_str());
514 objectsLoaded = findObject->loadObjects(objectsPath);
517 UWARN(
"No objects loaded from \"%s\"", objectsPath.toStdString().c_str());
520 else if(!objectPath.isEmpty())
522 if(!vocabularyPath.isEmpty() && !findObject->loadVocabulary(vocabularyPath))
524 UERROR(
"Failed to load vocabulary \"%s\"", vocabularyPath.toStdString().c_str());
531 findObject->updateObjects();
532 findObject->updateVocabulary();
536 UWARN(
"No object loaded from \"%s\"", objectsPath.toStdString().c_str());
539 else if(!vocabularyPath.isEmpty() && !findObject->loadVocabulary(vocabularyPath))
541 UERROR(
"Failed to load vocabulary \"%s\"", vocabularyPath.toStdString().c_str());
545 if(!scenePath.isEmpty())
547 scene = cv::imread(scenePath.toStdString());
550 UERROR(
"Failed to load scene \"%s\"", scenePath.toStdString().c_str());
556 QApplication
app(argc, argv);
559 app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) );
574 QCoreApplication
app(argc, argv);
582 findObject->detect(scene, info);
586 UINFO(
"%d objects detected! (%d ms)", (
int)info.
objDetected_.size(), time.elapsed());
590 UINFO(
"Object %d detected! (%d ms)", (
int)info.
objDetected_.begin().key(), time.elapsed());
592 else if(find_object::Settings::getGeneral_sendNoObjDetectedEvents())
594 UINFO(
"No objects detected. (%d ms)", time.elapsed());
597 if(!jsonPath.isEmpty())
600 UINFO(
"JSON written to \"%s\"", jsonPath.toStdString().c_str());
605 TcpServerPool tcpServerPool(findObject, tcpThreads, find_object::Settings::getGeneral_port());
611 if(find_object::Settings::getCamera_6useTcpCamera())
616 QObject::connect(camera, SIGNAL(imageReceived(
const cv::Mat &)), findObject, SLOT(detect(
const cv::Mat &)));
617 QObject::connect(camera, SIGNAL(finished()), &app, SLOT(quit()));
621 UERROR(
"Camera initialization failed!");
631 if(!sessionPath.isEmpty())
633 if(findObject->isSessionModified())
635 UINFO(
"The session has been modified, updating the session file...");
636 if(findObject->saveSession(sessionPath))
638 UINFO(
"Session \"%s\" successfully saved (%d objects)!",
639 sessionPath.toStdString().c_str(), findObject->objects().size());
644 UINFO(
"The session has not been modified, session file not created...");
static QString iniDefaultPath()
static void setLevel(ULogger::Level level)
static void setPrintTime(bool printTime)
static void setType(Type type, const std::string &fileName=kDefaultLogFileName, bool append=true)
QMultiMap< int, QTransform > objDetected_
static void setParameter(const QString &key, const QVariant &value)
static void init(const QString &fileName)
static const DescriptionsMap & getDescriptions()
QMap< QString, QVariant > ParametersMap
void update(const cv::Mat &image)
static void setPrintWhere(bool printWhere)
void Sleep(unsigned int ms)
ULogger class and convenient macros.
static void write(const DetectionInfo &info, const QString &path)
static const ParametersMap & getDefaultParameters()
ROSCPP_DECL bool exists(const std::string &service_name, bool print_failure_reason)
int main(int argc, char *argv[])
static void saveSettings(const QString &fileName=QString())