Export: added option to remove not textured/colored polygons. Cloud generation: Black pixels can be projected. Added RoiRatios options to 3D Rendering and Export. Added fill depth holes option to Export.

This commit is contained in:
matlabbe
2017-01-16 01:32:53 -05:00
parent f8ec338fa3
commit 8f797e81ae
7 changed files with 583 additions and 346 deletions

View File

@@ -170,6 +170,7 @@ public:
int getCloudDecimation(int index) const; // 0=map, 1=odom
double getCloudMaxDepth(int index) const; // 0=map, 1=odom
double getCloudMinDepth(int index) const; // 0=map, 1=odom
std::vector<float> getCloudRoiRatios(int index) const; // 0=map, 1=odom
double getCloudOpacity(int index) const; // 0=map, 1=odom
int getCloudPointSize(int index) const; // 0=map, 1=odom
@@ -380,6 +381,7 @@ private:
QVector<QSpinBox*> _3dRenderingDecimation;
QVector<QDoubleSpinBox*> _3dRenderingMaxDepth;
QVector<QDoubleSpinBox*> _3dRenderingMinDepth;
QVector<QLineEdit*> _3dRenderingRoiRatios;
QVector<QDoubleSpinBox*> _3dRenderingOpacity;
QVector<QSpinBox*> _3dRenderingPtSize;
QVector<QCheckBox*> _3dRenderingShowScans;

View File

