22 #include <qtconcurrentrun.h>
24 #include <QApplication>
26 #include <QProgressDialog>
29 #if defined(CV_WINDOWS)
36 #ifdef USE_PYTHON_MODULE
37 ecvDeepSemanticSegmentationTool::ecvDeepSemanticSegmentationTool(
40 Ui::DeepSemanticSegmentationDlg(),
41 m_show_progress(true) {
43 connect(detectToolButton, &QAbstractButton::clicked,
this,
44 &ecvDeepSemanticSegmentationTool::detect);
45 connect(appyToolButton, &QAbstractButton::clicked,
this,
46 &ecvDeepSemanticSegmentationTool::apply);
47 connect(cancelToolButton, &QAbstractButton::clicked,
this,
48 &ecvDeepSemanticSegmentationTool::cancel);
49 connect(selectAllRadioButton, &QAbstractButton::clicked,
this,
50 &ecvDeepSemanticSegmentationTool::selectAllClasses);
51 connect(unselectAllRadioButton, &QAbstractButton::clicked,
this,
52 &ecvDeepSemanticSegmentationTool::selectAllClasses);
55 ecvDeepSemanticSegmentationTool::~ecvDeepSemanticSegmentationTool() {}
57 bool ecvDeepSemanticSegmentationTool::linkWith(QWidget* win) {
65 bool ecvDeepSemanticSegmentationTool::addEntity(
ccHObject* entity) {
70 if (pointNumber < 65536) {
71 CVLog::Warning(QString(
"[ecvDeepSemanticSegmentationTool::addEntity] "
72 "Skip entity [%1] as the point number of it is "
73 "%2 lower than min limit 65536!")
74 .arg(entity->
getName(), pointNumber));
83 unsigned ecvDeepSemanticSegmentationTool::getNumberOfValidEntities()
const {
84 return m_entity.getChildrenNumber();
87 bool ecvDeepSemanticSegmentationTool::start() {
91 if (!m_clusters_map.empty()) {
92 m_clusters_map.clear();
94 if (!m_clusters.empty()) {
98 if (m_selectedEntity.getChildrenNumber() != 0) {
99 m_selectedEntity.detachAllChildren();
102 unsigned childNum = getNumberOfValidEntities();
103 if (childNum == 0)
return false;
105 selectedTreeWiget->headerItem()->setCheckState(0, Qt::Checked);
106 for (
unsigned i = 0; i < getNumberOfValidEntities(); ++i) {
107 QTreeWidgetItem* item =
new QTreeWidgetItem();
108 item->setCheckState(0, Qt::Checked);
109 item->setText(1, m_entity.getChild(i)->getName());
110 selectedTreeWiget->insertTopLevelItem(i, item);
113 #ifdef USE_PYTHON_MODULE
120 void ecvDeepSemanticSegmentationTool::apply() {
121 if (m_clusters_map.empty())
123 performSegmentation();
130 void ecvDeepSemanticSegmentationTool::detect() {
131 if (performSegmentation() > 0) {
132 exportClustersToSF();
133 refreshSelectedClouds();
137 void ecvDeepSemanticSegmentationTool::refreshSelectedClouds() {
139 for (
unsigned i = 0; i < m_selectedEntity.getChildrenNumber(); ++i) {
140 m_selectedEntity.getChild(i)->setRedrawFlagRecursive(
true);
145 void ecvDeepSemanticSegmentationTool::cancel() {
150 void ecvDeepSemanticSegmentationTool::stop(
bool state) {
154 void ecvDeepSemanticSegmentationTool::clear() {
155 m_entity.detachAllChildren();
156 for (
int i = 0; i < selectedTreeWiget->topLevelItemCount(); ++i) {
157 delete selectedTreeWiget->takeTopLevelItem(i);
160 m_clusters_map.clear();
162 m_selectedEntity.detachAllChildren();
165 void ecvDeepSemanticSegmentationTool::getSegmentations(
167 if (exportModeComboBox->currentIndex() == 0) {
168 exportClustersToEntities(
result);
169 }
else if (exportModeComboBox->currentIndex() == 1) {
170 exportClustersToSF();
174 void ecvDeepSemanticSegmentationTool::updateSelectedEntity() {
175 m_selectedEntity.detachAllChildren();
176 for (
int i = 0; i < selectedTreeWiget->topLevelItemCount(); ++i) {
177 QTreeWidgetItem* item = selectedTreeWiget->topLevelItem(i);
178 if (item->checkState(0) == Qt::Checked) {
179 for (
unsigned j = 0; j < getNumberOfValidEntities(); ++j) {
180 if (item->text(1) == m_entity.getChild(j)->getName()) {
181 m_selectedEntity.addChild(m_entity.getChild(j),
190 void ecvDeepSemanticSegmentationTool::exportClustersToSF() {
192 m_selectedEntity.filterChildren(selectedClouds,
false,
194 if (m_clusters.size() != selectedClouds.size()) {
196 "[ecvDeepSemanticSegmentationTool] dimensions do not match!");
200 std::vector<std::vector<ScalarType>> scalarsVector;
201 ccEntityAction::ConvertToScalarType<size_t>(m_clusters, scalarsVector);
204 "[ecvDeepSemanticSegmentationTool::exportClustersToSF] import "
208 void ecvDeepSemanticSegmentationTool::exportClustersToEntities(
210 bool needFresh =
false;
211 for (
unsigned int i = 0; i < m_selectedEntity.getChildrenNumber(); ++i) {
236 for (ClassMap::ClusterMap::const_iterator it = clusterMap.begin();
237 it != clusterMap.end(); ++it) {
240 res->
setName(it->first.c_str());
250 result.push_back(ecvGroup);
255 refreshSelectedClouds();
258 for (
unsigned i = 0; i < m_selectedEntity.getChildrenNumber(); ++i) {
259 m_selectedEntity.getChild(i)->setEnabled(
false);
263 void ecvDeepSemanticSegmentationTool::getSelectedFilterClasses(
264 std::vector<size_t>& filteredClasses) {
265 if (!filteredClasses.empty()) {
266 filteredClasses.clear();
269 if (unlabeledCheckBox->isChecked()) filteredClasses.push_back(0);
270 if (manMadeTerrainCheckBox->isChecked()) filteredClasses.push_back(1);
271 if (naturalTerrainCheckBox->isChecked()) filteredClasses.push_back(2);
272 if (highVegetationCheckBox->isChecked()) filteredClasses.push_back(3);
273 if (lowVegetationCheckBox->isChecked()) filteredClasses.push_back(4);
274 if (buildingsCheckBox->isChecked()) filteredClasses.push_back(5);
275 if (hardScapeCheckBox->isChecked()) filteredClasses.push_back(6);
276 if (scanningArtifactsCheckBox->isChecked()) filteredClasses.push_back(7);
277 if (carsCheckBox->isChecked()) filteredClasses.push_back(8);
278 if (utilityPoleCheckBox->isChecked()) filteredClasses.push_back(9);
279 if (insulatorCheckBox->isChecked()) filteredClasses.push_back(10);
280 if (electricalWireCheckBox->isChecked()) filteredClasses.push_back(11);
281 if (crossBarCheckBox->isChecked()) filteredClasses.push_back(12);
282 if (stickCheckBox->isChecked()) filteredClasses.push_back(13);
283 if (fuseCheckBox->isChecked()) filteredClasses.push_back(14);
284 if (wireClipCheckBox->isChecked()) filteredClasses.push_back(15);
285 if (linkerInsulatorCheckBox->isChecked()) filteredClasses.push_back(16);
286 if (personsCheckBox->isChecked()) filteredClasses.push_back(17);
287 if (trafficSignCheckBox->isChecked()) filteredClasses.push_back(18);
288 if (trafficLightCheckBox->isChecked()) filteredClasses.push_back(19);
291 void ecvDeepSemanticSegmentationTool::selectAllClasses() {
292 bool state = selectAllRadioButton->isChecked();
293 QList<QCheckBox*> list = classGroupBox->findChildren<QCheckBox*>();
295 foreach (QCheckBox* ncheckBox, list) {
297 ncheckBox->setChecked(state);
302 int ecvDeepSemanticSegmentationTool::performSegmentation() {
303 m_clusters_map.clear();
305 updateSelectedEntity();
308 int check_result = checkSelected();
309 if (check_result != 1) {
314 int start_status = startDetection();
315 if (start_status != 1) {
320 size_t entityNumber = m_selectedEntity.getChildrenNumber();
321 if (m_clusters_map.size() != entityNumber) {
329 int ecvDeepSemanticSegmentationTool::checkSelected() {
331 if (m_selectedEntity.getChildrenNumber() == 0) {
332 CVLog::Warning(
"no selected point cloud, please select one again!");
336 std::vector<size_t> selectedFilters;
337 getSelectedFilterClasses(selectedFilters);
338 if (selectedFilters.empty()) {
340 "no selected class, please select at least one to continue!");
349 int ecvDeepSemanticSegmentationTool::startDetection() {
356 QString tipInfo =
"Operation in progress, please wait for a while";
357 if (useVotesCheckBox->isChecked()) {
358 tipInfo +=
"\n(disable votes to speed up!)";
361 QProgressDialog progressCb(tipInfo, QString(), 0, 0);
363 if (m_show_progress) {
364 progressCb.setWindowTitle(tr(
"Deep Semantic Segmentation"));
366 QApplication::processEvents();
373 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
374 QFuture<void> future = QtConcurrent::run([
this]() { this->
doCompute(); });
376 QFuture<void> future = QtConcurrent::run(
379 while (!future.isFinished()) {
380 #if defined(CV_WINDOWS)
385 if (m_show_progress) progressCb.setValue(++progress);
391 if (m_show_progress) {
393 QApplication::processEvents();
396 CVLog::Print(QString(
"Deep Semantic Segmentation: finish cost %1 s")
407 #ifdef USE_PYTHON_MODULE
409 cloudViewer::utility::DeepSemanticSegmentation dss;
410 dss.setEnableSampling(samplingCheckBox->isChecked());
411 dss.setEnableVotes(useVotesCheckBox->isChecked());
412 dss.setInputCloud(&m_selectedEntity);
413 dss.compute(m_clusters, m_clusters_map);
415 if (m_clusters_map.empty()) {
421 std::vector<size_t> filteredClasses;
422 getSelectedFilterClasses(filteredClasses);
423 for (
auto itMap = m_clusters_map.begin();
424 itMap != m_clusters_map.end();) {
425 auto& clusterMap = *itMap;
426 for (
auto it = clusterMap.begin(); it != clusterMap.end();) {
430 QString(
"ignore class index {%1}").arg(index));
435 auto ret = std::find(filteredClasses.begin(),
436 filteredClasses.end(), index);
437 if (ret == filteredClasses.end() ||
438 it->second.size() < clusterMinSizeSpinBox->value()) {
439 it = clusterMap.erase(it);
446 if (clusterMap.empty()) {
447 itMap = m_clusters_map.erase(itMap);
454 }
catch (
const std::exception&) {
459 CVLog::Warning(
"python interface library has not been compiled!");
static int s_computeStatus
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Print(const char *format,...)
Prints out a formatted message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
virtual void setVisible(bool state)
Sets entity visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
static ccPointCloud * ToPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccPointCloud.
Hierarchical CLOUDVIEWER Object.
unsigned getChildrenNumber() const
Returns the number of children.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
ccHObject * getParent() const
Returns parent object.
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
ccHObject * getChild(unsigned childPos) const
Returns the ith child.
virtual QString getName() const
Returns object name.
virtual void setName(const QString &name)
Sets object name.
bool isKindOf(CV_CLASS_ENUM type) const
Generic overlay dialog interface.
virtual void stop(bool accepted)
Stops process/dialog.
virtual bool start()
Starts process.
virtual bool linkWith(QWidget *win)
Links the overlay dialog with a MDI window.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void setCurrentDisplayedScalarField(int index)
Sets the currently displayed scalar field.
bool hasDisplayedScalarField() const override
Returns whether an active scalar field is available or not.
int getCurrentDisplayedScalarFieldIndex() const
Returns the currently displayed scalar field index (or -1 if none)
static ccPointCloud * From(const cloudViewer::GenericIndexedCloud *cloud, const ccGenericPointCloud *sourceCloud=nullptr)
Creates a new point cloud object from a GenericIndexedCloud.
void deleteScalarField(int index) override
Deletes a specific scalar field.
unsigned size() const override
std::map< std::string, std::vector< size_t > > ClusterMap
static int FindindexByValue(const std::string &value)
bool importToSF(const ccHObject::Container &selectedEntities, const std::vector< std::vector< ScalarType >> &scalarsVector, const std::string &name)
void Sleep(int milliseconds)