Added TcpRequest tool (ask a running find_object to process an image and wait results over TCP)

Refactored CameraTcpClient to CameraTcpServer (to send images we connect to find_object, instead of connecting find_object to an image server), removed parameter CameraIP

git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@364 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
matlabbe 2014-08-02 06:09:27 +00:00
parent b28ca440e8
commit 167aeee4bc
18 changed files with 359 additions and 250 deletions

View File

@ -240,8 +240,7 @@ int main(int argc, char* argv[])
} }
if(!QFile::exists(configPath)) if(!QFile::exists(configPath))
{ {
UERROR("Configuration file doesn't exist : %s", configPath.toStdString().c_str()); UWARN("Configuration file \"%s\" doesn't exist, it will be created with default values...", configPath.toStdString().c_str());
showUsage();
} }
} }
else else
@ -292,7 +291,7 @@ int main(int argc, char* argv[])
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 #ifdef WITH_JSONCPP
UINFO(" JSON path: \"%s\"", configPath.toStdString().c_str()); UINFO(" JSON path: \"%s\"", jsonPath.toStdString().c_str());
#endif #endif
////////////////////////// //////////////////////////
@ -355,7 +354,7 @@ int main(int argc, char* argv[])
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
TcpServer tcpServer(Settings::getGeneral_port()); TcpServer tcpServer(Settings::getGeneral_port());
printf("IP: %s\nport: %d\n", tcpServer.getHostAddress().toString().toStdString().c_str(), tcpServer.getPort()); UINFO("Detection sent on port: %d (IP=%s)", tcpServer.getPort(), tcpServer.getHostAddress().toString().toStdString().c_str());
// connect stuff: // connect stuff:
// [FindObject] ---ObjectsDetected---> [TcpServer] // [FindObject] ---ObjectsDetected---> [TcpServer]
@ -383,19 +382,10 @@ int main(int argc, char* argv[])
// start processing! // start processing!
while(running && !camera.start()) while(running && !camera.start())
{
if(Settings::getCamera_6useTcpCamera())
{
UWARN("Camera initialization failed! (with server %s:%d) Trying again in 1 second...",
Settings::getCamera_7IP().toStdString().c_str(), Settings::getCamera_8port());
Sleep(1000);
}
else
{ {
UERROR("Camera initialization failed!"); UERROR("Camera initialization failed!");
running = false; running = false;
} }
}
if(running) if(running)
{ {
app.exec(); app.exec();

View File

@ -12,7 +12,7 @@
#include <QtCore/QTimer> #include <QtCore/QTimer>
#include <QtGui/QImage> #include <QtGui/QImage>
class CameraTcpClient; class CameraTcpServer;
class FINDOBJECT_EXP Camera : public QObject { class FINDOBJECT_EXP Camera : public QObject {
Q_OBJECT Q_OBJECT
@ -27,6 +27,7 @@ public:
void pause(); void pause();
int getTotalFrames(); int getTotalFrames();
int getCurrentFrameIndex(); int getCurrentFrameIndex();
int getPort();
void moveToFrame(int frame); void moveToFrame(int frame);
Q_SIGNALS: Q_SIGNALS:
@ -45,7 +46,7 @@ private:
QTimer cameraTimer_; QTimer cameraTimer_;
QList<std::string> images_; QList<std::string> images_;
unsigned int currentImageIndex_; unsigned int currentImageIndex_;
CameraTcpClient * cameraTcpClient_; CameraTcpServer * cameraTcpServer_;
}; };
#endif /* CAMERA_H_ */ #endif /* CAMERA_H_ */

View File

@ -65,8 +65,7 @@ class FINDOBJECT_EXP Settings
PARAMETER(Camera, 4imageRate, double, 2.0, "Image rate in Hz (0 Hz means as fast as possible)."); // Hz PARAMETER(Camera, 4imageRate, double, 2.0, "Image rate in Hz (0 Hz means as fast as possible)."); // Hz
PARAMETER(Camera, 5mediaPath, QString, "", "Video file or directory of images. If set, the camera is not used. See General->videoFormats and General->imageFormats for available formats."); PARAMETER(Camera, 5mediaPath, QString, "", "Video file or directory of images. If set, the camera is not used. See General->videoFormats and General->imageFormats for available formats.");
PARAMETER(Camera, 6useTcpCamera, bool, false, "Use TCP/IP input camera."); PARAMETER(Camera, 6useTcpCamera, bool, false, "Use TCP/IP input camera.");
PARAMETER(Camera, 7IP, QString, "127.0.0.1", "The images server's IP to connect when useTcpCamera is checked."); PARAMETER(Camera, 8port, int, 5000, "The images server's port when useTcpCamera is checked. Only one client at the same time is allowed.");
PARAMETER(Camera, 8port, int, 5000, "The images server's port to connect when useTcpCamera is checked.");
PARAMETER(Camera, 9queueSize, int, 1, "Maximum images buffered from TCP. If 0, all images are buffered."); PARAMETER(Camera, 9queueSize, int, 1, "Maximum images buffered from TCP. If 0, all images are buffered.");
//List format : [Index:item0;item1;item3;...] //List format : [Index:item0;item1;item3;...]

View File

@ -363,6 +363,11 @@ void AddObjectDialog::update(const cv::Mat & image)
ui_->cameraView->setData(keypoints, cvtCvMat2QImage(cameraImage_)); ui_->cameraView->setData(keypoints, cvtCvMat2QImage(cameraImage_));
ui_->cameraView->update(); ui_->cameraView->update();
} }
else
{
UWARN("Camera cannot get more images (maybe the end of stream is reached)...");
camera_->stop();
}
} }
cv::Rect AddObjectDialog::computeROI(const std::vector<cv::KeyPoint> & kpts) cv::Rect AddObjectDialog::computeROI(const std::vector<cv::KeyPoint> & kpts)