@@ -85,6 +85,9 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
connect(_ui->spinBox_decimation, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_maxDepth, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_minDepth, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->spinBox_fillDepthHoles, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->spinBox_fillDepthHolesError, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->lineEdit_roiRatios, SIGNAL(textChanged(const QString &)), this, SIGNAL(configChanged()));
connect(_ui->lineEdit_distortionModel, SIGNAL(textChanged(const QString &)), this, SIGNAL(configChanged()));
connect(_ui->toolButton_distortionModel, SIGNAL(clicked()), this, SLOT(selectDistortionModel()));
@@ -129,6 +132,7 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
connect(_ui->doubleSpinBox_gp3Mu, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_transferColorRadius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_cleanMesh, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SLOT(updateTexturingAvailability()));
@@ -199,6 +203,9 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
settings.setValue("regenerate_decimation", _ui->spinBox_decimation->value());
settings.setValue("regenerate_max_depth", _ui->doubleSpinBox_maxDepth->value());
settings.setValue("regenerate_min_depth", _ui->doubleSpinBox_minDepth->value());
settings.setValue("regenerate_fill_size", _ui->spinBox_fillDepthHoles->value());
settings.setValue("regenerate_fill_error", _ui->spinBox_fillDepthHolesError->value());
settings.setValue("regenerate_roi", _ui->lineEdit_roiRatios->text());
settings.setValue("regenerate_distortion_model", _ui->lineEdit_distortionModel->text());
settings.setValue("bilateral", _ui->groupBox_bilateral->isChecked());
@@ -239,6 +246,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
settings.setValue("mesh_mu", _ui->doubleSpinBox_gp3Mu->value());
settings.setValue("mesh_decimation_factor", _ui->doubleSpinBox_meshDecimationFactor->value());
settings.setValue("mesh_color_radius", _ui->doubleSpinBox_transferColorRadius->value());
settings.setValue("mesh_clean", _ui->checkBox_cleanMesh->isChecked());
settings.setValue("mesh_min_cluster_size", _ui->spinBox_mesh_minClusterSize->value());
settings.setValue("mesh_dense_strategy", _ui->comboBox_meshingApproach->currentIndex());
@@ -280,6 +288,9 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
_ui->spinBox_decimation->setValue(settings.value("regenerate_decimation", _ui->spinBox_decimation->value()).toInt());
_ui->doubleSpinBox_maxDepth->setValue(settings.value("regenerate_max_depth", _ui->doubleSpinBox_maxDepth->value()).toDouble());
_ui->doubleSpinBox_minDepth->setValue(settings.value("regenerate_min_depth", _ui->doubleSpinBox_minDepth->value()).toDouble());
_ui->spinBox_fillDepthHoles->setValue(settings.value("regenerate_fill_size", _ui->spinBox_fillDepthHoles->value()).toInt());
_ui->spinBox_fillDepthHolesError->setValue(settings.value("regenerate_fill_error", _ui->spinBox_fillDepthHolesError->value()).toInt());
_ui->lineEdit_roiRatios->setText(settings.value("regenerate_roi", _ui->lineEdit_roiRatios->text()).toString());
_ui->lineEdit_distortionModel->setText(settings.value("regenerate_distortion_model", _ui->lineEdit_distortionModel->text()).toString());
_ui->groupBox_bilateral->setChecked(settings.value("bilateral", _ui->groupBox_bilateral->isChecked()).toBool());
@@ -320,6 +331,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
_ui->doubleSpinBox_gp3Mu->setValue(settings.value("mesh_mu", _ui->doubleSpinBox_gp3Mu->value()).toDouble());
_ui->doubleSpinBox_meshDecimationFactor->setValue(settings.value("mesh_decimation_factor",_ui->doubleSpinBox_meshDecimationFactor->value()).toDouble());
_ui->doubleSpinBox_transferColorRadius->setValue(settings.value("mesh_color_radius",_ui->doubleSpinBox_transferColorRadius->value()).toDouble());
_ui->checkBox_cleanMesh->setChecked(settings.value("mesh_clean",_ui->checkBox_cleanMesh->isChecked()).toBool());
_ui->spinBox_mesh_minClusterSize->setValue(settings.value("mesh_min_cluster_size", _ui->spinBox_mesh_minClusterSize->value()).toInt());
_ui->comboBox_meshingApproach->setCurrentIndex(settings.value("mesh_dense_strategy", _ui->comboBox_meshingApproach->currentIndex()).toInt());
@@ -360,6 +372,9 @@ void ExportCloudsDialog::restoreDefaults()
_ui->spinBox_decimation->setValue(1);
_ui->doubleSpinBox_maxDepth->setValue(4);
_ui->doubleSpinBox_minDepth->setValue(0);
_ui->spinBox_fillDepthHoles->setValue(0);
_ui->spinBox_fillDepthHolesError->setValue(2);
_ui->lineEdit_roiRatios->setText("0.0 0.0 0.0 0.0");
_ui->lineEdit_distortionModel->setText("");
_ui->groupBox_bilateral->setChecked(false);
@@ -400,6 +415,7 @@ void ExportCloudsDialog::restoreDefaults()
_ui->doubleSpinBox_gp3Mu->setValue(2.5);
_ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
_ui->doubleSpinBox_transferColorRadius->setValue(0.05);
_ui->checkBox_cleanMesh->setChecked(true);
_ui->comboBox_meshingApproach->setCurrentIndex(1);
@@ -432,6 +448,8 @@ void ExportCloudsDialog::updateReconstructionFlavor()
_ui->groupBox_mls->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
_ui->comboBox_meshingApproach->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
_ui->label_denseReconstruction->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
_ui->doubleSpinBox_meshDecimationFactor->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
_ui->label_meshDecimation->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
_ui->groupBox_organized->setVisible(_ui->comboBox_pipeline->currentIndex() == 0);
updateDenseReconstruction();
}
@@ -1065,6 +1083,9 @@ bool ExportCloudsDialog::getExportedClouds(
if(_ui->spinBox_mesh_minClusterSize->value())
{
_progressDialog->appendText(tr("Filter small polygon clusters..."));
QApplication::processEvents();
// filter polygons
std::vector<std::set<int> > neighbors;
std::vector<std::set<int> > vertexToPolygons;
@@ -1085,7 +1106,11 @@ bool ExportCloudsDialog::getExportedClouds(
}
}
filteredPolygons.resize(oi);
int before = polygons.size();
polygons = filteredPolygons;
_progressDialog->appendText(tr("Filtered %1 polygons.").arg(before-oi));
QApplication::processEvents();
}
_progressDialog->appendText(tr("Mesh %1 created with %2 polygons (%3/%4).").arg(iter->first).arg(polygons.size()).arg(++i).arg(clouds.size()));
@@ -1107,63 +1132,10 @@ bool ExportCloudsDialog::getExportedClouds(
pcl::PolygonMesh::Ptr mesh(new pcl::PolygonMesh);
pcl::toPCLPointCloud2(*denseCloud, mesh->cloud);
mesh->polygons = densePolygons;
if(_ui->doubleSpinBox_meshDecimationFactor->isEnabled() &&
_ui->doubleSpinBox_meshDecimationFactor->value() > 0.0)
{
int count = mesh->polygons.size();
_progressDialog->appendText(tr("Mesh decimation (factor=%1) from %2 polygons...").arg(_ui->doubleSpinBox_meshDecimationFactor->value()).arg(count));
QApplication::processEvents();
mesh = util3d::meshDecimation(mesh, (float)_ui->doubleSpinBox_meshDecimationFactor->value());
_progressDialog->appendText(tr("Mesh decimated (factor=%1) from %2 to %3 polygons").arg(_ui->doubleSpinBox_meshDecimationFactor->value()).arg(count).arg(mesh->polygons.size()));
if(count < mesh->polygons.size())
{
_progressDialog->appendText(tr("Decimated mesh %1 has more polygons than before!").arg(iter->first), Qt::darkYellow);
_progressDialog->setAutoClose(false);
}
QApplication::processEvents();
organizedIndices.insert(std::make_pair(iter->first, denseToOrganizedIndices));
organizedCloudSizes.insert(std::make_pair(iter->first, cv::Size(iter->second->width, iter->second->height)));
if(_ui->doubleSpinBox_transferColorRadius->value() > 0.0 &&
(!_ui->checkBox_textureMapping->isEnabled() || !_ui->checkBox_textureMapping->isChecked()))
{
_progressDialog->appendText(tr("Transfering color from point cloud to mesh..."));
QApplication::processEvents();
// transfer color from point cloud to mesh
pcl::search::KdTree<pcl::PointXYZRGBNormal>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGBNormal>(true));
tree->setInputCloud(denseCloud);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr coloredCloud(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::fromPCLPointCloud2(mesh->cloud, *coloredCloud);
for(unsigned int i=0; i<coloredCloud->size(); ++i)
{
std::vector<int> kIndices;
std::vector<float> kDistances;
pcl::PointXYZRGBNormal pt;
pt.x = coloredCloud->at(i).x;
pt.y = coloredCloud->at(i).y;
pt.z = coloredCloud->at(i).z;
tree->radiusSearch(pt, _ui->doubleSpinBox_transferColorRadius->value(), kIndices, kDistances);
if(kIndices.size())
{
coloredCloud->at(i).r = denseCloud->at(kIndices[0]).r;
coloredCloud->at(i).g = denseCloud->at(kIndices[0]).g;
coloredCloud->at(i).b = denseCloud->at(kIndices[0]).b;
coloredCloud->at(i).a = denseCloud->at(kIndices[0]).a;
}
else
{
//white
coloredCloud->at(i).r = coloredCloud->at(i).g = coloredCloud->at(i).b = 255;
}
}
pcl::toPCLPointCloud2(*coloredCloud, mesh->cloud);
}
}
else
{
organizedIndices.insert(std::make_pair(iter->first, denseToOrganizedIndices));
organizedCloudSizes.insert(std::make_pair(iter->first, cv::Size(iter->second->width, iter->second->height)));
}
meshes.insert(std::make_pair(iter->first, mesh));
}
else
@@ -1334,31 +1306,6 @@ bool ExportCloudsDialog::getExportedClouds(
lostColors = true;
}
if(_ui->spinBox_mesh_minClusterSize->value())
{
// filter polygons
std::vector<std::set<int> > neighbors;
std::vector<std::set<int> > vertexToPolygons;
util3d::createPolygonIndexes(mesh->polygons,
mesh->cloud.height*mesh->cloud.width,
neighbors,
vertexToPolygons);
std::list<std::list<int> > clusters = util3d::clusterPolygons(
neighbors,
_ui->spinBox_mesh_minClusterSize->value());
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
int oi=0;
for(std::list<std::list<int> >::iterator iter=clusters.begin(); iter!=clusters.end(); ++iter)
{
for(std::list<int>::iterator jter=iter->begin(); jter!=iter->end(); ++jter)
{
filteredPolygons[oi++] = mesh->polygons.at(*jter);
}
}
filteredPolygons.resize(oi);
mesh->polygons = filteredPolygons;
}
_progressDialog->appendText(tr("Mesh %1 created with %2 polygons (%3/%4).").arg(iter->first).arg(mesh->polygons.size()).arg(++i).arg(clouds.size()));
QApplication::processEvents();
@@ -1392,6 +1339,7 @@ bool ExportCloudsDialog::getExportedClouds(
tree->setInputCloud(iter->second);
pcl::PointCloud<pcl::PointXYZRGB>::Ptr coloredCloud(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::fromPCLPointCloud2(mesh->cloud, *coloredCloud);
std::vector<bool> coloredPts(coloredCloud->size());
for(unsigned int i=0; i<coloredCloud->size(); ++i)
{
std::vector<int> kIndices;
@@ -1407,14 +1355,76 @@ bool ExportCloudsDialog::getExportedClouds(
coloredCloud->at(i).g = iter->second->at(kIndices[0]).g;
coloredCloud->at(i).b = iter->second->at(kIndices[0]).b;
coloredCloud->at(i).a = iter->second->at(kIndices[0]).a;
coloredPts.at(i) = true;
}
else
{
//white
coloredCloud->at(i).r = coloredCloud->at(i).g = coloredCloud->at(i).b = 255;
coloredPts.at(i) = false;
}
}
pcl::toPCLPointCloud2(*coloredCloud, mesh->cloud);
// remove polygons with no color
if(_ui->checkBox_cleanMesh->isChecked())
{
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
int oi=0;
for(unsigned int i=0; i<mesh->polygons.size(); ++i)
{
bool coloredPolygon = true;
for(unsigned int j=0; j<mesh->polygons[i].vertices.size(); ++j)
{
if(!coloredPts.at(mesh->polygons[i].vertices[j]))
{
coloredPolygon = false;
break;
}
}
if(coloredPolygon)
{
filteredPolygons[oi++] = mesh->polygons[i];
}
}
filteredPolygons.resize(oi);
mesh->polygons = filteredPolygons;
}
}
if(_ui->spinBox_mesh_minClusterSize->value() &&
!(_ui->checkBox_textureMapping->isEnabled() &&
_ui->checkBox_textureMapping->isChecked() &&
_ui->checkBox_cleanMesh->isChecked()))
{
_progressDialog->appendText(tr("Filter small polygon clusters..."));
QApplication::processEvents();
// filter polygons
std::vector<std::set<int> > neighbors;
std::vector<std::set<int> > vertexToPolygons;
util3d::createPolygonIndexes(mesh->polygons,
mesh->cloud.height*mesh->cloud.width,
neighbors,
vertexToPolygons);
std::list<std::list<int> > clusters = util3d::clusterPolygons(
neighbors,
_ui->spinBox_mesh_minClusterSize->value());
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
int oi=0;
for(std::list<std::list<int> >::iterator kter=clusters.begin(); kter!=clusters.end(); ++kter)
{
for(std::list<int>::iterator jter=kter->begin(); jter!=kter->end(); ++jter)
{
filteredPolygons[oi++] = mesh->polygons.at(*jter);
}
}
filteredPolygons.resize(oi);
int before = mesh->polygons.size();
mesh->polygons = filteredPolygons;
_progressDialog->appendText(tr("Filtered %1 polygons.").arg(before-oi));
QApplication::processEvents();
}
meshes.insert(std::make_pair(iter->first, mesh));
@@ -1582,32 +1592,128 @@ bool ExportCloudsDialog::getExportedClouds(
dir.filePath("tmp_textures").toStdString(),
_ui->spinBox_normalKSearch->value());
// Remove occluded polygons (polygons with no texture)
if(_ui->checkBox_cleanMesh->isChecked() &&
textureMesh->tex_coordinates.size())
{
// assume last texture is the occluded texture
textureMesh->tex_coordinates.pop_back();
textureMesh->tex_polygons.pop_back();
textureMesh->tex_materials.pop_back();
if(_ui->spinBox_mesh_minClusterSize->value())
{
_progressDialog->appendText(tr("Filter small polygon clusters..."));
QApplication::processEvents();
// concatenate all polygons
int totalSize = 0;
for(unsigned int t=0; t<textureMesh->tex_polygons.size(); ++t)
{
totalSize+=textureMesh->tex_polygons[t].size();
}
std::vector<pcl::Vertices> allPolygons(totalSize);
int oi=0;
for(unsigned int t=0; t<textureMesh->tex_polygons.size(); ++t)
{
for(unsigned int i=0; i<textureMesh->tex_polygons[t].size(); ++i)
{
allPolygons[oi++] = textureMesh->tex_polygons[t][i];
}
}
// filter polygons
std::vector<std::set<int> > neighbors;
std::vector<std::set<int> > vertexToPolygons;
util3d::createPolygonIndexes(allPolygons,
textureMesh->cloud.data.size()/textureMesh->cloud.point_step,
neighbors,
vertexToPolygons);
std::list<std::list<int> > clusters = util3d::clusterPolygons(
neighbors,
_ui->spinBox_mesh_minClusterSize->value());
std::set<int> validPolygons;
for(std::list<std::list<int> >::iterator kter=clusters.begin(); kter!=clusters.end(); ++kter)
{
for(std::list<int>::iterator jter=kter->begin(); jter!=kter->end(); ++jter)
{
validPolygons.insert(*jter);
}
}
// for each texture
int allPolygonsIndex = 0;
for(unsigned int t=0; t<textureMesh->tex_polygons.size(); ++t)
{
UASSERT(allPolygonsIndex < allPolygons.size());
std::vector<pcl::Vertices> filteredPolygons(textureMesh->tex_polygons[t].size());
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > filteredCoordinates(textureMesh->tex_coordinates[t].size());
#else
std::vector<Eigen::Vector2f> filteredCoordinates(textureMesh->tex_coordinates[t].size());
#endif
int oi=0;
unsigned int polygonSize = 0;
if(textureMesh->tex_polygons[t].size())
{
polygonSize = textureMesh->tex_polygons[t][0].vertices.size();
UASSERT(filteredCoordinates.size() == textureMesh->tex_polygons[t].size()*polygonSize);
for(unsigned int i=0; i<textureMesh->tex_polygons[t].size(); ++i)
{
if(validPolygons.find(allPolygonsIndex) != validPolygons.end())
{
filteredPolygons[oi] = textureMesh->tex_polygons[t].at(i);
for(unsigned int j=0; j<polygonSize; ++j)
{
filteredCoordinates[oi*polygonSize + j] = textureMesh->tex_coordinates[t][i*polygonSize + j];
}
++oi;
}
++allPolygonsIndex;
}
filteredPolygons.resize(oi);
filteredCoordinates.resize(oi*polygonSize);
textureMesh->tex_polygons[t] = filteredPolygons;
textureMesh->tex_coordinates[t] = filteredCoordinates;
}
}
_progressDialog->appendText(tr("Filtered %1 polygons.").arg(allPolygons.size()-validPolygons.size()));
QApplication::processEvents();
}
}
if(!_ui->checkBox_binary->isEnabled() && // not enabled -> we are not exporting to file
textureMesh->tex_coordinates.size() &&
textureMesh->tex_coordinates[0].size()) // assume first is the texture, second is occluded texture
textureMesh->tex_coordinates.size())
{
UDEBUG("");
// When not saving to file, tex_coordinates should be linked to points, not polygon vertices
int nPoints = textureMesh->cloud.data.size()/textureMesh->cloud.point_step;
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > tmpCoordinates = textureMesh->tex_coordinates[0];
#else
std::vector<Eigen::Vector2f> tmpCoordinates = textureMesh->tex_coordinates[0];
#endif
textureMesh->tex_coordinates[0].resize(nPoints);
int polygonSize = textureMesh->tex_polygons[0][0].vertices.size();
UASSERT(textureMesh->tex_polygons[0].size() == tmpCoordinates.size()/polygonSize);
for(unsigned int i=0; i<textureMesh->tex_polygons[0].size(); ++i)
// for each texture
for(unsigned int t=0; t<textureMesh->tex_coordinates.size(); ++t)
{
const pcl::Vertices & vertices = textureMesh->tex_polygons[0][i];
UASSERT(polygonSize == (int)vertices.vertices.size());
for(int j=0; j<polygonSize; ++j)
// When not saving to file, tex_coordinates should be linked to points, not polygon vertices
int nPoints = textureMesh->cloud.data.size()/textureMesh->cloud.point_step;
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > tmpCoordinates = textureMesh->tex_coordinates[t];
#else
std::vector<Eigen::Vector2f> tmpCoordinates = textureMesh->tex_coordinates[t];
#endif
textureMesh->tex_coordinates[t].resize(nPoints);
int polygonSize = textureMesh->tex_polygons[t][0].vertices.size();
UASSERT(textureMesh->tex_polygons[t].size() == tmpCoordinates.size()/polygonSize);
for(unsigned int i=0; i<textureMesh->tex_polygons[t].size(); ++i)
{
//uv
UASSERT((int)vertices.vertices[j] < nPoints);
UASSERT(i*polygonSize+j < tmpCoordinates.size());
textureMesh->tex_coordinates[0][vertices.vertices[j]] = tmpCoordinates[i*polygonSize+j];
const pcl::Vertices & vertices = textureMesh->tex_polygons[t][i];
UASSERT(polygonSize == (int)vertices.vertices.size());
for(int j=0; j<polygonSize; ++j)
{
//uv
UASSERT((int)vertices.vertices[j] < nPoints);
UASSERT(i*polygonSize+j < tmpCoordinates.size());
textureMesh->tex_coordinates[t][vertices.vertices[j]] = tmpCoordinates[i*polygonSize+j];
}
}
}
}
@@ -1678,6 +1784,11 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
d.uncompressData(&image, &depth, 0);
if(!image.empty() && !depth.empty())
{
if(_ui->spinBox_fillDepthHoles->value() > 0)
{
depth = util2d::fillDepthHoles(depth, _ui->spinBox_fillDepthHoles->value(), float(_ui->spinBox_fillDepthHolesError->value())/100.f);
}
if(!_ui->lineEdit_distortionModel->text().isEmpty() &&
QFileInfo(_ui->lineEdit_distortionModel->text()).exists())
{
@@ -1699,13 +1810,27 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
UASSERT(iter->first == d.id());
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
std::vector<float> roiRatios;
if(!_ui->lineEdit_roiRatios->text().isEmpty())
{
QStringList values = _ui->lineEdit_roiRatios->text().split(' ');
if(values.size() == 4)
{
roiRatios.resize(4);
for(int i=0; i<values.size(); ++i)
{
roiRatios[i] = uStr2Float(values[i].toStdString().c_str());
}
}
}
cloudWithoutNormals = util3d::cloudRGBFromSensorData(
d,
_ui->spinBox_decimation->value() == 0?1:_ui->spinBox_decimation->value(),
_ui->doubleSpinBox_maxDepth->value(),
_ui->doubleSpinBox_minDepth->value(),
indices.get(),
parameters);
parameters,
roiRatios);
if(cloudWithoutNormals->size())
{

View File

@@ -958,7 +958,8 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
_preferencesDialog->getCloudMaxDepth(1),
_preferencesDialog->getCloudMinDepth(1),
indices.get(),
_preferencesDialog->getAllParameters());
_preferencesDialog->getAllParameters(),
_preferencesDialog->getCloudRoiRatios(1));
if(indices->size())
{
cloud = util3d::transformPointCloud(cloud, pose);
@@ -2431,7 +2432,8 @@ std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> MainWindow::c
_preferencesDialog->getCloudMaxDepth(0),
_preferencesDialog->getCloudMinDepth(0),
indices.get(),
_preferencesDialog->getAllParameters());
_preferencesDialog->getAllParameters(),
_preferencesDialog->getCloudRoiRatios(0));
// view point
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
@@ -5478,6 +5480,8 @@ void MainWindow::setDefaultViews()
_ui->statusbar->setVisible(false);
this->setAspectRatio720p();
_cloudViewer->resetCamera();
_cloudViewer->setCameraLockZ(true);
_cloudViewer->setCameraTargetFollow(true);
}
void MainWindow::selectScreenCaptureFormat(bool checked)

