New feature: Depth confidence (#1520)

* New feature: Depth confidence

* iOS app updated to save depth confidence, added util2d::depthBleedingFiltering function

* Updated tools to show/extract depth confidence

* Android: moved smoothing in post-processing, fixed confidence registration, added depth bleeding error option.

* Fixed warning

* removed debug log

* Added new feature types, fixed rendering when exporting texture >4096 (#1469), added depth bleeding filter option to iOS

* fixed some warnings, android: added bleeding error option

* CI: try updating ros2 key

* added sudo

* antoher test

* bump ios app version
This commit is contained in:
matlabbe
2025-06-01 14:14:29 -07:00
committed by GitHub
parent 90d195237f
commit 6d4e8a4173
51 changed files with 2368 additions and 1006 deletions

View File

@@ -60,6 +60,7 @@ public:
QRectF sceneRect() const;
bool isImageShown() const;
bool isImageDepthShown() const;
bool isImageDepthConfidenceShown() const;
bool isFeaturesShown() const;
bool isLinesShown() const;
int getAlpha() const {return _alpha;}
@@ -82,6 +83,7 @@ public:
void setFeaturesShown(bool shown);
void setImageShown(bool shown);
void setImageDepthShown(bool shown);
void setImageDepthConfidenceShown(bool shown);
void setLinesShown(bool shown);
void setGraphicsViewMode(bool on);
void setGraphicsViewScaled(bool scaled);
@@ -98,8 +100,8 @@ public:
void addFeature(int id, const cv::KeyPoint & kpt, float depth, QColor color);
void addLine(float x1, float y1, float x2, float y2, QColor color, const QString & text = QString());
void setImage(const QImage & image, const std::vector<CameraModel> & models = std::vector<CameraModel>(), const Transform & pose = Transform());
void setImageDepth(const cv::Mat & imageDepth);
void setImageDepth(const QImage & image);
void setImageDepth(const cv::Mat & imageDepth, const cv::Mat & imageDepthConfidence = cv::Mat());
void setImageDepth(const QImage & image, const QImage & imageDepthConfidence = QImage());
void setFeatureColor(int id, QColor color);
void setFeaturesColor(QColor color);
void setAlpha(int alpha);
@@ -147,6 +149,7 @@ private:
QMenu * _menu;
QAction * _showImage;
QAction * _showImageDepth;
QAction * _showImageDepthConfidence;
QAction * _showFeatures;
QAction * _showLines;
QAction * _setFeatureColor;
@@ -175,9 +178,12 @@ private:
QList<QGraphicsLineItem*> _lines;
QGraphicsPixmapItem * _imageItem;
QGraphicsPixmapItem * _imageDepthItem;
QGraphicsPixmapItem * _imageDepthConfidenceItem;
QPixmap _image;
QPixmap _imageDepth;
QPixmap _imageDepthConfidence;
cv::Mat _imageDepthCv;
cv::Mat _imageDepthConfidenceCv;
std::vector<CameraModel> _models;
Transform _pose;
};

View File

@@ -208,6 +208,7 @@ public:
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
unsigned char getCloudConfidenceThr(int index) const; // 0=map, 1=odom
int getCloudColorScheme(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
@@ -466,6 +467,7 @@ private:
QVector<QDoubleSpinBox*> _3dRenderingMaxDepth;
QVector<QDoubleSpinBox*> _3dRenderingMinDepth;
QVector<QLineEdit*> _3dRenderingRoiRatios;
QVector<QSpinBox*> _3dRenderingDepthConfidenceThr;
QVector<QSpinBox*> _3dRenderingColorScheme;
QVector<QDoubleSpinBox*> _3dRenderingOpacity;
QVector<QSpinBox*> _3dRenderingPtSize;

View File

@@ -39,7 +39,7 @@ enum uCvQtDepthColorMap{
* depth (float32, uint16) image and RGB/BGR 8bits images.
* @param image the cv::Mat image (can be 1 channel [CV_8U, CV_16U or CV_32F] or 3 channels [CV_U8])
* @param isBgr if 3 channels, it is BGR or RGB order.
* @param colorMap gradient of color to use to visualize depth
* @param colorMap gradient of color to use to visualize depth or monochrome images
* @param depthMin fixed minimum range (m) of the depth gradient (if depthMax<=depthMin, max/min are computed based on data in depth image)
* @param depthMax fixed maximum range (m) of the depth gradient (if depthMax<=depthMin, max/min are computed based on data in depth image)
* @return the QImage
@@ -47,7 +47,7 @@ enum uCvQtDepthColorMap{
inline QImage uCvMat2QImage(
const cv::Mat & image,
bool isBgr = true,
uCvQtDepthColorMap colorMap = uCvQtDepthWhiteToBlack,
uCvQtDepthColorMap colorMap = uCvQtDepthBlackToWhite,
float depthMin = 0,
float depthMax = 0)
{
@@ -81,9 +81,30 @@ inline QImage uCvMat2QImage(
{
// mono grayscale
qtemp = QImage(image.data, image.cols, image.rows, image.cols, QImage::Format_Indexed8).copy();
QVector<QRgb> my_table;
for(int i = 0; i < 256; i++)
my_table.push_back(qRgb(i,i,i));
my_table.reserve(256);
if(colorMap == uCvQtDepthRedToBlue || colorMap == uCvQtDepthBlueToRed)
{
if(colorMap == uCvQtDepthBlueToRed) {
for(int i = 0; i < 256; i++)
my_table.push_back(QColor::fromHsv(255-i, 255, 255, 255).rgb());
}
else {
for(int i = 0; i < 256; i++)
my_table.push_back(QColor::fromHsv(i, 255, 255, 255).rgb());
}
}
else if(colorMap == uCvQtDepthBlackToWhite)
{
for(int i = 0; i < 256; i++)
my_table.push_back(qRgb(i,i,i));
}
else // uCvQtDepthWhiteToBlack
{
for(int i = 0; i < 256; i++)
my_table.push_back(qRgb(255-i,255-i,255-i));
}
qtemp.setColorTable(my_table);
}
else

View File

@@ -427,6 +427,10 @@ DatabaseViewer::DatabaseViewer(const QString & ini, QWidget * parent) :
connect(ui_->checkBox_showDisparityInsteadOfRight, SIGNAL(stateChanged(int)), this, SLOT(update3dView()));
connect(ui_->spinBox_decimation, SIGNAL(valueChanged(int)), this, SLOT(updateConstraintView()));
connect(ui_->spinBox_decimation, SIGNAL(valueChanged(int)), this, SLOT(update3dView()));
connect(ui_->spinBox_depthConfidence, SIGNAL(valueChanged(int)), this, SLOT(updateConstraintView()));
connect(ui_->spinBox_depthConfidence, SIGNAL(valueChanged(int)), this, SLOT(update3dView()));
connect(ui_->doubleSpinBox_depthEdgeBleedingError, SIGNAL(valueChanged(double)), this, SLOT(updateConstraintView()));
connect(ui_->doubleSpinBox_depthEdgeBleedingError, SIGNAL(valueChanged(double)), this, SLOT(update3dView()));
connect(ui_->groupBox_posefiltering, SIGNAL(clicked(bool)), this, SLOT(updateGraphView()));
connect(ui_->doubleSpinBox_posefilteringRadius, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
connect(ui_->doubleSpinBox_posefilteringAngle, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
@@ -457,6 +461,8 @@ DatabaseViewer::DatabaseViewer(const QString & ini, QWidget * parent) :
connect(ui_->checkBox_cameraProjection, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_showDisparityInsteadOfRight, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->spinBox_decimation, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->spinBox_depthConfidence, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_depthEdgeBleedingError, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->groupBox_posefiltering, SIGNAL(clicked(bool)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_posefilteringRadius, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_posefilteringAngle, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
@@ -616,6 +622,8 @@ void DatabaseViewer::readSettings()
ui_->doubleSpinBox_gainCompensationRadius->setValue(settings.value("gainCompensationRadius", ui_->doubleSpinBox_gainCompensationRadius->value()).toDouble());
ui_->doubleSpinBox_voxelSize->setValue(settings.value("voxelSize", ui_->doubleSpinBox_voxelSize->value()).toDouble());
ui_->spinBox_decimation->setValue(settings.value("decimation", ui_->spinBox_decimation->value()).toInt());
ui_->spinBox_depthConfidence->setValue(settings.value("depth_confidence_thr", ui_->spinBox_depthConfidence->value()).toInt());
ui_->doubleSpinBox_depthEdgeBleedingError->setValue(settings.value("depth_bleeding_error", ui_->doubleSpinBox_depthEdgeBleedingError->value()).toDouble());
ui_->checkBox_cameraProjection->setChecked(settings.value("camProj", ui_->checkBox_cameraProjection->isChecked()).toBool());
ui_->checkBox_showDisparityInsteadOfRight->setChecked(settings.value("showDisp", ui_->checkBox_showDisparityInsteadOfRight->isChecked()).toBool());
settings.endGroup();
@@ -707,6 +715,8 @@ void DatabaseViewer::writeSettings()
settings.setValue("gainCompensationRadius", ui_->doubleSpinBox_gainCompensationRadius->value());
settings.setValue("voxelSize", ui_->doubleSpinBox_voxelSize->value());
settings.setValue("decimation", ui_->spinBox_decimation->value());
settings.setValue("depth_confidence", ui_->spinBox_depthConfidence->value());
settings.setValue("depth_bleeding_error", ui_->doubleSpinBox_depthEdgeBleedingError->value());
settings.setValue("camProj", ui_->checkBox_cameraProjection->isChecked());
settings.setValue("showDisp", ui_->checkBox_showDisparityInsteadOfRight->isChecked());
settings.endGroup();
@@ -801,6 +811,8 @@ void DatabaseViewer::restoreDefaultSettings()
ui_->doubleSpinBox_gainCompensationRadius->setValue(0.0);
ui_->doubleSpinBox_voxelSize->setValue(0.0);
ui_->spinBox_decimation->setValue(1);
ui_->spinBox_depthConfidence->setValue(0);
ui_->doubleSpinBox_depthEdgeBleedingError->setValue(0.0);
ui_->checkBox_cameraProjection->setChecked(false);
ui_->checkBox_showDisparityInsteadOfRight->setChecked(false);
@@ -1584,6 +1596,11 @@ void DatabaseViewer::extractImages()
dir.mkdir(QString("%1/rgb").arg(path));
dir.mkdir(QString("%1/depth").arg(path));
dir.mkdir(QString("%1/calib").arg(path));
if(!data.depthConfidenceRaw().empty())
{
dir.mkdir(QString("%1/confidence").arg(path));
directoriesCreated = true;
}
directoriesCreated = true;
}
}
@@ -1668,7 +1685,14 @@ void DatabaseViewer::extractImages()
UWARN("Failed saving \"%s\"", QString("%1/rgb/%2.%3").arg(path).arg(id).arg(ext).toStdString().c_str());
if(!cv::imwrite(QString("%1/depth/%2.png").arg(path).arg(id).toStdString(), data.depthRaw().type()==CV_32FC1?util2d::cvtDepthFromFloat(data.depthRaw()):data.depthRaw()))
UWARN("Failed saving \"%s\"", QString("%1/depth/%2.png").arg(path).arg(id).toStdString().c_str());
UINFO(QString("Saved rgb/%1.%2 and depth/%1.png").arg(id).arg(ext).toStdString().c_str());
if(data.depthConfidenceRaw().empty()) {
UINFO(QString("Saved rgb/%1.%2 and depth/%1.png").arg(id).arg(ext).toStdString().c_str());
}
else {
if(!cv::imwrite(QString("%1/confidence/%2.png").arg(path).arg(id).toStdString(), data.depthConfidenceRaw()))
UWARN("Failed saving \"%s\"", QString("%1/confidence/%2.png").arg(path).arg(id).toStdString().c_str());
UINFO(QString("Saved rgb/%1.%2, depth/%1.png and confidence/%1.png").arg(id).arg(ext).toStdString().c_str());
}
}
else
{
@@ -4807,7 +4831,7 @@ void DatabaseViewer::update(int value,
if(!imgDepth.empty())
{
view->setImageDepth(imgDepth);
view->setImageDepth(imgDepth, data.depthConfidenceRaw());
if(img.isNull())
{
rect.setWidth(imgDepth.cols);
@@ -5266,6 +5290,12 @@ void DatabaseViewer::update(int value,
{
if(!data.depthOrRightRaw().empty())
{
if(!data.depthRaw().empty() && ui_->doubleSpinBox_depthEdgeBleedingError->value() > 0.0) {
cv::Mat depth = data.depthRaw();
util2d::depthBleedingFiltering(depth, ui_->doubleSpinBox_depthEdgeBleedingError->value());
data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
}
if(!data.imageRaw().empty())
{
std::vector<pcl::PointCloud<pcl::PointXYZRGB>::Ptr> clouds;
@@ -5281,8 +5311,13 @@ void DatabaseViewer::update(int value,
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud = util3d::cloudFromDepthRGB(
data.imageRaw(),
depth,
data.depthConfidenceRaw(),
data.cameraModels()[0],
ui_->spinBox_decimation->value(),0,0,indices.get());
ui_->spinBox_decimation->value(),
0,
0,
(unsigned char)ui_->spinBox_depthConfidence->value(),
indices.get());
if(indices->size())
{
clouds.push_back(util3d::transformPointCloud(cloud, data.cameraModels()[0].localTransform()));
@@ -5291,7 +5326,14 @@ void DatabaseViewer::update(int value,
}
else
{
clouds = util3d::cloudsRGBFromSensorData(data, ui_->spinBox_decimation->value(), 0, 0, &allIndices, ui_->parameters_toolbox->getParameters());
clouds = util3d::cloudsRGBFromSensorData(
data,
ui_->spinBox_decimation->value(),
0,
0,
&allIndices,
ui_->parameters_toolbox->getParameters(),std::vector<float>(),
(unsigned char)ui_->spinBox_depthConfidence->value());
}
UASSERT(clouds.size() == allIndices.size());
for(size_t i=0; i<allIndices.size(); ++i)
@@ -5366,7 +5408,14 @@ void DatabaseViewer::update(int value,
std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> clouds;
std::vector<pcl::IndicesPtr> allIndices;
clouds = util3d::cloudsFromSensorData(data, ui_->spinBox_decimation->value(), 0, 0, &allIndices, ui_->parameters_toolbox->getParameters());
clouds = util3d::cloudsFromSensorData(
data,
ui_->spinBox_decimation->value(),
0,
0,
&allIndices, ui_->parameters_toolbox->getParameters(),
std::vector<float>(),
(unsigned char)ui_->spinBox_depthConfidence->value());
UASSERT(clouds.size() == allIndices.size());
for(size_t i=0; i<allIndices.size(); ++i)
{
@@ -6494,11 +6543,37 @@ void DatabaseViewer::updateConstraintView(
pcl::IndicesPtr indicesTo(new std::vector<int>);
if(!dataFrom.imageRaw().empty() && !dataFrom.depthOrRightRaw().empty())
{
cloudFrom=util3d::cloudRGBFromSensorData(dataFrom, ui_->spinBox_decimation->value(), 0, 0, indicesFrom.get(), ui_->parameters_toolbox->getParameters());
if(!dataFrom.depthRaw().empty() && ui_->doubleSpinBox_depthEdgeBleedingError->value() > 0.0) {
cv::Mat depth = dataFrom.depthRaw();
util2d::depthBleedingFiltering(depth, ui_->doubleSpinBox_depthEdgeBleedingError->value());
dataFrom.setRGBDImage(dataFrom.imageRaw(), depth, dataFrom.depthConfidenceRaw(), dataFrom.cameraModels());
}
cloudFrom=util3d::cloudRGBFromSensorData(
dataFrom,
ui_->spinBox_decimation->value(),
0,
0,
indicesFrom.get(),
ui_->parameters_toolbox->getParameters(),
std::vector<float>(),
(unsigned char)ui_->spinBox_depthConfidence->value());
}
if(!dataTo.imageRaw().empty() && !dataTo.depthOrRightRaw().empty())
{
cloudTo=util3d::cloudRGBFromSensorData(dataTo, ui_->spinBox_decimation->value(), 0, 0, indicesTo.get(), ui_->parameters_toolbox->getParameters());
if(!dataTo.depthRaw().empty() && ui_->doubleSpinBox_depthEdgeBleedingError->value() > 0.0) {
cv::Mat depth = dataTo.depthRaw();
util2d::depthBleedingFiltering(depth, ui_->doubleSpinBox_depthEdgeBleedingError->value());
dataTo.setRGBDImage(dataTo.imageRaw(), depth, dataTo.depthConfidenceRaw(), dataTo.cameraModels());
}
cloudTo=util3d::cloudRGBFromSensorData(
dataTo,
ui_->spinBox_decimation->value(),
0,
0,
indicesTo.get(),
ui_->parameters_toolbox->getParameters(),
std::vector<float>(),
(unsigned char)ui_->spinBox_depthConfidence->value());
}
if(cloudTo.get() && indicesTo->size())

View File

@@ -151,6 +151,9 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
connect(_ui->lineEdit_distortionModel, SIGNAL(textChanged(const QString &)), this, SIGNAL(configChanged()));
connect(_ui->toolButton_distortionModel, SIGNAL(clicked()), this, SLOT(selectDistortionModel()));
connect(_ui->spinBox_depthConfidence, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_depthEdgeFiltering, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_bilateral, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_bilateral, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor()));
connect(_ui->doubleSpinBox_bilateral_sigmaS, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
@@ -401,6 +404,8 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
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("regenerate_min_depth_confidence", _ui->spinBox_depthConfidence->value());
settings.setValue("regenerate_edge_bleeding_error", _ui->doubleSpinBox_depthEdgeFiltering->value());
settings.setValue("bilateral", _ui->checkBox_bilateral->isChecked());
settings.setValue("bilateral_sigma_s", _ui->doubleSpinBox_bilateral_sigmaS->value());
@@ -584,6 +589,8 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
_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->spinBox_depthConfidence->setValue(settings.value("regenerate_min_depth_confidence", _ui->spinBox_depthConfidence->value()).toInt());
_ui->doubleSpinBox_depthEdgeFiltering->setValue(settings.value("regenerate_edge_bleeding_error", _ui->doubleSpinBox_depthEdgeFiltering->value()).toDouble());
_ui->checkBox_bilateral->setChecked(settings.value("bilateral", _ui->checkBox_bilateral->isChecked()).toBool());
_ui->doubleSpinBox_bilateral_sigmaS->setValue(settings.value("bilateral_sigma_s", _ui->doubleSpinBox_bilateral_sigmaS->value()).toDouble());
@@ -770,6 +777,8 @@ void ExportCloudsDialog::restoreDefaults()
_ui->spinBox_fillDepthHolesError->setValue(2);
_ui->lineEdit_roiRatios->setText("0.0 0.0 0.0 0.0");
_ui->lineEdit_distortionModel->setText("");
_ui->spinBox_depthConfidence->setValue(0);
_ui->doubleSpinBox_depthEdgeFiltering->setValue(0.0);
_ui->checkBox_bilateral->setChecked(false);
_ui->doubleSpinBox_bilateral_sigmaS->setValue(10.0);
@@ -3685,20 +3694,30 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
{
const Signature & s = cachedSignatures.find(iter->first).value();
data = s.sensorData();
cv::Mat image,depth;
cv::Mat image,depth,confidence;
data.uncompressData(
_ui->checkBox_fromDepth->isChecked()?&image:0,
_ui->checkBox_fromDepth->isChecked()?&depth:0,
!_ui->checkBox_fromDepth->isChecked()?&scan:0);
!_ui->checkBox_fromDepth->isChecked()?&scan:0,
0,
0,
0,
0,
_ui->checkBox_fromDepth->isChecked()?&confidence:0);
}
else if(_dbDriver)
{
cv::Mat image,depth;
cv::Mat image,depth,confidence;
_dbDriver->getNodeData(iter->first, data, _ui->checkBox_fromDepth->isChecked(), !_ui->checkBox_fromDepth->isChecked(), false, false);
data.uncompressData(
_ui->checkBox_fromDepth->isChecked()?&image:0,
_ui->checkBox_fromDepth->isChecked()?&depth:0,
!_ui->checkBox_fromDepth->isChecked()?&scan:0);
!_ui->checkBox_fromDepth->isChecked()?&scan:0,
0,
0,
0,
0,
_ui->checkBox_fromDepth->isChecked()?&confidence:0);
}
if(_ui->checkBox_fromDepth->isChecked() && !data.imageRaw().empty() && !data.depthOrRightRaw().empty())
@@ -3719,6 +3738,12 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
model.undistort(depth);
}
// edge bleeding filter
if(!depth.empty() && _ui->doubleSpinBox_depthEdgeFiltering->value()>0.0)
{
util2d::depthBleedingFiltering(depth, _ui->doubleSpinBox_depthEdgeFiltering->value());
}
// bilateral filtering
if(!depth.empty() && _ui->checkBox_bilateral->isChecked())
{
@@ -3729,7 +3754,7 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
if(!depth.empty())
{
data.setRGBDImage(data.imageRaw(), depth, data.cameraModels());
data.setRGBDImage(data.imageRaw(), depth, data.depthConfidenceRaw(), data.cameraModels());
}
UASSERT(iter->first == data.id());
@@ -3754,7 +3779,8 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
_ui->doubleSpinBox_minDepth->value(),
indices.get(),
parameters,
roiRatios);
roiRatios,
(unsigned char)_ui->spinBox_depthConfidence->value());
if(cloudWithoutNormals->size())
{

View File

@@ -181,7 +181,8 @@ ImageView::ImageView(QWidget * parent) :
_depthColorMapMinRange(0),
_depthColorMapMaxRange(0),
_imageItem(0),
_imageDepthItem(0)
_imageDepthItem(0),
_imageDepthConfidenceItem(0)
{
#if QT_VERSION >= 0x050000
_savedFileName = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
@@ -209,9 +210,12 @@ ImageView::ImageView(QWidget * parent) :
_showImage = _menu->addAction(tr("Show image"));
_showImage->setCheckable(true);
_showImage->setChecked(true);
_showImageDepth = _menu->addAction(tr("Show image depth"));
_showImageDepth = _menu->addAction(tr("Show depth image"));
_showImageDepth->setCheckable(true);
_showImageDepth->setChecked(false);
_showImageDepthConfidence = _menu->addAction(tr("Show depth confidence"));
_showImageDepthConfidence->setCheckable(true);
_showImageDepthConfidence->setChecked(false);
_featureMenu = _menu->addMenu("Features");
_showFeatures = _featureMenu->addAction(tr("Show features"));
_showFeatures->setCheckable(true);
@@ -293,6 +297,7 @@ void ImageView::saveSettings(QSettings & settings, const QString & group) const
}
settings.setValue("image_shown", this->isImageShown());
settings.setValue("depth_shown", this->isImageDepthShown());
settings.setValue("confidence_shown", this->isImageDepthConfidenceShown());
settings.setValue("features_shown", this->isFeaturesShown());
settings.setValue("features_size", this->getFeaturesSize());
settings.setValue("lines_shown", this->isLinesShown());
@@ -322,6 +327,7 @@ void ImageView::loadSettings(QSettings & settings, const QString & group)
}
this->setImageShown(settings.value("image_shown", this->isImageShown()).toBool());
this->setImageDepthShown(settings.value("depth_shown", this->isImageDepthShown()).toBool());
this->setImageDepthConfidenceShown(settings.value("confidence_shown", this->isImageDepthConfidenceShown()).toBool());
this->setFeaturesShown(settings.value("features_shown", this->isFeaturesShown()).toBool());
this->setFeaturesSize(settings.value("features_size", this->getFeaturesSize()).toInt());
this->setLinesShown(settings.value("lines_shown", this->isLinesShown()).toBool());
@@ -363,6 +369,11 @@ bool ImageView::isImageDepthShown() const
return _showImageDepth->isChecked();
}
bool ImageView::isImageDepthConfidenceShown() const
{
return _showImageDepthConfidence->isChecked();
}
bool ImageView::isFeaturesShown() const
{
return _showFeatures->isChecked();
@@ -466,6 +477,13 @@ void ImageView::setImageShown(bool shown)
void ImageView::setImageDepthShown(bool shown)
{
_showImageDepth->setChecked(shown);
if(shown)
{
_showImageDepthConfidence->setChecked(false);
if(_imageDepthConfidenceItem) {
_imageDepthConfidenceItem->setVisible(false);
}
}
if(_imageDepthItem)
{
_imageDepthItem->setVisible(_showImageDepth->isChecked());
@@ -478,6 +496,28 @@ void ImageView::setImageDepthShown(bool shown)
}
}
void ImageView::setImageDepthConfidenceShown(bool shown)
{
_showImageDepthConfidence->setChecked(shown);
if(shown)
{
_showImageDepth->setChecked(false);
if(_imageDepthItem) {
_imageDepthItem->setVisible(false);
}
}
if(_imageDepthConfidenceItem)
{
_imageDepthConfidenceItem->setVisible(_showImageDepthConfidence->isChecked());
this->updateOpacity();
}
if(!_graphicsView->isVisible())
{
this->update();
}
}
bool ImageView::isLinesShown() const
{
return _showLines->isChecked();
@@ -517,6 +557,8 @@ void ImageView::setGraphicsViewMode(bool on)
_graphicsView->setVisible(on);
_scaleMenu->setEnabled(on);
_mouseTracking->setEnabled(!on);
if(on)
{
for(QMultiMap<int, KeypointItem*>::iterator iter=_features.begin(); iter!=_features.end(); ++iter)
@@ -550,11 +592,20 @@ void ImageView::setGraphicsViewMode(bool on)
{
_imageDepthItem->setPixmap(_imageDepth);
}
else
else if(!_imageDepth.isNull())
{
_imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth);
_imageDepthItem->setVisible(_showImageDepth->isChecked());
}
if(_imageDepthConfidenceItem)
{
_imageDepthConfidenceItem->setPixmap(_imageDepthConfidence);
}
else if(!_imageDepthConfidence.isNull())
{
_imageDepthConfidenceItem = _graphicsView->scene()->addPixmap(_imageDepthConfidence);
_imageDepthConfidenceItem->setVisible(_showImageDepthConfidence->isChecked());
}
this->updateOpacity();
if(_graphicsViewScaled->isChecked())
@@ -790,7 +841,8 @@ void ImageView::paintEvent(QPaintEvent *event)
painter.save();
if(_showImage->isChecked() && !_image.isNull() &&
_showImageDepth->isChecked() && !_imageDepth.isNull())
((_showImageDepth->isChecked() && !_imageDepth.isNull()) ||
(_showImageDepthConfidence->isChecked()&&!_imageDepthConfidence.isNull())))
{
painter.setOpacity(0.5);
}
@@ -804,6 +856,10 @@ void ImageView::paintEvent(QPaintEvent *event)
{
painter.drawPixmap(QPoint(0,0), _imageDepth);
}
else if(_showImageDepthConfidence->isChecked() && !_imageDepthConfidence.isNull())
{
painter.drawPixmap(QPoint(0,0), _imageDepthConfidence);
}
painter.restore();
if(_showFeatures->isChecked())
@@ -966,6 +1022,11 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
this->setImageDepthShown(_showImageDepth->isChecked());
Q_EMIT configChanged();
}
else if(action == _showImageDepthConfidence)
{
this->setImageDepthConfidenceShown(_showImageDepthConfidence->isChecked());
Q_EMIT configChanged();
}
else if(action == _showLines)
{
this->setLinesShown(_showLines->isChecked());
@@ -988,8 +1049,9 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
}
else if(action == _colorMapBlackToWhite || action == _colorMapWhiteToBlack || action == _colorMapRedToBlue || action == _colorMapBlueToRed)
{
if(!_imageDepthCv.empty())
this->setImageDepth(_imageDepthCv);
if(!_imageDepthCv.empty()) {
this->setImageDepth(_imageDepthCv, _imageDepthConfidenceCv);
}
Q_EMIT configChanged();
}
else if(action == _colorMapMinRange)
@@ -999,8 +1061,9 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
if(ok)
{
this->setDepthColorMapRange(value, _depthColorMapMaxRange);
if(!_imageDepthCv.empty())
this->setImageDepth(_imageDepthCv);
if(!_imageDepthCv.empty()) {
this->setImageDepth(_imageDepthCv, _imageDepthConfidenceCv);
}
Q_EMIT configChanged();
}
}
@@ -1011,8 +1074,9 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
if(ok)
{
this->setDepthColorMapRange(_depthColorMapMinRange, value);
if(!_imageDepthCv.empty())
this->setImageDepth(_imageDepthCv);
if(!_imageDepthCv.empty()) {
this->setImageDepth(_imageDepthCv, _imageDepthConfidenceCv);
}
Q_EMIT configChanged();
}
}
@@ -1047,7 +1111,7 @@ void ImageView::contextMenuEvent(QContextMenuEvent * e)
}
}
if(action == _showImage || action ==_showImageDepth)
if(action == _showImage || action ==_showImageDepth || action ==_showImageDepthConfidence)
{
this->updateOpacity();
Q_EMIT configChanged();
@@ -1059,17 +1123,16 @@ void ImageView::mouseMoveEvent(QMouseEvent * event)
if(_mouseTracking->isChecked() &&
!_graphicsView->scene()->sceneRect().isNull() &&
!_image.isNull() &&
!_imageDepthCv.empty() &&
(_imageDepthCv.type() == CV_16UC1 || _imageDepthCv.type() == CV_32FC1))
!_imageDepthCv.empty() &&(_imageDepthCv.type() == CV_16UC1 || _imageDepthCv.type() == CV_32FC1))
{
float scale, offsetX, offsetY;
computeScaleOffsets(this->rect(), scale, offsetX, offsetY);
float u = (event->pos().x() - offsetX) / scale;
float v = (event->pos().y() - offsetY) / scale;
float depthScale = 1;
if(_image.width() > _imageDepth.width())
if(_image.width() > _imageDepthCv.cols)
{
depthScale = _imageDepth.width() / _image.width();
depthScale = float(_imageDepthCv.cols) / float(_image.width());
}
int ud = int(u*depthScale);
int vd = int(v*depthScale);
@@ -1077,33 +1140,47 @@ void ImageView::mouseMoveEvent(QMouseEvent * event)
ud < _imageDepthCv.cols &&
vd < _imageDepthCv.rows)
{
float depth = 0;
if(_imageDepthCv.type() == CV_32FC1)
if( _showImageDepthConfidence->isChecked() &&
!_imageDepthConfidenceCv.empty() &&
_imageDepthCv.size() == _imageDepthConfidenceCv.size())
{
depth = _imageDepthCv.at<float>(vd, ud);
unsigned char confidence = _imageDepthConfidenceCv.at<unsigned char>(vd, ud);
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QToolTip::showText(event->globalPosition().toPoint(), tr("Confidence=%1%").arg(confidence));
#else
QToolTip::showText(event->globalPos(), tr("Confidence=%1%").arg(confidence));
#endif
}
else
{
depth = float(_imageDepthCv.at<unsigned short>(vd, ud)) / 1000.0f;
}
float depth = 0;
if(_imageDepthCv.type() == CV_32FC1)
{
depth = _imageDepthCv.at<float>(vd, ud);
}
else
{
depth = float(_imageDepthCv.at<unsigned short>(vd, ud)) / 1000.0f;
}
cv::Point3f pt(0,0,0);
if(depth>0 && !_models.empty() && !_pose.isNull())
{
int subImageWidth = _imageDepthCv.cols / _models.size();
int subImageIndex = ud / subImageWidth;
UASSERT(subImageIndex < (int)_models.size());
float x,y,z;
_models[subImageIndex].project(u, v, depth, x, y, z);
pt = cv::Point3f(x,y,z);
pt = util3d::transformPoint(pt, _pose*_models[subImageIndex].localTransform());
}
cv::Point3f pt(0,0,0);
if(depth>0 && !_models.empty() && !_pose.isNull())
{
int subImageWidth = _imageDepthCv.cols / _models.size();
int subImageIndex = ud / subImageWidth;
UASSERT(subImageIndex < (int)_models.size());
float x,y,z;
_models[subImageIndex].project(u, v, depth, x, y, z);
pt = cv::Point3f(x,y,z);
pt = util3d::transformPoint(pt, _pose*_models[subImageIndex].localTransform());
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
QToolTip::showText(event->globalPosition().toPoint(), pt.x!=0?tr("Depth=%1m Map=(%2,%3,%4)").arg(depth).arg(pt.x).arg(pt.y).arg(pt.z):depth > 0?tr("Depth=%1m").arg(depth):tr("Depth=NA"));
QToolTip::showText(event->globalPosition().toPoint(), pt.x!=0?tr("Depth=%1m Map=(%2,%3,%4)").arg(depth).arg(pt.x).arg(pt.y).arg(pt.z):depth > 0?tr("Depth=%1m").arg(depth):tr("Depth=NA"));
#else
QToolTip::showText(event->globalPos(), pt.x!=0?tr("Depth=%1m Map=(%2,%3,%4)").arg(depth).arg(pt.x).arg(pt.y).arg(pt.z):depth > 0?tr("Depth=%1m").arg(depth):tr("Depth=NA"));
QToolTip::showText(event->globalPos(), pt.x!=0?tr("Depth=%1m Map=(%2,%3,%4)").arg(depth).arg(pt.x).arg(pt.y).arg(pt.z):depth > 0?tr("Depth=%1m").arg(depth):tr("Depth=NA"));
#endif
}
}
else
{
@@ -1115,23 +1192,31 @@ void ImageView::mouseMoveEvent(QMouseEvent * event)
void ImageView::updateOpacity()
{
if(_imageItem && _imageDepthItem)
if(_imageItem && (_imageDepthItem || _imageDepthConfidenceItem))
{
if(_imageItem->isVisible() && _imageDepthItem->isVisible())
if(_imageItem->isVisible() &&
((_imageDepthItem && _imageDepthItem->isVisible()) ||
(_imageDepthConfidenceItem && _imageDepthConfidenceItem->isVisible())))
{
QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect();
effect->setOpacity(0.5);
_imageDepthItem->setGraphicsEffect(effect);
}
else
{
_imageDepthItem->setGraphicsEffect(0);
if(_imageDepthItem) {
QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect();
effect->setOpacity(0.5);
_imageDepthItem->setGraphicsEffect(effect);
}
if(_imageDepthConfidenceItem) {
QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect();
effect->setOpacity(0.5);
_imageDepthConfidenceItem->setGraphicsEffect(effect);
}
return;
}
}
else if(_imageDepthItem)
{
if(_imageDepthItem) {
_imageDepthItem->setGraphicsEffect(0);
}
if(_imageDepthConfidenceItem) {
_imageDepthConfidenceItem->setGraphicsEffect(0);
}
}
void ImageView::setFeatures(const std::multimap<int, cv::KeyPoint> & refWords, const cv::Mat & depth, const QColor & color)
@@ -1261,15 +1346,23 @@ void ImageView::setImage(const QImage & image, const std::vector<CameraModel> &
}
}
void ImageView::setImageDepth(const cv::Mat & imageDepth)
void ImageView::setImageDepth(const cv::Mat & imageDepth, const cv::Mat & imageDepthConfidence)
{
_imageDepthCv = imageDepth;
setImageDepth(uCvMat2QImage(_imageDepthCv, true, getDepthColorMap(), _depthColorMapMinRange, _depthColorMapMaxRange));
_imageDepthConfidenceCv = imageDepthConfidence;
setImageDepth(
uCvMat2QImage(_imageDepthCv, true, getDepthColorMap(), _depthColorMapMinRange, _depthColorMapMaxRange),
uCvMat2QImage(_imageDepthConfidenceCv, true, getDepthColorMap()));
}
void ImageView::setImageDepth(const QImage & imageDepth)
void ImageView::setImageDepth(const QImage & imageDepth, const QImage & imageDepthConfidence)
{
_imageDepth = QPixmap::fromImage(imageDepth);
if(!imageDepthConfidence.isNull()) {
_imageDepthConfidence = QPixmap::fromImage(imageDepthConfidence);
} else {
_showImageDepthConfidence->setChecked(false);
}
UASSERT(_imageDepth.width() && _imageDepth.height());
@@ -1279,6 +1372,9 @@ void ImageView::setImageDepth(const QImage & imageDepth)
{
// scale depth to rgb
_imageDepth = _imageDepth.scaled(_image.size());
if(!_imageDepthConfidence.isNull()) {
_imageDepthConfidence = _imageDepthConfidence.scaled(_image.size());
}
}
if(_graphicsView->isVisible())
@@ -1286,11 +1382,18 @@ void ImageView::setImageDepth(const QImage & imageDepth)
if(_imageDepthItem)
{
_imageDepthItem->setPixmap(_imageDepth);
if(_imageDepthConfidenceItem) {
_imageDepthConfidenceItem->setPixmap(_imageDepthConfidence);
}
}
else
{
_imageDepthItem = _graphicsView->scene()->addPixmap(_imageDepth);
_imageDepthItem->setVisible(_showImageDepth->isChecked());
if(!_imageDepthConfidence.isNull()) {
_imageDepthConfidenceItem = _graphicsView->scene()->addPixmap(_imageDepthConfidence);
_imageDepthConfidenceItem->setVisible(_showImageDepthConfidence->isChecked());
}
this->updateOpacity();
}
}
@@ -1471,6 +1574,12 @@ void ImageView::clear()
delete _imageDepthItem;
_imageDepthItem = 0;
}
if(_imageDepthConfidenceItem)
{
_graphicsView->scene()->removeItem(_imageDepthConfidenceItem);
delete _imageDepthConfidenceItem;
_imageDepthConfidenceItem = 0;
}
_imageDepth = QPixmap();
_graphicsView->scene()->setSceneRect(QRectF());

View File

@@ -1225,13 +1225,15 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
pcl::IndicesPtr indices(new std::vector<int>);
cloud = util3d::cloudRGBFromSensorData(*data,
cloud = util3d::cloudRGBFromSensorData(
*data,
_preferencesDialog->getCloudDecimation(1),
_preferencesDialog->getCloudMaxDepth(1),
_preferencesDialog->getCloudMinDepth(1),
indices.get(),
_preferencesDialog->getAllParameters(),
_preferencesDialog->getCloudRoiRatios(1));
_preferencesDialog->getCloudRoiRatios(1),
_preferencesDialog->getCloudConfidenceThr(1));
if(indices->size())
{
cloud = util3d::transformPointCloud(cloud, pose);
@@ -1717,7 +1719,7 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
_ui->imageView_odometry->setImage(uCvMat2QImage(data->imageRaw()));
if(_ui->imageView_odometry->isImageDepthShown() && !data->depthOrRightRaw().empty())
{
_ui->imageView_odometry->setImageDepth(data->depthOrRightRaw());
_ui->imageView_odometry->setImageDepth(data->depthOrRightRaw(), data->depthConfidenceRaw());
}
if( odom.info().type == (int)Odometry::kTypeF2M ||
@@ -2342,7 +2344,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
}
if(!signature.sensorData().depthOrRightRaw().empty())
{
_ui->imageView_source->setImageDepth(signature.sensorData().depthOrRightRaw());
_ui->imageView_source->setImageDepth(signature.sensorData().depthOrRightRaw(), signature.sensorData().depthConfidenceRaw());
}
if(img.isNull() && signature.sensorData().depthOrRightRaw().empty())
{
@@ -2374,7 +2376,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
}
if(!loopSignature.sensorData().depthOrRightRaw().empty())
{
_ui->imageView_loopClosure->setImageDepth(loopSignature.sensorData().depthOrRightRaw());
_ui->imageView_loopClosure->setImageDepth(loopSignature.sensorData().depthOrRightRaw(), loopSignature.sensorData().depthConfidenceRaw());
}
if(_ui->imageView_loopClosure->sceneRect().isNull())
{
@@ -3717,7 +3719,8 @@ std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> MainWindow::c
_preferencesDialog->getCloudMinDepth(0),
indices.get(),
allParameters,
_preferencesDialog->getCloudRoiRatios(0));
_preferencesDialog->getCloudRoiRatios(0),
_preferencesDialog->getCloudConfidenceThr(0));
// view point
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
@@ -8186,6 +8189,12 @@ void MainWindow::exportImages()
QDir dir;
dir.mkdir(QString("%1/rgb").arg(path));
dir.mkdir(QString("%1/depth").arg(path));
if(!data.depthConfidenceRaw().empty())
{
QDir dir;
dir.mkdir(QString("%1/confidence").arg(path));
}
}
if(data.cameraModels().size() > 1)
@@ -8244,7 +8253,14 @@ void MainWindow::exportImages()
UWARN("Failed saving \"%s\"", QString("%1/rgb/%2.%3").arg(path).arg(id).arg(ext).toStdString().c_str());
if(!cv::imwrite(QString("%1/depth/%2.png").arg(path).arg(id).toStdString(), data.depthRaw().type()==CV_32FC1?util2d::cvtDepthFromFloat(data.depthRaw()):data.depthRaw()))
UWARN("Failed saving \"%s\"", QString("%1/depth/%2.png").arg(path).arg(id).toStdString().c_str());
info = tr("Saved rgb/%1.%2 and depth/%1.png.").arg(id).arg(ext);
if(data.depthConfidenceRaw().empty()) {
info = tr("Saved rgb/%1.%2 and depth/%1.png.").arg(id).arg(ext);
}
else {
if(!cv::imwrite(QString("%1/confidence/%2.png").arg(path).arg(id).toStdString(), data.depthConfidenceRaw()))
UWARN("Failed saving \"%s\"", QString("%1/confidence/%2.png").arg(path).arg(id).toStdString().c_str());
info = tr("Saved rgb/%1.%2, depth/%1.png and confidence/%1.png.").arg(id).arg(ext);
}
}
else if(!data.imageRaw().empty())
{

View File

@@ -551,6 +551,10 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_3dRenderingRoiRatios[0] = _ui->lineEdit_roiRatios;
_3dRenderingRoiRatios[1] = _ui->lineEdit_roiRatios_odom;
_3dRenderingDepthConfidenceThr.resize(2);
_3dRenderingDepthConfidenceThr[0] = _ui->spinBox_depthConf;
_3dRenderingDepthConfidenceThr[1] = _ui->spinBox_depthConf_odom;
_3dRenderingColorScheme.resize(2);
_3dRenderingColorScheme[0] = _ui->spinBox_colorScheme;
_3dRenderingColorScheme[1] = _ui->spinBox_colorScheme_odom;
@@ -622,6 +626,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
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(_3dRenderingDepthConfidenceThr[i], SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingShowScans[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingShowFeatures[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_3dRenderingShowFrustums[i], SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
@@ -2030,6 +2035,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
_3dRenderingMaxDepth[i]->setValue(0.0);
_3dRenderingMinDepth[i]->setValue(0.0);
_3dRenderingRoiRatios[i]->setText("0.0 0.0 0.0 0.0");
_3dRenderingDepthConfidenceThr[i]->setValue(0);
_3dRenderingShowScans[i]->setChecked(true);
_3dRenderingShowFeatures[i]->setChecked(i==0?false:true);
_3dRenderingShowFrustums[i]->setChecked(false);
@@ -2548,6 +2554,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
_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());
_3dRenderingDepthConfidenceThr[i]->setValue(settings.value(QString("depthConf%1").arg(i), _3dRenderingDepthConfidenceThr[i]->value()).toInt());
_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());
_3dRenderingShowFrustums[i]->setChecked(settings.value(QString("showFrustums%1").arg(i), _3dRenderingShowFrustums[i]->isChecked()).toBool());
@@ -3156,6 +3163,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
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("depthConf%1").arg(i), _3dRenderingDepthConfidenceThr[i]->value());
settings.setValue(QString("showScans%1").arg(i), _3dRenderingShowScans[i]->isChecked());
settings.setValue(QString("showFeatures%1").arg(i), _3dRenderingShowFeatures[i]->isChecked());
settings.setValue(QString("showFrustums%1").arg(i), _3dRenderingShowFrustums[i]->isChecked());
@@ -6105,6 +6113,11 @@ std::vector<float> PreferencesDialog::getCloudRoiRatios(int index) const
}
return roiRatios;
}
unsigned char PreferencesDialog::getCloudConfidenceThr(int index) const
{
UASSERT(index >= 0 && index <= 1);
return (unsigned char)_3dRenderingDepthConfidenceThr[index]->value();
}
int PreferencesDialog::getCloudColorScheme(int index) const
{
UASSERT(index >= 0 && index <= 1);

View File

@@ -61,7 +61,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>419</width>
<width>307</width>
<height>389</height>
</rect>
</property>
@@ -392,7 +392,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>418</width>
<width>306</width>
<height>389</height>
</rect>
</property>
@@ -1643,7 +1643,7 @@
<item>
<widget class="QToolBox" name="toolBox">
<property name="currentIndex">
<number>2</number>
<number>1</number>
</property>
<widget class="QWidget" name="page_3">
<property name="geometry">
@@ -1805,9 +1805,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>276</width>
<height>1201</height>
<y>-316</y>
<width>518</width>
<height>1071</height>
</rect>
</property>
<attribute name="label">
@@ -1816,24 +1816,57 @@
<layout class="QVBoxLayout" name="verticalLayout_16">
<item>
<layout class="QGridLayout" name="gridLayout_9" columnstretch="0,0">
<item row="6" column="1">
<widget class="QLabel" name="label_53">
<item row="3" column="1">
<widget class="QLabel" name="label_octomap_empty_3">
<property name="text">
<string>OctoMap</string>
</property>
</widget>
</item>
<item row="15" column="1">
<widget class="QLabel" name="label_57">
<property name="text">
<string>Crop radius when filtering empty space from 2d occupancy grid.</string>
<string>Ground cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="15" column="0">
<item row="14" column="1">
<widget class="QLabel" name="label_61">
<property name="text">
<string>Minimum depth confidence.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="18" column="1">
<widget class="QLabel" name="label_59">
<property name="text">
<string>Show probabilistic occupancy grid in Graph View.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QCheckBox" name="checkBox_grid_regenerateFromSavedGrid">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_grid_empty">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QSpinBox" name="spinBox_cropRadius">
<property name="suffix">
<string> pixels</string>
@@ -1843,13 +1876,13 @@
</property>
</widget>
</item>
<item row="16" column="0">
<widget class="QCheckBox" name="checkBox_grid_showProbMap">
<item row="20" column="1">
<widget class="QLabel" name="label_logger_level_2">
<property name="text">
<string/>
<string>For stereo data, show disparity instead of right image in main views.</string>
</property>
<property name="checked">
<bool>false</bool>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
@@ -1869,33 +1902,17 @@
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QSpinBox" name="spinBox_grid_depth">
<property name="prefix">
<string/>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>16</number>
</property>
<property name="value">
<number>16</number>
</property>
</widget>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item row="5" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_17">
<item>
<widget class="QToolButton" name="toolButton_groundColor">
<widget class="QToolButton" name="toolButton_frontierColor">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_groundColor">
<widget class="QLineEdit" name="lineEdit_frontierColor">
<property name="readOnly">
<bool>true</bool>
</property>
@@ -1903,18 +1920,18 @@
</item>
</layout>
</item>
<item row="9" column="1">
<widget class="QLabel" name="label_octomap_cubes">
<item row="17" column="1">
<widget class="QLabel" name="label_57">
<property name="text">
<string>OctoMap: Rendering type</string>
<string>Crop radius when filtering empty space from 2d occupancy grid.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_grid_frontiers">
<item row="18" column="0">
<widget class="QCheckBox" name="checkBox_grid_showProbMap">
<property name="text">
<string/>
</property>
@@ -1923,10 +1940,20 @@
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QLabel" name="label_54">
<item row="19" column="1">
<widget class="QLabel" name="label_60">
<property name="text">
<string>Voxel size (for clouds and scans)</string>
<string>Create RGB-D cloud from RGB projection on scan.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLabel" name="label_55">
<property name="text">
<string>Local grid: regenerate from saved grid instead of sensors</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -1943,20 +1970,13 @@
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QCheckBox" name="checkBox_grid_regenerateFromSavedGrid">
<item row="9" column="1">
<widget class="QLabel" name="label_octomap_cubes">
<property name="text">
<string/>
<string>OctoMap: Rendering type</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_octomap">
<property name="text">
<string/>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
@@ -1980,8 +2000,8 @@
</property>
</widget>
</item>
<item row="18" column="0">
<widget class="QCheckBox" name="checkBox_showDisparityInsteadOfRight">
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_grid_frontiers">
<property name="text">
<string/>
</property>
@@ -1990,105 +2010,7 @@
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="QLabel" name="label_59">
<property name="text">
<string>Show probabilistic occupancy grid in Graph View.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="18" column="1">
<widget class="QLabel" name="label_logger_level_2">
<property name="text">
<string>For stereo data, show disparity instead of right image in main views.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_octomap_empty_3">
<property name="text">
<string>Ground cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainCompensationRadius">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_octomap_empty_4">
<property name="text">
<string>Empty cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QToolButton" name="toolButton_emptyColor">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_emptyColor">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QToolButton" name="toolButton_obstacleColor">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_obstacleColor">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="17" column="0">
<item row="19" column="0">
<widget class="QCheckBox" name="checkBox_cameraProjection">
<property name="text">
<string/>
@@ -2098,20 +2020,10 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_grid_empty">
<item row="0" column="1">
<widget class="QLabel" name="label_octomap_empty">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLabel" name="label_55">
<property name="text">
<string>Local grid: regenerate from saved grid instead of sensors</string>
<string>Show empty space</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -2128,20 +2040,17 @@
</property>
</widget>
</item>
<item row="17" column="1">
<widget class="QLabel" name="label_60">
<item row="6" column="1">
<widget class="QLabel" name="label_53">
<property name="text">
<string>Create RGB-D cloud from RGB projection on scan.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
<string>OctoMap</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_octomap_empty">
<item row="16" column="1">
<widget class="QLabel" name="label_54">
<property name="text">
<string>Show empty space</string>
<string>Voxel size (for clouds and scans)</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -2167,6 +2076,64 @@
</item>
</widget>
</item>
<item row="10" column="0">
<widget class="QSpinBox" name="spinBox_grid_depth">
<property name="prefix">
<string/>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>16</number>
</property>
<property name="value">
<number>16</number>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainCompensationRadius">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_octomap_frontiers_3">
<property name="text">
<string>Frontier cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_octomap_empty_4">
<property name="text">
<string>Empty cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QLabel" name="label_56">
<property name="text">
@@ -2177,7 +2144,32 @@
</property>
</widget>
</item>
<item row="14" column="0">
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_octomap">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QToolButton" name="toolButton_groundColor">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_groundColor">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="16" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSize">
<property name="suffix">
<string> m</string>
@@ -2199,27 +2191,17 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_octomap_frontiers_3">
<property name="text">
<string>Frontier cell color</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_17">
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QToolButton" name="toolButton_frontierColor">
<widget class="QToolButton" name="toolButton_obstacleColor">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_frontierColor">
<widget class="QLineEdit" name="lineEdit_obstacleColor">
<property name="readOnly">
<bool>true</bool>
</property>
@@ -2227,6 +2209,82 @@
</item>
</layout>
</item>
<item row="20" column="0">
<widget class="QCheckBox" name="checkBox_showDisparityInsteadOfRight">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QToolButton" name="toolButton_emptyColor">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_emptyColor">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="15" column="1">
<widget class="QLabel" name="label_62">
<property name="text">
<string>Depth's edge bleeding filtering error.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_depthEdgeBleedingError">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QSpinBox" name="spinBox_depthConfidence">
<property name="suffix">
<string> %</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
@@ -2468,7 +2526,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>294</width>
<width>296</width>
<height>272</height>
</rect>
</property>
@@ -2642,8 +2700,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>181</width>
<height>485</height>
<width>428</width>
<height>196</height>
</rect>
</property>
<attribute name="label">

View File

@@ -23,9 +23,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-2495</y>
<y>-654</y>
<width>861</width>
<height>6426</height>
<height>6498</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_13">
@@ -710,6 +710,26 @@
<layout class="QVBoxLayout" name="verticalLayout_14">
<item>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,1">
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_roiRatios"/>
</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="5" column="1">
<widget class="QSpinBox" name="spinBox_fillDepthHolesError">
<property name="suffix">
<string> %</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="label_134">
<property name="text">
@@ -720,13 +740,10 @@
</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>
<item row="4" column="1">
<widget class="QSpinBox" name="spinBox_fillDepthHoles">
<property name="suffix">
<string> pixels</string>
</property>
</widget>
</item>
@@ -749,21 +766,18 @@
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_198">
<item row="3" column="2">
<widget class="QLabel" name="label_135">
<property name="text">
<string>Fill depth hole error.</string>
<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>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_roiRatios"/>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_distortionModel"/>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth">
@@ -794,39 +808,6 @@
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="checkBox_subtraction">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="lineEdit_distortionModel"/>
</item>
<item row="8" column="2">
<widget class="QLabel" name="label_137">
<property name="text">
<string>Cloud subtraction. Superposed points from different nodes are filtered.</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="2">
<widget class="QLabel" name="label_132">
<property name="text">
@@ -850,13 +831,6 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="spinBox_fillDepthHolesError">
<property name="suffix">
<string> %</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QToolButton" name="toolButton_distortionModel">
<property name="text">
@@ -864,24 +838,57 @@
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="checkBox_bilateral">
<item row="10" column="2">
<widget class="QLabel" name="label_137">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_133">
<property name="text">
<string>3D cloud minimum depth.</string>
<string>Cloud subtraction. Superposed points from different nodes are filtered.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="2">
<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="10" column="1">
<widget class="QCheckBox" name="checkBox_subtraction">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="checkBox_bilateral">
<property name="text">
<string/>
</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="8" column="2">
<widget class="QLabel" name="label_136">
<property name="text">
<string>Bilateral filtering of the depth image. Reduce noise in depth images.</string>
@@ -891,10 +898,52 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="spinBox_fillDepthHoles">
<item row="7" column="2">
<widget class="QLabel" name="label_147">
<property name="text">
<string>Depth's edge bleeding filter error (0 means disabled). Reduce depth noise around edges.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_depthEdgeFiltering">
<property name="suffix">
<string> pixels</string>
<string> m</string>
</property>
<property name="decimals">
<number>2</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="9" column="2">
<widget class="QLabel" name="label_149">
<property name="text">
<string>Minimum depth confidence: 0% is low confidence, 100% is high confidence. Ignored if no depth confidence images were recorded or if set to 0%.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QSpinBox" name="spinBox_depthConfidence">
<property name="suffix">
<string> %</string>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>

View File

@@ -63,7 +63,7 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-659</y>
<y>0</y>
<width>713</width>
<height>4705</height>
</rect>
@@ -95,7 +95,7 @@
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex">
<number>12</number>
<number>1</number>
</property>
<widget class="QWidget" name="page_22">
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,0">
@@ -750,96 +750,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
<layout class="QVBoxLayout" name="verticalLayout_112">
<item>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,1">
<item row="5" column="0">
<widget class="QLineEdit" name="lineEdit_roiRatios"/>
</item>
<item row="15" column="0">
<widget class="QSpinBox" name="spinBox_ptsize">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>64</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="10" column="2">
<widget class="QLabel" name="label_355">
<property name="text">
<string>Floor filtering height (0=Disabled). This is done in /map frame.</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="2">
<widget class="QLabel" name="label_169">
<property name="text">
<string>Noise filtering min neighbors.</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="QDoubleSpinBox" name="doubleSpinBox_normalRadiusSearch">
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="13" column="2">
<widget class="QLabel" name="label_459">
<property name="text">
<string>Default color scheme key.</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="1">
<widget class="QSpinBox" name="spinBox_colorScheme_odom"/>
</item>
<item row="13" column="0">
<widget class="QSpinBox" name="spinBox_colorScheme"/>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_maxDepth_odom">
<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>0.000000000000000</double>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_roiRatios_odom"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_154">
<property name="text">
@@ -853,157 +763,24 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_137">
<property name="text">
<string>Odometry</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_showClouds">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</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">
<string>Show 3D clouds.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_decimation_odom">
<item row="9" column="0">
<widget class="QSpinBox" name="spinBox_noiseMinNeighbors">
<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="2" column="2">
<widget class="QLabel" name="label_108">
<property name="text">
<string>Decimation (1-2-4-8-...). Negative decimation is done from RGB size instead of depth size (if depth is smaller than RGB, it may be interpolated depending of the decimation value).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity">
<property name="suffix">
<string/>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
<number>1000</number>
</property>
<property name="value">
<double>1.000000000000000</double>
<number>5</number>
</property>
</widget>
</item>
<item row="14" column="2">
<widget class="QLabel" name="label_155">
<property name="text">
<string>Opacity.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
<item row="5" column="0">
<widget class="QLineEdit" name="lineEdit_roiRatios"/>
</item>
<item row="15" column="2">
<widget class="QLabel" name="label_157">
<property name="text">
<string>Point size (1..64).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_noiseRadius">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.050000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<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="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_maxDepth">
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_maxDepth_odom">
<property name="suffix">
<string> m</string>
</property>
@@ -1016,60 +793,6 @@ Show a yellow background when the number of odometry inliers goes under this thr
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>4.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_132">
<property name="text">
<string>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="4" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth">
<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>0.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth_odom">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
@@ -1088,10 +811,13 @@ 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">
<item row="14" column="0">
<widget class="QSpinBox" name="spinBox_colorScheme"/>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_108">
<property name="text">
<string>ROI ratios [left right top bottom] between 0 and 1.</string>
<string>Decimation (1-2-4-8-...). Negative decimation is done from RGB size instead of depth size (if depth is smaller than RGB, it may be interpolated depending of the decimation value).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -1101,90 +827,23 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_floorFilterHeight">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<item row="12" column="0">
<widget class="QSpinBox" name="spinBox_normalKSearch">
<property name="minimum">
<double>-10.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxel">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="15" column="1">
<widget class="QSpinBox" name="spinBox_ptsize_odom">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>64</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QLabel" name="label_168">
<property name="text">
<string>Noise filtering radius (0=disabled). Done after voxel filtering.</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>
<number>0</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>5</number>
<number>10</number>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QLabel" name="label_338">
<item row="15" column="2">
<widget class="QLabel" name="label_155">
<property name="text">
<string>Ceiling filtering height (0=Disabled). This is done in /map frame.</string>
<string>Opacity.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -1194,20 +853,46 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="label_171">
<property name="text">
<string>Voxel filtering size (0=disabled).</string>
<item row="15" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity_odom">
<property name="suffix">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
<property name="decimals">
<number>2</number>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="9" column="0">
<item row="13" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_normalRadiusSearch">
<property name="singleStep">
<double>0.010000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<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="10" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_ceilingFilterHeight">
<property name="suffix">
<string> m</string>
@@ -1229,23 +914,29 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QSpinBox" name="spinBox_normalKSearch">
<property name="minimum">
<number>0</number>
<item row="4" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<number>10</number>
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="11" column="2">
<widget class="QLabel" name="label_210">
<item row="1" column="2">
<widget class="QLabel" name="label_119">
<property name="text">
<string>Normal K search. If not 0, normals will be computed and added to created cloud for visualization (keys 7, 8 and 9).</string>
<string>Show 3D clouds.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -1255,7 +946,181 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="12" column="2">
<item row="8" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_noiseRadius">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.050000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_137">
<property name="text">
<string>Odometry</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</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="14" column="1">
<widget class="QSpinBox" name="spinBox_colorScheme_odom"/>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_353">
<property name="text">
<string>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="16" column="2">
<widget class="QLabel" name="label_157">
<property name="text">
<string>Point size (1..64).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="16" column="0">
<widget class="QSpinBox" name="spinBox_ptsize">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>64</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="3" column="0">
<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="7" column="2">
<widget class="QLabel" name="label_171">
<property name="text">
<string>Voxel filtering size (0=disabled).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="11" column="2">
<widget class="QLabel" name="label_355">
<property name="text">
<string>Floor filtering height (0=Disabled). This is done in /map frame.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="10" column="2">
<widget class="QLabel" name="label_338">
<property name="text">
<string>Ceiling filtering height (0=Disabled). This is done in /map frame.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_floorFilterHeight">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>-10.000000000000000</double>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_showClouds">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="2">
<widget class="QLabel" name="label_427">
<property name="text">
<string>Normal radius search. If not 0, normals will be computed and added to created cloud for visualization (keys 7, 8 and 9).</string>
@@ -1268,8 +1133,117 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity_odom">
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_decimation_odom">
<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="4" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_minDepth_odom">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxel">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="14" column="2">
<widget class="QLabel" name="label_459">
<property name="text">
<string>Default color scheme key.</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="2">
<widget class="QLabel" name="label_210">
<property name="text">
<string>Normal K search. If not 0, normals will be computed and added to created cloud for visualization (keys 7, 8 and 9).</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_132">
<property name="text">
<string>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="5" column="1">
<widget class="QLineEdit" name="lineEdit_roiRatios_odom"/>
</item>
<item row="8" column="2">
<widget class="QLabel" name="label_168">
<property name="text">
<string>Noise filtering radius (0=disabled). Done after voxel filtering.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_opacity">
<property name="suffix">
<string/>
</property>
@@ -1287,6 +1261,77 @@ Show a yellow background when the number of odometry inliers goes under this thr
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="QSpinBox" name="spinBox_ptsize_odom">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>64</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QLabel" name="label_169">
<property name="text">
<string>Noise filtering min neighbors.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="label_298">
<property name="text">
<string>Minimum depth confidence.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="spinBox_depthConf_odom">
<property name="suffix">
<string> %</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QSpinBox" name="spinBox_depthConf">
<property name="suffix">
<string> %</string>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
</layout>
</item>
<item>