2011-10-25 15:48:19 +00:00
|
|
|
#include <QtGui/QApplication>
|
2014-05-21 15:24:24 +00:00
|
|
|
#include <QtCore/QDir>
|
|
|
|
|
#include <QtCore/QFile>
|
2014-07-31 20:11:46 +00:00
|
|
|
#include "find_object/MainWindow.h"
|
|
|
|
|
#include "find_object/Settings.h"
|
|
|
|
|
#include "find_object/FindObject.h"
|
|
|
|
|
#include "find_object/Camera.h"
|
|
|
|
|
#include "find_object/TcpServer.h"
|
2014-08-04 01:33:52 +00:00
|
|
|
#include "find_object/JsonWriter.h"
|
2014-07-31 20:11:46 +00:00
|
|
|
#include "find_object/utilite/ULogger.h"
|
2014-07-31 19:02:31 +00:00
|
|
|
|
|
|
|
|
bool running = true;
|
2014-05-21 15:24:24 +00:00
|
|
|
|
2014-05-22 15:35:34 +00:00
|
|
|
#ifdef WIN32
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
BOOL WINAPI my_handler(DWORD signal)
|
|
|
|
|
{
|
|
|
|
|
if (signal == CTRL_C_EVENT)
|
|
|
|
|
{
|
|
|
|
|
printf("\nCtrl-C caught! Quitting application...\n");
|
2014-07-31 19:02:31 +00:00
|
|
|
QCoreApplication::quit();
|
2014-05-22 15:35:34 +00:00
|
|
|
}
|
|
|
|
|
return TRUE;
|
2014-07-31 19:02:31 +00:00
|
|
|
running = false;
|
2014-05-22 15:35:34 +00:00
|
|
|
}
|
|
|
|
|
#else
|
2014-05-21 15:24:24 +00:00
|
|
|
#include <signal.h>
|
2014-05-22 15:35:34 +00:00
|
|
|
void my_handler(int s)
|
|
|
|
|
{
|
2014-05-22 15:18:29 +00:00
|
|
|
printf("\nCtrl-C caught! Quitting application...\n");
|
2014-07-31 19:02:31 +00:00
|
|
|
QCoreApplication::quit();
|
|
|
|
|
running = false;
|
|
|
|
|
}
|
|
|
|
|
inline void Sleep(unsigned int ms)
|
|
|
|
|
{
|
|
|
|
|
struct timespec req;
|
|
|
|
|
struct timespec rem;
|
|
|
|
|
req.tv_sec = ms / 1000;
|
|
|
|
|
req.tv_nsec = (ms - req.tv_sec * 1000) * 1000 * 1000;
|
|
|
|
|
nanosleep (&req, &rem);
|
2014-05-21 15:24:24 +00:00
|
|
|
}
|
2014-05-22 15:35:34 +00:00
|
|
|
#endif
|
2014-05-21 15:24:24 +00:00
|
|
|
|
2014-07-31 19:02:31 +00:00
|
|
|
void setupQuitSignal()
|
|
|
|
|
{
|
|
|
|
|
// Catch ctrl-c to close Qt
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
if (!SetConsoleCtrlHandler(my_handler, TRUE))
|
|
|
|
|
{
|
2014-07-31 20:59:25 +00:00
|
|
|
UERROR("Could not set control (ctrl-c) handler");
|
2014-07-31 19:02:31 +00:00
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
struct sigaction sigIntHandler;
|
|
|
|
|
sigIntHandler.sa_handler = my_handler;
|
|
|
|
|
sigemptyset(&sigIntHandler.sa_mask);
|
|
|
|
|
sigIntHandler.sa_flags = 0;
|
|
|
|
|
sigaction(SIGINT, &sigIntHandler, NULL);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-21 15:24:24 +00:00
|
|
|
void showUsage()
|
|
|
|
|
{
|
|
|
|
|
printf("\nUsage:\n"
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
" Find-Object.exe [options]\n"
|
|
|
|
|
#else
|
|
|
|
|
" find_object [options]\n"
|
|
|
|
|
#endif
|
|
|
|
|
"Options:\n"
|
2014-08-01 21:11:26 +00:00
|
|
|
" --console Don't use the GUI (by default the camera will be\n"
|
|
|
|
|
" started automatically). Option --objects must also be\n"
|
2014-05-21 15:24:24 +00:00
|
|
|
" used with valid objects.\n"
|
2014-08-01 21:11:26 +00:00
|
|
|
" --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"
|
|
|
|
|
" --help Show usage.\n", Settings::iniDefaultPath().toStdString().c_str());
|
2014-08-04 01:33:52 +00:00
|
|
|
if(JsonWriter::available())
|
2014-08-01 21:11:26 +00:00
|
|
|
{
|
2014-08-04 01:33:52 +00:00
|
|
|
printf(" --json \"path\" Path to an output JSON file (only in --console mode with --scene).\n");
|
2014-08-01 21:11:26 +00:00
|
|
|
}
|
2014-08-04 01:33:52 +00:00
|
|
|
exit(-1);
|
2014-08-01 21:11:26 +00:00
|
|
|
}
|
|
|
|
|
|
2011-10-25 15:48:19 +00:00
|
|
|
int main(int argc, char* argv[])
|
|
|
|
|
{
|
2014-07-31 19:02:31 +00:00
|
|
|
ULogger::setType(ULogger::kTypeConsole);
|
|
|
|
|
ULogger::setLevel(ULogger::kInfo);
|
|
|
|
|
ULogger::setPrintWhere(false);
|
|
|
|
|
ULogger::setPrintTime(false);
|
2011-10-25 15:48:19 +00:00
|
|
|
|
2014-07-31 19:02:31 +00:00
|
|
|
//////////////////////////
|
|
|
|
|
// parse options BEGIN
|
|
|
|
|
//////////////////////////
|
2014-05-21 15:24:24 +00:00
|
|
|
bool guiMode = true;
|
|
|
|
|
QString objectsPath = "";
|
2014-08-01 21:11:26 +00:00
|
|
|
QString scenePath = "";
|
2014-05-21 15:24:24 +00:00
|
|
|
QString configPath = Settings::iniDefaultPath();
|
2014-08-01 21:11:26 +00:00
|
|
|
QString jsonPath;
|
2014-05-21 15:24:24 +00:00
|
|
|
|
|
|
|
|
for(int i=1; i<argc; ++i)
|
|
|
|
|
{
|
2014-08-01 21:11:26 +00:00
|
|
|
if(strcmp(argv[i], "-objs") == 0 ||
|
|
|
|
|
strcmp(argv[i], "--objs") == 0 ||
|
|
|
|
|
strcmp(argv[i], "-objects") == 0 ||
|
|
|
|
|
strcmp(argv[i], "--objects") == 0)
|
2014-05-21 15:24:24 +00:00
|
|
|
{
|
|
|
|
|
++i;
|
|
|
|
|
if(i < argc)
|
|
|
|
|
{
|
|
|
|
|
objectsPath = argv[i];
|
|
|
|
|
if(objectsPath.contains('~'))
|
|
|
|
|
{
|
|
|
|
|
objectsPath.replace('~', QDir::homePath());
|
|
|
|
|
}
|
|
|
|
|
if(!QDir(objectsPath).exists())
|
|
|
|
|
{
|
2014-08-01 21:11:26 +00:00
|
|
|
UERROR("Objects path not valid : %s", objectsPath.toStdString().c_str());
|
|
|
|
|
showUsage();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
showUsage();
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if(strcmp(argv[i], "-scene") == 0 ||
|
|
|
|
|
strcmp(argv[i], "--scene") == 0)
|
|
|
|
|
{
|
|
|
|
|
++i;
|
|
|
|
|
if(i < argc)
|
|
|
|
|
{
|
|
|
|
|
scenePath = argv[i];
|
|
|
|
|
if(scenePath.contains('~'))
|
|
|
|
|
{
|
|
|
|
|
scenePath.replace('~', QDir::homePath());
|
|
|
|
|
}
|
|
|
|
|
if(!QFile(scenePath).exists())
|
|
|
|
|
{
|
|
|
|
|
UERROR("Scene path not valid : %s", scenePath.toStdString().c_str());
|
2014-05-21 15:24:24 +00:00
|
|
|
showUsage();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
showUsage();
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2014-08-01 21:11:26 +00:00
|
|
|
if(strcmp(argv[i], "-config") == 0 ||
|
|
|
|
|
strcmp(argv[i], "--config") == 0)
|
2014-05-21 15:24:24 +00:00
|
|
|
{
|
|
|
|
|
++i;
|
|
|
|
|
if(i < argc)
|
|
|
|
|
{
|
|
|
|
|
configPath = argv[i];
|
|
|
|
|
if(configPath.contains('~'))
|
|
|
|
|
{
|
|
|
|
|
configPath.replace('~', QDir::homePath());
|
|
|
|
|
}
|
|
|
|
|
if(!QFile::exists(configPath))
|
|
|
|
|
{
|
2014-08-02 06:09:27 +00:00
|
|
|
UWARN("Configuration file \"%s\" doesn't exist, it will be created with default values...", configPath.toStdString().c_str());
|
2014-05-21 15:24:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
showUsage();
|
|
|
|
|
}
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2014-08-01 21:11:26 +00:00
|
|
|
if(strcmp(argv[i], "-console") == 0 ||
|
|
|
|
|
strcmp(argv[i], "--console") == 0)
|
2014-05-21 15:24:24 +00:00
|
|
|
{
|
|
|
|
|
guiMode = false;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2014-08-01 21:11:26 +00:00
|
|
|
if(strcmp(argv[i], "-help") == 0 ||
|
|
|
|
|
strcmp(argv[i], "--help") == 0)
|
2014-05-21 15:24:24 +00:00
|
|
|
{
|
|
|
|
|
showUsage();
|
|
|
|
|
}
|
2014-08-04 01:33:52 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-05-21 15:24:24 +00:00
|
|
|
|
2014-07-31 19:02:31 +00:00
|
|
|
UERROR("Unrecognized option : %s", argv[i]);
|
2014-05-21 15:24:24 +00:00
|
|
|
showUsage();
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-31 19:02:31 +00:00
|
|
|
UINFO("Options:");
|
|
|
|
|
UINFO(" GUI mode = %s", guiMode?"true":"false");
|
|
|
|
|
UINFO(" Objects path: \"%s\"", objectsPath.toStdString().c_str());
|
2014-08-01 21:11:26 +00:00
|
|
|
UINFO(" Scene path: \"%s\"", scenePath.toStdString().c_str());
|
2014-07-31 19:02:31 +00:00
|
|
|
UINFO(" Settings path: \"%s\"", configPath.toStdString().c_str());
|
2014-08-04 01:33:52 +00:00
|
|
|
if(JsonWriter::available())
|
|
|
|
|
{
|
|
|
|
|
UINFO(" JSON path: \"%s\"", jsonPath.toStdString().c_str());
|
|
|
|
|
}
|
2014-07-31 19:02:31 +00:00
|
|
|
|
|
|
|
|
//////////////////////////
|
|
|
|
|
// parse options END
|
|
|
|
|
//////////////////////////
|
2014-05-21 15:24:24 +00:00
|
|
|
|
2014-07-31 19:02:31 +00:00
|
|
|
// Load settings, should be loaded before creating other objects
|
|
|
|
|
Settings::init(configPath);
|
2014-05-21 15:24:24 +00:00
|
|
|
|
2014-07-31 19:02:31 +00:00
|
|
|
// Create FindObject
|
|
|
|
|
FindObject * findObject = new FindObject();
|
2014-05-21 15:24:24 +00:00
|
|
|
|
2014-07-31 19:02:31 +00:00
|
|
|
// Load objects if path is set
|
2014-05-21 15:24:24 +00:00
|
|
|
int objectsLoaded = 0;
|
|
|
|
|
if(!objectsPath.isEmpty())
|
|
|
|
|
{
|
2014-07-31 19:02:31 +00:00
|
|
|
objectsLoaded = findObject->loadObjects(objectsPath);
|
2014-05-21 15:24:24 +00:00
|
|
|
if(!objectsLoaded)
|
|
|
|
|
{
|
2014-07-31 19:02:31 +00:00
|
|
|
UWARN("No objects loaded from \"%s\"", objectsPath.toStdString().c_str());
|
2014-05-21 15:24:24 +00:00
|
|
|
}
|
|
|
|
|
}
|
2014-08-01 21:11:26 +00:00
|
|
|
cv::Mat scene;
|
|
|
|
|
if(!scenePath.isEmpty())
|
|
|
|
|
{
|
|
|
|
|
scene = cv::imread(scenePath.toStdString());
|
|
|
|
|
if(scene.empty())
|
|
|
|
|
{
|
|
|
|
|
UERROR("Failed to load scene \"%s\"", scenePath.toStdString().c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-05-21 15:24:24 +00:00
|
|
|
|
|
|
|
|
if(guiMode)
|
|
|
|
|
{
|
2014-07-31 19:02:31 +00:00
|
|
|
QApplication app(argc, argv);
|
|
|
|
|
MainWindow mainWindow(findObject, 0); // ownership transfered
|
|
|
|
|
|
2014-05-21 15:24:24 +00:00
|
|
|
app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) );
|
|
|
|
|
mainWindow.show();
|
2014-07-31 19:02:31 +00:00
|
|
|
|
2014-08-01 21:11:26 +00:00
|
|
|
if(!scene.empty())
|
|
|
|
|
{
|
|
|
|
|
mainWindow.update(scene);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-31 19:02:31 +00:00
|
|
|
app.exec();
|
2014-08-01 21:11:26 +00:00
|
|
|
|
|
|
|
|
// Save settings
|
|
|
|
|
Settings::saveSettings();
|
2014-05-21 15:24:24 +00:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2014-07-31 19:02:31 +00:00
|
|
|
if(objectsLoaded == 0)
|
|
|
|
|
{
|
|
|
|
|
UERROR("In console mode, at least one object must be loaded! See -console option.");
|
|
|
|
|
delete findObject;
|
|
|
|
|
showUsage();
|
|
|
|
|
}
|
2014-05-21 15:24:24 +00:00
|
|
|
|
2014-07-31 19:02:31 +00:00
|
|
|
QCoreApplication app(argc, argv);
|
2014-08-01 21:11:26 +00:00
|
|
|
|
|
|
|
|
if(!scene.empty())
|
|
|
|
|
{
|
|
|
|
|
// process the scene and exit
|
2014-08-04 01:33:52 +00:00
|
|
|
QTime time;
|
|
|
|
|
time.start();
|
|
|
|
|
DetectionInfo info;
|
|
|
|
|
findObject->detect(scene, info);
|
2014-07-31 19:02:31 +00:00
|
|
|
|
2014-08-04 01:33:52 +00:00
|
|
|
if(info.objDetected_.size() > 1)
|
2014-08-01 21:11:26 +00:00
|
|
|
{
|
2014-08-04 01:33:52 +00:00
|
|
|
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());
|
2014-08-01 21:11:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2014-07-31 19:02:31 +00:00
|
|
|
{
|
2014-08-01 21:11:26 +00:00
|
|
|
Camera camera;
|
2014-08-04 01:33:52 +00:00
|
|
|
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)));
|
2014-08-01 21:11:26 +00:00
|
|
|
|
|
|
|
|
// [Camera] ---Image---> [FindObject]
|
|
|
|
|
QObject::connect(&camera, SIGNAL(imageReceived(const cv::Mat &)), findObject, SLOT(detect(const cv::Mat &)));
|
2014-08-03 22:40:37 +00:00
|
|
|
QObject::connect(&camera, SIGNAL(finished()), &app, SLOT(quit()));
|
2014-08-01 21:11:26 +00:00
|
|
|
|
|
|
|
|
//use camera in settings
|
|
|
|
|
setupQuitSignal();
|
|
|
|
|
|
|
|
|
|
// start processing!
|
|
|
|
|
while(running && !camera.start())
|
2014-07-31 19:02:31 +00:00
|
|
|
{
|
2014-08-02 06:09:27 +00:00
|
|
|
UERROR("Camera initialization failed!");
|
|
|
|
|
running = false;
|
2014-07-31 19:02:31 +00:00
|
|
|
}
|
2014-08-01 21:11:26 +00:00
|
|
|
if(running)
|
2014-07-31 19:02:31 +00:00
|
|
|
{
|
2014-08-01 21:11:26 +00:00
|
|
|
app.exec();
|
2014-07-31 19:02:31 +00:00
|
|
|
}
|
2014-08-01 21:11:26 +00:00
|
|
|
|
|
|
|
|
// cleanup
|
|
|
|
|
camera.stop();
|
2014-08-04 01:33:52 +00:00
|
|
|
tcpServer.close();
|
2014-05-22 15:35:34 +00:00
|
|
|
}
|
2014-07-31 19:02:31 +00:00
|
|
|
|
|
|
|
|
delete findObject;
|
2014-05-22 15:18:29 +00:00
|
|
|
}
|
2011-10-25 15:48:19 +00:00
|
|
|
}
|