ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
EuclideanClusterSegmentation.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 
9 
10 #include <Utils/cc2sm.h>
11 #include <Utils/sm2cc.h>
12 
13 #include "PclUtils/PCLModules.h"
14 #include "Tools/Common/ecvTools.h" // must below above three
16 
17 // CV_DB_LIB
18 #include <ecvPointCloud.h>
19 
20 // ECV_PLUGINS
21 #include <ecvMainAppInterface.h>
22 
23 // QT
24 #include <QMainWindow>
25 
26 // SYSTEM
27 #include <iostream>
28 #include <sstream>
29 
32  tr("EuclideanCluster Segmentation"),
33  tr("EuclideanCluster Segmentation"),
34  tr("EuclideanCluster Segmentation from clouds"),
35  ":/toolbar/PclAlgorithms/icons/"
36  "EuclideanClusterSegmentation.png")),
37  m_dialog(nullptr),
38  m_randomClusterColor(false),
39  m_clusterTolerance(0.02f),
40  m_minClusterSize(100),
41  m_maxClusterSize(25000) {}
42 
44  // we must delete parent-less dialogs ourselves!
45  if (m_dialog && m_dialog->parent() == nullptr) delete m_dialog;
46 }
47 
49  // do we have a selected cloud?
50  int have_cloud = isFirstSelectedCcPointCloud();
51  if (have_cloud != 1) return -11;
52 
53  return 1;
54 }
55 
57  // initialize the dialog object
58  if (!m_dialog)
59  m_dialog =
61 
62  if (!m_dialog->exec()) return 0;
63 
64  return 1;
65 }
66 
68  if (!m_dialog) return;
69 
70  // get the parameters from the dialog
71  m_randomClusterColor = m_dialog->randomClusterColorCheckBox->isChecked();
73  static_cast<float>(m_dialog->clusterToleranceSpinbox->value());
74  m_minClusterSize = m_dialog->minClusterSizeSpinBox->value();
75  m_maxClusterSize = m_dialog->maxClusterSizeSpinBox->value();
76 }
77 
80  return -52;
81  }
82  return 1;
83 }
84 
87  if (!cloud) return -1;
88 
89  // get xyz as pcl point cloud
90  PointCloudT::Ptr xyzCloud = cc2smReader(cloud).getXYZ2();
91  if (!xyzCloud) return -1;
92 
93  // cluster segmentation
94  std::vector<pcl::PointIndices> cluster_indices;
95  if (!PCLModules::EuclideanCluster<PointT>(
96  xyzCloud, cluster_indices, m_clusterTolerance, m_minClusterSize,
98  return -1;
99  }
100  if (cluster_indices.size() == 0 || cluster_indices.size() > 300) {
101  return -53;
102  }
103 
104  // for each cluster
105  std::vector<std::vector<size_t>> clusterIndices;
106  for (auto& cluster : cluster_indices) {
107  std::vector<size_t> cs;
108  cs.resize(cluster.indices.size());
109  for (size_t i = 0; i < cluster.indices.size(); ++i) {
110  cs[i] = (static_cast<size_t>(cluster.indices[i]));
111  }
112 
113  clusterIndices.push_back(cs);
114  }
115 
116  bool error = false;
117  ccHObject* group =
118  ecvTools::GetClousterGroup(cloud, clusterIndices, m_minClusterSize,
120 
121  if (group) {
122  group->setName(group->getName() +
123  tr("-Tolerance(%1)-ClusterSize(%2-%3)")
124  .arg(m_clusterTolerance)
125  .arg(m_minClusterSize)
126  .arg(m_maxClusterSize));
127 
128  unsigned count = group->getChildrenNumber();
129  m_app->dispToConsole(tr("[EuclideanClusterSegmentation] %1 cluster(s) "
130  "where created from cloud '%2'")
131  .arg(cluster_indices.size())
132  .arg(cloud->getName()));
133 
134  if (error) {
135  m_app->dispToConsole(tr("Error(s) occurred during the generation "
136  "of clusters! Result may be incomplete"),
138  }
139 
140  cloud->setEnabled(false);
141  if (cloud->getParent()) cloud->getParent()->addChild(group);
142 
143  emit newEntity(group);
144 
145  } else if (error) {
146  return -54;
147  } else {
148  return -1;
149  }
150 
151  return 1;
152 }
153 
155  switch (errorCode) {
156  // THESE CASES CAN BE USED TO OVERRIDE OR ADD FILTER-SPECIFIC ERRORS
157  // CODES ALSO IN DERIVED CLASSES DEFULAT MUST BE ""
158  case -51:
159  return tr(
160  "Selected entity does not have any suitable scalar field "
161  "or RGB.");
162  case -52:
163  return tr(
164  "Wrong Parameters. One or more parameters cannot be "
165  "accepted");
166  case -53:
167  return tr(
168  "EuclideanCluster Segmentation could not get any cluster "
169  "or "
170  "the clusters are more than 300 for the given dataset. Try "
171  "relaxing your parameters");
172  case -54:
173  return tr("An error occurred during the generation of clusters!");
174  }
175 
176  return BasePclModule::getErrorMessage(errorCode);
177 }
int count
Base abstract class for each implemented PCL filter.
Definition: BasePclModule.h:53
int isFirstSelectedCcPointCloud()
Returns 1 if the first selected object is a ccPointCloud.
void newEntity(ccHObject *)
Signal emitted when a new entity is created by the filter.
ecvMainAppInterface * m_app
Associated application interface.
virtual QString getErrorMessage(int errorCode)
Returns the error message corresponding to a given error code.
ccPointCloud * getSelectedEntityAsCCPointCloud() const
Returns the first selected entity as a ccPointCloud.
virtual void getParametersFromDialog()
Collects parameters from the filter dialog (if openDialog is successful)
virtual int checkSelected()
Checks if current selection is compliant with the filter.
virtual int compute()
Performs the actual filter job.
virtual QString getErrorMessage(int errorCode)
Returns the error message corresponding to a given error code.
Hierarchical CLOUDVIEWER Object.
Definition: ecvHObject.h:25
unsigned getChildrenNumber() const
Returns the number of children.
Definition: ecvHObject.h:312
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
ccHObject * getParent() const
Returns parent object.
Definition: ecvHObject.h:245
virtual QString getName() const
Returns object name.
Definition: ecvObject.h:72
virtual void setName(const QString &name)
Sets object name.
Definition: ecvObject.h:75
virtual void setEnabled(bool state)
Sets the "enabled" property.
Definition: ecvObject.h:102
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
virtual QWidget * getActiveWindow()=0
virtual void dispToConsole(QString message, ConsoleMessageLevel level=STD_CONSOLE_MESSAGE)=0
static void error(char *msg)
Definition: lsd.c:159
PCL filter description.
Definition: BasePclModule.h:26