View File

@ -8,7 +8,7 @@ SET(headers_ui
../include/${PROJECT_PREFIX}/TcpServer.h ../include/${PROJECT_PREFIX}/TcpServer.h
../include/${PROJECT_PREFIX}/ObjWidget.h ../include/${PROJECT_PREFIX}/ObjWidget.h
./AddObjectDialog.h ./AddObjectDialog.h
./CameraTcpClient.h ./CameraTcpServer.h
./ParametersToolBox.h ./ParametersToolBox.h
./AboutDialog.h ./AboutDialog.h
./RectItem.h ./RectItem.h
@ -46,7 +46,7 @@ SET(SRC_FILES
./RectItem.cpp ./RectItem.cpp
./QtOpenCV.cpp ./QtOpenCV.cpp
./Camera.cpp ./Camera.cpp
./CameraTcpClient.cpp ./CameraTcpServer.cpp
./ParametersToolBox.cpp ./ParametersToolBox.cpp
./Settings.cpp ./Settings.cpp
./ObjWidget.cpp ./ObjWidget.cpp

View File

@ -11,12 +11,12 @@
#include <opencv2/imgproc/imgproc.hpp> #include <opencv2/imgproc/imgproc.hpp>
#include <QtCore/QFile> #include <QtCore/QFile>
#include "utilite/UDirectory.h" #include "utilite/UDirectory.h"
#include "CameraTcpClient.h" #include "CameraTcpServer.h"
Camera::Camera(QObject * parent) : Camera::Camera(QObject * parent) :
QObject(parent), QObject(parent),
currentImageIndex_(0), currentImageIndex_(0),
cameraTcpClient_(new CameraTcpClient(this)) cameraTcpServer_(0)
{ {
qRegisterMetaType<cv::Mat>("cv::Mat"); qRegisterMetaType<cv::Mat>("cv::Mat");
connect(&cameraTimer_, SIGNAL(timeout()), this, SLOT(takeImage())); connect(&cameraTimer_, SIGNAL(timeout()), this, SLOT(takeImage()));
@ -33,7 +33,12 @@ void Camera::stop()
capture_.release(); capture_.release();
images_.clear(); images_.clear();
currentImageIndex_ = 0; currentImageIndex_ = 0;
cameraTcpClient_->close(); if(cameraTcpServer_)
{
cameraTcpServer_->close();
delete cameraTcpServer_;
cameraTcpServer_ = 0;
}
} }
void Camera::pause() void Camera::pause()
@ -79,6 +84,15 @@ void Camera::moveToFrame(int frame)
} }
} }
int Camera::getPort()
{
if(cameraTcpServer_)
{
return cameraTcpServer_->getPort();
}
return 0;
}
void Camera::takeImage() void Camera::takeImage()
{ {
cv::Mat img; cv::Mat img;
@ -93,33 +107,29 @@ void Camera::takeImage()
img = cv::imread(images_[currentImageIndex_++]); img = cv::imread(images_[currentImageIndex_++]);
} }
} }
else else if(cameraTcpServer_)
{ {
img = cameraTcpClient_->getImage(); img = cameraTcpServer_->getImage();
if(cameraTcpClient_->imagesBuffered() > 0 && Settings::getCamera_9queueSize() == 0) if(cameraTcpServer_->imagesBuffered() > 0 && Settings::getCamera_9queueSize() == 0)
{ {
UWARN("%d images buffered so far...", cameraTcpClient_->imagesBuffered()); UWARN("%d images buffered so far...", cameraTcpServer_->imagesBuffered());
}
while(img.empty() && cameraTcpClient_->waitForReadyRead())
{
img = cameraTcpClient_->getImage();
}
if(img.empty())
{
if(!cameraTcpClient_->waitForConnected())
{
UWARN("Connection is lost, trying to reconnect to server (%s:%d)... (at the rate of the camera: %d ms)",
Settings::getCamera_7IP().toStdString().c_str(),
Settings::getCamera_8port(),
cameraTimer_.interval());
cameraTcpClient_->connectToHost(Settings::getCamera_7IP(), Settings::getCamera_8port());
}
} }
} }
if(img.empty()) if(img.empty())
{ {
UWARN("Camera: Could not grab a frame, the end of the feed may be reached..."); if(cameraTcpServer_)
{
if(!cameraTcpServer_->isConnected())
{
cameraTcpServer_->waitForNewConnection(100);
}
}
else
{
// In case of a directory of images or a video
Q_EMIT imageReceived(cv::Mat()); // empty image to notify that there are no more images
}
} }
else else
{ {
@ -146,17 +156,22 @@ void Camera::takeImage()
bool Camera::start() bool Camera::start()
{ {
if(!capture_.isOpened() && images_.empty() && !cameraTcpClient_->isOpen()) if(!capture_.isOpened() && images_.empty() && cameraTcpServer_ == 0)
{ {
if(Settings::getCamera_6useTcpCamera()) if(Settings::getCamera_6useTcpCamera())
{ {
cameraTcpClient_->connectToHost(Settings::getCamera_7IP(), Settings::getCamera_8port()); cameraTcpServer_ = new CameraTcpServer(Settings::getCamera_8port(), this);
if(!cameraTcpClient_->waitForConnected()) if(!cameraTcpServer_->isListening())
{ {
UWARN("Camera: Cannot connect to server \"%s:%d\"", UWARN("CameraTCP: Cannot listen to port %d", cameraTcpServer_->getPort());
Settings::getCamera_7IP().toStdString().c_str(), delete cameraTcpServer_;
Settings::getCamera_8port()); cameraTcpServer_ = 0;
cameraTcpClient_->close(); }
else
{
UINFO("CameraTCP: listening to port %d (IP=%s)",
cameraTcpServer_->getPort(),
cameraTcpServer_->getHostAddress().toString().toStdString().c_str());
} }
} }
else else
@ -215,7 +230,7 @@ bool Camera::start()
} }
} }
} }
if(!capture_.isOpened() && images_.empty() && !cameraTcpClient_->isOpen()) if(!capture_.isOpened() && images_.empty() && cameraTcpServer_ == 0)
{ {
UERROR("Camera: Failed to open a capture object!"); UERROR("Camera: Failed to open a capture object!");
return false; return false;

View File

@ -1,96 +0,0 @@
/*
* CameraTcpClient.cpp
*
* Created on: 2014-07-31
* Author: mathieu
*/
#include "find_object/Settings.h"
#include "find_object/utilite/ULogger.h"
#include "CameraTcpClient.h"
CameraTcpClient::CameraTcpClient(QObject *parent) :
QTcpSocket(parent),
blockSize_(0)
{
connect(this, SIGNAL(readyRead()), this, SLOT(readReceivedData()));
connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
connect(this, SIGNAL(disconnected()), this, SLOT(connectionLost()));
}
cv::Mat CameraTcpClient::getImage()
{
cv::Mat img;
if(images_.size())
{
// if queue changed after tcp connection ended with images still in the buffer
int queue = Settings::getCamera_9queueSize();
while(queue > 0 && images_.size() > queue)
{
images_.pop_front();
}
img = images_.front();
images_.pop_front();
}
return img;
}
void CameraTcpClient::readReceivedData()
{
QDataStream in(this);
in.setVersion(QDataStream::Qt_4_0);
if (blockSize_ == 0)
{
if (this->bytesAvailable() < (int)sizeof(quint64))
{
return;
}
in >> blockSize_;
}
if (this->bytesAvailable() < (int)blockSize_)
{
return;
}
std::vector<unsigned char> buf(blockSize_);
in.readRawData((char*)buf.data(), blockSize_);
images_.push_back(cv::imdecode(buf, cv::IMREAD_UNCHANGED));
int queue = Settings::getCamera_9queueSize();
while(queue > 0 && images_.size() > queue)
{
images_.pop_front();
}
blockSize_ = 0;
}
void CameraTcpClient::displayError(QAbstractSocket::SocketError socketError)
{
switch (socketError)
{
case QAbstractSocket::RemoteHostClosedError:
break;
case QAbstractSocket::HostNotFoundError:
UWARN("CameraTcp: Tcp error: The host was not found. Please "
"check the host name and port settings.\n");
break;
case QAbstractSocket::ConnectionRefusedError:
UWARN("CameraTcp: The connection was refused by the peer. "
"Make sure your images server is running, "
"and check that the host name and port "
"settings are correct.");
break;
default:
UERROR("The following error occurred: %s.", this->errorString().toStdString().c_str());
break;
}
}
void CameraTcpClient::connectionLost()
{
//printf("[WARNING] CameraTcp: Connection lost!\n");
}

165
src/CameraTcpServer.cpp Normal file
View File

@ -0,0 +1,165 @@
/*
* CameraTcpClient.cpp
*
* Created on: 2014-07-31
* Author: mathieu
*/
#include "find_object/Settings.h"
#include "find_object/utilite/ULogger.h"
#include "CameraTcpServer.h"
#include <QtNetwork/QTcpSocket>
#include <QtNetwork/QNetworkInterface>
#include <QtCore/QDataStream>
CameraTcpServer::CameraTcpServer(quint16 port, QObject *parent) :
QTcpServer(parent),
blockSize_(0)
{
this->setMaxPendingConnections(1);
if (!this->listen(QHostAddress::Any, port))
{
UERROR("Unable to start the Camera TCP server: %s", this->errorString().toStdString().c_str());
return;
}
connect(this, SIGNAL(newConnection()), this, SLOT(addClient()));
}
cv::Mat CameraTcpServer::getImage()
{
cv::Mat img;
if(images_.size())
{
// if queue changed after tcp connection ended with images still in the buffer
int queue = Settings::getCamera_9queueSize();
while(queue > 0 && images_.size() > queue)
{
images_.pop_front();
}
img = images_.front();
images_.pop_front();
}
if(this->findChildren<QTcpSocket*>().size() == 1)
{
this->findChildren<QTcpSocket*>().first()->waitForReadyRead(100);
}
return img;
}
bool CameraTcpServer::isConnected() const
{
return this->findChildren<QTcpSocket*>().size() > 0;
}
QHostAddress CameraTcpServer::getHostAddress() const
{
QHostAddress hostAddress;
QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
for (int i = 0; i < ipAddressesList.size(); ++i)
{
if (ipAddressesList.at(i) != QHostAddress::LocalHost && ipAddressesList.at(i).toIPv4Address())
{
hostAddress = ipAddressesList.at(i).toString();
break;
}
}
// if we did not find one, use IPv4 localhost
if (hostAddress.isNull())
{
hostAddress = QHostAddress(QHostAddress::LocalHost);
}
return hostAddress;
}
quint16 CameraTcpServer::getPort() const
{
return this->serverPort();
}
void CameraTcpServer::addClient()
{
QTcpSocket * client = this->nextPendingConnection();
QList<QTcpSocket*> clients = this->findChildren<QTcpSocket*>();
if(clients.size() > 1)
{
UWARN("A client is already connected. Only one connection allowed at the same time.");
client->close();
client->deleteLater();
}
else
{
connect(client, SIGNAL(readyRead()), this, SLOT(readReceivedData()));
connect(client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
connect(client, SIGNAL(disconnected()), this, SLOT(connectionLost()));
}
}
void CameraTcpServer::readReceivedData()
{
QTcpSocket * client = (QTcpSocket*)sender();
QDataStream in(client);
in.setVersion(QDataStream::Qt_4_0);
if (blockSize_ == 0)
{
if (client->bytesAvailable() < (int)sizeof(quint64))
{
return;
}
in >> blockSize_;
}
if (client->bytesAvailable() < (int)blockSize_)
{
return;
}
std::vector<unsigned char> buf(blockSize_);
in.readRawData((char*)buf.data(), blockSize_);
images_.push_back(cv::imdecode(buf, cv::IMREAD_UNCHANGED));
int queue = Settings::getCamera_9queueSize();
while(queue > 0 && images_.size() > queue)
{
images_.pop_front();
}
blockSize_ = 0;
}
void CameraTcpServer::displayError(QAbstractSocket::SocketError socketError)
{
switch (socketError)
{
case QAbstractSocket::RemoteHostClosedError:
break;
case QAbstractSocket::HostNotFoundError:
UWARN("CameraTcp: Tcp error: The host was not found. Please "
"check the host name and port settings.\n");
break;
case QAbstractSocket::ConnectionRefusedError:
UWARN("CameraTcp: The connection was refused by the peer. "
"Make sure your images server is running, "
"and check that the host name and port "
"settings are correct.");
break;
default:
//UERROR("The following error occurred: %s.", this->errorString().toStdString().c_str());
break;
}
}
void CameraTcpServer::connectionLost()
{
//printf("[WARNING] CameraTcp: Connection lost!\n");
((QTcpSocket*)sender())->close();
sender()->deleteLater();
blockSize_ = 0; // reset
}

View File

@ -8,22 +8,29 @@
#ifndef CAMERATCPCLIENT_H_ #ifndef CAMERATCPCLIENT_H_
#define CAMERATCPCLIENT_H_ #define CAMERATCPCLIENT_H_
#include <QtNetwork/QTcpSocket> #include <QtNetwork/QTcpServer>
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
class CameraTcpClient : public QTcpSocket class CameraTcpServer : public QTcpServer
{ {
Q_OBJECT; Q_OBJECT;
public: public:
CameraTcpClient(QObject * parent = 0); CameraTcpServer(quint16 port = 0, QObject * parent = 0);
cv::Mat getImage(); cv::Mat getImage();
int imagesBuffered() const {return images_.size();} int imagesBuffered() const {return images_.size();}
bool isConnected() const;
QHostAddress getHostAddress() const;
quint16 getPort() const;
private Q_SLOTS: private Q_SLOTS:
void readReceivedData(); void readReceivedData();
void displayError(QAbstractSocket::SocketError socketError); void displayError(QAbstractSocket::SocketError socketError);
void connectionLost(); void connectionLost();
private Q_SLOTS:
void addClient();
private: private:
quint64 blockSize_; quint64 blockSize_;
QVector<cv::Mat> images_; QVector<cv::Mat> images_;

View File

@ -99,8 +99,8 @@ MainWindow::MainWindow(FindObject * findObject, Camera * camera, QWidget * paren
ui_->toolBox->getParameterWidget(Settings::kCamera_3imageHeight())->setEnabled(false); ui_->toolBox->getParameterWidget(Settings::kCamera_3imageHeight())->setEnabled(false);
ui_->toolBox->getParameterWidget(Settings::kCamera_5mediaPath())->setEnabled(false); ui_->toolBox->getParameterWidget(Settings::kCamera_5mediaPath())->setEnabled(false);
ui_->toolBox->getParameterWidget(Settings::kCamera_6useTcpCamera())->setEnabled(false); ui_->toolBox->getParameterWidget(Settings::kCamera_6useTcpCamera())->setEnabled(false);
ui_->toolBox->getParameterWidget(Settings::kCamera_7IP())->setEnabled(false);
ui_->toolBox->getParameterWidget(Settings::kCamera_8port())->setEnabled(false); ui_->toolBox->getParameterWidget(Settings::kCamera_8port())->setEnabled(false);
ui_->toolBox->getParameterWidget(Settings::kCamera_9queueSize())->setEnabled(false);
ui_->actionCamera_from_video_file->setVisible(false); ui_->actionCamera_from_video_file->setVisible(false);
ui_->actionCamera_from_TCP_IP->setVisible(false); ui_->actionCamera_from_TCP_IP->setVisible(false);
ui_->actionCamera_from_directory_of_images->setVisible(false); ui_->actionCamera_from_directory_of_images->setVisible(false);
@ -270,7 +270,7 @@ void MainWindow::setupTCPServer()
connect(this, SIGNAL(objectsFound(QMultiMap<int,QPair<QRect,QTransform> >)), tcpServer_, SLOT(publishObjects(QMultiMap<int,QPair<QRect,QTransform> >))); connect(this, SIGNAL(objectsFound(QMultiMap<int,QPair<QRect,QTransform> >)), tcpServer_, SLOT(publishObjects(QMultiMap<int,QPair<QRect,QTransform> >)));
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("IP: %s port: %d", tcpServer_->getHostAddress().toString().toStdString().c_str(), tcpServer_->getPort()); UINFO("Detection sent on port: %d (IP=%s)", tcpServer_->getPort(), tcpServer_->getHostAddress().toString().toStdString().c_str());
} }
void MainWindow::setSourceImageText(const QString & text) void MainWindow::setSourceImageText(const QString & text)
@ -430,6 +430,10 @@ void MainWindow::removeObject(ObjWidget * object)
} }
findObject_->removeObject(object->id()); findObject_->removeObject(object->id());
object->deleteLater(); object->deleteLater();
if(Settings::getGeneral_autoUpdateObjects())
{
this->updateVocabulary();
}
if(!camera_->isRunning() && !sceneImage_.empty()) if(!camera_->isRunning() && !sceneImage_.empty())
{ {
this->update(); this->update();
@ -641,19 +645,20 @@ void MainWindow::setupCameraFromTcpIp()
} }
else else
{ {
QString ip = QInputDialog::getText(this, tr("Server IP..."), "IP: ", QLineEdit::Normal, Settings::getCamera_7IP()); bool ok;
if(!ip.isEmpty()) int port = QInputDialog::getInteger(this, tr("Server port..."), "Port: ", Settings::getCamera_8port(), 1, USHRT_MAX, 1, &ok);
{
int port = QInputDialog::getInteger(this, tr("Server port..."), "Port: ", Settings::getCamera_8port());
if(port > 0) if(ok)
{
int queue = QInputDialog::getInteger(this, tr("Queue size..."), "Images buffer size (0 means infinite): ", Settings::getCamera_9queueSize(), 0, 2147483647, 1, &ok);
if(ok)
{ {
Settings::setCamera_6useTcpCamera(true); Settings::setCamera_6useTcpCamera(true);
ui_->toolBox->updateParameter(Settings::kCamera_6useTcpCamera()); ui_->toolBox->updateParameter(Settings::kCamera_6useTcpCamera());
Settings::setCamera_7IP(ip);
ui_->toolBox->updateParameter(Settings::kCamera_7IP());
Settings::setCamera_8port(port); Settings::setCamera_8port(port);
ui_->toolBox->updateParameter(Settings::kCamera_8port()); ui_->toolBox->updateParameter(Settings::kCamera_8port());
Settings::setCamera_9queueSize(queue);
ui_->toolBox->updateParameter(Settings::kCamera_9queueSize());
if(camera_->isRunning()) if(camera_->isRunning())
{ {
this->stopProcessing(); this->stopProcessing();
@ -786,6 +791,13 @@ void MainWindow::startProcessing()
ui_->horizontalSlider_frames->setMaximum(totalFrames-1); ui_->horizontalSlider_frames->setMaximum(totalFrames-1);
} }
//update camera port if TCP is used
ui_->label_port_image->setText("-");
if(Settings::getCamera_6useTcpCamera() && camera_->getPort())
{
ui_->label_port_image->setNum(camera_->getPort());
}
if(updateStatusMessage) if(updateStatusMessage)
{ {
this->statusBar()->showMessage(tr("Camera started."), 2000); this->statusBar()->showMessage(tr("Camera started."), 2000);
@ -800,7 +812,7 @@ void MainWindow::startProcessing()
if(Settings::getCamera_6useTcpCamera()) if(Settings::getCamera_6useTcpCamera())
{ {
QMessageBox::critical(this, tr("Camera error"), tr("Camera initialization failed! (with server %1:%2)").arg(Settings::getCamera_7IP()).arg(Settings::getCamera_8port())); QMessageBox::critical(this, tr("Camera error"), tr("Camera initialization failed! (with port %1)").arg(Settings::getCamera_8port()));
} }
else else
{ {
@ -829,6 +841,7 @@ void MainWindow::stopProcessing()
ui_->horizontalSlider_frames->setEnabled(false); ui_->horizontalSlider_frames->setEnabled(false);
ui_->horizontalSlider_frames->setValue(0); ui_->horizontalSlider_frames->setValue(0);
ui_->label_frame->setVisible(false); ui_->label_frame->setVisible(false);
ui_->label_port_image->setText("-");
} }
void MainWindow::pauseProcessing() void MainWindow::pauseProcessing()
@ -876,6 +889,12 @@ void MainWindow::rectHovered(int objId)
void MainWindow::update(const cv::Mat & image) void MainWindow::update(const cv::Mat & image)
{ {
if(image.empty())
{
UWARN("Camera cannot get more images (maybe the end of stream is reached)...");
return;
}
// reset objects color // reset objects color
for(QMap<int, ObjWidget*>::iterator iter=objWidgets_.begin(); iter!=objWidgets_.end(); ++iter) for(QMap<int, ObjWidget*>::iterator iter=objWidgets_.begin(); iter!=objWidgets_.end(); ++iter)
{ {

View File

@ -448,6 +448,13 @@
<property name="verticalSpacing"> <property name="verticalSpacing">
<number>0</number> <number>0</number>
</property> </property>
<item row="4" column="1">
<widget class="QLabel" name="label_timeMatching">
<property name="text">
<string>000</string>
</property>
</widget>
</item>
<item row="3" column="2"> <item row="3" column="2">
<widget class="QLabel" name="label_9"> <widget class="QLabel" name="label_9">
<property name="text"> <property name="text">
@ -476,13 +483,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1">
<widget class="QLabel" name="label_timeMatching">
<property name="text">
<string>000</string>
</property>
</widget>
</item>
<item row="5" column="2"> <item row="5" column="2">
<widget class="QLabel" name="label_12"> <widget class="QLabel" name="label_12">
<property name="text"> <property name="text">
@ -619,7 +619,7 @@
<item row="11" column="0"> <item row="11" column="0">
<widget class="QLabel" name="label_19"> <widget class="QLabel" name="label_19">
<property name="text"> <property name="text">
<string>Port</string> <string>Output detection port</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -658,6 +658,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="12" column="0">
<widget class="QLabel" name="label_21">
<property name="text">
<string>Input image port</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QLabel" name="label_port_image">
<property name="text">
<string>NA</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>

View File

@ -1,3 +1,4 @@
ADD_SUBDIRECTORY( tcpObjectsClient ) ADD_SUBDIRECTORY( tcpObjectsClient )
ADD_SUBDIRECTORY( tcpImagesServer ) ADD_SUBDIRECTORY( tcpImagesServer )
ADD_SUBDIRECTORY( tcpRequest )
ADD_SUBDIRECTORY( similarity ) ADD_SUBDIRECTORY( similarity )

View File

@ -15,17 +15,17 @@
#include <QtGui/QTransform> #include <QtGui/QTransform>
ImagesTcpServer::ImagesTcpServer(float hz, const QString & path, QObject * parent) : ImagesTcpServer::ImagesTcpServer(float hz, const QString & path, QObject * parent) :
QTcpServer(parent) QTcpSocket(parent)
{ {
// Set camera parameters // Set camera parameters
Settings::setCamera_4imageRate(hz); Settings::setCamera_4imageRate(hz);
Settings::setCamera_5mediaPath(path); Settings::setCamera_5mediaPath(path);
connect(this, SIGNAL(newConnection()), this, SLOT(addClient()));
connect(&camera_, SIGNAL(imageReceived(const cv::Mat &)), this, SLOT(publishImage(const cv::Mat &))); connect(&camera_, SIGNAL(imageReceived(const cv::Mat &)), this, SLOT(publishImage(const cv::Mat &)));
connect(this, SIGNAL(connected()), this, SLOT(startCamera()));
} }
QHostAddress ImagesTcpServer::getHostAddress() const QHostAddress ImagesTcpServer::getHostAddress()
{ {
QHostAddress hostAddress; QHostAddress hostAddress;
@ -49,21 +49,21 @@ QHostAddress ImagesTcpServer::getHostAddress() const
return hostAddress; return hostAddress;
} }
quint16 ImagesTcpServer::getPort() const
{
return this->serverPort();
}
void ImagesTcpServer::publishImage(const cv::Mat & image) void ImagesTcpServer::publishImage(const cv::Mat & image)
{ {
QList<QTcpSocket*> clients = this->findChildren<QTcpSocket*>(); if(image.empty())
if(clients.size()) {
printf("No more images...\n");
camera_.pause();
Q_EMIT connectionLost();
}
else
{
if(this->waitForConnected())
{ {
std::vector<unsigned char> buf; std::vector<unsigned char> buf;
cv::imencode(".png", image, buf); cv::imencode(".png", image, buf);
for(QList<QTcpSocket*>::iterator iter = clients.begin(); iter!=clients.end(); ++iter)
{
QByteArray block; QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly); QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0); out.setVersion(QDataStream::Qt_4_0);
@ -71,20 +71,20 @@ void ImagesTcpServer::publishImage(const cv::Mat & image)
out.writeRawData((char*)buf.data(), (int)buf.size()); out.writeRawData((char*)buf.data(), (int)buf.size());
out.device()->seek(0); out.device()->seek(0);
out << (quint64)(block.size() - sizeof(quint64)); out << (quint64)(block.size() - sizeof(quint64));
(*iter)->write(block); this->write(block);
}
} }
else else
{ {
printf("Paused...\n"); printf("Lost connection...\n");
camera_.pause(); camera_.pause();
Q_EMIT connectionLost();
}
} }
} }
void ImagesTcpServer::addClient() void ImagesTcpServer::startCamera()
{ {
QTcpSocket * client = this->nextPendingConnection();
connect(client, SIGNAL(disconnected()), client, SLOT(deleteLater()));
if(!camera_.isRunning()) if(!camera_.isRunning())
{ {
printf("Start...\n"); printf("Start...\n");

View File

@ -5,27 +5,29 @@
* Author: mathieu * Author: mathieu
*/ */
#ifndef TCPCLIENT_H_ #ifndef IMAGESTCPSERVER_H_
#define TCPCLIENT_H_ #define IMAGESTCPSERVER_H_
#include "find_object/Camera.h" #include "find_object/Camera.h"
#include <QtNetwork/QTcpServer> #include <QtNetwork/QTcpSocket>
class ImagesTcpServer : public QTcpServer class ImagesTcpServer : public QTcpSocket
{ {
Q_OBJECT Q_OBJECT
public:
static QHostAddress getHostAddress();
public: public:
ImagesTcpServer(float hz = 10.0f, const QString & path = "", QObject * parent = 0); ImagesTcpServer(float hz = 10.0f, const QString & path = "", QObject * parent = 0);
QHostAddress getHostAddress() const;
quint16 getPort() const;
private Q_SLOTS: private Q_SLOTS:
void addClient(); void startCamera();
void publishImage(const cv::Mat & image); void publishImage(const cv::Mat & image);
Q_SIGNALS:
void connectionLost();
private: private:
Camera camera_; Camera camera_;
}; };

View File

@ -11,11 +11,11 @@
void showUsage() void showUsage()
{ {
printf("imagesTcpServer [options]\n" printf("\ntcpImagesServer [options] port\n"
" Options:\n" " Options:\n"
" -hz #.# Image rate (default 10 Hz).\n" " --hz #.# Image rate (default 10 Hz).\n"
" -p # Set manually a port to which the clients will connect.\n" " --host #.#.#.# Set host address.\n"
" -path \"\" Set a path of a directory of images or a video file.\n"); " --path \"\" Set a path of a directory of images or a video file.\n");
exit(-1); exit(-1);
} }
@ -23,15 +23,19 @@ int main(int argc, char * argv[])
{ {
QString ipAddress; QString ipAddress;
float hz = 10.0f; float hz = 10.0f;
quint16 port = 0;
QString path; QString path;
for(int i=1; i<argc; ++i) if(argc < 2)
{ {
if(strcmp(argv[i], "-hz") == 0) showUsage();
}
for(int i=1; i<argc-1; ++i)
{
if(strcmp(argv[i], "-hz") == 0 || strcmp(argv[i], "--hz") == 0)
{ {
++i; ++i;
if(i < argc) if(i < argc-1)
{ {
hz = std::atof(argv[i]); hz = std::atof(argv[i]);
if(hz < 0.0f) if(hz < 0.0f)
@ -46,18 +50,12 @@ int main(int argc, char * argv[])
} }
continue; continue;
} }
if(strcmp(argv[i], "-p") == 0) if(strcmp(argv[i], "-host") == 0 || strcmp(argv[i], "--host") == 0)
{ {
++i; ++i;
if(i < argc) if(i < argc-1)
{ {
int v = std::atoi(argv[i]); ipAddress = argv[i];
if(v < 0)
{
printf("[ERROR] Port not valid : %s\n", argv[i]);
showUsage();
}
port = v;
} }
else else
{ {
@ -65,10 +63,10 @@ int main(int argc, char * argv[])
} }
continue; continue;
} }
if(strcmp(argv[i], "-path") == 0) if(strcmp(argv[i], "-path") == 0 || strcmp(argv[i], "--path") == 0)
{ {
++i; ++i;
if(i < argc) if(i < argc-1)
{ {
path = argv[i]; path = argv[i];
} }
@ -83,24 +81,29 @@ int main(int argc, char * argv[])
showUsage(); showUsage();
} }
quint16 port = std::atoi(argv[argc-1]);
if(!path.isEmpty()) if(!path.isEmpty())
{ {
printf("Using images from path \"%s\"\n", path.toStdString().c_str()); printf("Using images from path \"%s\"\n", path.toStdString().c_str());
} }
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
ImagesTcpServer server(hz, path); ImagesTcpServer server(hz, path);
if (!server.listen(QHostAddress::Any, port)) QObject::connect(&server, SIGNAL(connectionLost()), &app, SLOT(quit()));
if(ipAddress.isEmpty())
{ {
printf("ERROR: Unable to start the TCP server: %s\n", server.errorString().toStdString().c_str()); ipAddress = server.getHostAddress().toString();
}
server.connectToHost(ipAddress, port);
if(!server.waitForConnected())
{
printf("ERROR: Unable to connect to %s:%d\n", ipAddress.toStdString().c_str(), port);
return -1; return -1;
} }
printf("Images server waiting on \"%s:%d\"...\n",
server.getHostAddress().toString().toStdString().c_str(), server.getPort());
return app.exec(); return app.exec();
} }

View File

@ -12,15 +12,13 @@
#include <QtCore/QPointF> #include <QtCore/QPointF>
#include <QtCore/QTime> #include <QtCore/QTime>
TcpClient::TcpClient(const QString & hostname, quint16 port, QObject *parent) : TcpClient::TcpClient(QObject *parent) :
QTcpSocket(parent), QTcpSocket(parent),
blockSize_(0) blockSize_(0)
{ {
connect(this, SIGNAL(readyRead()), this, SLOT(readReceivedData())); connect(this, SIGNAL(readyRead()), this, SLOT(readReceivedData()));
connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError))); connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
connect(this, SIGNAL(disconnected()), this, SLOT(connectionLost())); connect(this, SIGNAL(disconnected()), this, SLOT(connectionLost()));
this->connectToHost(hostname, port);
} }
void TcpClient::readReceivedData() void TcpClient::readReceivedData()

View File

@ -14,7 +14,7 @@ class TcpClient : public QTcpSocket
{ {
Q_OBJECT; Q_OBJECT;
public: public:
TcpClient(const QString & hostname, quint16 port, QObject * parent = 0); TcpClient(QObject * parent = 0);
private Q_SLOTS: private Q_SLOTS:
void readReceivedData(); void readReceivedData();

View File

@ -11,7 +11,7 @@
void showUsage() void showUsage()
{ {
printf("tcpClient [hostname] port\n"); printf("\ntcpObjectsClient [hostname] port\n");
exit(-1); exit(-1);
} }
@ -36,31 +36,17 @@ int main(int argc, char * argv[])
} }
if(ipAddress.isEmpty()) if(ipAddress.isEmpty())
{
// find out which IP to connect to
QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
// use the first non-localhost IPv4 address
for (int i = 0; i < ipAddressesList.size(); ++i)
{
if (ipAddressesList.at(i) != QHostAddress::LocalHost &&
ipAddressesList.at(i).toIPv4Address())
{
ipAddress = ipAddressesList.at(i).toString();
break;
}
}
// if we did not find one, use IPv4 localhost
if (ipAddress.isEmpty())
{ {
ipAddress = QHostAddress(QHostAddress::LocalHost).toString(); ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
} }
}
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
printf("Connecting to \"%s:%d\"...\n", ipAddress.toStdString().c_str(), port); printf("Connecting to \"%s:%d\"...\n", ipAddress.toStdString().c_str(), port);
TcpClient client(ipAddress, port); TcpClient client;
client.connectToHost(ipAddress, port);
if(client.waitForConnected()) if(client.waitForConnected())
{ {