Added tcpService tool to Add/Remove objects through TCP

git-svn-id: http://find-object.googlecode.com/svn/trunk/find_object@420 620bd6b2-0a58-f614-fd9a-1bd335dccda9
This commit is contained in:
matlabbe
2015-01-12 01:19:09 +00:00
parent 5d1f30cc09
commit 82f953b911
10 changed files with 546 additions and 63 deletions
+72 -23
View File
@@ -46,7 +46,8 @@ FindObject::FindObject(QObject * parent) :
QObject(parent),
vocabulary_(new Vocabulary()),
detector_(Settings::createKeypointDetector()),
extractor_(Settings::createDescriptorExtractor())
extractor_(Settings::createDescriptorExtractor()),
sessionModified_(false)
{
qRegisterMetaType<find_object::DetectionInfo>("find_object::DetectionInfo");
UASSERT(detector_ != 0 && extractor_ != 0);
@@ -101,7 +102,7 @@ bool FindObject::loadSession(const QString & path)
// this will fill objectsDescriptors_ matrix
updateVocabulary();
}
sessionModified_ = false;
return true;
}
else
@@ -111,7 +112,7 @@ bool FindObject::loadSession(const QString & path)
return false;
}
bool FindObject::saveSession(const QString & path) const
bool FindObject::saveSession(const QString & path)
{
if(!path.isEmpty() && QFileInfo(path).suffix().compare("bin") == 0)
{
@@ -132,6 +133,7 @@ bool FindObject::saveSession(const QString & path) const
}
file.close();
sessionModified_ = false;
return true;
}
UERROR("Path \"%s\" not valid (should be *.bin)", path.toStdString().c_str());
@@ -243,6 +245,28 @@ void FindObject::removeAllObjects()
clearVocabulary();
}
void FindObject::addObjectAndUpdate(const cv::Mat & image, int id, const QString & filename)
{
const ObjSignature * s = this->addObject(image, id, filename);
if(s)
{
QList<int> ids;
ids.push_back(s->id());
updateObjects(ids);
updateVocabulary();
}
}
void FindObject::removeObjectAndUpdate(int id)
{
if(objects_.contains(id))
{
delete objects_.value(id);
objects_.remove(id);
}
updateVocabulary();
}
void FindObject::updateDetectorExtractor()
{
delete detector_;
@@ -561,39 +585,63 @@ private:
int timeExtraction_;
};
void FindObject::updateObjects()
void FindObject::updateObjects(const QList<int> & ids)
{
if(objects_.size())
QList<ObjSignature*> objectsList;
if(ids.size())
{
for(int i=0; i<ids.size(); ++i)
{
if(objects_.contains(ids[i]))
{
objectsList.push_back(objects_[ids[i]]);
}
else
{
UERROR("Not found object %d!", ids[i]);
}
}
}
else
{
objectsList = objects_.values();
}
if(objectsList.size())
{
sessionModified_ = true;
int threadCounts = Settings::getGeneral_threads();
if(threadCounts == 0)
{
threadCounts = objects_.size();
threadCounts = objectsList.size();
}
QTime time;
time.start();
UINFO("Features extraction from %d objects...", objects_.size());
QList<ObjSignature*> objectsList = objects_.values();
for(int i=0; i<objectsList.size(); i+=threadCounts)
if(objectsList.size())
{
QVector<ExtractFeaturesThread*> threads;
for(int k=i; k<i+threadCounts && k<objectsList.size(); ++k)
UINFO("Features extraction from %d objects...", objectsList.size());
for(int i=0; i<objectsList.size(); i+=threadCounts)
{
threads.push_back(new ExtractFeaturesThread(detector_, extractor_, objectsList.at(k)->id(), objectsList.at(k)->image()));
threads.back()->start();
}
for(int j=0; j<threads.size(); ++j)
{
threads[j]->wait();
int id = threads[j]->objectId();
objects_.value(id)->setData(threads[j]->keypoints(), threads[j]->descriptors());
QVector<ExtractFeaturesThread*> threads;
for(int k=i; k<i+threadCounts && k<objectsList.size(); ++k)
{
threads.push_back(new ExtractFeaturesThread(detector_, extractor_, objectsList.at(k)->id(), objectsList.at(k)->image()));
threads.back()->start();
}
for(int j=0; j<threads.size(); ++j)
{
threads[j]->wait();
int id = threads[j]->objectId();
objects_.value(id)->setData(threads[j]->keypoints(), threads[j]->descriptors());
}
}
UINFO("Features extraction from %d objects... done! (%d ms)", objectsList.size(), time.elapsed());
}
UINFO("Features extraction from %d objects... done! (%d ms)", objects_.size(), time.elapsed());
}
else
{
@@ -667,6 +715,7 @@ void FindObject::updateVocabulary()
if(Settings::getGeneral_invertedSearch())
{
sessionModified_ = true;
QTime time;
time.start();
bool incremental = Settings::getGeneral_vocabularyIncremental();
+95 -35
View File
@@ -311,6 +311,10 @@ void MainWindow::setupTCPServer()
ui_->label_ipAddress->setText(tcpServer_->getHostAddress().toString());
ui_->label_port->setNum(tcpServer_->getPort());
UINFO("Detection sent on port: %d (IP=%s)", tcpServer_->getPort(), tcpServer_->getHostAddress().toString().toStdString().c_str());
//connect services
connect(tcpServer_, SIGNAL(addObject(const cv::Mat &, int, const QString &)), this, SLOT(addObjectFromTcp(const cv::Mat &, int, const QString &)));
connect(tcpServer_, SIGNAL(removeObject(int)), this, SLOT(removeObject(int)));
}
void MainWindow::setSourceImageText(const QString & text)
@@ -459,7 +463,7 @@ bool MainWindow::saveSettings(const QString & path) const
int MainWindow::loadObjects(const QString & dirPath)
{
int loadedObjects = 0;
QList<int> loadedObjects;
QString formats = Settings::getGeneral_imageFormats().remove('*').remove('.');
UDirectory dir(dirPath.toStdString(), formats.toStdString());
if(dir.isValid())
@@ -467,17 +471,18 @@ int MainWindow::loadObjects(const QString & dirPath)
const std::list<std::string> & names = dir.getFileNames(); // sorted in natural order
for(std::list<std::string>::const_iterator iter=names.begin(); iter!=names.end(); ++iter)
{
if(this->addObjectFromFile((dirPath.toStdString()+dir.separator()+*iter).c_str()))
int id = this->addObjectFromFile((dirPath.toStdString()+dir.separator()+*iter).c_str());
if(id >= 0)
{
++loadedObjects;
loadedObjects.push_back(id);
}
}
if(loadedObjects)
if(loadedObjects.size())
{
this->updateObjects();
this->updateObjects(loadedObjects);
}
}
return loadedObjects;
return loadedObjects.size();
}
int MainWindow::saveObjects(const QString & dirPath)
@@ -560,6 +565,18 @@ void MainWindow::removeObject(find_object::ObjWidget * object)
}
}
void MainWindow::removeObject(int id)
{
if(objWidgets_.contains(id))
{
removeObject(objWidgets_[id]);
}
else
{
UERROR("Remove object: Object %d not found!", id);
}
}
void MainWindow::removeAllObjects()
{
qDeleteAll(objWidgets_);
@@ -677,12 +694,20 @@ void MainWindow::addObjectsFromFiles(const QStringList & fileNames)
{
if(fileNames.size())
{
QList<int> ids;
for(int i=0; i<fileNames.size(); ++i)
{
this->addObjectFromFile(fileNames.at(i));
int id = this->addObjectFromFile(fileNames.at(i));
if(id >= 0)
{
ids.push_back(id);
}
}
if(ids.size())
{
objectsModified_ = true;
updateObjects(ids);
}
objectsModified_ = true;
updateObjects();
}
}
@@ -691,7 +716,7 @@ void MainWindow::addObjectsFromFiles()
addObjectsFromFiles(QFileDialog::getOpenFileNames(this, tr("Add objects..."), Settings::workingDirectory(), tr("Image Files (%1)").arg(Settings::getGeneral_imageFormats())));
}
bool MainWindow::addObjectFromFile(const QString & filePath)
int MainWindow::addObjectFromFile(const QString & filePath)
{
const ObjSignature * s = findObject_->addObject(filePath);
if(s)
@@ -701,12 +726,36 @@ bool MainWindow::addObjectFromFile(const QString & filePath)
ui_->actionSave_objects->setEnabled(true);
ui_->actionSave_session->setEnabled(true);
this->showObject(obj);
return true;
return s->id();
}
else
{
QMessageBox::critical(this, tr("Error adding object"), tr("Failed to add object from \"%1\"").arg(filePath));
return false;
return -1;
}
}
void MainWindow::addObjectFromTcp(const cv::Mat & image, int id, const QString & filePath)
{
if(objWidgets_.contains(id))
{
UERROR("Add Object: Object %d is already added.", id);
}
const ObjSignature * s = findObject_->addObject(image, id, filePath);
if(s)
{
ObjWidget * obj = new ObjWidget(s->id(), std::vector<cv::KeyPoint>(), cvtCvMat2QImage(s->image()));
objWidgets_.insert(obj->id(), obj);
ui_->actionSave_objects->setEnabled(true);
ui_->actionSave_session->setEnabled(true);
this->showObject(obj);
QList<int> ids;
ids.push_back(obj->id());
updateObjects(ids);
}
else
{
UERROR("Add Object: Error adding object %d.", id);
}
}
@@ -883,30 +932,41 @@ void MainWindow::showObject(ObjWidget * obj)
}
}
void MainWindow::updateObjects(const QList<int> & ids)
{
if(ids.size())
{
this->statusBar()->showMessage(tr("Updating %1 objects...").arg(ids.size()));
QApplication::processEvents();
findObject_->updateObjects(ids);
updateVocabulary();
QList<ObjSignature*> signatures = findObject_->objects().values();
for(int i=0; i<signatures.size(); ++i)
{
if(ids.contains(signatures[i]->id()))
{
objWidgets_.value(signatures[i]->id())->setData(signatures[i]->keypoints(), cvtCvMat2QImage(signatures[i]->image()));
//update object labels
QLabel * title = qFindChild<QLabel*>(this, QString("%1title").arg(signatures[i]->id()));
title->setText(QString("%1 (%2)").arg(signatures[i]->id()).arg(QString::number(signatures[i]->keypoints().size())));
}
}
if(!camera_->isRunning() && !sceneImage_.empty())
{
this->update(sceneImage_);
}
this->statusBar()->clearMessage();
}
}
void MainWindow::updateObjects()
{
this->statusBar()->showMessage(tr("Updating %1 objects...").arg(findObject_->objects().size()));
QApplication::processEvents();
findObject_->updateObjects();
updateVocabulary();
QList<ObjSignature*> signatures = findObject_->objects().values();
for(int i=0; i<signatures.size(); ++i)
{
objWidgets_.value(signatures[i]->id())->setData(signatures[i]->keypoints(), cvtCvMat2QImage(signatures[i]->image()));
//update object labels
QLabel * title = qFindChild<QLabel*>(this, QString("%1title").arg(signatures[i]->id()));
title->setText(QString("%1 (%2)").arg(signatures[i]->id()).arg(QString::number(signatures[i]->keypoints().size())));
}
if(!camera_->isRunning() && !sceneImage_.empty())
{
this->update(sceneImage_);
}
this->statusBar()->clearMessage();
updateObjects(objWidgets_.keys());
}
void MainWindow::updateVocabulary()
@@ -1374,7 +1434,7 @@ void MainWindow::notifyParametersChanged(const QStringList & paramChanged)
{
if(detectorDescriptorParamsChanged)
{
this->updateObjects();
this->updateObjects(objWidgets_.keys());
}
else if(nearestNeighborParamsChanged)
{
+96 -2
View File
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QtNetwork/QNetworkInterface>
#include <QtNetwork/QTcpSocket>
#include <QtGui/QTransform>
#include <opencv2/highgui/highgui.hpp>
namespace find_object {
@@ -98,8 +99,101 @@ void TcpServer::publishDetectionInfo(const DetectionInfo & info)
void TcpServer::addClient()
{
QTcpSocket * client = this->nextPendingConnection();
connect(client, SIGNAL(disconnected()), client, SLOT(deleteLater()));
while(this->hasPendingConnections())
{
QTcpSocket * client = this->nextPendingConnection();
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 TcpServer::readReceivedData()
{
QTcpSocket * client = (QTcpSocket*)sender();
QDataStream in(client);
in.setVersion(QDataStream::Qt_4_0);
if (blockSizes_.value(client->socketDescriptor(), 0) == 0)
{
if (client->bytesAvailable() < (int)sizeof(quint64))
{
return;
}
in >> blockSizes_[client->socketDescriptor()];
}
if (client->bytesAvailable() < (int)blockSizes_[client->socketDescriptor()])
{
return;
}
quint32 serviceType;
in >> serviceType;
bool ok = true;
if(serviceType == kAddObject)
{
int id;
in >> id;
QString fileName;
in >> fileName;
quint64 imageSize;
in >> imageSize;
std::vector<unsigned char> buf(imageSize);
in.readRawData((char*)buf.data(), imageSize);
cv::Mat image = cv::imdecode(buf, cv::IMREAD_UNCHANGED);
UINFO("TCP service: Add %d \"%s\"", id, fileName.toStdString().c_str());
Q_EMIT addObject(image, id, fileName);
}
else if(serviceType == kRemoveObject)
{
int id;
in >> id;
UINFO("TCP service: Remove %d", id);
Q_EMIT removeObject(id);
}
else
{
UERROR("Unknown service type called %d", serviceType);
ok = false;
}
blockSizes_.remove(client->socketDescriptor());
client->write(QByteArray(ok?"1":"0")); // send acknowledge
}
void TcpServer::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 TcpServer::connectionLost()
{
//printf("[WARNING] CameraTcp: Connection lost!\n");
blockSizes_.remove(((QTcpSocket*)sender())->socketDescriptor());
((QTcpSocket*)sender())->close();
sender()->deleteLater();
}
} // namespace find_object