Added "Camera from TCP/IP..." action. Find-Object can connect to a server to receive images over TCP/IP. Look at the "imagesTcpServer" example to know how to send a images. The stream format is [quint64 size, std::vector<unsigned char> data]. The data array is decoded to a cv:Mat image using cv::imdecode(data, cv::IMREAD_UNCHANGED). In the server example, the images are encoded like that: cv::imencode(".png", image, data).
git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@280 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
parent
2d3b4ebebe
commit
19b5776ba4
@ -65,6 +65,7 @@ ENDIF(APPLE AND BUILD_AS_BUNDLE)
|
|||||||
ADD_SUBDIRECTORY( app )
|
ADD_SUBDIRECTORY( app )
|
||||||
ADD_SUBDIRECTORY( example )
|
ADD_SUBDIRECTORY( example )
|
||||||
ADD_SUBDIRECTORY( tcpClient )
|
ADD_SUBDIRECTORY( tcpClient )
|
||||||
|
ADD_SUBDIRECTORY( imagesTcpServer )
|
||||||
ADD_SUBDIRECTORY( console_app )
|
ADD_SUBDIRECTORY( console_app )
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
44
imagesTcpServer/CMakeLists.txt
Normal file
44
imagesTcpServer/CMakeLists.txt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
### Qt Gui stuff ###
|
||||||
|
SET(headers_ui
|
||||||
|
../src/Camera.h
|
||||||
|
ImagesTcpServer.h
|
||||||
|
)
|
||||||
|
#This will generate moc_* for Qt
|
||||||
|
QT4_WRAP_CPP(moc_srcs ${headers_ui})
|
||||||
|
### Qt Gui stuff end###
|
||||||
|
|
||||||
|
SET(SRC_FILES
|
||||||
|
../src/Camera.cpp
|
||||||
|
../src/Settings.cpp
|
||||||
|
../src/QtOpenCV.cpp
|
||||||
|
../src/utilite/UDirectory.cpp
|
||||||
|
../src/utilite/UFile.cpp
|
||||||
|
ImagesTcpServer.cpp
|
||||||
|
main.cpp
|
||||||
|
${moc_srcs}
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(INCLUDE_DIRS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${OpenCV_INCLUDE_DIRS}
|
||||||
|
../src
|
||||||
|
)
|
||||||
|
|
||||||
|
INCLUDE(${QT_USE_FILE})
|
||||||
|
|
||||||
|
SET(LIBRARIES
|
||||||
|
${OpenCV_LIBS}
|
||||||
|
${QT_LIBRARIES}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make sure the compiler can find include files from our library.
|
||||||
|
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
|
||||||
|
|
||||||
|
# Add binary called "example" that is built from the source file "main.cpp".
|
||||||
|
# The extension is automatically found.
|
||||||
|
ADD_EXECUTABLE(imagesTcpServer ${SRC_FILES})
|
||||||
|
TARGET_LINK_LIBRARIES(imagesTcpServer ${LIBRARIES})
|
||||||
|
|
||||||
|
SET_TARGET_PROPERTIES( imagesTcpServer
|
||||||
|
PROPERTIES OUTPUT_NAME ${PROJECT_PREFIX}-imagesTcpServer)
|
||||||
|
|
||||||
91
imagesTcpServer/ImagesTcpServer.cpp
Normal file
91
imagesTcpServer/ImagesTcpServer.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* ImagesTcpServer.cpp
|
||||||
|
*
|
||||||
|
* Created on: 2014-05-21
|
||||||
|
* Author: mathieu
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ImagesTcpServer.h"
|
||||||
|
|
||||||
|
#include <QtNetwork/QNetworkInterface>
|
||||||
|
#include <QtNetwork/QTcpSocket>
|
||||||
|
#include <QtGui/QTransform>
|
||||||
|
#include "Settings.h"
|
||||||
|
#include "QtOpenCV.h"
|
||||||
|
|
||||||
|
ImagesTcpServer::ImagesTcpServer(float hz, quint16 port, QObject * parent) :
|
||||||
|
QTcpServer(parent)
|
||||||
|
{
|
||||||
|
// Set camera parameters
|
||||||
|
Settings::setCamera_4imageRate(hz);
|
||||||
|
|
||||||
|
connect(this, SIGNAL(newConnection()), this, SLOT(addClient()));
|
||||||
|
connect(&camera_, SIGNAL(imageReceived(const cv::Mat &)), this, SLOT(publishImage(const cv::Mat &)));
|
||||||
|
}
|
||||||
|
|
||||||
|
QHostAddress ImagesTcpServer::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 ImagesTcpServer::getPort() const
|
||||||
|
{
|
||||||
|
return this->serverPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImagesTcpServer::publishImage(const cv::Mat & image)
|
||||||
|
{
|
||||||
|
QList<QTcpSocket*> clients = this->findChildren<QTcpSocket*>();
|
||||||
|
if(clients.size())
|
||||||
|
{
|
||||||
|
std::vector<unsigned char> buf;
|
||||||
|
cv::imencode(".png", image, buf);
|
||||||
|
|
||||||
|
for(QList<QTcpSocket*>::iterator iter = clients.begin(); iter!=clients.end(); ++iter)
|
||||||
|
{
|
||||||
|
QByteArray block;
|
||||||
|
QDataStream out(&block, QIODevice::WriteOnly);
|
||||||
|
out.setVersion(QDataStream::Qt_4_0);
|
||||||
|
out << (quint64)0;
|
||||||
|
out.writeRawData((char*)buf.data(), buf.size());
|
||||||
|
out.device()->seek(0);
|
||||||
|
out << (quint64)(block.size() - sizeof(quint64));
|
||||||
|
(*iter)->write(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Paused...\n");
|
||||||
|
camera_.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImagesTcpServer::addClient()
|
||||||
|
{
|
||||||
|
QTcpSocket * client = this->nextPendingConnection();
|
||||||
|
connect(client, SIGNAL(disconnected()), client, SLOT(deleteLater()));
|
||||||
|
if(!camera_.isRunning())
|
||||||
|
{
|
||||||
|
printf("Start...\n");
|
||||||
|
camera_.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
34
imagesTcpServer/ImagesTcpServer.h
Normal file
34
imagesTcpServer/ImagesTcpServer.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* ImagesTcpServer.h
|
||||||
|
*
|
||||||
|
* Created on: 2014-05-21
|
||||||
|
* Author: mathieu
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TCPCLIENT_H_
|
||||||
|
#define TCPCLIENT_H_
|
||||||
|
|
||||||
|
#include "Camera.h"
|
||||||
|
#include <QtNetwork/QTcpServer>
|
||||||
|
|
||||||
|
class ImagesTcpServer : public QTcpServer
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ImagesTcpServer(float hz = 10.0f, quint16 port = 0, QObject * parent = 0);
|
||||||
|
|
||||||
|
QHostAddress getHostAddress() const;
|
||||||
|
quint16 getPort() const;
|
||||||
|
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void addClient();
|
||||||
|
void publishImage(const cv::Mat & image);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float hz_;
|
||||||
|
Camera camera_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* TCPCLIENT_H_ */
|
||||||
86
imagesTcpServer/main.cpp
Normal file
86
imagesTcpServer/main.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* main.cpp
|
||||||
|
*
|
||||||
|
* Created on: 2014-05-05
|
||||||
|
* Author: mathieu
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QtNetwork/QNetworkInterface>
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include "ImagesTcpServer.h"
|
||||||
|
|
||||||
|
void showUsage()
|
||||||
|
{
|
||||||
|
printf("imagesTcpServer [options]\n"
|
||||||
|
" Options:\n"
|
||||||
|
" -hz #.# Image rate (default 10 Hz).\n"
|
||||||
|
" -p # Set manually a port.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char * argv[])
|
||||||
|
{
|
||||||
|
QString ipAddress;
|
||||||
|
float hz = 10.0f;
|
||||||
|
quint16 port = 0;
|
||||||
|
|
||||||
|
for(int i=1; i<argc; ++i)
|
||||||
|
{
|
||||||
|
if(strcmp(argv[i], "-hz") == 0)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if(i < argc)
|
||||||
|
{
|
||||||
|
hz = std::atof(argv[i]);
|
||||||
|
if(hz < 0.0f)
|
||||||
|
{
|
||||||
|
printf("[ERROR] Image rate not valid : %s\n", argv[i]);
|
||||||
|
showUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
showUsage();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(strcmp(argv[i], "-p") == 0)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if(i < argc)
|
||||||
|
{
|
||||||
|
int v = std::atoi(argv[i]);
|
||||||
|
if(v < 0)
|
||||||
|
{
|
||||||
|
printf("[ERROR] Port not valid : %s\n", argv[i]);
|
||||||
|
showUsage();
|
||||||
|
}
|
||||||
|
port = v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
showUsage();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Unrecognized option: %s\n", argv[i]);
|
||||||
|
showUsage();
|
||||||
|
}
|
||||||
|
|
||||||
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
|
ImagesTcpServer server(hz, port);
|
||||||
|
|
||||||
|
if (!server.listen(QHostAddress::Any, port))
|
||||||
|
{
|
||||||
|
printf("ERROR: Unable to start the TCP server: %s\n", server.errorString().toStdString().c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Images server waiting on \"%s:%d\"...\n",
|
||||||
|
server.getHostAddress().toString().toStdString().c_str(), server.getPort());
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
|
||||||
182
src/Camera.cpp
182
src/Camera.cpp
@ -8,6 +8,76 @@
|
|||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include "utilite/UDirectory.h"
|
#include "utilite/UDirectory.h"
|
||||||
|
#include "QtOpenCV.h"
|
||||||
|
|
||||||
|
CameraTcpClient::CameraTcpClient(QObject *parent) :
|
||||||
|
QTcpSocket(parent),
|
||||||
|
blockSize_(0)
|
||||||
|
{
|
||||||
|
connect(this, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||||
|
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 = image_;
|
||||||
|
image_ = cv::Mat();
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraTcpClient::readData()
|
||||||
|
{
|
||||||
|
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_);
|
||||||
|
image_ = cv::imdecode(buf, cv::IMREAD_UNCHANGED);
|
||||||
|
blockSize_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraTcpClient::displayError(QAbstractSocket::SocketError socketError)
|
||||||
|
{
|
||||||
|
switch (socketError)
|
||||||
|
{
|
||||||
|
case QAbstractSocket::RemoteHostClosedError:
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::HostNotFoundError:
|
||||||
|
printf("[ERROR] CameraTcp: Tcp error: The host was not found. Please "
|
||||||
|
"check the host name and port settings.\n");
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::ConnectionRefusedError:
|
||||||
|
printf("[ERROR] 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.\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("The following error occurred: %s.\n", this->errorString().toStdString().c_str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraTcpClient::connectionLost()
|
||||||
|
{
|
||||||
|
printf("[WARNING] CameraTcp: Connection lost!\n");
|
||||||
|
}
|
||||||
|
|
||||||
Camera::Camera(QObject * parent) :
|
Camera::Camera(QObject * parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
@ -28,6 +98,7 @@ void Camera::stop()
|
|||||||
capture_.release();
|
capture_.release();
|
||||||
images_.clear();
|
images_.clear();
|
||||||
currentImageIndex_ = 0;
|
currentImageIndex_ = 0;
|
||||||
|
cameraTcpClient_.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::pause()
|
void Camera::pause()
|
||||||
@ -87,6 +158,21 @@ void Camera::takeImage()
|
|||||||
img = cv::imread(images_[currentImageIndex_++]);
|
img = cv::imread(images_[currentImageIndex_++]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
img = cameraTcpClient_.getImage();
|
||||||
|
while(img.empty() && cameraTcpClient_.waitForReadyRead())
|
||||||
|
{
|
||||||
|
img = cameraTcpClient_.getImage();
|
||||||
|
}
|
||||||
|
if(!cameraTcpClient_.waitForConnected())
|
||||||
|
{
|
||||||
|
printf("Connection is lost, try reconnecting to server (%s:%d)...\n",
|
||||||
|
Settings::getCamera_7IP().toStdString().c_str(),
|
||||||
|
Settings::getCamera_8port());
|
||||||
|
cameraTcpClient_.connectToHost(Settings::getCamera_7IP(), Settings::getCamera_8port());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(img.empty())
|
if(img.empty())
|
||||||
{
|
{
|
||||||
@ -117,62 +203,76 @@ void Camera::takeImage()
|
|||||||
|
|
||||||
bool Camera::start()
|
bool Camera::start()
|
||||||
{
|
{
|
||||||
if(!capture_.isOpened() && images_.empty())
|
if(!capture_.isOpened() && images_.empty() && !cameraTcpClient_.isOpen())
|
||||||
{
|
{
|
||||||
QString path = Settings::getCamera_5mediaPath();
|
if(Settings::getCamera_6useTcpCamera())
|
||||||
if(UDirectory::exists(path.toStdString()))
|
|
||||||
{
|
{
|
||||||
//Images directory
|
cameraTcpClient_.connectToHost(Settings::getCamera_7IP(), Settings::getCamera_8port());
|
||||||
QString ext = Settings::getGeneral_imageFormats();
|
if(!cameraTcpClient_.waitForConnected())
|
||||||
ext.remove('*');
|
|
||||||
ext.remove('.');
|
|
||||||
UDirectory dir(path.toStdString(), ext.toStdString()); // this will load fileNames matching the extensions (in natural order)
|
|
||||||
const std::list<std::string> & fileNames = dir.getFileNames();
|
|
||||||
currentImageIndex_ = 0;
|
|
||||||
images_.clear();
|
|
||||||
// Modify to have full path
|
|
||||||
for(std::list<std::string>::const_iterator iter = fileNames.begin(); iter!=fileNames.end(); ++iter)
|
|
||||||
{
|
{
|
||||||
images_.append(path.toStdString() + UDirectory::separator() + *iter);
|
printf("[WARNING] Camera: Cannot connect to server \"%s:%d\"\n",
|
||||||
}
|
Settings::getCamera_7IP().toStdString().c_str(),
|
||||||
printf("Camera: Reading %d images from directory \"%s\"...\n", (int)images_.size(), path.toStdString().c_str());
|
Settings::getCamera_8port());
|
||||||
if(images_.isEmpty())
|
cameraTcpClient_.close();
|
||||||
{
|
|
||||||
printf("[WARNING] Directory \"%s\" is empty (no images matching the \"%s\" extensions). "
|
|
||||||
"If you want to disable loading automatically this directory, "
|
|
||||||
"clear the Camera/mediaPath parameter. By default, webcam will be used instead of the directory.\n",
|
|
||||||
path.toStdString().c_str(),
|
|
||||||
ext.toStdString().c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!path.isEmpty())
|
else
|
||||||
{
|
{
|
||||||
//Video file
|
QString path = Settings::getCamera_5mediaPath();
|
||||||
capture_.open(path.toStdString().c_str());
|
if(UDirectory::exists(path.toStdString()))
|
||||||
if(!capture_.isOpened())
|
|
||||||
{
|
{
|
||||||
printf("[WARNING] Cannot open file \"%s\". If you want to disable loading automatically this video file, clear the Camera/mediaPath parameter. By default, webcam will be used instead of the file.\n", path.toStdString().c_str());
|
//Images directory
|
||||||
|
QString ext = Settings::getGeneral_imageFormats();
|
||||||
|
ext.remove('*');
|
||||||
|
ext.remove('.');
|
||||||
|
UDirectory dir(path.toStdString(), ext.toStdString()); // this will load fileNames matching the extensions (in natural order)
|
||||||
|
const std::list<std::string> & fileNames = dir.getFileNames();
|
||||||
|
currentImageIndex_ = 0;
|
||||||
|
images_.clear();
|
||||||
|
// Modify to have full path
|
||||||
|
for(std::list<std::string>::const_iterator iter = fileNames.begin(); iter!=fileNames.end(); ++iter)
|
||||||
|
{
|
||||||
|
images_.append(path.toStdString() + UDirectory::separator() + *iter);
|
||||||
|
}
|
||||||
|
printf("Camera: Reading %d images from directory \"%s\"...\n", (int)images_.size(), path.toStdString().c_str());
|
||||||
|
if(images_.isEmpty())
|
||||||
|
{
|
||||||
|
printf("[WARNING] Camera: Directory \"%s\" is empty (no images matching the \"%s\" extensions). "
|
||||||
|
"If you want to disable loading automatically this directory, "
|
||||||
|
"clear the Camera/mediaPath parameter. By default, webcam will be used instead of the directory.\n",
|
||||||
|
path.toStdString().c_str(),
|
||||||
|
ext.toStdString().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else if(!path.isEmpty())
|
||||||
{
|
{
|
||||||
printf("Camera: Reading from video file \"%s\"...\n", path.toStdString().c_str());
|
//Video file
|
||||||
|
capture_.open(path.toStdString().c_str());
|
||||||
|
if(!capture_.isOpened())
|
||||||
|
{
|
||||||
|
printf("[WARNING] Camera: Cannot open file \"%s\". If you want to disable loading automatically this video file, clear the Camera/mediaPath parameter. By default, webcam will be used instead of the file.\n", path.toStdString().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Camera: Reading from video file \"%s\"...\n", path.toStdString().c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if(!capture_.isOpened() && images_.empty())
|
||||||
if(!capture_.isOpened() && images_.empty())
|
|
||||||
{
|
|
||||||
//set camera device
|
|
||||||
capture_.open(Settings::getCamera_1deviceId());
|
|
||||||
if(Settings::getCamera_2imageWidth() && Settings::getCamera_3imageHeight())
|
|
||||||
{
|
{
|
||||||
capture_.set(CV_CAP_PROP_FRAME_WIDTH, double(Settings::getCamera_2imageWidth()));
|
//set camera device
|
||||||
capture_.set(CV_CAP_PROP_FRAME_HEIGHT, double(Settings::getCamera_3imageHeight()));
|
capture_.open(Settings::getCamera_1deviceId());
|
||||||
|
if(Settings::getCamera_2imageWidth() && Settings::getCamera_3imageHeight())
|
||||||
|
{
|
||||||
|
capture_.set(CV_CAP_PROP_FRAME_WIDTH, double(Settings::getCamera_2imageWidth()));
|
||||||
|
capture_.set(CV_CAP_PROP_FRAME_HEIGHT, double(Settings::getCamera_3imageHeight()));
|
||||||
|
}
|
||||||
|
printf("Camera: Reading from camera device %d...\n", Settings::getCamera_1deviceId());
|
||||||
}
|
}
|
||||||
printf("Camera: Reading from camera device %d...\n", Settings::getCamera_1deviceId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!capture_.isOpened() && images_.empty())
|
if(!capture_.isOpened() && images_.empty() && !cameraTcpClient_.isOpen())
|
||||||
{
|
{
|
||||||
printf("[ERROR] Failed to open a capture object!\n");
|
printf("[ERROR] Camera: Failed to open a capture object!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
src/Camera.h
22
src/Camera.h
@ -8,6 +8,27 @@
|
|||||||
#include <opencv2/highgui/highgui.hpp>
|
#include <opencv2/highgui/highgui.hpp>
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
|
#include <QtGui/QImage>
|
||||||
|
#include <QtNetwork/QTcpSocket>
|
||||||
|
|
||||||
|
class CameraTcpClient : public QTcpSocket
|
||||||
|
{
|
||||||
|
Q_OBJECT;
|
||||||
|
public:
|
||||||
|
CameraTcpClient(QObject * parent = 0);
|
||||||
|
cv::Mat getImage();
|
||||||
|
bool isConnected() const {return connected_;}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void readData();
|
||||||
|
void displayError(QAbstractSocket::SocketError socketError);
|
||||||
|
void connectionLost();
|
||||||
|
|
||||||
|
private:
|
||||||
|
quint64 blockSize_;
|
||||||
|
cv::Mat image_;
|
||||||
|
bool connected_;
|
||||||
|
};
|
||||||
|
|
||||||
class Camera : public QObject {
|
class Camera : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -40,6 +61,7 @@ private:
|
|||||||
QTimer cameraTimer_;
|
QTimer cameraTimer_;
|
||||||
QList<std::string> images_;
|
QList<std::string> images_;
|
||||||
unsigned int currentImageIndex_;
|
unsigned int currentImageIndex_;
|
||||||
|
CameraTcpClient cameraTcpClient_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* CAMERA_H_ */
|
#endif /* CAMERA_H_ */
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
#include <QtGui/QCloseEvent>
|
#include <QtGui/QCloseEvent>
|
||||||
#include <QtGui/QCheckBox>
|
#include <QtGui/QCheckBox>
|
||||||
#include <QtGui/QScrollBar>
|
#include <QtGui/QScrollBar>
|
||||||
|
#include <QtGui/QInputDialog>
|
||||||
|
|
||||||
#include "utilite/UDirectory.h"
|
#include "utilite/UDirectory.h"
|
||||||
|
|
||||||
@ -136,6 +137,7 @@ MainWindow::MainWindow(Camera * camera, const QString & settings, QWidget * pare
|
|||||||
connect(ui_->actionLoad_objects, SIGNAL(triggered()), this, SLOT(loadObjects()));
|
connect(ui_->actionLoad_objects, SIGNAL(triggered()), this, SLOT(loadObjects()));
|
||||||
connect(ui_->actionCamera_from_video_file, SIGNAL(triggered()), this, SLOT(setupCameraFromVideoFile()));
|
connect(ui_->actionCamera_from_video_file, SIGNAL(triggered()), this, SLOT(setupCameraFromVideoFile()));
|
||||||
connect(ui_->actionCamera_from_directory_of_images, SIGNAL(triggered()), this, SLOT(setupCameraFromImagesDirectory()));
|
connect(ui_->actionCamera_from_directory_of_images, SIGNAL(triggered()), this, SLOT(setupCameraFromImagesDirectory()));
|
||||||
|
connect(ui_->actionCamera_from_TCP_IP, SIGNAL(triggered()), this, SLOT(setupCameraFromTcpIp()));
|
||||||
connect(ui_->actionAbout, SIGNAL(triggered()), aboutDialog_ , SLOT(exec()));
|
connect(ui_->actionAbout, SIGNAL(triggered()), aboutDialog_ , SLOT(exec()));
|
||||||
connect(ui_->actionRestore_all_default_settings, SIGNAL(triggered()), ui_->toolBox, SLOT(resetAllPages()));
|
connect(ui_->actionRestore_all_default_settings, SIGNAL(triggered()), ui_->toolBox, SLOT(resetAllPages()));
|
||||||
connect(ui_->actionRemove_all_objects, SIGNAL(triggered()), this, SLOT(removeAllObjects()));
|
connect(ui_->actionRemove_all_objects, SIGNAL(triggered()), this, SLOT(removeAllObjects()));
|
||||||
@ -149,7 +151,7 @@ MainWindow::MainWindow(Camera * camera, const QString & settings, QWidget * pare
|
|||||||
connect(ui_->horizontalSlider_frames, SIGNAL(valueChanged(int)), ui_->label_frame, SLOT(setNum(int)));
|
connect(ui_->horizontalSlider_frames, SIGNAL(valueChanged(int)), ui_->label_frame, SLOT(setNum(int)));
|
||||||
ui_->pushButton_play->setVisible(true);
|
ui_->pushButton_play->setVisible(true);
|
||||||
ui_->pushButton_pause->setVisible(false);
|
ui_->pushButton_pause->setVisible(false);
|
||||||
ui_->pushButton_stop->setEnabled(true);
|
ui_->pushButton_stop->setEnabled(false);
|
||||||
ui_->horizontalSlider_frames->setEnabled(false);
|
ui_->horizontalSlider_frames->setEnabled(false);
|
||||||
ui_->label_frame->setVisible(false);
|
ui_->label_frame->setVisible(false);
|
||||||
|
|
||||||
@ -162,6 +164,7 @@ MainWindow::MainWindow(Camera * camera, const QString & settings, QWidget * pare
|
|||||||
|
|
||||||
ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
|
ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
|
||||||
ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
|
ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
|
||||||
|
ui_->actionCamera_from_TCP_IP->setChecked(Settings::getCamera_6useTcpCamera());
|
||||||
|
|
||||||
ui_->label_ipAddress->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
ui_->label_ipAddress->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||||
ui_->label_port->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
ui_->label_port->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||||
@ -554,6 +557,7 @@ void MainWindow::setupCameraFromVideoFile()
|
|||||||
}
|
}
|
||||||
ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty());
|
ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty());
|
||||||
ui_->actionCamera_from_directory_of_images->setChecked(false);
|
ui_->actionCamera_from_directory_of_images->setChecked(false);
|
||||||
|
ui_->actionCamera_from_TCP_IP->setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupCameraFromImagesDirectory()
|
void MainWindow::setupCameraFromImagesDirectory()
|
||||||
@ -581,6 +585,42 @@ void MainWindow::setupCameraFromImagesDirectory()
|
|||||||
}
|
}
|
||||||
ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty());
|
ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty());
|
||||||
ui_->actionCamera_from_video_file->setChecked(false);
|
ui_->actionCamera_from_video_file->setChecked(false);
|
||||||
|
ui_->actionCamera_from_TCP_IP->setChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::setupCameraFromTcpIp()
|
||||||
|
{
|
||||||
|
if(!ui_->actionCamera_from_TCP_IP->isChecked())
|
||||||
|
{
|
||||||
|
Settings::setCamera_6useTcpCamera(false);
|
||||||
|
ui_->toolBox->updateParameter(Settings::kCamera_6useTcpCamera());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString ip = QInputDialog::getText(this, tr("Server IP..."), "IP: ", QLineEdit::Normal, Settings::getCamera_7IP());
|
||||||
|
if(!ip.isEmpty())
|
||||||
|
{
|
||||||
|
int port = QInputDialog::getInteger(this, tr("Server port..."), "Port: ", Settings::getCamera_8port());
|
||||||
|
|
||||||
|
if(port > 0)
|
||||||
|
{
|
||||||
|
Settings::setCamera_6useTcpCamera(true);
|
||||||
|
ui_->toolBox->updateParameter(Settings::kCamera_6useTcpCamera());
|
||||||
|
Settings::setCamera_7IP(ip);
|
||||||
|
ui_->toolBox->updateParameter(Settings::kCamera_7IP());
|
||||||
|
Settings::setCamera_8port(port);
|
||||||
|
ui_->toolBox->updateParameter(Settings::kCamera_8port());
|
||||||
|
if(camera_->isRunning())
|
||||||
|
{
|
||||||
|
this->stopProcessing();
|
||||||
|
}
|
||||||
|
this->startProcessing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui_->actionCamera_from_directory_of_images->setChecked(false);
|
||||||
|
ui_->actionCamera_from_video_file->setChecked(false);
|
||||||
|
ui_->actionCamera_from_TCP_IP->setChecked(Settings::getCamera_6useTcpCamera());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showObject(ObjWidget * obj)
|
void MainWindow::showObject(ObjWidget * obj)
|
||||||
@ -936,6 +976,7 @@ void MainWindow::startProcessing()
|
|||||||
ui_->actionLoad_scene_from_file->setEnabled(false);
|
ui_->actionLoad_scene_from_file->setEnabled(false);
|
||||||
ui_->actionCamera_from_directory_of_images->setEnabled(false);
|
ui_->actionCamera_from_directory_of_images->setEnabled(false);
|
||||||
ui_->actionCamera_from_video_file->setEnabled(false);
|
ui_->actionCamera_from_video_file->setEnabled(false);
|
||||||
|
ui_->actionCamera_from_TCP_IP->setEnabled(false);
|
||||||
ui_->label_timeRefreshRate->setVisible(true);
|
ui_->label_timeRefreshRate->setVisible(true);
|
||||||
|
|
||||||
//update control bar
|
//update control bar
|
||||||
@ -963,7 +1004,14 @@ void MainWindow::startProcessing()
|
|||||||
}
|
}
|
||||||
if(this->isVisible())
|
if(this->isVisible())
|
||||||
{
|
{
|
||||||
QMessageBox::critical(this, tr("Camera error"), tr("Camera initialization failed! (with device %1)").arg(Settings::getCamera_1deviceId()));
|
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()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Camera error"), tr("Camera initialization failed! (with device %1)").arg(Settings::getCamera_1deviceId()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -985,6 +1033,7 @@ void MainWindow::stopProcessing()
|
|||||||
ui_->actionLoad_scene_from_file->setEnabled(true);
|
ui_->actionLoad_scene_from_file->setEnabled(true);
|
||||||
ui_->actionCamera_from_directory_of_images->setEnabled(true);
|
ui_->actionCamera_from_directory_of_images->setEnabled(true);
|
||||||
ui_->actionCamera_from_video_file->setEnabled(true);
|
ui_->actionCamera_from_video_file->setEnabled(true);
|
||||||
|
ui_->actionCamera_from_TCP_IP->setEnabled(true);
|
||||||
ui_->pushButton_play->setVisible(true);
|
ui_->pushButton_play->setVisible(true);
|
||||||
ui_->pushButton_pause->setVisible(false);
|
ui_->pushButton_pause->setVisible(false);
|
||||||
ui_->pushButton_stop->setEnabled(false);
|
ui_->pushButton_stop->setEnabled(false);
|
||||||
@ -1655,22 +1704,24 @@ void MainWindow::update(const cv::Mat & image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit homographies
|
// Emit homographies
|
||||||
if(objectsDetected.size())
|
if(objectsDetected.size() > 1)
|
||||||
{
|
{
|
||||||
if(objectsDetected.size() > 1)
|
printf("(%s) %d objects detected!\n",
|
||||||
{
|
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
||||||
printf("(%s) %d objects detected!\n",
|
(int)objectsDetected.size());
|
||||||
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
|
||||||
(int)objectsDetected.size());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("(%s) Object %d detected!\n",
|
|
||||||
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
|
||||||
(int)objectsDetected.begin().key());
|
|
||||||
}
|
|
||||||
emit objectsFound(objectsDetected);
|
|
||||||
}
|
}
|
||||||
|
else if(objectsDetected.size() == 1)
|
||||||
|
{
|
||||||
|
printf("(%s) Object %d detected!\n",
|
||||||
|
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str(),
|
||||||
|
(int)objectsDetected.begin().key());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("(%s) No objects detected.\n",
|
||||||
|
QTime::currentTime().toString("HH:mm:ss.zzz").toStdString().c_str());
|
||||||
|
}
|
||||||
|
emit objectsFound(objectsDetected);
|
||||||
ui_->label_objectsDetected->setNum(objectsDetected.size());
|
ui_->label_objectsDetected->setNum(objectsDetected.size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1740,7 +1791,7 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
|
|||||||
bool nearestNeighborParamsChanged = false;
|
bool nearestNeighborParamsChanged = false;
|
||||||
for(QStringList::const_iterator iter = paramChanged.begin(); iter!=paramChanged.end(); ++iter)
|
for(QStringList::const_iterator iter = paramChanged.begin(); iter!=paramChanged.end(); ++iter)
|
||||||
{
|
{
|
||||||
printf("Parameter changed: %s\n", iter->toStdString().c_str());
|
printf("Parameter changed: %s -> \"%s\"\n", iter->toStdString().c_str(), Settings::getParameter(*iter).toString().toStdString().c_str());
|
||||||
if(lastObjectsUpdateParameters_.value(*iter) != Settings::getParameter(*iter))
|
if(lastObjectsUpdateParameters_.value(*iter) != Settings::getParameter(*iter))
|
||||||
{
|
{
|
||||||
if(!detectorDescriptorParamsChanged && iter->contains("Feature2D"))
|
if(!detectorDescriptorParamsChanged && iter->contains("Feature2D"))
|
||||||
@ -1788,5 +1839,5 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
|
|||||||
|
|
||||||
ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
|
ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
|
||||||
ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
|
ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
|
||||||
|
ui_->actionCamera_from_TCP_IP->setChecked(Settings::getCamera_6useTcpCamera());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,6 +66,7 @@ private slots:
|
|||||||
void loadSceneFromFile();
|
void loadSceneFromFile();
|
||||||
void setupCameraFromVideoFile();
|
void setupCameraFromVideoFile();
|
||||||
void setupCameraFromImagesDirectory();
|
void setupCameraFromImagesDirectory();
|
||||||
|
void setupCameraFromTcpIp();
|
||||||
void removeObject(ObjWidget * object);
|
void removeObject(ObjWidget * object);
|
||||||
void removeAllObjects();
|
void removeAllObjects();
|
||||||
void updateObjectsSize();
|
void updateObjectsSize();
|
||||||
|
|||||||
@ -39,7 +39,6 @@ cv::Mat cvtQImage2CvMat(const QImage & image)
|
|||||||
cvImage = cv::Mat(image.height(), image.width(), CV_8UC3);
|
cvImage = cv::Mat(image.height(), image.width(), CV_8UC3);
|
||||||
unsigned char * data = cvImage.data;
|
unsigned char * data = cvImage.data;
|
||||||
const IplImage test = cvImage;
|
const IplImage test = cvImage;
|
||||||
printf("%d vs %d\n", cvImage.cols*int(cvImage.elemSize()), test.widthStep);
|
|
||||||
for(int y = 0; y < image.height(); ++y, data+=cvImage.cols*cvImage.elemSize())
|
for(int y = 0; y < image.height(); ++y, data+=cvImage.cols*cvImage.elemSize())
|
||||||
{
|
{
|
||||||
for(int x = 0; x < image.width(); ++x)
|
for(int x = 0; x < image.width(); ++x)
|
||||||
|
|||||||
@ -60,6 +60,9 @@ class Settings
|
|||||||
PARAMETER(Camera, 3imageHeight, int, 480, "Image height (0 means default height from camera).");
|
PARAMETER(Camera, 3imageHeight, int, 480, "Image height (0 means default height from camera).");
|
||||||
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, 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 to connect when useTcpCamera is checked.");
|
||||||
|
|
||||||
//List format : [Index:item0;item1;item3;...]
|
//List format : [Index:item0;item1;item3;...]
|
||||||
PARAMETER(Feature2D, 1Detector, QString, "7:Dense;Fast;GFTT;MSER;ORB;SIFT;Star;SURF;BRISK" , "Keypoint detector.");
|
PARAMETER(Feature2D, 1Detector, QString, "7:Dense;Fast;GFTT;MSER;ORB;SIFT;Star;SURF;BRISK" , "Keypoint detector.");
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>826</width>
|
<width>826</width>
|
||||||
<height>689</height>
|
<height>713</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -228,6 +228,7 @@
|
|||||||
<addaction name="actionLoad_scene_from_file"/>
|
<addaction name="actionLoad_scene_from_file"/>
|
||||||
<addaction name="actionCamera_from_directory_of_images"/>
|
<addaction name="actionCamera_from_directory_of_images"/>
|
||||||
<addaction name="actionCamera_from_video_file"/>
|
<addaction name="actionCamera_from_video_file"/>
|
||||||
|
<addaction name="actionCamera_from_TCP_IP"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionStart_camera"/>
|
<addaction name="actionStart_camera"/>
|
||||||
<addaction name="actionPause_camera"/>
|
<addaction name="actionPause_camera"/>
|
||||||
@ -346,7 +347,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>198</width>
|
<width>198</width>
|
||||||
<height>559</height>
|
<height>583</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_objects">
|
<layout class="QVBoxLayout" name="verticalLayout_objects">
|
||||||
@ -764,6 +765,14 @@
|
|||||||
<string>Load settings...</string>
|
<string>Load settings...</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionCamera_from_TCP_IP">
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Camera from TCP/IP...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user