mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-03 01:50:24 +08:00
GUI export: Added cloud filtering option
This commit is contained in:
@@ -232,7 +232,9 @@ private:
|
|||||||
bool regenerateClouds,
|
bool regenerateClouds,
|
||||||
int regenerateDecimation,
|
int regenerateDecimation,
|
||||||
float regenerateVoxelSize,
|
float regenerateVoxelSize,
|
||||||
float regenerateMaxDepth) const;
|
float regenerateMaxDepth,
|
||||||
|
float filteringRadius,
|
||||||
|
float filteringMinNeighbors) const;
|
||||||
|
|
||||||
bool getExportedScans(std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans);
|
bool getExportedScans(std::map<int, pcl::PointCloud<pcl::PointXYZ>::Ptr > & scans);
|
||||||
bool getExportedClouds(
|
bool getExportedClouds(
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
|||||||
connect(_ui->doubleSpinBox_voxelSize, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_voxelSize, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_maxDepth, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_maxDepth, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
|
||||||
|
connect(_ui->groupBox_filtering, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->doubleSpinBox_filteringRadius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->spinBox_filteringMinNeighbors, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
||||||
|
|
||||||
connect(_ui->groupBox_assemble, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
|
connect(_ui->groupBox_assemble, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_voxelSize_assembled, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_voxelSize_assembled, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
|
||||||
@@ -102,6 +106,10 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
|
|||||||
settings.setValue("regenerate_voxel", this->getGenerateVoxel());
|
settings.setValue("regenerate_voxel", this->getGenerateVoxel());
|
||||||
settings.setValue("regenerate_max_depth", this->getGenerateMaxDepth());
|
settings.setValue("regenerate_max_depth", this->getGenerateMaxDepth());
|
||||||
|
|
||||||
|
settings.setValue("filtering", this->getFiltering());
|
||||||
|
settings.setValue("filtering_radius", this->getFilteringRadius());
|
||||||
|
settings.setValue("filtering_min_neighbors", this->getFilteringMinNeighbors());
|
||||||
|
|
||||||
settings.setValue("assemble", this->getAssemble());
|
settings.setValue("assemble", this->getAssemble());
|
||||||
settings.setValue("assemble_voxel", this->getAssembleVoxel());
|
settings.setValue("assemble_voxel", this->getAssembleVoxel());
|
||||||
|
|
||||||
@@ -143,6 +151,10 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
|||||||
_ui->doubleSpinBox_voxelSize->setValue(settings.value("regenerate_voxel", this->getGenerateVoxel()).toDouble());
|
_ui->doubleSpinBox_voxelSize->setValue(settings.value("regenerate_voxel", this->getGenerateVoxel()).toDouble());
|
||||||
_ui->doubleSpinBox_maxDepth->setValue(settings.value("regenerate_max_depth", this->getGenerateMaxDepth()).toDouble());
|
_ui->doubleSpinBox_maxDepth->setValue(settings.value("regenerate_max_depth", this->getGenerateMaxDepth()).toDouble());
|
||||||
|
|
||||||
|
_ui->groupBox_filtering->setChecked(settings.value("filtering", this->getFiltering()).toBool());
|
||||||
|
_ui->doubleSpinBox_filteringRadius->setValue(settings.value("filtering_radius", this->getFilteringRadius()).toDouble());
|
||||||
|
_ui->spinBox_filteringMinNeighbors->setValue(settings.value("filtering_min_neighbors", this->getFilteringMinNeighbors()).toInt());
|
||||||
|
|
||||||
_ui->groupBox_assemble->setChecked(settings.value("assemble", this->getAssemble()).toBool());
|
_ui->groupBox_assemble->setChecked(settings.value("assemble", this->getAssemble()).toBool());
|
||||||
_ui->doubleSpinBox_voxelSize_assembled->setValue(settings.value("assemble_voxel", this->getAssembleVoxel()).toDouble());
|
_ui->doubleSpinBox_voxelSize_assembled->setValue(settings.value("assemble_voxel", this->getAssembleVoxel()).toDouble());
|
||||||
|
|
||||||
@@ -182,6 +194,10 @@ void ExportCloudsDialog::restoreDefaults()
|
|||||||
_ui->doubleSpinBox_voxelSize->setValue(0.01);
|
_ui->doubleSpinBox_voxelSize->setValue(0.01);
|
||||||
_ui->doubleSpinBox_maxDepth->setValue(4);
|
_ui->doubleSpinBox_maxDepth->setValue(4);
|
||||||
|
|
||||||
|
_ui->groupBox_filtering->setChecked(false);
|
||||||
|
_ui->doubleSpinBox_filteringRadius->setValue(0.02);
|
||||||
|
_ui->spinBox_filteringMinNeighbors->setValue(2);
|
||||||
|
|
||||||
_ui->groupBox_assemble->setChecked(true);
|
_ui->groupBox_assemble->setChecked(true);
|
||||||
_ui->doubleSpinBox_voxelSize_assembled->setValue(0.01);
|
_ui->doubleSpinBox_voxelSize_assembled->setValue(0.01);
|
||||||
|
|
||||||
@@ -263,11 +279,23 @@ double ExportCloudsDialog::getGenerateMaxDepth() const
|
|||||||
return _ui->doubleSpinBox_maxDepth->value();
|
return _ui->doubleSpinBox_maxDepth->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ExportCloudsDialog::getFiltering() const
|
||||||
|
{
|
||||||
|
return _ui->groupBox_filtering->isChecked();
|
||||||
|
}
|
||||||
|
double ExportCloudsDialog::getFilteringRadius() const
|
||||||
|
{
|
||||||
|
return _ui->doubleSpinBox_filteringRadius->value();
|
||||||
|
}
|
||||||
|
int ExportCloudsDialog::getFilteringMinNeighbors() const
|
||||||
|
{
|
||||||
|
return _ui->spinBox_filteringMinNeighbors->value();
|
||||||
|
}
|
||||||
|
|
||||||
bool ExportCloudsDialog::getAssemble() const
|
bool ExportCloudsDialog::getAssemble() const
|
||||||
{
|
{
|
||||||
return _ui->groupBox_assemble->isChecked();
|
return _ui->groupBox_assemble->isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
double ExportCloudsDialog::getAssembleVoxel() const
|
double ExportCloudsDialog::getAssembleVoxel() const
|
||||||
{
|
{
|
||||||
return _ui->doubleSpinBox_voxelSize_assembled->value();
|
return _ui->doubleSpinBox_voxelSize_assembled->value();
|
||||||
|
|||||||
@@ -61,6 +61,10 @@ public:
|
|||||||
double getGenerateVoxel() const;
|
double getGenerateVoxel() const;
|
||||||
double getGenerateMaxDepth() const;
|
double getGenerateMaxDepth() const;
|
||||||
|
|
||||||
|
bool getFiltering() const;
|
||||||
|
double getFilteringRadius() const;
|
||||||
|
int getFilteringMinNeighbors() const;
|
||||||
|
|
||||||
bool getAssemble() const;
|
bool getAssemble() const;
|
||||||
double getAssembleVoxel() const;
|
double getAssembleVoxel() const;
|
||||||
|
|
||||||
|
|||||||
@@ -4619,7 +4619,9 @@ bool MainWindow::getExportedClouds(
|
|||||||
_exportDialog->getGenerate(),
|
_exportDialog->getGenerate(),
|
||||||
_exportDialog->getGenerateDecimation(),
|
_exportDialog->getGenerateDecimation(),
|
||||||
_exportDialog->getGenerateVoxel(),
|
_exportDialog->getGenerateVoxel(),
|
||||||
_exportDialog->getGenerateMaxDepth());
|
_exportDialog->getGenerateMaxDepth(),
|
||||||
|
_exportDialog->getFiltering()?_exportDialog->getFilteringRadius():0.0f,
|
||||||
|
_exportDialog->getFiltering()?_exportDialog->getFilteringMinNeighbors():0.0f);
|
||||||
|
|
||||||
if(_exportDialog->getAssemble())
|
if(_exportDialog->getAssemble())
|
||||||
{
|
{
|
||||||
@@ -4642,14 +4644,29 @@ bool MainWindow::getExportedClouds(
|
|||||||
|
|
||||||
_initProgressDialog->appendText(tr("Voxelize assembled cloud (%1 points, voxel size = %2 m)...")
|
_initProgressDialog->appendText(tr("Voxelize assembled cloud (%1 points, voxel size = %2 m)...")
|
||||||
.arg(assembledCloud->size())
|
.arg(assembledCloud->size())
|
||||||
.arg(_exportDialog->getGenerateVoxel()));
|
.arg(_exportDialog->getAssembleVoxel()));
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
if(_exportDialog->getGenerateVoxel())
|
if(_exportDialog->getAssembleVoxel())
|
||||||
{
|
{
|
||||||
assembledCloud = util3d::voxelize(
|
assembledCloud = util3d::voxelize(
|
||||||
assembledCloud,
|
assembledCloud,
|
||||||
_exportDialog->getGenerateVoxel());
|
_exportDialog->getAssembleVoxel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_initProgressDialog->appendText(tr("Noise filtering (%1 points, radius = %2 m, min neighbors = %3)...")
|
||||||
|
.arg(assembledCloud->size())
|
||||||
|
.arg(_exportDialog->getFilteringRadius())
|
||||||
|
.arg(_exportDialog->getFilteringMinNeighbors()));
|
||||||
|
if(_exportDialog->getFiltering() &&
|
||||||
|
_exportDialog->getFilteringRadius() > 0.0 &&
|
||||||
|
_exportDialog->getFilteringMinNeighbors() > 0)
|
||||||
|
{
|
||||||
|
pcl::IndicesPtr indices = util3d::radiusFiltering(assembledCloud, (float)_exportDialog->getFilteringRadius(), _exportDialog->getFilteringMinNeighbors());
|
||||||
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFiltered(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||||
|
pcl::copyPointCloud(*assembledCloud, *indices, *cloudFiltered);
|
||||||
|
assembledCloud = cloudFiltered;
|
||||||
|
}
|
||||||
|
|
||||||
clouds.clear();
|
clouds.clear();
|
||||||
clouds.insert(std::make_pair(0, assembledCloud));
|
clouds.insert(std::make_pair(0, assembledCloud));
|
||||||
}
|
}
|
||||||
@@ -5488,7 +5505,9 @@ std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr > MainWindow::getClouds(
|
|||||||
bool regenerateClouds,
|
bool regenerateClouds,
|
||||||
int regenerateDecimation,
|
int regenerateDecimation,
|
||||||
float regenerateVoxelSize,
|
float regenerateVoxelSize,
|
||||||
float regenerateMaxDepth) const
|
float regenerateMaxDepth,
|
||||||
|
float filteringRadius,
|
||||||
|
float filteringMinNeighbors) const
|
||||||
{
|
{
|
||||||
std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr> clouds;
|
std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr> clouds;
|
||||||
int i=0;
|
int i=0;
|
||||||
@@ -5542,6 +5561,14 @@ std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr > MainWindow::getClouds(
|
|||||||
|
|
||||||
if(cloud->size())
|
if(cloud->size())
|
||||||
{
|
{
|
||||||
|
if(filteringRadius > 0.0f && filteringMinNeighbors > 0)
|
||||||
|
{
|
||||||
|
pcl::IndicesPtr indices = util3d::radiusFiltering(cloud, filteringRadius, filteringMinNeighbors);
|
||||||
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFiltered(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||||
|
pcl::copyPointCloud(*cloud, *indices, *cloudFiltered);
|
||||||
|
cloud = cloudFiltered;
|
||||||
|
}
|
||||||
|
|
||||||
clouds.insert(std::make_pair(iter->first, cloud));
|
clouds.insert(std::make_pair(iter->first, cloud));
|
||||||
inserted = true;
|
inserted = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>807</width>
|
<width>814</width>
|
||||||
<height>847</height>
|
<height>898</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@@ -23,9 +23,9 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>-178</y>
|
<y>0</y>
|
||||||
<width>766</width>
|
<width>773</width>
|
||||||
<height>949</height>
|
<height>1064</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||||
@@ -166,6 +166,73 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_filtering">
|
||||||
|
<property name="title">
|
||||||
|
<string>Cloud filtering (remove noisy points)</string>
|
||||||
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_9" columnstretch="0,1">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label_110">
|
||||||
|
<property name="text">
|
||||||
|
<string>Radius search.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_filteringRadius">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> m</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.001000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.020000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QSpinBox" name="spinBox_filteringMinNeighbors">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_112">
|
||||||
|
<property name="text">
|
||||||
|
<string>Minimum neighbors in the search radius.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_assemble">
|
<widget class="QGroupBox" name="groupBox_assemble">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
|||||||
Reference in New Issue
Block a user