ParametersToolBox.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2011-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #include "find_object/Settings.h"
29 
30 #include "ParametersToolBox.h"
31 #include <QComboBox>
32 #include <QDoubleSpinBox>
33 #include <QLineEdit>
34 #include <QLabel>
35 #include <QGroupBox>
36 #include <QCheckBox>
37 #include <QVBoxLayout>
38 #include <QMessageBox>
39 #include <stdio.h>
41 #include <opencv2/opencv_modules.hpp>
42 
43 namespace find_object {
44 
46  QToolBox(parent)
47 {
48 }
49 
51 {
52 }
53 
54 QWidget * ParametersToolBox::getParameterWidget(const QString & key)
55 {
56  return this->findChild<QWidget*>(key);
57 }
58 
59 QStringList ParametersToolBox::resetPage(int index)
60 {
61  QStringList paramChanged;
62  const QObjectList & children = this->widget(index)->children();
63  for(int j=0; j<children.size();++j)
64  {
65  QString key = children.at(j)->objectName();
66  // ignore only the nextObjID setting, to avoid problem with saved objects
67  if(key.compare(Settings::kGeneral_nextObjID()) != 0)
68  {
69  QVariant value = Settings::getDefaultParameters().value(key, QVariant());
70  if(value.isValid())
71  {
72  Settings::setParameter(key, value);
73 
74  if(qobject_cast<QComboBox*>(children.at(j)))
75  {
76  if(((QComboBox*)children.at(j))->currentIndex() != value.toString().split(':').first().toInt())
77  {
78  ((QComboBox*)children.at(j))->setCurrentIndex(value.toString().split(':').first().toInt());
79  paramChanged.append(key);
80  }
81  }
82  else if(qobject_cast<QSpinBox*>(children.at(j)))
83  {
84  if(((QSpinBox*)children.at(j))->value() != value.toInt())
85  {
86  ((QSpinBox*)children.at(j))->setValue(value.toInt());
87  paramChanged.append(key);
88  }
89  }
90  else if(qobject_cast<QDoubleSpinBox*>(children.at(j)))
91  {
92  if(((QDoubleSpinBox*)children.at(j))->value() != value.toDouble())
93  {
94  ((QDoubleSpinBox*)children.at(j))->setValue(value.toDouble());
95  paramChanged.append(key);
96  }
97  }
98  else if(qobject_cast<QCheckBox*>(children.at(j)))
99  {
100  if(((QCheckBox*)children.at(j))->isChecked() != value.toBool())
101  {
102  ((QCheckBox*)children.at(j))->setChecked(value.toBool());
103  paramChanged.append(key);
104  }
105  }
106  else if(qobject_cast<QLineEdit*>(children.at(j)))
107  {
108  if(((QLineEdit*)children.at(j))->text().compare(value.toString()) != 0)
109  {
110  ((QLineEdit*)children.at(j))->setText(value.toString());
111  paramChanged.append(key);
112  }
113  }
114  }
115  }
116  }
117  return paramChanged;
118 }
119 
121 {
122  this->blockSignals(true);
123  QStringList paramChanged = this->resetPage(this->currentIndex());
124  this->blockSignals(false);
125  Q_EMIT parametersChanged(paramChanged);
126 }
127 
129 {
130  QStringList paramChanged;
131  this->blockSignals(true);
132  for(int i=0; i< this->count(); ++i)
133  {
134  paramChanged.append(this->resetPage(i));
135  }
136  this->blockSignals(false);
137  Q_EMIT parametersChanged(paramChanged);
138 }
139 
141 {
142  //show/hide not used parameters
143  QComboBox * descriptorBox = this->findChild<QComboBox*>(Settings::kFeature2D_2Descriptor());
144  QComboBox * detectorBox = this->findChild<QComboBox*>(Settings::kFeature2D_1Detector());
145  if(descriptorBox && detectorBox)
146  {
147  QString group = Settings::kFeature2D_2Descriptor().split('/').first();
148  QWidget * panel = 0;
149  for(int i=0; i<this->count(); ++i)
150  {
151  if(this->widget(i)->objectName().compare(group) == 0)
152  {
153  panel = this->widget(i);
154  break;
155  }
156  }
157  if(panel)
158  {
159  const QObjectList & objects = panel->children();
160  QString descriptorName = descriptorBox->currentText();
161  QString detectorName = detectorBox->currentText();
162 
163  for(int i=0; i<objects.size(); ++i)
164  {
165  if(!objects[i]->objectName().isEmpty())
166  {
167  if(objects[i]->objectName().contains(descriptorName) || objects[i]->objectName().contains(detectorName))
168  {
169  ((QWidget*)objects[i])->setVisible(true);
170  }
171  else if(objects[i]->objectName().contains("Fast") && detectorName == QString("ORB"))
172  {
173  ((QWidget*)objects[i])->setVisible(true); // ORB uses some FAST parameters
174  }
175  else if(!objects[i]->objectName().split('/').at(1).at(0).isDigit())
176  {
177  ((QWidget*)objects[i])->setVisible(false);
178  }
179  }
180  }
181  }
182  }
183 
184  QComboBox * nnBox = this->findChild<QComboBox*>(Settings::kNearestNeighbor_1Strategy());
185  if(nnBox)
186  {
187  QString group = Settings::kNearestNeighbor_1Strategy().split('/').first();
188  QWidget * panel = 0;
189  for(int i=0; i<this->count(); ++i)
190  {
191  if(this->widget(i)->objectName().compare(group) == 0)
192  {
193  panel = this->widget(i);
194  break;
195  }
196  }
197  if(panel)
198  {
199  const QObjectList & objects = panel->children();
200  QString nnName = nnBox->currentText();
201 
202  for(int i=0; i<objects.size(); ++i)
203  {
204  if(!objects[i]->objectName().isEmpty())
205  {
206  if(objects[i]->objectName().contains(nnName))
207  {
208  ((QWidget*)objects[i])->setVisible(true);
209  }
210  else if(!objects[i]->objectName().split('/').at(1).at(0).isDigit())
211  {
212  ((QWidget*)objects[i])->setVisible(false);
213  if(nnBox->currentIndex() < 6 && objects[i]->objectName().split('/').at(1).contains("search"))
214  {
215  //show flann search parameters
216  ((QWidget*)objects[i])->setVisible(true);
217  }
218  }
219  else if(objects[i]->objectName().split('/').at(1).contains("Distance_type"))
220  {
221  // don't show distance when bruteforce is selected
222  ((QWidget*)objects[i])->setVisible(nnBox->currentIndex() != 6);
223  }
224  }
225  }
226  }
227  }
228 }
229 
231 {
232  this->removeItem(0); // remove dummy page used in .ui
233  QWidget * currentItem = 0;
234  const ParametersMap & parameters = Settings::getParameters();
235  for(ParametersMap::const_iterator iter=parameters.constBegin();
236  iter!=parameters.constEnd();
237  ++iter)
238  {
239  QStringList splitted = iter.key().split('/');
240  QString group = splitted.first();
241  QString name = splitted.last();
242  if(currentItem == 0 || currentItem->objectName().compare(group) != 0)
243  {
244  currentItem = new QWidget(this);
245  this->addItem(currentItem, group);
246  currentItem->setObjectName(group);
247  QVBoxLayout * layout = new QVBoxLayout(currentItem);
248  currentItem->setLayout(layout);
249  layout->setContentsMargins(0,0,0,0);
250  layout->setSpacing(0);
251  layout->addSpacerItem(new QSpacerItem(0,0, QSizePolicy::Minimum, QSizePolicy::Expanding));
252 
253  addParameter(layout, iter.key(), iter.value());
254  }
255  else
256  {
257  addParameter((QVBoxLayout*)currentItem->layout(), iter.key(), iter.value());
258  }
259  }
260 
262 }
263 
264 void ParametersToolBox::updateParameter(const QString & key)
265 {
266  QWidget * widget = this->findChild<QWidget*>(key);
267  QString type = Settings::getParametersType().value(key);
268  if(type.compare("QString") == 0)
269  {
270  QString value = Settings::getParameter(key).toString();
271  if(value.contains(';'))
272  {
273  // It's a list, just change the index
274  QStringList splitted = value.split(':');
275  ((QComboBox*)widget)->setCurrentIndex(splitted.first().toInt());
276  }
277  else
278  {
279  ((QLineEdit*)widget)->setText(value);
280  }
281  }
282  else if(type.compare("int") == 0)
283  {
284  ((QSpinBox*)widget)->setValue(Settings::getParameter(key).toInt());
285  }
286  else if(type.compare("uint") == 0)
287  {
288  ((QSpinBox*)widget)->setValue(Settings::getParameter(key).toInt());
289  }
290  else if(type.compare("double") == 0)
291  {
292  ((QDoubleSpinBox*)widget)->setValue(Settings::getParameter(key).toDouble());
293  }
294  else if(type.compare("float") == 0)
295  {
296  ((QDoubleSpinBox*)widget)->setValue(Settings::getParameter(key).toDouble());
297  }
298  else if(type.compare("bool") == 0)
299  {
300  ((QCheckBox*)widget)->setChecked(Settings::getParameter(key).toBool());
301  }
302 }
303 
304 void ParametersToolBox::addParameter(QVBoxLayout * layout,
305  const QString & key,
306  const QVariant & value)
307 {
308  QString type = Settings::getParametersType().value(key);
309  if(type.compare("QString") == 0)
310  {
311  addParameter(layout, key, value.toString());
312  }
313  else if(type.compare("int") == 0)
314  {
315  addParameter(layout, key, value.toInt());
316  }
317  else if(type.compare("uint") == 0)
318  {
319  addParameter(layout, key, value.toInt());
320  }
321  else if(type.compare("double") == 0)
322  {
323  addParameter(layout, key, value.toDouble());
324  }
325  else if(type.compare("float") == 0)
326  {
327  addParameter(layout, key, value.toDouble());
328  }
329  else if(type.compare("bool") == 0)
330  {
331  addParameter(layout, key, value.toBool());
332  }
333 }
334 
335 void ParametersToolBox::addParameter(QVBoxLayout * layout,
336  const QString & key,
337  const QString & value)
338 {
339  if(value.contains(';'))
340  {
341  QComboBox * widget = new QComboBox(this);
342  widget->setObjectName(key);
343  QStringList splitted = value.split(':');
344  widget->addItems(splitted.last().split(';'));
345 
346  if(key.compare(Settings::kFeature2D_1Detector()) == 0)
347  {
348 #if FINDOBJECT_NONFREE == 0
349 #if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && (CV_MINOR_VERSION < 3 || (CV_MINOR_VERSION==3 && !defined(OPENCV_DEV))))
350  widget->setItemData(5, 0, Qt::UserRole - 1); // disable SIFT
351 #endif
352  widget->setItemData(7, 0, Qt::UserRole - 1); // disable SURF
353 #endif
354 #if CV_MAJOR_VERSION < 3
355  widget->setItemData(9, 0, Qt::UserRole - 1); // disable AGAST
356  widget->setItemData(10, 0, Qt::UserRole - 1); // disable KAZE
357  widget->setItemData(11, 0, Qt::UserRole - 1); // disable AKAZE
358 #else
359  widget->setItemData(0, 0, Qt::UserRole - 1); // disable Dense
360 #ifndef HAVE_OPENCV_XFEATURES2D
361  widget->setItemData(6, 0, Qt::UserRole - 1); // disable Star
362 #endif
363 #endif
364 #if FINDOBJECT_TORCH == 0
365  widget->setItemData(12, 0, Qt::UserRole - 1); // disable SuperPointTorch
366 #endif
367  }
368  if(key.compare(Settings::kFeature2D_2Descriptor()) == 0)
369  {
370 #if FINDOBJECT_NONFREE == 0
371 #if CV_MAJOR_VERSION < 4 || (CV_MAJOR_VERSION == 4 && (CV_MINOR_VERSION < 3 || (CV_MINOR_VERSION==3 && !defined(OPENCV_DEV))))
372  widget->setItemData(2, 0, Qt::UserRole - 1); // disable SIFT
373 #endif
374  widget->setItemData(3, 0, Qt::UserRole - 1); // disable SURF
375 #endif
376 #if CV_MAJOR_VERSION < 3
377  widget->setItemData(6, 0, Qt::UserRole - 1); // disable KAZE
378  widget->setItemData(7, 0, Qt::UserRole - 1); // disable AKAZE
379  widget->setItemData(8, 0, Qt::UserRole - 1); // disable LUCID
380  widget->setItemData(9, 0, Qt::UserRole - 1); // disable LATCH
381  widget->setItemData(10, 0, Qt::UserRole - 1); // disable DAISY
382 #else
383 
384 #ifndef HAVE_OPENCV_XFEATURES2D
385  widget->setItemData(0, 0, Qt::UserRole - 1); // disable Brief
386  widget->setItemData(5, 0, Qt::UserRole - 1); // disable Freak
387  widget->setItemData(8, 0, Qt::UserRole - 1); // disable LUCID
388  widget->setItemData(9, 0, Qt::UserRole - 1); // disable LATCH
389  widget->setItemData(10, 0, Qt::UserRole - 1); // disable DAISY
390 #endif
391 #endif
392 #if FINDOBJECT_TORCH == 0
393  widget->setItemData(11, 0, Qt::UserRole - 1); // disable SuperPointTorch
394 #endif
395  }
396  if(key.compare(Settings::kNearestNeighbor_1Strategy()) == 0)
397  {
398 #if FINDOBJECT_NONFREE == 0 && CV_MAJOR_VERSION < 3
399  // disable FLANN approaches (cannot be used with binary descriptors)
400  widget->setItemData(0, 0, Qt::UserRole - 1);
401  widget->setItemData(1, 0, Qt::UserRole - 1);
402  widget->setItemData(2, 0, Qt::UserRole - 1);
403  widget->setItemData(3, 0, Qt::UserRole - 1);
404  widget->setItemData(4, 0, Qt::UserRole - 1);
405 #endif
406  }
407  if(key.compare(Settings::kHomography_method()) == 0)
408  {
409 #if CV_MAJOR_VERSION < 3
410  // disable RHO approach
411  widget->setItemData(2, 0, Qt::UserRole - 1);
412 #endif
413  }
414 
415  widget->setCurrentIndex(splitted.first().toInt());
416  connect(widget, SIGNAL(currentIndexChanged(int)), this, SLOT(changeParameter(int)));
417  addParameter(layout, key, widget);
418  }
419  else
420  {
421  QLineEdit * widget = new QLineEdit(value, this);
422  widget->setObjectName(key);
423  connect(widget, SIGNAL(editingFinished()), this, SLOT(changeParameter()));
424  addParameter(layout, key, widget);
425  }
426 }
427 
428 void ParametersToolBox::addParameter(QVBoxLayout * layout,
429  const QString & key,
430  const double & value)
431 {
432  QDoubleSpinBox * widget = new QDoubleSpinBox(this);
433  int decimals = 0;
434  int decimalValue = 0;
435 
436  QString str = QString::number(Settings::getDefaultParameters().value(key).toDouble());
437  str.remove( QRegExp("0+$") );
438 
439  if(!str.isEmpty())
440  {
441  str.replace(',', '.');
442  QStringList items = str.split('.');
443  if(items.size() == 2)
444  {
445  decimals = items.back().length();
446  decimalValue = items.back().toInt();
447  }
448  }
449 
450  double def = Settings::getDefaultParameters().value(key).toDouble();
451  if(def<0.001 || (decimals >= 4 && decimalValue>0))
452  {
453  widget->setDecimals(5);
454  widget->setSingleStep(0.0001);
455  }
456  else if(def<0.01 || (decimals >= 3 && decimalValue>0))
457  {
458  widget->setDecimals(4);
459  widget->setSingleStep(0.001);
460  }
461  else if(def<0.1 || (decimals >= 2 && decimalValue>0))
462  {
463  widget->setDecimals(3);
464  widget->setSingleStep(0.01);
465  }
466  else if(def<1.0 || (decimals >= 1 && decimalValue>0))
467  {
468  widget->setDecimals(2);
469  widget->setSingleStep(0.1);
470  }
471  else
472  {
473  widget->setDecimals(1);
474  }
475 
476  if(def>0.0)
477  {
478  widget->setMaximum(def*1000000.0);
479  }
480  else if(def==0.0)
481  {
482  widget->setMaximum(1000000.0);
483  }
484  else if(def<0.0)
485  {
486  widget->setMinimum(def*1000000.0);
487  widget->setMaximum(0.0);
488  }
489  widget->setValue(value);
490  widget->setObjectName(key);
491  connect(widget, SIGNAL(editingFinished()), this, SLOT(changeParameter()));
492  addParameter(layout, key, widget);
493 }
494 
495 void ParametersToolBox::addParameter(QVBoxLayout * layout,
496  const QString & key,
497  const int & value)
498 {
499  QSpinBox * widget = new QSpinBox(this);
500  int def = Settings::getDefaultParameters().value(key).toInt();
501 
502  if(def>0)
503  {
504  widget->setMaximum(def*1000000);
505  }
506  else if(def == 0)
507  {
508  widget->setMaximum(1000000);
509  }
510  else if(def<0)
511  {
512  widget->setMinimum(def*1000000);
513  widget->setMaximum(0);
514  }
515  widget->setValue(value);
516  widget->setObjectName(key);
517  connect(widget, SIGNAL(editingFinished()), this, SLOT(changeParameter()));
518  addParameter(layout, key, widget);
519 }
520 
521 void ParametersToolBox::addParameter(QVBoxLayout * layout,
522  const QString & key,
523  const bool & value)
524 {
525  QCheckBox * widget = new QCheckBox(this);
526  widget->setChecked(value);
527  widget->setObjectName(key);
528  connect(widget, SIGNAL(toggled(bool)), this, SLOT(changeParameter(bool)));
529  addParameter(layout, key, widget);
530 }
531 
532 void ParametersToolBox::addParameter(QVBoxLayout * layout, const QString & key, QWidget * widget)
533 {
534  QHBoxLayout * hLayout = new QHBoxLayout();
535  layout->insertLayout(layout->count()-1, hLayout);
536  QString tmp = key.split('/').last();
537  if(tmp.at(0).isDigit())
538  {
539  tmp.remove(0,1);
540  }
541  QLabel * label = new QLabel(tmp, this);
542  label->setObjectName(key+"/label");
543  label->setToolTip(QString("<FONT>%1</FONT>").arg(Settings::getDescriptions().value(key, "")));
544  label->setTextInteractionFlags(Qt::TextSelectableByMouse);
545  hLayout->addWidget(label);
546  hLayout->addWidget(widget);
547 }
548 
549 void ParametersToolBox::changeParameter(const QString & value)
550 {
551  if(sender())
552  {
553  Settings::setParameter(sender()->objectName(), value);
554  QStringList paramChanged;
555  paramChanged.append(sender()->objectName());
556  Q_EMIT parametersChanged(paramChanged);
557  }
558 }
560 {
561  if(sender())
562  {
563  QDoubleSpinBox * doubleSpinBox = qobject_cast<QDoubleSpinBox*>(sender());
564  QSpinBox * spinBox = qobject_cast<QSpinBox*>(sender());
565  QLineEdit * lineEdit = qobject_cast<QLineEdit*>(sender());
566  if(doubleSpinBox)
567  {
568  Settings::setParameter(sender()->objectName(), doubleSpinBox->value());
569  }
570  else if(spinBox)
571  {
572  if(spinBox->objectName().compare(Settings::kHomography_minimumInliers()) == 0 &&
573  spinBox->value() < 4)
574  {
575  Settings::setHomography_minimumInliers(4);
576  spinBox->blockSignals(true);
577  this->updateParameter(Settings::kHomography_minimumInliers());
578  spinBox->blockSignals(false);
579  }
580  else
581  {
582  Settings::setParameter(sender()->objectName(), spinBox->value());
583  }
584  }
585  else if(lineEdit)
586  {
587  Settings::setParameter(sender()->objectName(), lineEdit->text());
588  }
589  QStringList paramChanged;
590  paramChanged.append(sender()->objectName());
591  Q_EMIT parametersChanged(paramChanged);
592  }
593 }
594 
596 {
597  if(sender())
598  {
599  // Workaround as stateChanged(int) is not always emitted, using toggled(bool) instead
600  changeParameter(sender(), value?Qt::Checked:Qt::Unchecked);
601  }
602 }
603 
605 {
606  if(sender())
607  {
608  changeParameter(sender(), value);
609  }
610 }
611 
612 void ParametersToolBox::changeParameter(QObject * sender, int value)
613 {
614  if(sender)
615  {
616  QStringList paramChanged;
617  QComboBox * comboBox = qobject_cast<QComboBox*>(sender);
618  QCheckBox * checkBox = qobject_cast<QCheckBox*>(sender);
619 
620  bool descriptorChanged = false;
621  if(comboBox && comboBox->objectName().compare(Settings::kFeature2D_1Detector()) == 0)
622  {
623  QComboBox * descriptorBox = (QComboBox*)this->getParameterWidget(Settings::kFeature2D_2Descriptor());
624  if(comboBox->objectName().compare(Settings::kFeature2D_1Detector()) == 0 &&
625  comboBox->currentText() != descriptorBox->currentText() &&
626  Settings::getFeature2D_2Descriptor().contains(comboBox->currentText()))
627  {
628  QMessageBox::StandardButton b = QMessageBox::question(this,
629  tr("Use corresponding descriptor type?"),
630  tr("Current selected detector type (\"%1\") has its own corresponding descriptor type.\n"
631  "Do you want to use its corresponding descriptor?")
632  .arg(comboBox->currentText()),
633  QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
634  if(b == QMessageBox::Yes)
635  {
636  int index = descriptorBox->findText(comboBox->currentText());
637  if(index >= 0)
638  {
639  QStringList tmp = Settings::getFeature2D_2Descriptor().split(':');
640  UASSERT(tmp.size() == 2);
641  QString newTmp = QString::number(index)+":"+tmp.back();
642  Settings::setFeature2D_2Descriptor(newTmp);
643  descriptorBox->blockSignals(true);
644  this->updateParameter(Settings::kFeature2D_2Descriptor());
645  descriptorBox->blockSignals(false);
646  paramChanged.append(Settings::kFeature2D_2Descriptor());
647  descriptorChanged = true;
648  }
649  else
650  {
651  UERROR("Combo box detector type not found \"%s\"?!", comboBox->currentText().toStdString().c_str());
652  }
653  }
654  }
655  }
656 
657  bool nnStrategyChanged = false;
658  //verify binary issue with nearest neighbor strategy
659  if((comboBox && (comboBox->objectName().compare(Settings::kFeature2D_2Descriptor()) == 0 ||
660  comboBox->objectName().compare(Settings::kNearestNeighbor_1Strategy()) == 0)) ||
661  descriptorChanged ||
662  (checkBox && checkBox->objectName().compare(Settings::kNearestNeighbor_7ConvertBinToFloat()) == 0))
663  {
664  QComboBox * descriptorBox = (QComboBox*)this->getParameterWidget(Settings::kFeature2D_2Descriptor());
665  QComboBox * nnBox = (QComboBox*)this->getParameterWidget(Settings::kNearestNeighbor_1Strategy());
666  QComboBox * distBox = (QComboBox*)this->getParameterWidget(Settings::kNearestNeighbor_2Distance_type());
667  QCheckBox * binToFloatCheckbox = (QCheckBox*)this->getParameterWidget(Settings::kNearestNeighbor_7ConvertBinToFloat());
668  bool isBinaryDescriptor = descriptorBox->currentText().compare("ORB") == 0 ||
669  descriptorBox->currentText().compare("Brief") == 0 ||
670  descriptorBox->currentText().compare("BRISK") == 0 ||
671  descriptorBox->currentText().compare("FREAK") == 0 ||
672  descriptorBox->currentText().compare("AKAZE") == 0 ||
673  descriptorBox->currentText().compare("LATCH") == 0 ||
674  descriptorBox->currentText().compare("LUCID") == 0;
675  bool binToFloat = binToFloatCheckbox->isChecked();
676  if(isBinaryDescriptor && !binToFloat && nnBox->currentText().compare("Lsh") != 0 && nnBox->currentText().compare("BruteForce") != 0)
677  {
678  QMessageBox::warning(this,
679  tr("Warning"),
680  tr("Current selected descriptor type (\"%1\") is binary while nearest neighbor strategy is not (\"%2\").\n"
681  "Falling back to \"BruteForce\" nearest neighbor strategy with Hamming distance (by default).")
682  .arg(descriptorBox->currentText())
683  .arg(nnBox->currentText()));
684  QString tmp = Settings::getNearestNeighbor_1Strategy();
685  *tmp.begin() = '6'; // set BruteForce
686  Settings::setNearestNeighbor_1Strategy(tmp);
687  tmp = Settings::getNearestNeighbor_2Distance_type();
688  *tmp.begin() = '8'; // set HAMMING
689  Settings::setNearestNeighbor_2Distance_type(tmp);
690  nnBox->blockSignals(true);
691  distBox->blockSignals(true);
692  this->updateParameter(Settings::kNearestNeighbor_1Strategy());
693  this->updateParameter(Settings::kNearestNeighbor_2Distance_type());
694  nnBox->blockSignals(false);
695  distBox->blockSignals(false);
696  if(sender == nnBox)
697  {
699  return;
700  }
701  nnStrategyChanged = true;
702  paramChanged.append(Settings::kNearestNeighbor_1Strategy());
703  paramChanged.append(Settings::kNearestNeighbor_2Distance_type());
704  }
705  else if((!isBinaryDescriptor || binToFloat) && nnBox->currentText().compare("Lsh") == 0)
706  {
707  if(binToFloat)
708  {
709  QMessageBox::warning(this,
710  tr("Warning"),
711  tr("Current selected descriptor type (\"%1\") is binary, but binary to float descriptors conversion is activated while nearest neighbor strategy is (\"%2\").\n"
712  "Disabling binary to float descriptors conversion and use Hamming distance (by default).")
713  .arg(descriptorBox->currentText())
714  .arg(nnBox->currentText()));
715 
716  binToFloatCheckbox->blockSignals(true);
717  if(checkBox && checkBox->objectName().compare(Settings::kNearestNeighbor_7ConvertBinToFloat()) == 0)
718  {
719  Settings::setParameter(checkBox->objectName(), false);
720  value = 0;
721  }
722  else
723  {
724  paramChanged.append(Settings::kNearestNeighbor_7ConvertBinToFloat());
725  }
726  this->updateParameter(Settings::kNearestNeighbor_7ConvertBinToFloat());
727  binToFloatCheckbox->blockSignals(false);
728 
729  QString tmp = Settings::getNearestNeighbor_2Distance_type();
730  *tmp.begin() = '8'; // set HAMMING
731  Settings::setNearestNeighbor_2Distance_type(tmp);
732  distBox->blockSignals(true);
733  this->updateParameter(Settings::kNearestNeighbor_2Distance_type());
734  distBox->blockSignals(false);
735  paramChanged.append(Settings::kNearestNeighbor_2Distance_type());
736  }
737  else
738  {
739  QMessageBox::warning(this,
740  tr("Warning"),
741  tr("Current selected descriptor type (\"%1\") is not binary while nearest neighbor strategy is (\"%2\").\n"
742  "Falling back to \"KDTree\" nearest neighbor strategy with Euclidean_L2 distance (by default).")
743  .arg(descriptorBox->currentText())
744  .arg(nnBox->currentText()));
745 
746  QString tmp = Settings::getNearestNeighbor_1Strategy();
747  *tmp.begin() = '1'; // set KDTree
748  Settings::setNearestNeighbor_1Strategy(tmp);
749  tmp = Settings::getNearestNeighbor_2Distance_type();
750  *tmp.begin() = '0'; // set EUCLIDEAN_L2
751  Settings::setNearestNeighbor_2Distance_type(tmp);
752  nnBox->blockSignals(true);
753  distBox->blockSignals(true);
754  this->updateParameter(Settings::kNearestNeighbor_1Strategy());
755  this->updateParameter(Settings::kNearestNeighbor_2Distance_type());
756  nnBox->blockSignals(false);
757  distBox->blockSignals(false);
758  if(sender == nnBox)
759  {
761  return;
762  }
763  nnStrategyChanged = true;
764  paramChanged.append(Settings::kNearestNeighbor_1Strategy());
765  paramChanged.append(Settings::kNearestNeighbor_2Distance_type());
766  }
767  }
768  }
769 
770  // Distance issue when using nearest neighbor strategy using CV_32F type, though Lsh support all type (doesn't crash at least)
771  if(nnStrategyChanged ||
772  (comboBox && (comboBox->objectName().compare(Settings::kNearestNeighbor_1Strategy()) == 0 ||
773  comboBox->objectName().compare(Settings::kNearestNeighbor_2Distance_type()) == 0)))
774  {
775  QComboBox * nnBox = (QComboBox*)this->getParameterWidget(Settings::kNearestNeighbor_1Strategy());
776  QComboBox * distBox = (QComboBox*)this->getParameterWidget(Settings::kNearestNeighbor_2Distance_type());
777  if(nnBox->currentText().compare("BruteForce") != 0 && nnBox->currentText().compare("Lsh") != 0 && distBox->currentIndex() > 1)
778  {
779  QMessageBox::warning(this,
780  tr("Warning"),
781  tr("Current selected nearest neighbor strategy type (\"%1\") cannot handle distance strategy (\"%2\").\n"
782  "Falling back to \"EUCLIDEAN_L2\" distance strategy (by default).")
783  .arg(nnBox->currentText())
784  .arg(distBox->currentText()));
785  QString tmp = Settings::getNearestNeighbor_2Distance_type();
786  *tmp.begin() = '0'; // set index
787  Settings::setNearestNeighbor_2Distance_type(tmp);
788  distBox->blockSignals(true);
789  this->updateParameter(Settings::kNearestNeighbor_2Distance_type());
790  distBox->blockSignals(false);
791  if(sender == distBox)
792  {
794  return;
795  }
796  paramChanged.append(Settings::kNearestNeighbor_2Distance_type());
797  }
798  }
799 
800  if(comboBox)
801  {
802  QStringList items;
803  for(int i=0; i<comboBox->count(); ++i)
804  {
805  items.append(comboBox->itemText(i));
806  }
807  QString merged = QString::number(value) + QString(":") + items.join(";");
808  Settings::setParameter(sender->objectName(), merged);
809  }
810 
811  if(checkBox)
812  {
813  Settings::setParameter(sender->objectName(), value==Qt::Checked?true:false);
814  }
815 
817 
818  paramChanged.append(sender->objectName());
819  Q_EMIT parametersChanged(paramChanged);
820  }
821 }
822 
823 } // namespace find_object
static QVariant getParameter(const QString &key)
Definition: Settings.h:343
static const ParametersType & getParametersType()
Definition: Settings.h:339
void parametersChanged(const QStringList &name)
#define UASSERT(condition)
static const ParametersMap & getParameters()
Definition: Settings.h:338
void addParameter(QVBoxLayout *layout, const QString &key, const QVariant &value)
static void setParameter(const QString &key, const QVariant &value)
Definition: Settings.h:341
static const DescriptionsMap & getDescriptions()
Definition: Settings.h:340
QMap< QString, QVariant > ParametersMap
Definition: Settings.h:41
QWidget * getParameterWidget(const QString &key)
QStringList resetPage(int index)
#define UERROR(...)
ULogger class and convenient macros.
void updateParameter(const QString &key)
static const ParametersMap & getDefaultParameters()
Definition: Settings.h:337


find_object_2d
Author(s): Mathieu Labbe
autogenerated on Mon Dec 12 2022 03:20:09