View File

@@ -315,6 +315,10 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_3dRenderingMinDepth[0] = _ui->doubleSpinBox_minDepth;
_3dRenderingMinDepth[1] = _ui->doubleSpinBox_minDepth_odom;
_3dRenderingRoiRatios.resize(2);
_3dRenderingRoiRatios[0] = _ui->lineEdit_roiRatios;
_3dRenderingRoiRatios[1] = _ui->lineEdit_roiRatios_odom;
_3dRenderingOpacity.resize(2);
_3dRenderingOpacity[0] = _ui->doubleSpinBox_opacity;
_3dRenderingOpacity[1] = _ui->doubleSpinBox_opacity_odom;
@@ -357,6 +361,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
connect(_3dRenderingDecimation[i], SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingMaxDepth[i], SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingMinDepth[i], SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingRoiRatios[i], SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingShowScans[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingShowFeatures[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
@@ -1233,6 +1238,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
_3dRenderingDecimation[i]->setValue(4);
_3dRenderingMaxDepth[i]->setValue(0.0);
_3dRenderingMinDepth[i]->setValue(0.0);
_3dRenderingRoiRatios[i]->setText("0.0 0.0 0.0 0.0");
_3dRenderingShowScans[i]->setChecked(true);
_3dRenderingShowFeatures[i]->setChecked(i==0?false:true);
@@ -1623,6 +1629,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
_3dRenderingDecimation[i]->setValue(settings.value(QString("decimation%1").arg(i), _3dRenderingDecimation[i]->value()).toInt());
_3dRenderingMaxDepth[i]->setValue(settings.value(QString("maxDepth%1").arg(i), _3dRenderingMaxDepth[i]->value()).toDouble());
_3dRenderingMinDepth[i]->setValue(settings.value(QString("minDepth%1").arg(i), _3dRenderingMinDepth[i]->value()).toDouble());
_3dRenderingRoiRatios[i]->setText(settings.value(QString("roiRatios%1").arg(i), _3dRenderingRoiRatios[i]->text()).toString());
_3dRenderingShowScans[i]->setChecked(settings.value(QString("showScans%1").arg(i), _3dRenderingShowScans[i]->isChecked()).toBool());
_3dRenderingShowFeatures[i]->setChecked(settings.value(QString("showFeatures%1").arg(i), _3dRenderingShowFeatures[i]->isChecked()).toBool());
@@ -2005,6 +2012,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
settings.setValue(QString("decimation%1").arg(i), _3dRenderingDecimation[i]->value());
settings.setValue(QString("maxDepth%1").arg(i), _3dRenderingMaxDepth[i]->value());
settings.setValue(QString("minDepth%1").arg(i), _3dRenderingMinDepth[i]->value());
settings.setValue(QString("roiRatios%1").arg(i), _3dRenderingRoiRatios[i]->text());
settings.setValue(QString("showScans%1").arg(i), _3dRenderingShowScans[i]->isChecked());
settings.setValue(QString("showFeatures%1").arg(i), _3dRenderingShowFeatures[i]->isChecked());
@@ -3950,6 +3958,24 @@ double PreferencesDialog::getCloudMinDepth(int index) const
UASSERT(index >= 0 && index <= 1);
return _3dRenderingMinDepth[index]->value();
}
std::vector<float> PreferencesDialog::getCloudRoiRatios(int index) const
{
UASSERT(index >= 0 && index <= 1);
std::vector<float> roiRatios;
if(!_3dRenderingRoiRatios[index]->text().isEmpty())
{
QStringList values = _3dRenderingRoiRatios[index]->text().split(' ');
if(values.size() == 4)
{
roiRatios.resize(4);
for(int i=0; i<values.size(); ++i)
{
roiRatios[i] = uStr2Float(values[i].toStdString().c_str());
}
}
}
return roiRatios;
}
double PreferencesDialog::getCloudOpacity(int index) const
{
UASSERT(index >= 0 && index <= 1);

View File

@@ -23,9 +23,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-1525</y>
<y>0</y>
<width>773</width>
<height>2568</height>
<height>2728</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
@@ -151,25 +151,6 @@
<layout class="QVBoxLayout" name="verticalLayout_14">
<item>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,1">
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_maxDepth">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>4.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_108">
<property name="text">
@@ -180,49 +161,6 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox_decimation">
<property name="minimum">
<number>-32</number>
</property>
<property name="maximum">
<number>32</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_134">
<property name="text">
<string>Path to a depth distortion model to apply (output from depth calibration).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_132">
<property name="text">
<string>3D cloud maximum depth (0 means no limit).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_133">
<property name="text">
<string>3D cloud minimum depth.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth">
<property name="suffix">
@@ -242,16 +180,131 @@
</property>
</widget>
</item>
<item row="3" column="1">
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_distortionModel"/>
</item>
<item row="3" column="0">
<item row="6" column="0">
<widget class="QToolButton" name="toolButton_distortionModel">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="spinBox_fillDepthHoles">
<property name="suffix">
<string> pixels</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="spinBox_fillDepthHolesError">
<property name="suffix">
<string> %</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_132">
<property name="text">
<string>3D cloud maximum depth (0 means no limit).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_133">
<property name="text">
<string>3D cloud minimum depth.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="label_197">
<property name="text">
<string>Fill depth hole size (0 means no fill).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_maxDepth">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>4.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox_decimation">
<property name="minimum">
<number>-32</number>
</property>
<property name="maximum">
<number>32</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="label_134">
<property name="text">
<string>Path to a depth distortion model to apply (output from depth calibration).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_198">
<property name="text">
<string>Fill depth hole error.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_135">
<property name="text">
<string>ROI ratios [left, right, top, bottom] between 0 and 1. Only generate 3D points for pixels inside the region of interest (RGB image).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_roiRatios"/>
</item>
</layout>
</item>
<item>
@@ -1052,43 +1105,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
<layout class="QVBoxLayout" name="verticalLayout_15">
<item>
<layout class="QGridLayout" name="gridLayout_10" columnstretch="0,1">
<item row="2" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_meshDecimationFactor">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>0.990000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_textureMapping">
<property name="text">
<string>Texture mapping. Images of the cameras will be projected on the mesh(es). Output is a *.obj format. Only available on Export or when clouds are not assembled.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Min polygon cluster size</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QSpinBox" name="spinBox_mesh_minClusterSize">
<property name="maximum">
<number>999</number>
@@ -1098,7 +1115,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
<item row="2" column="1">
<widget class="QLabel" name="label_meshDecimation">
<property name="text">
<string>Mesh quadric decimation factor (0=no decimation). Used to reduce the number of polygons. Higher the factor, lower the output resolution (less polygons).</string>
<string>Mesh quadric decimation factor (0=no decimation). Used to reduce the number of polygons. Higher the factor, lower the output resolution (less polygons). Can be used only when dense reconstruction flavor is selected.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -1168,6 +1185,59 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_meshDecimationFactor">
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>0.990000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_textureMapping">
<property name="text">
<string>Texture mapping. Images of the cameras will be projected on the mesh(es). Output is a *.obj format. Only available on Export or when clouds are not assembled.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Min polygon cluster size</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_meshDecimation_3">
<property name="text">
<string>Clean mesh from polygons without color or texture.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="checkBox_cleanMesh">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>

View File

@@ -64,8 +64,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>678</width>
<height>2632</height>
<width>673</width>
<height>2649</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
@@ -86,7 +86,7 @@
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex">
<number>3</number>
<number>1</number>
</property>
<widget class="QWidget" name="page_22">
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
@@ -487,7 +487,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxel">
<property name="suffix">
<string> m</string>
@@ -506,7 +506,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="6" column="2">
<item row="7" column="2">
<widget class="QLabel" name="label_168">
<property name="text">
<string>3D cloud noise filtering radius (0=disabled). Done after voxel filtering.</string>
@@ -538,6 +538,88 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="18" column="2">
<widget class="QLabel" name="label_123">
<property name="text">
<string>Show 3D features.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QCheckBox" name="checkBox_showScans">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QCheckBox" name="checkBox_showOdomScans">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="2">
<widget class="QLabel" name="label_110">
<property name="text">
<string>Show scans.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QSpinBox" name="spinBox_noiseMinNeighbors">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_132">
<property name="text">
<string>3D cloud maximum depth (0 means no limit).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox_showOdomClouds">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth">
<property name="suffix">
@@ -557,7 +639,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="17" column="1">
<item row="18" column="1">
<widget class="QCheckBox" name="checkBox_showOdomFeatures">
<property name="text">
<string/>
@@ -567,53 +649,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="17" column="2">
<widget class="QLabel" name="label_123">
<property name="text">
<string>Show 3D features.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QCheckBox" name="checkBox_showScans">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QCheckBox" name="checkBox_showOdomScans">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="12" column="2">
<widget class="QLabel" name="label_110">
<property name="text">
<string>Show scans.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="13" column="0">
<item row="14" column="0">
<widget class="QSpinBox" name="spinBox_downsamplingScan">
<property name="minimum">
<number>1</number>
@@ -623,7 +659,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="13" column="2">
<item row="14" column="2">
<widget class="QLabel" name="label_273">
<property name="text">
<string>Scan downsampling step size.</string>
@@ -636,7 +672,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="14" column="0">
<item row="15" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSizeScan">
<property name="suffix">
<string> m</string>
@@ -655,7 +691,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="14" column="1">
<item row="15" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSizeScan_odom">
<property name="suffix">
<string> m</string>
@@ -674,7 +710,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="15" column="1">
<item row="16" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity_odom_scan">
<property name="suffix">
<string/>
@@ -693,7 +729,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="7" column="2">
<item row="8" column="2">
<widget class="QLabel" name="label_169">
<property name="text">
<string>3D cloud noise filtering min neighbors.</string>
@@ -706,7 +742,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="18" column="1">
<item row="19" column="1">
<widget class="QSpinBox" name="spinBox_ptsize_odom_features">
<property name="minimum">
<number>1</number>
@@ -716,7 +752,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="18" column="2">
<item row="19" column="2">
<widget class="QLabel" name="label_166">
<property name="text">
<string>Feature point size.</string>
@@ -729,7 +765,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="10" column="0">
<item row="11" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity">
<property name="suffix">
<string/>
@@ -748,7 +784,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="11" column="0">
<item row="12" column="0">
<widget class="QSpinBox" name="spinBox_ptsize">
<property name="minimum">
<number>1</number>
@@ -761,7 +797,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="11" column="2">
<item row="12" column="2">
<widget class="QLabel" name="label_157">
<property name="text">
<string>3D cloud point size (1..64).</string>
@@ -774,7 +810,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="16" column="1">
<item row="17" column="1">
<widget class="QSpinBox" name="spinBox_ptsize_odom_scan">
<property name="minimum">
<number>1</number>
@@ -784,7 +820,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="17" column="0">
<item row="18" column="0">
<widget class="QCheckBox" name="checkBox_showFeatures">
<property name="text">
<string/>
@@ -871,7 +907,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="19" column="2">
<item row="20" column="2">
<widget class="QLabel" name="label_213">
<property name="text">
<string>Show graphs.</string>
@@ -910,7 +946,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="5" column="2">
<item row="6" column="2">
<widget class="QLabel" name="label_171">
<property name="text">
<string>3D cloud voxel filtering size (0=disabled).</string>
@@ -923,7 +959,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_noiseRadius">
<property name="suffix">
<string> m</string>
@@ -942,33 +978,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QSpinBox" name="spinBox_noiseMinNeighbors">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_132">
<property name="text">
<string>3D cloud maximum depth (0 means no limit).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="18" column="0">
<item row="19" column="0">
<widget class="QSpinBox" name="spinBox_ptsize_features">
<property name="minimum">
<number>1</number>
@@ -978,7 +988,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="8" column="2">
<item row="9" column="2">
<widget class="QLabel" name="label_210">
<property name="text">
<string>3D cloud normal K search. If not 0, normals will be computed and added to created cloud for visualization (keys 7, 8 and 9).</string>
@@ -991,7 +1001,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="13" column="1">
<item row="14" column="1">
<widget class="QSpinBox" name="spinBox_downsamplingScan_odom">
<property name="minimum">
<number>1</number>
@@ -1001,7 +1011,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="14" column="2">
<item row="15" column="2">
<widget class="QLabel" name="label_271">
<property name="text">
<string>Scan voxel size.</string>
@@ -1014,7 +1024,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="15" column="0">
<item row="16" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity_scan">
<property name="suffix">
<string/>
@@ -1033,7 +1043,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="15" column="2">
<item row="16" column="2">
<widget class="QLabel" name="label_156">
<property name="text">
<string>Scan opacity.</string>
@@ -1046,7 +1056,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QSpinBox" name="spinBox_normalKSearch">
<property name="minimum">
<number>0</number>
@@ -1059,7 +1069,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="10" column="1">
<item row="11" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity_odom">
<property name="suffix">
<string/>
@@ -1078,7 +1088,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="10" column="2">
<item row="11" column="2">
<widget class="QLabel" name="label_155">
<property name="text">
<string>3D cloud opacity.</string>
@@ -1091,7 +1101,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="11" column="1">
<item row="12" column="1">
<widget class="QSpinBox" name="spinBox_ptsize_odom">
<property name="minimum">
<number>1</number>
@@ -1104,7 +1114,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="16" column="0">
<item row="17" column="0">
<widget class="QSpinBox" name="spinBox_ptsize_scan">
<property name="minimum">
<number>1</number>
@@ -1114,7 +1124,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="16" column="2">
<item row="17" column="2">
<widget class="QLabel" name="label_158">
<property name="text">
<string>Scan point size (1..64).</string>
@@ -1140,16 +1150,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="checkBox_showOdomClouds">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_119">
<property name="text">
@@ -1163,7 +1163,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="20" column="2">
<item row="21" column="2">
<widget class="QLabel" name="label_243">
<property name="text">
<string>Show labels.</string>
@@ -1176,7 +1176,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="19" column="0">
<item row="20" column="0">
<widget class="QCheckBox" name="checkBox_showGraphs">
<property name="text">
<string/>
@@ -1186,7 +1186,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="20" column="0">
<item row="21" column="0">
<widget class="QCheckBox" name="checkBox_showLabels">
<property name="text">
<string/>
@@ -1196,7 +1196,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="9" column="2">
<item row="10" column="2">
<widget class="QLabel" name="label_338">
<property name="text">
<string>Gain compensation.</string>
@@ -1209,7 +1209,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QCheckBox" name="checkBox_gainCompensation">
<property name="text">
<string/>
@@ -1219,6 +1219,25 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_353">
<property name="text">
<string>3D cloud ROI ratios [left, right, top, bottom] between 0 and 1.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLineEdit" name="lineEdit_roiRatios"/>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_roiRatios_odom"/>
</item>
</layout>
</item>
<item>