#include #include #include #include #include #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" #include "find_object/JsonWriter.h" #include "find_object/utilite/ULogger.h" bool running = true; #ifdef WIN32 #include BOOL WINAPI my_handler(DWORD signal) { if (signal == CTRL_C_EVENT) { printf("\nCtrl-C caught! Quitting application...\n"); QCoreApplication::quit(); } return TRUE; running = false; } #else #include void my_handler(int s) { printf("\nCtrl-C caught! Quitting application...\n"); 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); } #endif void setupQuitSignal() { // Catch ctrl-c to close Qt #ifdef WIN32 if (!SetConsoleCtrlHandler(my_handler, TRUE)) { UERROR("Could not set control (ctrl-c) handler"); } #else struct sigaction sigIntHandler; sigIntHandler.sa_handler = my_handler; sigemptyset(&sigIntHandler.sa_mask); sigIntHandler.sa_flags = 0; sigaction(SIGINT, &sigIntHandler, NULL); #endif } void showUsage() { printf("\nUsage:\n" #ifdef WIN32 " Find-Object.exe [options]\n" #else " find_object [options]\n" #endif "Options:\n" " --console Don't use the GUI (by default the camera will be\n" " started automatically). Option --objects must also be\n" " used with valid objects.\n" " --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" " --params Show all parameters.\n" " --My/Parameter \"value\" Set find-Object's parameter (look --params for parameters' name).\n" " It will override the one in --config. Example to set 4 threads:\n" " $ find_object --General/threads 4\n" " --help Show usage.\n", Settings::iniDefaultPath().toStdString().c_str()); if(JsonWriter::available()) { printf(" --json \"path\" Path to an output JSON file (only in --console mode with --scene).\n"); } exit(-1); } int main(int argc, char* argv[]) { ULogger::setType(ULogger::kTypeConsole); ULogger::setLevel(ULogger::kInfo); ULogger::setPrintWhere(false); ULogger::setPrintTime(false); ////////////////////////// // parse options BEGIN ////////////////////////// bool guiMode = true; QString objectsPath = ""; QString scenePath = ""; QString configPath = Settings::iniDefaultPath(); QString jsonPath; ParametersMap customParameters; for(int i=1; i 2) { //strip the "--" name.remove(0, 2); if(parameters.contains(name)) { ++i; if(i < argc) { customParameters.insert(name, argv[i]); } else { showUsage(); } continue; } } UERROR("Unrecognized option : %s", argv[i]); showUsage(); } UINFO("Options:"); UINFO(" GUI mode = %s", guiMode?"true":"false"); UINFO(" Objects path: \"%s\"", objectsPath.toStdString().c_str()); UINFO(" Scene path: \"%s\"", scenePath.toStdString().c_str()); UINFO(" Settings path: \"%s\"", configPath.toStdString().c_str()); if(JsonWriter::available()) { UINFO(" JSON path: \"%s\"", jsonPath.toStdString().c_str()); } for(ParametersMap::iterator iter= customParameters.begin(); iter!=customParameters.end(); ++iter) { UINFO(" Param \"%s\"=\"%s\"", iter.key().toStdString().c_str(), iter.value().toString().toStdString().c_str()); } ////////////////////////// // parse options END ////////////////////////// // Load settings, should be loaded before creating other objects Settings::init(configPath); // Override custom parameters: for(ParametersMap::iterator iter= customParameters.begin(); iter!=customParameters.end(); ++iter) { Settings::setParameter(iter.key(), iter.value()); } // Create FindObject FindObject * findObject = new FindObject(); // Load objects if path is set int objectsLoaded = 0; if(!objectsPath.isEmpty()) { objectsLoaded = findObject->loadObjects(objectsPath); if(!objectsLoaded) { UWARN("No objects loaded from \"%s\"", objectsPath.toStdString().c_str()); } } cv::Mat scene; if(!scenePath.isEmpty()) { scene = cv::imread(scenePath.toStdString()); if(scene.empty()) { UERROR("Failed to load scene \"%s\"", scenePath.toStdString().c_str()); } } if(guiMode) { QApplication app(argc, argv); MainWindow mainWindow(findObject, 0); // ownership transfered app.connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) ); mainWindow.show(); if(!scene.empty()) { mainWindow.update(scene); } app.exec(); // Save settings Settings::saveSettings(); } else { if(objectsLoaded == 0) { UERROR("In console mode, at least one object must be loaded! See -console option."); delete findObject; showUsage(); } QCoreApplication app(argc, argv); if(!scene.empty()) { // process the scene and exit QTime time; time.start(); DetectionInfo info; findObject->detect(scene, info); if(info.objDetected_.size() > 1) { UINFO("%d objects detected! (%d ms)", (int)info.objDetected_.size(), time.elapsed()); } else if(info.objDetected_.size() == 1) { UINFO("Object %d detected! (%d ms)", (int)info.objDetected_.begin().key(), time.elapsed()); } else if(Settings::getGeneral_sendNoObjDetectedEvents()) { UINFO("No objects detected. (%d ms)", time.elapsed()); } if(!jsonPath.isEmpty() && JsonWriter::available()) { JsonWriter::write(info, jsonPath); UINFO("JSON written to \"%s\"", jsonPath.toStdString().c_str()); } } else { Camera camera; TcpServer tcpServer(Settings::getGeneral_port()); UINFO("Detection sent on port: %d (IP=%s)", tcpServer.getPort(), tcpServer.getHostAddress().toString().toStdString().c_str()); // connect stuff: // [FindObject] ---ObjectsDetected---> [TcpServer] QObject::connect(findObject, SIGNAL(objectsFound(DetectionInfo)), &tcpServer, SLOT(publishDetectionInfo(DetectionInfo))); // [Camera] ---Image---> [FindObject] QObject::connect(&camera, SIGNAL(imageReceived(const cv::Mat &)), findObject, SLOT(detect(const cv::Mat &))); QObject::connect(&camera, SIGNAL(finished()), &app, SLOT(quit())); //use camera in settings setupQuitSignal(); // start processing! while(running && !camera.start()) { UERROR("Camera initialization failed!"); running = false; } if(running) { app.exec(); } // cleanup camera.stop(); tcpServer.close(); } delete findObject; } }