ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
qCanupo2DViewDialog.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "qCanupo2DViewDialog.h"
9 
10 // local
11 #include "qCanupoTools.h"
12 
13 // CV_DB_LIB
14 #include <ecvDisplayTools.h>
15 #include <ecvMainAppInterface.h>
16 #include <ecvPointCloud.h>
17 #include <ecvPolyline.h>
18 #include <ecvSphere.h>
19 
20 // Qt
21 #include <QApplication>
22 #include <QFileDialog>
23 #include <QFileInfo>
24 #include <QMainWindow>
25 #include <QMessageBox>
26 #include <QPushButton>
27 #include <QSettings>
28 
29 // system
30 #include <assert.h>
31 
32 #include <limits>
33 
34 static bool s_firstDisplay = true;
35 
37  const CorePointDescSet* descriptors1,
38  const CorePointDescSet* descriptors2,
39  QString cloud1Name,
40  QString cloud2Name,
41  int class1 /*=1*/,
42  int class2 /*=2*/,
43  const CorePointDescSet* evaluationDescriptors /*=0*/,
44  ecvMainAppInterface* app /*=0*/)
45  : QDialog(app ? app->getActiveWindow() : 0),
46  Ui::Canupo2DViewDialog(),
47  m_app(app),
48  m_classifierSaved(false),
49  m_descriptors1(descriptors1),
50  m_descriptors2(descriptors2),
51  m_evaluationDescriptors(evaluationDescriptors),
52  m_class1(class1),
53  m_cloud1Name(cloud1Name),
54  m_cloud2Name(cloud2Name),
55  m_class2(class2),
56  m_cloud(0),
57  m_poly(0),
58  m_polyVertices(0),
59  m_selectedPointIndex(-1),
60  m_pickingRadius(5) {
61  setupUi(this);
62 
63  // update legend
64  cloud1NameLabel->setText(QString("class %1: ").arg(m_class1) +
65  m_cloud1Name); // blue points
66  cloud2NameLabel->setText(QString("class %1: ").arg(m_class2) +
67  m_cloud2Name); // red points
68 
69  s_firstDisplay = true;
70 
71  // setup 2D view
72  {
73  // QWidget* glWidget = 0;
74  // m_app->createGLWindow(m_glWindow, glWidget);
75  // assert(m_glWindow && glWidget);
76 
77  // ecvGui::ParamStruct params = ecvDisplayTools::GetDisplayParameters();
78  // params.backgroundCol = ecvColor::white;
79  // params.textDefaultCol = ecvColor::black;
80  // params.pointsDefaultCol = ecvColor::black;
81  // params.drawBackgroundGradient = false;
82  // params.displayCross = false;
83  // ecvDisplayTools::SetDisplayParameters(params);
84  // ecvDisplayTools::SetPerspectiveState(false,true);
85  // ecvDisplayTools::SetInteractionMode(ecvDisplayTools::PAN_ONLY() |
86  // ecvDisplayTools::INTERACT_SEND_ALL_SIGNALS);
87  // ecvDisplayTools::SetPickingMode(ecvDisplayTools::NO_PICKING);
88  // ecvDisplayTools::DisplayOverlayEntities(false);
89  // add window to the dedicated layout
90  viewFrame->setLayout(new QHBoxLayout());
91  /*viewFrame->layout()->addWidget(ecvDisplayTools::GetCurrentScreen());
92 
93  connect(ecvDisplayTools::TheInstance(), SIGNAL(leftButtonClicked(int,
94  int)), this, SLOT(addOrSelectPoint(int, int)));
95  connect(ecvDisplayTools::TheInstance(), SIGNAL(rightButtonClicked(int,
96  int)), this, SLOT(removePoint(int, int)));
97  connect(ecvDisplayTools::TheInstance(), SIGNAL(mouseMoved(int, int,
98  Qt::MouseButtons)), this, SLOT(moveSelectedPoint(int, int,
99  Qt::MouseButtons))); connect(ecvDisplayTools::TheInstance(),
100  SIGNAL(buttonReleased()), this, SLOT(deselectPoint()));*/
101  }
102 
103  updateScalesList(true);
104 
105  // loadParamsFromPersistentSettings();
106  connect(resetToolButton, SIGNAL(clicked()), this, SLOT(resetBoundary()));
107  connect(statisticsToolButton, SIGNAL(clicked()), this,
108  SLOT(computeStatistics()));
109  connect(savePushButton, SIGNAL(clicked()), this, SLOT(saveClassifier()));
110  connect(donePushButton, SIGNAL(clicked()), this, SLOT(checkBeforeAccept()));
111  connect(pointSizeSpinBox, SIGNAL(valueChanged(int)), this,
112  SLOT(setPointSize(int)));
113  connect(scalesCountSpinBox, SIGNAL(valueChanged(int)), this,
114  SLOT(onScalesCountSpinBoxChanged(int)));
115 }
116 
118  reset();
119 
121  // m_app->destroyGLWindow(m_glWindow);
122  }
123 }
124 
126  // update list of scales
127  if (!m_descriptors1 || !m_descriptors2) {
128  scalesListLineEdit->setText("Invalid descriptors!");
129  scalesCountSpinBox->setEnabled(false);
130  } else {
131  const std::vector<float>& allScales = m_descriptors1->scales();
132  int maxScaleCount = static_cast<int>(allScales.size());
133  scalesCountSpinBox->setRange(1, maxScaleCount);
134  if (firstTime) scalesCountSpinBox->setValue(maxScaleCount);
135 
136  int currentScaleCount = scalesCountSpinBox->value();
137  QStringList scalesList;
138  for (int i = 0; i < currentScaleCount; ++i)
139  scalesList << QString::number(
140  allScales[maxScaleCount - currentScaleCount + i]);
141 
142  scalesListLineEdit->setText(scalesList.join(" "));
143  scalesCountSpinBox->setEnabled(true);
144  }
145 }
146 
148  // if (ecvDisplayTools::GetCurrentScreen())
149  // ecvDisplayTools::GetOwnDB()->removeAllChildren();
150 
151  if (m_poly) delete m_poly;
152  m_poly = 0;
153  m_polyVertices = 0; // m_polyVertices is a child of m_poly
154 
155  if (m_cloud) delete m_cloud;
156  m_cloud = 0;
157 }
158 
159 void qCanupo2DViewDialog::getActiveScales(std::vector<float>& scales) const {
160  scales.clear();
161 
162  if (!m_descriptors1) return;
163 
164  // take only the right number (among the smallest)
165  const std::vector<float>& allScales = m_descriptors1->scales();
166  int maxScaleCount = static_cast<int>(allScales.size());
167  int currentScaleCount = scalesCountSpinBox->value();
168  assert(currentScaleCount >= 1 && currentScaleCount <= maxScaleCount);
169  currentScaleCount = std::min<int>(currentScaleCount, maxScaleCount);
170  scales.resize(currentScaleCount);
171  for (int i = 0; i < currentScaleCount; ++i) {
172  // take only the smallest values (scales are sorted from the biggest to
173  // the smallest)
174  scales[i] = allScales[maxScaleCount - currentScaleCount + i];
175  }
176 }
177 
178 // Training in progress
179 static bool s_training = false;
180 static int s_trainingValue = 0;
181 
183  if (!m_descriptors1 || !m_descriptors2) return false;
184 
185  s_training = true;
186  s_trainingValue = scalesCountSpinBox->value();
187  statisticsToolButton->setEnabled(false);
188  setEnabled(false);
189  QApplication::processEvents();
190 
191  // take only the right number (among the smallest)
192  std::vector<float> scales;
193  getActiveScales(scales);
194 
195  // reset display
196  reset();
197 
198  // Reset classifier and re-train it!
202 
203  m_cloud = new ccPointCloud("CANUPO projections");
205  *m_descriptors2, scales, m_cloud,
207  delete m_cloud;
208  m_cloud = 0;
209 
210  s_training = false;
211  setEnabled(true);
212 
213  return false;
214  }
215 
217 
218  // show reference points as spheres
219  {
221  ccGLMatrix matPos;
224  ccSphere* spherePos = new ccSphere(l, &matPos);
225  spherePos->setColor(ecvColor::red);
226  spherePos->showColors(true);
227  spherePos->enableStippling(true);
228  m_cloud->addChild(spherePos);
229  addObject(spherePos);
230 
231  ccGLMatrix matNeg;
234  ccSphere* sphereNeg = new ccSphere(l, &matNeg);
235  sphereNeg->setColor(ecvColor::blue);
236  sphereNeg->showColors(true);
237  sphereNeg->enableStippling(true);
238  m_cloud->addChild(sphereNeg);
239  addObject(sphereNeg);
240  }
241 
242  // update/create boundary representation
243  resetBoundary();
244 
245  if (s_firstDisplay) {
246  updateZoom();
247  s_firstDisplay = false;
248  }
249 
250  s_training = false;
251  setEnabled(true);
252 
253  // we need a valid classifier to compute statistics!
254  statisticsToolButton->setEnabled(true);
255 
256  return true;
257 }
258 
260  if (s_training) {
261  scalesCountSpinBox->blockSignals(true);
262  scalesCountSpinBox->setValue(s_trainingValue);
263  scalesCountSpinBox->blockSignals(false);
264  } else {
265  // update list of scales
266  updateScalesList(false);
267 
268  trainClassifier();
269  }
270 }
271 
274  std::vector<float> scales;
275  getActiveScales(scales);
276 
277  Classifier classifier = m_classifier;
278  updateClassifierPath(classifier);
279 
281  *m_descriptors2, scales, params)) {
282  QStringList info;
283  info << QString("Class %1 (%2)").arg(m_class1).arg(m_cloud1Name);
284  info << QString("\tTotal: %1").arg(params.true1 + params.false1);
285  info << QString("\tTruly classified: %1").arg(params.true1);
286  info << QString("\tFalsely classified: %1").arg(params.false1);
287  info << QString("\tDist. to boundary: %1 +/- %2")
288  .arg(params.mu1)
289  .arg(sqrt(params.var1));
290  info << QString("");
291  info << QString("Class %1 (%2)").arg(m_class2).arg(m_cloud2Name);
292  info << QString("\tTotal: %1").arg(params.true2 + params.false2);
293  info << QString("\tTruly classified: %1").arg(params.true2);
294  info << QString("\tFalsely classified: %1").arg(params.false2);
295  info << QString("\tDist. to boundary: %1 +/- %2")
296  .arg(params.mu2)
297  .arg(sqrt(params.var2));
298  info << QString("");
299  info << QString("Balanced accuracy (ba) = %1").arg(params.ba());
300  info << QString("Fisher Discriminant Ratio (fdr) = %1")
301  .arg(params.fdr());
302 
303  QMessageBox::information(this, "Statistics", info.join("\n"),
304  QMessageBox::Ok);
305  }
306 }
307 
309  // if (ecvDisplayTools::GetCurrentScreen())
310  //{
311  // ecvDisplayTools::SetPointSize(static_cast<float>(value));
312  // ecvDisplayTools::RedrawDisplay();
313  // }
314 }
315 
317  if (!m_classifierSaved) {
318  if (QMessageBox::warning(this, "Classifier has not been saved!",
319  "Do you really want to close the dialog "
320  "before saving the classifier?",
321  QMessageBox::Yes,
322  QMessageBox::No) == QMessageBox::No)
323  return;
324  }
325 
326  accept();
327 }
328 
331 
332  if (!m_poly) {
333  assert(!m_polyVertices);
334  m_polyVertices = new ccPointCloud("vertices");
338  m_poly->showColors(true);
339  m_poly->setWidth(2);
340  m_poly->showVertices(true);
342  addObject(m_poly);
343  }
344 
345  m_poly->clear();
347 
348  unsigned pathLength = static_cast<unsigned>(m_classifier.path.size());
349  if (pathLength > 1) {
350  if (!m_poly->reserve(pathLength) ||
351  !m_polyVertices->reserve(pathLength))
352  return;
353 
354  for (unsigned i = 0; i < pathLength; ++i)
356  m_classifier.path[i].x, m_classifier.path[i].y,
357  -std::numeric_limits<PointCoordinateType>::epsilon()));
358 
359  m_poly->addPointIndex(0, pathLength);
360  }
361 
363 }
364 
366  // select file to save
367  QSettings settings("qCanupo");
368  settings.beginGroup("Classif");
369  QString currentPath =
370  settings.value("MscCurrentPath", QApplication::applicationDirPath())
371  .toString();
372 
373  QString filename = QFileDialog::getSaveFileName(this, "Save Classifier",
374  currentPath, "*.prm");
375  if (filename.isEmpty()) return;
376 
377  // update the classifier's path
378  Classifier classifier = m_classifier;
379  updateClassifierPath(classifier);
380 
381  QString error;
382  if (classifier.save(filename, error)) {
383  m_classifierSaved = true;
384  if (m_app)
386  QString("Classifier file saved: '%1'").arg(filename));
387  } else {
388  if (m_app)
391  }
392 
393  // we update current file path
394  currentPath = QFileInfo(filename).absolutePath();
395  settings.setValue("MscCurrentPath", currentPath);
396 }
397 
399  // update the classifier's path
400  if (m_poly) {
401  classifier.path.resize(m_poly->size());
402  for (unsigned i = 0; i < m_poly->size(); ++i) {
403  const CCVector3* P = m_poly->getPoint(i);
404  classifier.path[i] = Classifier::Point2D(P->x, P->y);
405  }
406  }
407 }
408 
410  if (!obj) return;
411  obj->setVisible(true);
412  // ecvDisplayTools::AddToOwnDB(obj);
413 }
414 
419 }
420 
422  m_pickingRadius = std::max(radius, 1);
423 }
424 
427  assert(false);
428  return CCVector3(0, 0, 0);
429  }
430 
431  // we must convert the mouse click to the polyline coordinate system
432  ccGLCameraParameters camera;
434 
436  CCVector3 P2D(pos2D.x, pos2D.y, 0);
437 
438  CCVector3d P3D;
439  camera.unproject(P2D, P3D);
440 
441  // DGM: the Z value is meaningless!
442  P3D.z = 0;
443 
444  return CCVector3::fromArray(P3D.u);
445 }
446 
448  if (!m_poly || !ecvDisplayTools::GetCurrentScreen()) return -1;
449 
450  P = getClickPos(x, y);
451 
452  // look for the closest vertex
453  int closeIndex = -1;
454  float closestSquareDist = 0;
455  for (unsigned i = 0; i < m_poly->size(); ++i) {
456  float squareDist = (*m_poly->getPoint(i) - P).norm2();
457  if (closeIndex < 0 || squareDist < closestSquareDist) {
458  closestSquareDist = squareDist;
459  closeIndex = static_cast<int>(i);
460  }
461  }
462 
463  return closeIndex;
464 }
465 
467  if (!m_poly || !ecvDisplayTools::GetCurrentScreen()) return;
468 
469  CCVector3 P;
470  int closeIndex = getClosestVertex(x, y, P);
471 
472  // B = closest vertex
473  const CCVector3* B = (closeIndex >= 0 ? m_poly->getPoint(closeIndex) : 0);
474 
475  // picking radius
476  double maxPickingDist = static_cast<double>(m_pickingRadius) *
478 
479  // to allow 'mouse move" tracking event
482 
483  // is the closest point close enough?
484  if (closeIndex >= 0) {
485  assert(B);
486  if ((P - *B).norm() <= maxPickingDist) {
487  // we select the closest vertex
488  m_selectedPointIndex = closeIndex;
489  return;
490  }
491  }
492 
493  // let's look if the click fall 'inside' a segment
494  double nearestProjectionDist = maxPickingDist;
495  CCVector3 nearestProj = P;
496  int nearestSegIndex = -1;
497  for (unsigned i = 0; i + 1 < m_poly->size(); ++i) {
498  const CCVector3* A = m_poly->getPoint(i);
499  const CCVector3* B = m_poly->getPoint(i + 1);
500 
501  CCVector3 AB = (*B - *A);
502  CCVector3 AP = (P - *A);
503 
504  PointCoordinateType dot = AB.dot(AP);
505 
506  // projection falls inside the segment?
507  dot /= AB.norm2();
508  if (dot > 0 && dot < PC_ONE) {
509  CCVector3 AH = AB * dot;
510  CCVector3 HP = AP - AH;
511  double dist = HP.norm();
512 
513  if (dist < nearestProjectionDist) {
514  nearestProjectionDist = dist;
515  nearestProj = AH + *A;
516  nearestSegIndex = static_cast<int>(i);
517  }
518  }
519  }
520 
521  if (nearestSegIndex >= 0) {
522  // if we have a candidate
523  closeIndex = nearestSegIndex;
524  P = nearestProj; // shall we really replace P by its projection on the
525  } else {
526  // we'll add the point to the nearest end (i.e. front or back)
527  const CCVector3* A = m_poly->getPoint(0);
528  const CCVector3* B = m_poly->getPoint(m_poly->size() - 1);
529  if ((P - *A).norm2() < (P - *B).norm2()) {
530  closeIndex = -1;
531  } else {
532  closeIndex = static_cast<int>(m_poly->size() - 1);
533  }
534  }
535 
536  // add the point to the vertices cloud
537  ccPointCloud* vertices =
538  dynamic_cast<ccPointCloud*>(m_poly->getAssociatedCloud());
539  if (!vertices) {
540  assert(false);
541  return;
542  }
543  unsigned newIndexInCloud = vertices->size();
544  vertices->reserve(newIndexInCloud + 1);
545  vertices->addPoint(P);
546 
547  // add the corresponding point index at the end of the polyline
548  //(whatever the case to avoid complicated tests later)
549  m_poly->reserve(m_poly->size() + 1);
550  m_poly->addPointIndex(newIndexInCloud);
551 
552  m_selectedPointIndex = closeIndex + 1;
553 
554  // eventually we must shift the indexes starting from newIndexInPoly
555  unsigned newIndexInPoly = static_cast<unsigned>(m_selectedPointIndex);
556  while (newIndexInPoly < m_poly->size()) {
557  unsigned previousIndexInCloud =
558  m_poly->getPointGlobalIndex(newIndexInPoly);
559  m_poly->setPointIndex(newIndexInPoly, newIndexInCloud);
560  newIndexInCloud = previousIndexInCloud;
561  ++newIndexInPoly;
562  }
563 
565 }
566 
568  if (!m_poly || !ecvDisplayTools::GetCurrentScreen()) return;
569 
570  // we can't accept less than 2 vertices!
571  unsigned polySize = m_poly->size();
572  if (polySize < 3) return;
573 
574  CCVector3 P;
575  int closeIndex = getClosestVertex(x, y, P);
576 
577  // nothing to do
578  if (closeIndex < 0) return;
579 
580  // picking radius
581  double maxPickingDist = static_cast<double>(m_pickingRadius) *
583 
584  // B = closest vertex
585  const CCVector3* B = (closeIndex >= 0 ? m_poly->getPoint(closeIndex) : 0);
586  if ((P - *B).norm() > maxPickingDist) {
587  // too far
588  return;
589  }
590 
591  // shift all indexes on the polyline only (we don't bother with the vertices
592  // cloud!)
593  for (unsigned i = static_cast<unsigned>(closeIndex); i < polySize - 1; ++i)
595  m_poly->resize(polySize - 1);
596 
597  // ecvDisplayTools::RedrawDisplay();
598 }
599 
601  int y,
602  Qt::MouseButtons buttons) {
603  if (buttons != Qt::LeftButton) return;
604  if (m_selectedPointIndex < 0) return;
605  if (!m_poly || !ecvDisplayTools::GetCurrentScreen()) return;
606 
607  CCVector3 newP = getClickPos(x, y);
608 
609  assert(static_cast<int>(m_poly->size()) > m_selectedPointIndex);
610  CCVector3* P =
612  *P = newP;
613 
614  // TODO: in theory we should update the vertices cloud bounding-box
615  //(but we as never use it...)
616 
618 }
619 
621  // to disable 'mouse move' event tracking
625 
627 }
constexpr PointCoordinateType PC_ONE
'1' as a PointCoordinateType value
Definition: CVConst.h:67
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
Definition: CVGeom.h:798
float PointCoordinateType
Type of the coordinates of a (N-D) point.
Definition: CVTypes.h:16
std::string filename
int size
cmdLineReadable * params[]
Classifier.
Definition: classifier.h:23
bool save(QString filename, QString &error)
Saves classifier as a CANUPO's classifier file (.prm)
Definition: classifier.cpp:299
int class1
Definition: classifier.h:70
Vector2Tpl< float > Point2D
2D point
Definition: classifier.h:26
std::vector< Point2D > path
Definition: classifier.h:72
Point2D refPointPos
Definition: classifier.h:74
int class2
Definition: classifier.h:70
Point2D refPointNeg
Definition: classifier.h:74
Set of (core) point descriptors.
const std::vector< float > & scales() const
Returns associated scales.
Type y
Definition: CVGeom.h:137
Type u[3]
Definition: CVGeom.h:139
Type x
Definition: CVGeom.h:137
Type z
Definition: CVGeom.h:137
Type x
Definition: CVGeom.h:36
Type y
Definition: CVGeom.h:36
Type dot(const Vector3Tpl &v) const
Dot product.
Definition: CVGeom.h:408
Type norm2() const
Returns vector square norm.
Definition: CVGeom.h:417
Type norm() const
Returns vector norm.
Definition: CVGeom.h:424
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
Definition: CVGeom.h:268
Bounding box structure.
Definition: ecvBBox.h:25
virtual void setVisible(bool state)
Sets entity visibility.
virtual void showColors(bool state)
Sets colors visibility.
void setTranslation(const Vector3Tpl< float > &Tr)
Sets translation (float version)
Float version of ccGLMatrixTpl.
Definition: ecvGLMatrix.h:19
void enableStippling(bool state)
Enables polygon stippling.
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
virtual void setColor(const ecvColor::Rgb &col)
Sets primitive color (shortcut)
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
virtual ccBBox getDisplayBB_recursive(bool relative)
Returns the bounding-box of this entity and it's children WHEN DISPLAYED.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
void clear() override
Clears the entity from all its points and features.
Colored polyline.
Definition: ecvPolyline.h:24
void setVertexMarkerWidth(int width)
Sets the width of vertex markers.
Definition: ecvPolyline.h:137
void showVertices(bool state)
Sets whether to display or hide the polyline vertices.
Definition: ecvPolyline.h:129
void setColor(const ecvColor::Rgb &col)
Sets the polyline color.
Definition: ecvPolyline.h:81
void setWidth(PointCoordinateType width)
Sets the width of the line.
Sphere (primitive)
Definition: ecvSphere.h:16
T getMaxBoxDim() const
Returns maximal box dimension.
Definition: BoundingBox.h:185
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
unsigned size() const override
Definition: PointCloudTpl.h:38
void clear(bool unusedParam=true) override
Clears the cloud.
Definition: Polyline.cpp:15
virtual bool addPointIndex(unsigned globalIndex)
Point global index insertion mechanism.
virtual GenericIndexedCloudPersist * getAssociatedCloud()
Returns the associated (source) cloud.
unsigned size() const override
Returns the number of points.
virtual void setPointIndex(unsigned localIndex, unsigned globalIndex)
Sets global index for a given element.
virtual unsigned getPointGlobalIndex(unsigned localIndex) const
virtual bool resize(unsigned n)
Presets the size of the vector used to store point references.
virtual bool reserve(unsigned n)
Reserves some memory for hosting the point references.
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
static INTERACTION_FLAGS PAN_ONLY()
static void GetGLCameraParameters(ccGLCameraParameters &params)
Returns the current OpenGL camera parameters.
static CCVector3d ToVtkCoordinates(int x, int y, int z=0)
static void SetInteractionMode(INTERACTION_FLAGS flags)
static double ComputeActualPixelSize()
static QWidget * GetCurrentScreen()
static ccHObject * GetOwnDB()
Returns window own DB.
static void UpdateConstellationCenterAndZoom(const ccBBox *aBox=nullptr, bool redraw=true)
Center and zoom on a given bounding box.
static void RedrawDisplay(bool only2D=false, bool forceRedraw=true)
Main application interface (for plugins)
virtual void dispToConsole(QString message, ConsoleMessageLevel level=STD_CONSOLE_MESSAGE)=0
Classifier m_classifier
Associated classifier.
bool m_classifierSaved
Whether the classifier has been saved (at least once)
virtual ~qCanupo2DViewDialog()
Destructor.
ccPointCloud * m_cloud
Associated cloud.
void reset()
Resets display.
const CorePointDescSet * m_evaluationDescriptors
bool trainClassifier()
Trains the classifier (with the current number of scales!)
void setPickingRadius(int radius)
Sets picking radius (for polyline vertices)
const CorePointDescSet * m_descriptors1
CCVector3 getClickPos(int x, int y) const
Returns the click position in 3D.
void updateScalesList(bool firstTime)
Updates the list of active scales.
void updateClassifierPath(Classifier &classifier) const
Updates classifier path with the currently displayed polyline.
void addOrSelectPoint(int, int)
const CorePointDescSet * m_descriptors2
qCanupo2DViewDialog(const CorePointDescSet *descriptors1, const CorePointDescSet *descriptors2, QString cloud1Name, QString cloud2Name, int class1=1, int class2=2, const CorePointDescSet *evaluationDescriptors=0, ecvMainAppInterface *app=0)
Default constructor.
void computeStatistics()
Computes statistics with the current classifier.
int m_pickingRadius
Picking radius.
void moveSelectedPoint(int, int, Qt::MouseButtons)
void resetBoundary()
Updates the boundary representation.
void getActiveScales(std::vector< float > &scales) const
Returns the list of active scales.
int m_selectedPointIndex
Currently selected polyline point.
void addObject(ccHObject *obj)
Adds a custom object to the 2D view.
ecvMainAppInterface * m_app
Gives access to the application (data-base, UI, etc.)
void updateZoom()
Updates zoom.
ccPointCloud * m_polyVertices
Associated polyline vertices.
ccPolyline * m_poly
Associated polyline.
int getClosestVertex(int x, int y, CCVector3 &P) const
Returns closest vertex.
static bool EvaluateClassifier(const Classifier &classifier, const CorePointDescSet &descriptors1, const CorePointDescSet &descriptors2, const std::vector< float > &scales, EvalParameters &params)
Evaluates a classifier.
static bool TrainClassifier(Classifier &classifier, const CorePointDescSet &descriptors1, const CorePointDescSet &descriptors2, const std::vector< float > &scales, ccPointCloud *mscCloud, const CorePointDescSet *evaluationDescriptors=0, ecvMainAppInterface *app=0)
Trains a classifier.
__host__ __device__ float dot(float2 a, float2 b)
Definition: cutil_math.h:1119
int max(int a, int b)
Definition: cutil_math.h:48
static double dist(double x1, double y1, double x2, double y2)
Definition: lsd.c:207
static void error(char *msg)
Definition: lsd.c:159
constexpr Rgb magenta(MAX, 0, MAX)
constexpr Rgb red(MAX, 0, 0)
constexpr Rgb blue(0, 0, MAX)
static bool s_firstDisplay
static int s_trainingValue
static bool s_training
OpenGL camera parameters.
bool unproject(const CCVector3d &input2D, CCVector3d &output3D) const
Unprojects a 2D point (+ normalized 'z' coordinate) in 3D.
Classifer evaluation parameters.
Definition: qCanupoTools.h:107