Added "--tcp_threads" argument for multi-threaded detections (on multiple ports)

This commit is contained in:
matlabbe
2015-11-30 00:27:57 -05:00
parent 164da72169
commit cff1d4eac7
12 changed files with 304 additions and 90 deletions
+11 -1
View File
@@ -1,4 +1,14 @@
SET(headers_ui
TcpServerPool.h
)
IF("${FINDOBJECT_QT_VERSION}" STREQUAL "4")
QT4_WRAP_CPP(moc_srcs ${headers_ui})
ELSE()
QT5_WRAP_CPP(moc_srcs ${headers_ui})
ENDIF()
SET(INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/../include
${CMAKE_CURRENT_SOURCE_DIR}
@@ -17,7 +27,7 @@ SET(LIBRARIES
#include files
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
SET(SRC_FILES main.cpp)
SET(SRC_FILES main.cpp ${moc_srcs} )
# For Apple set the icns file containing icons
IF(APPLE AND BUILD_AS_BUNDLE)
+130
View File
@@ -0,0 +1,130 @@
/*
* TcpServerPool.h
*
* Created on: Nov 29, 2015
* Author: mathieu
*/
#ifndef TCPSERVERPOOL_H_
#define TCPSERVERPOOL_H_
#include <find_object/FindObject.h>
#include <find_object/TcpServer.h>
#include <find_object/utilite/ULogger.h>
#include <QtCore/QThread>
#include <QtCore/QSemaphore>
class FindObjectWorker : public QObject
{
Q_OBJECT;
public:
FindObjectWorker(
find_object::FindObject * sharedFindObject,
QSemaphore * sharedSemaphore,
int maxSemaphoreResources,
QObject * parent = 0) :
QObject(parent),
sharedFindObject_(sharedFindObject),
sharedSemaphore_(sharedSemaphore),
maxSemaphoreResources_(maxSemaphoreResources)
{
UASSERT(sharedFindObject != 0);
UASSERT(sharedSemaphore != 0);
UASSERT(maxSemaphoreResources > 0);
}
public Q_SLOTS:
void detect(const cv::Mat & image)
{
sharedSemaphore_->acquire(1);
UINFO("Thread %p detecting...", (void *)this->thread());
find_object::DetectionInfo info;
sharedFindObject_->detect(image, info);
Q_EMIT objectsFound(info);
sharedSemaphore_->release(1);
}
void addObjectAndUpdate(const cv::Mat & image, int id, const QString & filePath)
{
//block everyone!
sharedSemaphore_->acquire(maxSemaphoreResources_);
UINFO("Thread %p adding object %d (%s)...", (void *)this->thread(), id, filePath.toStdString().c_str());
sharedFindObject_->addObjectAndUpdate(image, id, filePath);
sharedSemaphore_->release(maxSemaphoreResources_);
}
void removeObjectAndUpdate(int id)
{
//block everyone!
sharedSemaphore_->acquire(maxSemaphoreResources_);
UINFO("Thread %p removing object %d...", (void *)this->thread(), id);
sharedFindObject_->removeObjectAndUpdate(id);
sharedSemaphore_->release(maxSemaphoreResources_);
}
Q_SIGNALS:
void objectsFound(const find_object::DetectionInfo &);
private:
find_object::FindObject * sharedFindObject_; //shared findobject
QSemaphore * sharedSemaphore_;
int maxSemaphoreResources_;
};
class TcpServerPool : public QObject
{
Q_OBJECT;
public:
TcpServerPool(find_object::FindObject * sharedFindObject, int threads, int port) :
sharedFindObject_(sharedFindObject),
sharedSemaphore_(threads)
{
UASSERT(sharedFindObject != 0);
UASSERT(port!=0);
UASSERT(threads>=1);
qRegisterMetaType<cv::Mat>("cv::Mat");
threadPool_.resize(threads);
for(int i=0; i<threads; ++i)
{
find_object::TcpServer * tcpServer = new find_object::TcpServer(port++);
UINFO("TcpServer set on port: %d (IP=%s)",
tcpServer->getPort(),
tcpServer->getHostAddress().toString().toStdString().c_str());
threadPool_[i] = new QThread(this);
FindObjectWorker * worker = new FindObjectWorker(sharedFindObject, &sharedSemaphore_, threads);
tcpServer->moveToThread(threadPool_[i]);
worker->moveToThread(threadPool_[i]);
connect(threadPool_[i], SIGNAL(finished()), tcpServer, SLOT(deleteLater()));
connect(threadPool_[i], SIGNAL(finished()), worker, SLOT(deleteLater()));
// connect stuff:
QObject::connect(worker, SIGNAL(objectsFound(find_object::DetectionInfo)), tcpServer, SLOT(publishDetectionInfo(find_object::DetectionInfo)));
QObject::connect(tcpServer, SIGNAL(detectObject(const cv::Mat &)), worker, SLOT(detect(const cv::Mat &)));
QObject::connect(tcpServer, SIGNAL(addObject(const cv::Mat &, int, const QString &)), worker, SLOT(addObjectAndUpdate(const cv::Mat &, int, const QString &)));
QObject::connect(tcpServer, SIGNAL(removeObject(int)), worker, SLOT(removeObjectAndUpdate(int)));
threadPool_[i]->start();
}
}
virtual ~TcpServerPool()
{
for(int i=0; i<threadPool_.size(); ++i)
{
threadPool_[i]->quit();
threadPool_[i]->wait();
}
}
private:
find_object::FindObject * sharedFindObject_;
QVector<QThread*> threadPool_;
QSemaphore sharedSemaphore_;
};
#endif /* TCPSERVERPOOL_H_ */
+51 -26
View File
@@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "find_object/TcpServer.h"
#include "find_object/JsonWriter.h"
#include "find_object/utilite/ULogger.h"
#include "TcpServerPool.h"
bool running = true;
@@ -112,8 +113,13 @@ void showUsage()
" and \"General/vocabularyFixed\" will be also enabled. Ignored if \"--session\" is set.\n"
" --images_not_saved Don't keep images in RAM after the features are extracted (only\n"
" in console mode). Images won't be saved if an output session is set.\n"
" --tcp_threads # Number of TCP threads (default 1, only in --console mode). \"--General/port\" parameter should not be 0.\n"
" Port numbers start from \"General/port\" value. \"Detect\" TCP service can be\n"
" executed at the same time by multiple threads. \"Add/Remove\" TCP services\n"
" cannot be called by multiple threads, so calling these services on a port\n "
" will block all other threads on the other ports.\n"
" --debug Show debug log.\n"
" --debug-time Show debug log with time.\n"
" --log-time Show log with time.\n"
" --params Show all parameters.\n"
" --defaults Use default parameters (--config is ignored).\n"
" --My/Parameter \"value\" Set find-Object's parameter (look --params for parameters' name).\n"
@@ -146,6 +152,7 @@ int main(int argc, char* argv[])
QString jsonPath;
find_object::ParametersMap customParameters;
bool imagesSaved = true;
int tcpThreads = 1;
for(int i=1; i<argc; ++i)
{
@@ -322,11 +329,10 @@ int main(int argc, char* argv[])
ULogger::setLevel(ULogger::kDebug);
continue;
}
if(strcmp(argv[i], "-debug-time") == 0 ||
strcmp(argv[i], "--debug-time") == 0)
if(strcmp(argv[i], "-log-time") == 0 ||
strcmp(argv[i], "--log-time") == 0)
{
ULogger::setPrintWhere(true);
ULogger::setLevel(ULogger::kDebug);
ULogger::setPrintTime(true);
continue;
}
@@ -353,6 +359,25 @@ int main(int argc, char* argv[])
}
continue;
}
if(strcmp(argv[i], "-tcp_threads") == 0 ||
strcmp(argv[i], "--tcp_threads") == 0)
{
++i;
if(i < argc)
{
tcpThreads = atoi(argv[i]);
if(tcpThreads < 1)
{
printf("tcp_threads should be >= 1!\n");
showUsage();
}
}
else
{
showUsage();
}
continue;
}
if(strcmp(argv[i], "--params") == 0)
{
find_object::ParametersMap parameters = find_object::Settings::getDefaultParameters();
@@ -578,31 +603,28 @@ int main(int argc, char* argv[])
}
else
{
find_object::Camera camera;
find_object::TcpServer tcpServer(find_object::Settings::getGeneral_port());
UINFO("Detection sent on port: %d (IP=%s)", tcpServer.getPort(), tcpServer.getHostAddress().toString().toStdString().c_str());
TcpServerPool tcpServerPool(findObject, tcpThreads, find_object::Settings::getGeneral_port());
// connect stuff:
// [FindObject] ---ObjectsDetected---> [TcpServer]
QObject::connect(findObject, SIGNAL(objectsFound(find_object::DetectionInfo)), &tcpServer, SLOT(publishDetectionInfo(find_object::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()));
//connect services
QObject::connect(&tcpServer, SIGNAL(addObject(const cv::Mat &, int, const QString &)), findObject, SLOT(addObjectAndUpdate(const cv::Mat &, int, const QString &)));
QObject::connect(&tcpServer, SIGNAL(removeObject(int)), findObject, SLOT(removeObjectAndUpdate(int)));
//use camera in settings
setupQuitSignal();
// start processing!
while(running && !camera.start())
//If TCP camera is used
find_object::Camera * camera = 0;
if(find_object::Settings::getCamera_6useTcpCamera())
{
UERROR("Camera initialization failed!");
running = false;
camera = new find_object::Camera();
// [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()));
if(!camera->start())
{
UERROR("Camera initialization failed!");
running = false;
}
}
// start processing!
if(running)
{
app.exec();
@@ -626,8 +648,11 @@ int main(int argc, char* argv[])
}
// cleanup
camera.stop();
tcpServer.close();
if(camera)
{
camera->stop();
delete camera;
}
}
delete findObject;