38 #include "ui_mainWindow.h" 50 #include "opencv2/calib3d/calib3d.hpp" 51 #include "opencv2/imgproc/imgproc.hpp" 52 #include <opencv2/opencv_modules.hpp> 53 #if CV_MAJOR_VERSION < 3 54 #include <opencv2/gpu/gpu.hpp> 56 #include <opencv2/core/cuda.hpp> 59 #include <QtCore/QTextStream> 60 #include <QtCore/QFile> 61 #include <QtCore/QBuffer> 62 #include <QtCore/QThread> 63 #include <QtCore/QLineF> 65 #include <QFileDialog> 66 #include <QMessageBox> 67 #include <QGraphicsScene> 68 #include <QGraphicsRectItem> 71 #include <QProgressDialog> 72 #include <QCloseEvent> 75 #include <QInputDialog> 85 findObject_(findObject),
88 lowestRefreshRate_(99),
89 objectsModified_(false),
94 ui_ =
new Ui_mainWindow();
97 this->setStatusBar(
new QStatusBar());
105 ui_->likelihoodPlot->setGraphicsView(
true);
107 ui_->dockWidget_statistics->setVisible(
false);
108 ui_->dockWidget_parameters->setVisible(
false);
109 ui_->dockWidget_plot->setVisible(
false);
110 ui_->widget_controls->setVisible(
false);
115 this->restoreGeometry(geometry);
116 this->restoreState(state);
119 ui_->toolBox->setupUi();
128 ui_->toolBox->getParameterWidget(Settings::kCamera_1deviceId())->setEnabled(
false);
129 ui_->toolBox->getParameterWidget(Settings::kCamera_2imageWidth())->setEnabled(
false);
130 ui_->toolBox->getParameterWidget(Settings::kCamera_3imageHeight())->setEnabled(
false);
131 ui_->toolBox->getParameterWidget(Settings::kCamera_5mediaPath())->setEnabled(
false);
132 ui_->toolBox->getParameterWidget(Settings::kCamera_6useTcpCamera())->setEnabled(
false);
133 ui_->toolBox->getParameterWidget(Settings::kCamera_8port())->setEnabled(
false);
134 ui_->toolBox->getParameterWidget(Settings::kCamera_9queueSize())->setEnabled(
false);
135 ui_->actionCamera_from_video_file->setVisible(
false);
136 ui_->actionCamera_from_TCP_IP->setVisible(
false);
137 ui_->actionCamera_from_directory_of_images->setVisible(
false);
138 ui_->actionLoad_scene_from_file->setVisible(
false);
141 #if CV_MAJOR_VERSION < 3 142 if(cv::gpu::getCudaEnabledDeviceCount() == 0)
144 if(cv::cuda::getCudaEnabledDeviceCount() == 0)
147 #if FINDOBJECT_NONFREE == 1 148 ui_->toolBox->updateParameter(Settings::kFeature2D_SURF_gpu());
149 ui_->toolBox->getParameterWidget(Settings::kFeature2D_SURF_gpu())->setEnabled(
false);
150 ui_->toolBox->getParameterWidget(Settings::kFeature2D_SURF_keypointsRatio())->setEnabled(
false);
152 ui_->toolBox->updateParameter(Settings::kFeature2D_Fast_gpu());
153 ui_->toolBox->updateParameter(Settings::kFeature2D_ORB_gpu());
154 ui_->toolBox->updateParameter(Settings::kNearestNeighbor_BruteForce_gpu());
155 ui_->toolBox->getParameterWidget(Settings::kFeature2D_Fast_gpu())->setEnabled(
false);
156 ui_->toolBox->getParameterWidget(Settings::kFeature2D_Fast_keypointsRatio())->setEnabled(
false);
157 ui_->toolBox->getParameterWidget(Settings::kFeature2D_ORB_gpu())->setEnabled(
false);
158 ui_->toolBox->getParameterWidget(Settings::kNearestNeighbor_BruteForce_gpu())->setEnabled(
false);
161 connect((QDoubleSpinBox*)
ui_->toolBox->getParameterWidget(Settings::kCamera_4imageRate()),
162 SIGNAL(editingFinished()),
164 SLOT(updateImageRate()));
165 ui_->menuView->addAction(
ui_->dockWidget_statistics->toggleViewAction());
166 ui_->menuView->addAction(
ui_->dockWidget_parameters->toggleViewAction());
167 ui_->menuView->addAction(
ui_->dockWidget_objects->toggleViewAction());
168 ui_->menuView->addAction(
ui_->dockWidget_plot->toggleViewAction());
169 connect(
ui_->toolBox, SIGNAL(parametersChanged(
const QStringList &)),
this, SLOT(
notifyParametersChanged(
const QStringList &)));
171 ui_->imageView_source->setTextLabel(tr(
"Press \"space\" to start the camera or drop an image here..."));
172 ui_->imageView_source->setMirrorView(Settings::getGeneral_mirrorView());
173 connect((QCheckBox*)
ui_->toolBox->getParameterWidget(Settings::kGeneral_mirrorView()),
174 SIGNAL(stateChanged(
int)),
178 ui_->widget_controls->setVisible(Settings::getGeneral_controlsShown());
179 connect((QCheckBox*)
ui_->toolBox->getParameterWidget(Settings::kGeneral_controlsShown()),
180 SIGNAL(stateChanged(
int)),
185 connect(
ui_->pushButton_restoreDefaults, SIGNAL(clicked()),
ui_->toolBox, SLOT(resetCurrentPage()));
186 connect(
ui_->pushButton_updateObjects, SIGNAL(clicked()),
this, SLOT(
updateObjects()));
187 connect(
ui_->horizontalSlider_objectsSize, SIGNAL(valueChanged(
int)),
this, SLOT(
updateObjectsSize()));
189 ui_->actionStop_camera->setEnabled(
false);
190 ui_->actionPause_camera->setEnabled(
false);
191 ui_->actionSave_objects->setEnabled(
false);
192 ui_->actionSave_session->setEnabled(
false);
199 connect(
ui_->actionStop_camera, SIGNAL(triggered()),
this, SLOT(
stopProcessing()));
201 connect(
ui_->actionExit, SIGNAL(triggered()),
this, SLOT(close()));
202 connect(
ui_->actionSave_objects, SIGNAL(triggered()),
this, SLOT(
saveObjects()));
203 connect(
ui_->actionLoad_objects, SIGNAL(triggered()),
this, SLOT(
loadObjects()));
207 connect(
ui_->actionAbout, SIGNAL(triggered()),
aboutDialog_ , SLOT(exec()));
208 connect(
ui_->actionRestore_all_default_settings, SIGNAL(triggered()),
ui_->toolBox, SLOT(resetAllPages()));
209 connect(
ui_->actionRemove_all_objects, SIGNAL(triggered()),
this, SLOT(
removeAllObjects()));
210 connect(
ui_->actionSave_settings, SIGNAL(triggered()),
this, SLOT(
saveSettings()));
211 connect(
ui_->actionLoad_settings, SIGNAL(triggered()),
this, SLOT(
loadSettings()));
212 connect(
ui_->actionSave_session, SIGNAL(triggered()),
this, SLOT(
saveSession()));
213 connect(
ui_->actionLoad_session, SIGNAL(triggered()),
this, SLOT(
loadSession()));
214 connect(
ui_->actionSave_vocabulary, SIGNAL(triggered()),
this, SLOT(
saveVocabulary()));
215 connect(
ui_->actionLoad_vocabulary, SIGNAL(triggered()),
this, SLOT(
loadVocabulary()));
222 connect(
ui_->horizontalSlider_frames, SIGNAL(valueChanged(
int)),
this, SLOT(
moveCameraFrame(
int)));
223 connect(
ui_->horizontalSlider_frames, SIGNAL(valueChanged(
int)),
ui_->label_frame, SLOT(setNum(
int)));
224 ui_->pushButton_play->setVisible(
true);
225 ui_->pushButton_pause->setVisible(
false);
226 ui_->pushButton_stop->setEnabled(
false);
227 ui_->horizontalSlider_frames->setEnabled(
false);
228 ui_->label_frame->setVisible(
false);
230 ui_->objects_area->addAction(
ui_->actionAdd_object_from_scene);
231 ui_->objects_area->addAction(
ui_->actionAdd_objects_from_files);
232 ui_->objects_area->setContextMenuPolicy(Qt::ActionsContextMenu);
234 ui_->actionStart_camera->setShortcut(Qt::Key_Space);
235 ui_->actionPause_camera->setShortcut(Qt::Key_Space);
237 ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !
UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
238 ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() &&
UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()));
239 ui_->actionCamera_from_TCP_IP->setChecked(Settings::getCamera_6useTcpCamera());
241 ui_->label_ipAddress->setTextInteractionFlags(Qt::TextSelectableByMouse);
242 ui_->label_port->setTextInteractionFlags(Qt::TextSelectableByMouse);
250 for(QMap<int, ObjSignature *>::const_iterator iter =
findObject_->
objects().constBegin();
254 ObjWidget * obj =
new ObjWidget(iter.key(), iter.value()->keypoints(), iter.value()->words(), iter.value()->image().empty()?QImage():
cvtCvMat2QImage(iter.value()->image()));
264 ui_->actionSave_objects->setEnabled(
true);
265 ui_->actionSave_session->setEnabled(
true);
270 ui_->actionSave_session->setEnabled(
true);
274 if(Settings::getGeneral_autoStartCamera())
281 connect(
ui_->imageDrop_objects, SIGNAL(imagesReceived(
const QStringList &)),
this, SLOT(
addObjectsFromFiles(
const QStringList &)));
282 connect(
ui_->imageDrop_scene, SIGNAL(imagesReceived(
const QStringList &)),
this, SLOT(
loadSceneFromFile(
const QStringList &)));
284 ui_->imageView_source->setFocus();
289 disconnect(
camera_, SIGNAL(imageReceived(
const cv::Mat &)),
this, SLOT(
update(
const cv::Mat &)));
305 int ret = QMessageBox::question(
this, tr(
"Save new objects"), tr(
"Do you want to save added objects?"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
308 case QMessageBox::Yes:
311 case QMessageBox::Cancel:
314 case QMessageBox::No:
333 if(event->key() == Qt::Key_Space)
335 if(
ui_->actionStart_camera->isEnabled())
339 else if(
ui_->actionPause_camera->isEnabled())
360 connect(
tcpServer_, SIGNAL(addObject(
const cv::Mat &,
int,
const QString &)),
this, SLOT(
addObjectFromTcp(
const cv::Mat &,
int,
const QString &)));
366 ui_->imageView_source->setTextLabel(text);
373 QMessageBox::StandardButton b = QMessageBox::question(
this, tr(
"Loading session..."),
374 tr(
"There are some objects (%1) already loaded, they will be " 375 "deleted when loading the session. Do you want to continue?").arg(
objWidgets_.size()),
376 QMessageBox::Yes | QMessageBox::No, QMessageBox::NoButton);
377 if(b != QMessageBox::Yes)
388 ui_->actionSave_objects->setEnabled(
false);
395 for(ParametersMap::const_iterator iter = parameters.begin(); iter!= parameters.constEnd(); ++iter)
397 ui_->toolBox->updateParameter(iter.key());
407 ui_->actionSave_objects->setEnabled(
true);
408 ui_->actionSave_session->setEnabled(
true);
412 QLabel * title = this->findChild<QLabel*>(QString(
"%1title").arg(iter.value()->id()));
413 title->setText(QString(
"%1 (%2)").arg(iter.value()->id()).arg(QString::number(iter.value()->keypoints().size())));
418 QMessageBox::information(
this, tr(
"Session loaded!"), tr(
"Session \"%1\" successfully loaded (%2 objects, %3 vocabulary words)!").arg(path).arg(
objWidgets_.size()).arg(
findObject_->
vocabulary()->
size()));
432 if(QFileInfo(path).suffix().compare(
"bin") != 0)
439 QMessageBox::information(
this, tr(
"Session saved!"), tr(
"Session \"%1\" successfully saved (%2 objects, %3 vocabulary words)!").arg(path).arg(
objWidgets_.size()).arg(
findObject_->
vocabulary()->
size()));
449 if(QFileInfo(path).suffix().compare(
"ini") != 0)
461 if(QFileInfo(path).suffix().compare(
"ini") != 0)
471 if(!path.isEmpty() && QFileInfo(path).suffix().compare(
"ini") == 0)
477 this->restoreGeometry(geometry);
478 this->restoreState(state);
482 for(ParametersMap::const_iterator iter = parameters.begin(); iter!= parameters.constEnd(); ++iter)
484 ui_->toolBox->updateParameter(iter.key());
489 UERROR(
"Path \"%s\" not valid (should be *.ini)", path.toStdString().c_str());
495 if(!path.isEmpty() && QFileInfo(path).suffix().compare(
"ini") == 0)
501 UERROR(
"Path \"%s\" not valid (should be *.ini)", path.toStdString().c_str());
507 QList<int> loadedObjects;
508 QString formats = Settings::getGeneral_imageFormats().remove(
'*').remove(
'.');
511 paths.append(dirPath);
515 QString currentDir = paths.front();
516 UDirectory dir(currentDir.toStdString(), formats.toStdString());
519 const std::list<std::string> & names = dir.
getFileNames();
520 for(std::list<std::string>::const_iterator iter=names.begin(); iter!=names.end(); ++iter)
522 int id = this->
addObjectFromFile((currentDir.toStdString()+dir.separator()+*iter).c_str());
525 loadedObjects.push_back(
id);
535 QStringList subDirs = d.entryList(QDir::AllDirs|QDir::NoDotAndDotDot, QDir::Name);
536 for(
int i=subDirs.size()-1; i>=0; --i)
538 paths.prepend(currentDir + QDir::separator() + subDirs[i]);
543 if(loadedObjects.size())
548 return loadedObjects.size();
557 for(QMap<int, ObjWidget*>::const_iterator iter=
objWidgets_.constBegin(); iter!=
objWidgets_.constEnd(); ++iter)
559 if(iter.value()->pixmap().save(QString(
"%1/%2.png").arg(dirPath).arg(iter.key())))
565 UERROR(
"Failed to save object %d", iter.key());
575 QString dirPath = QFileDialog::getExistingDirectory(
this, tr(
"Loading objects... Select a directory."),
Settings::workingDirectory());
576 if(!dirPath.isEmpty())
579 bool recursive =
false;
580 if(d.entryList(QDir::AllDirs | QDir::NoDotAndDotDot).size())
582 QMessageBox::StandardButton b = QMessageBox::question(
584 tr(
"Loading objects..."),
585 tr(
"The current directory contains subdirectories. Load objects recursively?"),
586 QMessageBox::Yes|QMessageBox::No,
588 recursive = b == QMessageBox::Yes;
594 QMessageBox::information(
this, tr(
"Loading..."), tr(
"%1 objects loaded from \"%2\".").arg(count).arg(dirPath));
598 QMessageBox::information(
this, tr(
"Loading..."), tr(
"No objects loaded from \"%1\"!").arg(dirPath));
604 QString dirPath = QFileDialog::getExistingDirectory(
this, tr(
"Saving objects... Select a directory."),
Settings::workingDirectory());
605 if(!dirPath.isEmpty())
610 QMessageBox::information(
this, tr(
"Saving..."), tr(
"%1 objects saved to \"%2\".").arg(count).arg(dirPath));
614 QMessageBox::warning(
this, tr(
"Saving..."), tr(
"No objects saved to %1!").arg(dirPath));
623 if(!Settings::getGeneral_vocabularyFixed() ||
624 !Settings::getGeneral_invertedSearch())
626 QMessageBox::StandardButton b = QMessageBox::question(
this, tr(
"Load vocabulary..."),
627 tr(
"Parameters \"General/vocabularyFixed\" and \"General/invertedSearch\" should be enabled to load a vocabulary. " 628 "Do you want to enable them now?"),
629 QMessageBox::Cancel | QMessageBox::Yes);
630 if(b == QMessageBox::Yes)
632 Settings::setGeneral_vocabularyFixed(
true);
633 Settings::setGeneral_invertedSearch(
true);
636 if(Settings::getGeneral_vocabularyFixed() &&
637 Settings::getGeneral_invertedSearch())
639 QString path = QFileDialog::getOpenFileName(
this, tr(
"Load vocabulary..."),
Settings::workingDirectory(),
"Data (*.yaml *.xml *.bin)");
646 QMessageBox::information(
this, tr(
"Loading..."), tr(
"Vocabulary loaded from \"%1\" (%2 words).").arg(path).arg(
findObject_->
vocabulary()->
size()));
650 QMessageBox::warning(
this, tr(
"Loading..."), tr(
"Failed to load vocabulary \"%1\"!").arg(path));
660 QMessageBox::warning(
this, tr(
"Saving vocabulary..."), tr(
"Vocabulary is empty!"));
663 QString path = QFileDialog::getSaveFileName(
this, tr(
"Save vocabulary..."),
Settings::workingDirectory(),
"Data (*.yaml *.xml *.bin)");
666 if( QFileInfo(path).suffix().compare(
"yaml") != 0 &&
667 QFileInfo(path).suffix().compare(
"xml") != 0 &&
668 QFileInfo(path).suffix().compare(
"bin") != 0)
670 path.append(
".yaml");
674 QMessageBox::information(
this, tr(
"Saving..."), tr(
"Vocabulary saved to \"%1\" (%2 words).").arg(path).arg(
findObject_->
vocabulary()->
size()));
678 QMessageBox::warning(
this, tr(
"Saving..."), tr(
"Failed to save vocabulary \"%1\"!").arg(path));
690 ui_->actionSave_objects->setEnabled(
false);
691 ui_->actionSave_session->setEnabled(
false);
694 object->deleteLater();
695 if(Settings::getGeneral_autoUpdateObjects())
714 UERROR(
"Remove object: Object %d not found!",
id);
722 ui_->actionSave_objects->setEnabled(
false);
742 int value =
ui_->horizontalSlider_objectsSize->value();
743 if((obj->
pixmap().width()*value)/100 > 4 && (obj->
pixmap().height()*value)/100 > 4)
745 obj->setVisible(
true);
746 obj->setMinimumSize((obj->
pixmap().width()*value)/100, (obj->
pixmap().height())*value/100);
750 obj->setVisible(
false);
757 bool mirrorView = Settings::getGeneral_mirrorView();
758 ui_->imageView_source->setMirrorView(mirrorView);
761 iter.value()->setMirrorView(mirrorView);
767 ui_->widget_controls->setVisible(Settings::getGeneral_controlsShown());
774 iter.value()->setFeaturesShown(
true);
782 iter.value()->setFeaturesShown(
false);
788 disconnect(
camera_, SIGNAL(imageReceived(
const cv::Mat &)),
this, SLOT(
update(
const cv::Mat &)));
801 if(dialog->exec() == QDialog::Accepted)
806 UASSERT(obj!=0 && signature!=0);
810 ui_->actionSave_objects->setEnabled(
true);
811 ui_->actionSave_session->setEnabled(
true);
814 ids.push_back(obj->
id());
824 connect(
camera_, SIGNAL(imageReceived(
const cv::Mat &)),
this, SLOT(
update(
const cv::Mat &)), Qt::UniqueConnection);
825 connect(
camera_, SIGNAL(imageReceived(
const cv::Mat &,
const find_object::Header &,
const cv::Mat &,
float)),
this, SLOT(
update(
const cv::Mat &,
const find_object::Header &,
const cv::Mat &,
float)), Qt::UniqueConnection);
840 for(
int i=0; i<fileNames.size(); ++i)
868 ui_->actionSave_objects->setEnabled(
true);
869 ui_->actionSave_session->setEnabled(
true);
875 QMessageBox::critical(
this, tr(
"Error adding object"), tr(
"Failed to add object from \"%1\"").arg(filePath));
884 UERROR(
"Add Object: Object %d is already added.",
id);
891 ui_->actionSave_objects->setEnabled(
true);
892 ui_->actionSave_session->setEnabled(
true);
895 ids.push_back(obj->
id());
900 UERROR(
"Add Object: Error adding object %d.",
id);
909 cv::Mat img = cv::imread(fileNames.first().toStdString().c_str());
913 ui_->label_timeRefreshRate->setVisible(
false);
920 QString fileName = QFileDialog::getOpenFileName(
this, tr(
"Load scene..."),
Settings::workingDirectory(), tr(
"Image Files (%1)").arg(Settings::getGeneral_imageFormats()));
921 if(!fileName.isEmpty())
923 cv::Mat img = cv::imread(fileName.toStdString().c_str());
927 ui_->label_timeRefreshRate->setVisible(
false);
934 if(!
ui_->actionCamera_from_video_file->isChecked())
936 Settings::setCamera_5mediaPath(
"");
937 ui_->toolBox->updateParameter(Settings::kCamera_5mediaPath());
941 QString fileName = QFileDialog::getOpenFileName(
this, tr(
"Setup camera from video file..."),
Settings::workingDirectory(), tr(
"Video Files (%1)").arg(Settings::getGeneral_videoFormats()));
942 if(!fileName.isEmpty())
944 Settings::setCamera_6useTcpCamera(
false);
945 ui_->toolBox->updateParameter(Settings::kCamera_6useTcpCamera());
947 Settings::setCamera_5mediaPath(fileName);
948 ui_->toolBox->updateParameter(Settings::kCamera_5mediaPath());
954 Settings::setGeneral_controlsShown(
true);
955 ui_->toolBox->updateParameter(Settings::kGeneral_controlsShown());
958 ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty());
959 ui_->actionCamera_from_directory_of_images->setChecked(
false);
960 ui_->actionCamera_from_TCP_IP->setChecked(
false);
965 if(!
ui_->actionCamera_from_directory_of_images->isChecked())
967 Settings::setCamera_5mediaPath(
"");
968 ui_->toolBox->updateParameter(Settings::kCamera_5mediaPath());
972 QString directory = QFileDialog::getExistingDirectory(
this, tr(
"Setup camera from directory of images..."),
Settings::workingDirectory());
973 if(!directory.isEmpty())
975 Settings::setCamera_6useTcpCamera(
false);
976 ui_->toolBox->updateParameter(Settings::kCamera_6useTcpCamera());
978 Settings::setCamera_5mediaPath(directory);
979 ui_->toolBox->updateParameter(Settings::kCamera_5mediaPath());
985 Settings::setGeneral_controlsShown(
true);
986 ui_->toolBox->updateParameter(Settings::kGeneral_controlsShown());
989 ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty());
990 ui_->actionCamera_from_video_file->setChecked(
false);
991 ui_->actionCamera_from_TCP_IP->setChecked(
false);
996 if(!
ui_->actionCamera_from_TCP_IP->isChecked())
998 Settings::setCamera_6useTcpCamera(
false);
999 ui_->toolBox->updateParameter(Settings::kCamera_6useTcpCamera());
1004 int port = QInputDialog::getInt(
this, tr(
"Server port..."),
"Port: ", Settings::getCamera_8port(), 1, USHRT_MAX, 1, &ok);
1008 int queue = QInputDialog::getInt(
this, tr(
"Queue size..."),
"Images buffer size (0 means infinite): ", Settings::getCamera_9queueSize(), 0, 2147483647, 1, &ok);
1011 Settings::setCamera_6useTcpCamera(
true);
1012 ui_->toolBox->updateParameter(Settings::kCamera_6useTcpCamera());
1013 Settings::setCamera_8port(port);
1014 ui_->toolBox->updateParameter(Settings::kCamera_8port());
1015 Settings::setCamera_9queueSize(queue);
1016 ui_->toolBox->updateParameter(Settings::kCamera_9queueSize());
1025 ui_->actionCamera_from_directory_of_images->setChecked(
false);
1026 ui_->actionCamera_from_video_file->setChecked(
false);
1027 ui_->actionCamera_from_TCP_IP->setChecked(Settings::getCamera_6useTcpCamera());
1036 QList<ObjWidget*> objs =
ui_->objects_area->findChildren<
ObjWidget*>();
1037 QVBoxLayout * vLayout =
new QVBoxLayout();
1038 ui_->toolBox->updateParameter(Settings::kGeneral_nextObjID());
1040 QLabel * title =
new QLabel(QString(
"%1 (%2)").arg(obj->
id()).arg(obj->
keypoints().size()),
this);
1041 QLabel * detectedLabel =
new QLabel(
this);
1042 title->setObjectName(QString(
"%1title").arg(obj->
id()));
1043 detectedLabel->setObjectName(QString(
"%1detection").arg(obj->
id()));
1044 QHBoxLayout * hLayout =
new QHBoxLayout();
1045 hLayout->addWidget(title);
1046 hLayout->addStretch(1);
1047 hLayout->addStretch(1);
1048 hLayout->addWidget(detectedLabel);
1049 vLayout->addLayout(hLayout);
1050 vLayout->addWidget(obj);
1053 connect(obj, SIGNAL(destroyed(QObject *)), title, SLOT(deleteLater()));
1054 connect(obj, SIGNAL(destroyed(QObject *)), detectedLabel, SLOT(deleteLater()));
1055 connect(obj, SIGNAL(destroyed(QObject *)), vLayout, SLOT(deleteLater()));
1056 ui_->verticalLayout_objects->insertLayout(
ui_->verticalLayout_objects->count()-1, vLayout);
1059 if(obj->
pixmap().width() > 0)
1061 QBuffer buffer(&ba);
1062 buffer.open(QIODevice::WriteOnly);
1063 obj->
pixmap().scaledToWidth(128).save(&buffer,
"JPEG");
1068 int objectsPanelWidth =
ui_->dockWidget_objects->width();
1069 if(objectsPanelWidth > 0 && (obj->
pixmap().width()*
ui_->horizontalSlider_objectsSize->value()) / 100 > objectsPanelWidth)
1071 ui_->horizontalSlider_objectsSize->setValue((objectsPanelWidth * 100) / obj->
pixmap().width());
1089 this->statusBar()->showMessage(tr(
"Updating %1 objects...").arg(ids.size()==0?
objWidgets_.size():ids.size()));
1093 QList<int> idsTmp = ids;
1094 if(idsTmp.size() == 0)
1100 for(
int i=0; i<signatures.size(); ++i)
1102 if(idsTmp.contains(signatures[i]->id()))
1104 objWidgets_.value(signatures[i]->
id())->updateData(signatures[i]->keypoints());
1107 QLabel * title = this->findChild<QLabel*>(QString(
"%1title").arg(signatures[i]->
id()));
1108 title->setText(QString(
"%1 (%2)").arg(signatures[i]->
id()).arg(QString::number(signatures[i]->keypoints().size())));
1110 QLabel * label = this->findChild<QLabel*>(QString(
"%1detection").arg(signatures[i]->
id()));
1121 this->statusBar()->clearMessage();
1127 this->statusBar()->showMessage(tr(
"Updating vocabulary..."));
1133 QList<int> idsTmp = ids;
1134 if(idsTmp.size() == 0)
1139 for(
int i=0; i<signatures.size(); ++i)
1141 if(idsTmp.contains(signatures[i]->id()))
1143 objWidgets_.value(signatures[i]->
id())->updateWords(signatures[i]->words());
1147 ui_->label_timeIndexing->setNum(time.elapsed());
1149 if(ids.size() &&
findObject_->
vocabulary()->
size() == 0 && Settings::getGeneral_vocabularyFixed() && Settings::getGeneral_invertedSearch())
1151 QMessageBox::warning(
this, tr(
"Vocabulary update"), tr(
"\"General/VocabularyFixed=true\" and the " 1152 "vocabulary is empty. New features cannot be matched to any words in the vocabulary."));
1155 this->statusBar()->clearMessage();
1156 ui_->dockWidget_objects->update();
1161 UINFO(
"Starting camera...");
1162 bool updateStatusMessage = this->statusBar()->currentMessage().isEmpty();
1163 if(updateStatusMessage)
1165 this->statusBar()->showMessage(tr(
"Starting camera..."));
1169 connect(
camera_, SIGNAL(imageReceived(
const cv::Mat &)),
this, SLOT(
update(
const cv::Mat &)), Qt::UniqueConnection);
1170 connect(
camera_, SIGNAL(imageReceived(
const cv::Mat &,
const find_object::Header &,
const cv::Mat &,
float)),
this, SLOT(
update(
const cv::Mat &,
const find_object::Header &,
const cv::Mat &,
float)), Qt::UniqueConnection);
1172 ui_->actionStop_camera->setEnabled(
true);
1173 ui_->actionPause_camera->setEnabled(
true);
1174 ui_->actionStart_camera->setEnabled(
false);
1175 ui_->actionLoad_scene_from_file->setEnabled(
false);
1176 ui_->actionCamera_from_directory_of_images->setEnabled(
false);
1177 ui_->actionCamera_from_video_file->setEnabled(
false);
1178 ui_->actionCamera_from_TCP_IP->setEnabled(
false);
1179 ui_->label_timeRefreshRate->setVisible(
true);
1182 ui_->pushButton_play->setVisible(
false);
1183 ui_->pushButton_pause->setVisible(
true);
1184 ui_->pushButton_stop->setEnabled(
true);
1188 ui_->label_frame->setVisible(
true);
1189 ui_->horizontalSlider_frames->setEnabled(
true);
1190 ui_->horizontalSlider_frames->setMaximum(totalFrames-1);
1194 ui_->label_port_image->setText(
"-");
1200 if(updateStatusMessage)
1202 this->statusBar()->showMessage(tr(
"Camera started."), 2000);
1207 if(updateStatusMessage)
1209 this->statusBar()->clearMessage();
1212 if(Settings::getCamera_6useTcpCamera())
1214 QMessageBox::critical(
this, tr(
"Camera error"), tr(
"Camera initialization failed! (with port %1)").arg(Settings::getCamera_8port()));
1218 QMessageBox::critical(
this, tr(
"Camera error"), tr(
"Camera initialization failed! (with device %1)").arg(Settings::getCamera_1deviceId()));
1227 disconnect(
camera_, SIGNAL(imageReceived(
const cv::Mat &)),
this, SLOT(
update(
const cv::Mat &)));
1232 ui_->actionStop_camera->setEnabled(
false);
1233 ui_->actionPause_camera->setEnabled(
false);
1234 ui_->actionStart_camera->setEnabled(
true);
1235 ui_->actionLoad_scene_from_file->setEnabled(
true);
1236 ui_->actionCamera_from_directory_of_images->setEnabled(
true);
1237 ui_->actionCamera_from_video_file->setEnabled(
true);
1238 ui_->actionCamera_from_TCP_IP->setEnabled(
true);
1239 ui_->pushButton_play->setVisible(
true);
1240 ui_->pushButton_pause->setVisible(
false);
1241 ui_->pushButton_stop->setEnabled(
false);
1242 ui_->horizontalSlider_frames->setEnabled(
false);
1243 ui_->horizontalSlider_frames->setValue(0);
1244 ui_->label_frame->setVisible(
false);
1245 ui_->label_port_image->setText(
"-");
1250 ui_->actionStop_camera->setEnabled(
true);
1251 ui_->actionPause_camera->setEnabled(
true);
1252 ui_->actionStart_camera->setEnabled(
false);
1255 ui_->pushButton_play->setVisible(
true);
1256 ui_->pushButton_pause->setVisible(
false);
1261 ui_->pushButton_play->setVisible(
false);
1262 ui_->pushButton_pause->setVisible(
true);
1269 if(
ui_->horizontalSlider_frames->isEnabled())
1281 if(objId>=0 && Settings::getGeneral_autoScroll())
1283 QLabel * label =
ui_->dockWidget_objects->findChild<QLabel*>(QString(
"%1title").arg(objId));
1286 ui_->objects_area->verticalScrollBar()->setValue(label->pos().y());
1300 UWARN(
"The image received is empty...");
1308 iter.value()->resetKptsColor();
1309 if(!Settings::getGeneral_invertedSearch())
1311 iter.value()->resetKptsWordID();
1315 QTime guiRefreshTime;
1320 guiRefreshTime.start();
1337 const QMap<int, QMultiMap<int, int> > & matches = info.
matches_;
1338 QMap<int, int> scores;
1339 int maxScoreId = -1;
1341 for(QMap<
int, QMultiMap<int, int> >::const_iterator jter=matches.constBegin(); jter!=matches.end();++jter)
1343 scores.insert(jter.key(), jter.value().size());
1344 if(maxScoreId == -1 || maxScore < jter.value().size())
1346 maxScoreId = jter.key();
1347 maxScore = jter.value().size();
1350 int id = jter.key();
1351 QLabel * label =
ui_->dockWidget_objects->findChild<QLabel*>(QString(
"%1detection").arg(
id));
1352 if(!Settings::getHomography_homographyComputed())
1354 label->setText(QString(
"%1 matches").arg(jter.value().size()));
1359 for(QMultiMap<int, int>::const_iterator iter = jter.value().constBegin(); iter!= jter.value().constEnd(); ++iter)
1362 ui_->imageView_source->setKptColor(iter.value(), obj->
color());
1363 if(!Settings::getGeneral_invertedSearch())
1365 obj->
setKptWordID(iter.key(),
ui_->imageView_source->words().value(iter.value(), -1));
1372 QLabel * label =
ui_->dockWidget_objects->findChild<QLabel*>(QString(
"%1detection").arg(
id));
1378 label->setText(QString(
"Too low matches (%1)").arg(jter.value().size()));
1382 label->setText(QString(
"Ignored, all inliers (%1 in %2 out)").arg(rejectedInliers.size()).arg(rejectedOutliers.size()));
1386 label->setText(QString(
"Not valid homography (%1 in %2 out)").arg(rejectedInliers.size()).arg(rejectedOutliers.size()));
1390 label->setText(QString(
"Too low inliers (%1 in %2 out)").arg(rejectedInliers.size()).arg(rejectedOutliers.size()));
1394 label->setText(QString(
"Corners not visible (%1 in %2 out)").arg(rejectedInliers.size()).arg(rejectedOutliers.size()));
1398 label->setText(QString(
"Angle too small (%1 in %2 out)").arg(rejectedInliers.size()).arg(rejectedOutliers.size()));
1409 int maxHomographyScoreId = -1;
1410 int maxHomographyScore = 0;
1411 QMultiMap<int, QMultiMap<int,int> >::const_iterator inliersIter = info.
objDetectedInliers_.constBegin();
1412 QMultiMap<int, QMultiMap<int,int> >::const_iterator outliersIter = info.
objDetectedOutliers_.constBegin();
1413 for(QMultiMap<int,QTransform>::iterator iter = info.
objDetected_.begin();
1415 ++iter, ++inliersIter, ++outliersIter)
1417 int id = iter.key();
1419 if(maxHomographyScoreId == -1 || maxHomographyScore < inliersIter.value().size())
1421 maxHomographyScoreId = id;
1422 maxHomographyScore = inliersIter.value().size();
1429 QTransform hTransform = iter.value();
1431 QRect rect = obj->
pixmap().rect();
1433 QPen rectPen(obj->
color());
1434 rectPen.setWidth(Settings::getHomography_rectBorderWidth());
1437 QMap<int, ObjSignature*>::const_iterator iter =
findObject_->
objects().constFind(
id);
1440 rect = iter.value()->rect();
1444 connect(rectItemScene, SIGNAL(hovered(
int)),
this, SLOT(
rectHovered(
int)));
1445 rectItemScene->setPen(rectPen);
1446 rectItemScene->setTransform(hTransform);
1447 ui_->imageView_source->addRect(rectItemScene);
1449 QGraphicsRectItem * rectItemObj =
new QGraphicsRectItem(rect);
1450 rectItemObj->setPen(rectPen);
1453 for(QMultiMap<int, int>::const_iterator iter = inliersIter.value().constBegin(); iter!= inliersIter.value().constEnd(); ++iter)
1456 ui_->imageView_source->setKptColor(iter.value(), obj->
color());
1457 if(!Settings::getGeneral_invertedSearch())
1459 obj->
setKptWordID(iter.key(),
ui_->imageView_source->words().value(iter.value(), -1));
1463 QLabel * label =
ui_->dockWidget_objects->findChild<QLabel*>(QString(
"%1detection").arg(
id));
1467 label->setText(QString(
"%1 objects found").arg(info.
objDetected_.count(
id)));
1471 label->setText(QString(
"%1 in %2 out").arg(inliersIter.value().size()).arg(outliersIter.value().size()));
1476 if(info.
objDetected_.size() && !Settings::getGeneral_autoScreenshotPath().isEmpty())
1478 QDir dir(Settings::getGeneral_autoScreenshotPath());
1481 QMessageBox::warning(
this, tr(
"Screenshot on detection"), tr(
"Directory \"%1\" doesn't " 1482 "exist, screenshot of the detection cannot be taken. Parameter \"%2\" is cleared.").arg(Settings::getGeneral_autoScreenshotPath()).arg(Settings::kGeneral_autoScreenshotPath()));
1483 Settings::setGeneral_autoScreenshotPath(
"");
1484 ui_->toolBox->updateParameter(Settings::kGeneral_autoScreenshotPath());
1488 QString path = Settings::getGeneral_autoScreenshotPath() + QDir::separator() + (QDateTime::currentDateTime().toString(
"yyMMddhhmmsszzz") +
".jpg");
1489 if(!
ui_->imageView_source->getSceneAsPixmap().save(path))
1491 UDEBUG(
"Failed to save screenshot \"%s\"! (%s is set)", path.toStdString().c_str(), Settings::kGeneral_autoScreenshotPath().toStdString().c_str());
1495 UINFO(
"Save screenshot \"%s\"! (%s is set)", path.toStdString().c_str(), Settings::kGeneral_autoScreenshotPath().toStdString().c_str());
1501 UDEBUG(
"Set likelihood score curve values (%d)", scores.size());
1503 QMap<int, int> inlierScores;
1504 for(QMap<int, int>::iterator iter=scores.begin(); iter!=scores.end(); ++iter)
1510 maxValue = values[0].size();
1511 for(
int i=1; i<values.size(); ++i)
1513 if(maxValue < values[i].size())
1515 maxValue = values[i].size();
1519 inlierScores.insert(iter.key(), maxValue);
1521 UDEBUG(
"Set inliers score curve values (%d)", inlierScores.size());
1523 if(
ui_->likelihoodPlot->isVisible())
1525 ui_->likelihoodPlot->update();
1532 if((maxScoreId>=0 || maxHomographyScoreId>=0) && Settings::getGeneral_autoScroll())
1534 QLabel * label =
ui_->dockWidget_objects->findChild<QLabel*>(QString(
"%1title").arg(maxHomographyScoreId>=0?maxHomographyScoreId:maxScoreId));
1537 ui_->objects_area->verticalScrollBar()->setValue(label->pos().y());
1544 UINFO(
"(%s) %d objects detected!",
1545 QTime::currentTime().toString(
"HH:mm:ss.zzz").toStdString().c_str(),
1550 UINFO(
"(%s) Object %d detected!",
1551 QTime::currentTime().toString(
"HH:mm:ss.zzz").toStdString().c_str(),
1554 else if(Settings::getGeneral_sendNoObjDetectedEvents())
1556 UINFO(
"(%s) No objects detected.",
1557 QTime::currentTime().toString(
"HH:mm:ss.zzz").toStdString().c_str());
1560 if(info.
objDetected_.size() > 0 || Settings::getGeneral_sendNoObjDetectedEvents())
1562 Q_EMIT
objectsFound(info, header, depth, depthConstant);
1568 guiRefreshTime.start();
1572 this->statusBar()->showMessage(tr(
"Cannot search, objects must be updated!"));
1586 iter.value()->update();
1590 ui_->imageView_source->update();
1595 if(
ui_->horizontalSlider_frames->isEnabled())
1597 ui_->horizontalSlider_frames->blockSignals(
true);
1600 ui_->horizontalSlider_frames->blockSignals(
false);
1604 int refreshRate = qRound(1000.0
f/
float(
updateRate_.restart()));
1612 if(Settings::getCamera_4imageRate()>0.0)
1614 ui_->label_timeRefreshRate->setText(QString(
"(%1 Hz - %2 Hz)").arg(QString::number(Settings::getCamera_4imageRate())).arg(QString::number(
lowestRefreshRate_)));
1624 ui_->label_timeRefreshGUI->setNum(guiRefreshTime.elapsed());
1630 bool detectorDescriptorParamsChanged =
false;
1631 bool nearestNeighborParamsChanged =
false;
1632 bool parameterChanged =
false;
1633 for(QStringList::const_iterator iter = paramChanged.begin(); iter!=paramChanged.end(); ++iter)
1638 parameterChanged =
true;
1639 UINFO(
"Parameter changed: %s -> \"%s\"", iter->toStdString().c_str(),
Settings::getParameter(*iter).toString().toStdString().c_str());
1641 if(iter->contains(
"Feature2D"))
1643 detectorDescriptorParamsChanged =
true;
1645 else if( (iter->contains(
"NearestNeighbor") && Settings::getGeneral_invertedSearch()) ||
1646 iter->compare(Settings::kGeneral_invertedSearch()) == 0 ||
1647 (iter->compare(Settings::kGeneral_vocabularyIncremental()) == 0 && Settings::getGeneral_invertedSearch()) ||
1648 (iter->compare(Settings::kGeneral_vocabularyFixed()) == 0 && Settings::getGeneral_invertedSearch()) ||
1649 (iter->compare(Settings::kGeneral_threads()) == 0 && !Settings::getGeneral_invertedSearch()) )
1651 nearestNeighborParamsChanged =
true;
1654 if(iter->compare(Settings::kGeneral_port()) == 0 &&
1655 Settings::getGeneral_port() !=
ui_->label_port->text().toInt() &&
1656 Settings::getGeneral_port() != 0)
1663 if(detectorDescriptorParamsChanged)
1669 if(Settings::getGeneral_autoUpdateObjects())
1671 if(detectorDescriptorParamsChanged)
1675 else if(nearestNeighborParamsChanged)
1680 else if(
objWidgets_.size() && (detectorDescriptorParamsChanged || nearestNeighborParamsChanged))
1682 this->statusBar()->showMessage(tr(
"A parameter has changed... \"Update objects\" may be required."));
1685 if(parameterChanged &&
1688 !(Settings::getGeneral_autoUpdateObjects() && detectorDescriptorParamsChanged))
1691 ui_->label_timeRefreshRate->setVisible(
false);
1693 ui_->actionCamera_from_video_file->setChecked(!Settings::getCamera_5mediaPath().isEmpty() && !
UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()) && !Settings::getCamera_6useTcpCamera());
1694 ui_->actionCamera_from_directory_of_images->setChecked(!Settings::getCamera_5mediaPath().isEmpty() &&
UDirectory::exists(Settings::getCamera_5mediaPath().toStdString()) && !Settings::getCamera_6useTcpCamera());
1695 ui_->actionCamera_from_TCP_IP->setChecked(Settings::getCamera_6useTcpCamera());
1697 if(Settings::getGeneral_debug())
void addObjectFromTcp(const cv::Mat &image, int id, const QString &filePath)
virtual void keyPressEvent(QKeyEvent *event)
void updateVocabulary(const QList< int > &ids=QList< int >())
void moveCameraFrame(int frame)
void setupCameraFromTcpIp()
static QVariant getParameter(const QString &key)
QHostAddress getHostAddress() const
std::vector< double > values
void showObjectsFeatures()
std::vector< cv::KeyPoint > sceneKeypoints_
bool detect(const cv::Mat &image, find_object::DetectionInfo &info) const
void updateObjectSize(find_object::ObjWidget *obj)
const cv::Mat & image() const
QMultiMap< int, RejectedCode > rejectedCodes_
static void loadWindowSettings(QByteArray &windowGeometry, QByteArray &windowState, const QString &fileName=QString())
QMap< int, QMultiMap< int, int > > matches_
void setData(const QMap< int, int > &dataMap, const QMap< int, int > &weightsMap)
void addObjectsFromFiles()
static void setLevel(ULogger::Level level)
void setPen(const QPen &pen)
bool loadSession(const QString &path, const ParametersMap &customParameters=ParametersMap())
const std::list< std::string > & getFileNames() const
void showObject(find_object::ObjWidget *obj)
#define UASSERT(condition)
void objectsFound(const find_object::DetectionInfo &, const find_object::Header &header, const cv::Mat &depth, float depthConstant)
static QString currentDetectorType()
static const ParametersMap & getParameters()
QMap< int, QByteArray > imagesMap_
void updateVocabulary(const QList< int > &ids=QList< int >())
void moveToFrame(int frame)
void setSourceImageText(const QString &text)
rtabmap::PdfPlotCurve * likelihoodCurve_
void removeObject(find_object::ObjWidget *object)
QMap< TimeStamp, float > timeStamps_
void updateDetectorExtractor()
const QMap< int, ObjSignature * > & objects() const
QMap< QString, QVariant > lastObjectsUpdateParameters_
AboutDialog * aboutDialog_
bool loadVocabulary(const QString &filePath)
QMultiMap< int, QTransform > objDetected_
void updateObjects(const QList< int > &ids=QList< int >())
void notifyParametersChanged(const QStringList ¶m)
float minMatchedDistance_
QMap< QString, QVariant > ParametersMap
void update(const cv::Mat &image)
const Vocabulary * vocabulary() const
static QString currentDescriptorType()
rtabmap::PdfPlotCurve * inliersCurve_
QMultiMap< int, QMultiMap< int, int > > rejectedInliers_
static void setPrintWhere(bool printWhere)
void rectHovered(int objId)
static ParametersMap loadSettings(const QString &fileName=QString())
QMultiMap< int, QMultiMap< int, int > > objDetectedInliers_
MainWindow(find_object::FindObject *findObject, find_object::Camera *camera=0, QWidget *parent=0)
static void saveWindowSettings(const QByteArray &windowGeometry, const QByteArray &windowState, const QString &fileName=QString())
static QString workingDirectory()
int addObjectFromFile(const QString &filePath)
void removeObject(int id)
virtual void closeEvent(QCloseEvent *event)
void addObjectFromScene()
bool saveSession(const QString &path)
QMultiMap< int, int > sceneWords_
ULogger class and convenient macros.
bool saveVocabulary(const QString &filePath) const
QMultiMap< int, QMultiMap< int, int > > rejectedOutliers_
static bool exists(const std::string &dirPath)
float maxMatchedDistance_
void setupCameraFromImagesDirectory()
QMultiMap< int, QMultiMap< int, int > > objDetectedOutliers_
int getCurrentFrameIndex()
static void saveSettings(const QString &fileName=QString())
const ObjSignature * addObject(const QString &filePath)
FINDOBJECT_EXP QImage cvtCvMat2QImage(const cv::Mat &image, bool isBgr=true)
void hideObjectsFeatures()
QMap< int, find_object::ObjWidget * > objWidgets_
void setupCameraFromVideoFile()
void retrieveObject(ObjWidget **widget, ObjSignature **signature)