mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-12 22:40:19 +08:00
Image Decimation can now be negative, meaning that decimation is done from RGB size instead of depth. If Depth size is smaller than RGB, it may be upsampled depending on the decimation value. Export Dialog: Fixed MLS not done even when checked.
This commit is contained in:
@@ -207,8 +207,8 @@ class RTABMAP_EXP Parameters
|
||||
RTABMAP_PARAM(Mem, GenerateIds, bool, true, "True=Generate location IDs, False=use input image IDs.");
|
||||
RTABMAP_PARAM(Mem, BadSignaturesIgnored, bool, false, "Bad signatures are ignored.");
|
||||
RTABMAP_PARAM(Mem, InitWMWithAllNodes, bool, false, "Initialize the Working Memory with all nodes in Long-Term Memory. When false, it is initialized with nodes of the previous session.");
|
||||
RTABMAP_PARAM(Mem, ImagePreDecimation, int, 1, "Image decimation (>=1) before features extraction.");
|
||||
RTABMAP_PARAM(Mem, ImagePostDecimation, int, 1, "Image decimation (>=1) of saved data in created signatures (after features extraction). Decimation is done from the original image.");
|
||||
RTABMAP_PARAM(Mem, ImagePreDecimation, int, 1, "Image decimation (>=1) before features extraction. 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).");
|
||||
RTABMAP_PARAM(Mem, ImagePostDecimation, int, 1, "Image decimation (>=1) of saved data in created signatures (after features extraction). Decimation is done from the original image. 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).");
|
||||
RTABMAP_PARAM(Mem, LaserScanDownsampleStepSize, int, 1, "If > 1, downsample the laser scans when creating a signature.");
|
||||
RTABMAP_PARAM(Mem, LaserScanNormalK, int, 0, "If > 0 and laser scans are 3D without normals, normals will be computed with K search neighbors when creating a signature.");
|
||||
RTABMAP_PARAM(Mem, UseOdomFeatures, bool, false, "Use odometry features.");
|
||||
@@ -370,7 +370,7 @@ class RTABMAP_EXP Parameters
|
||||
RTABMAP_PARAM(Odom, GuessMotion, bool, false, "Guess next transformation from the last motion computed.");
|
||||
RTABMAP_PARAM(Odom, KeyFrameThr, float, 0.3, "[Visual] Create a new keyframe when the number of inliers drops under this ratio of features in last frame. Setting the value to 0 means that a keyframe is created for each processed frame.");
|
||||
RTABMAP_PARAM(Odom, ScanKeyFrameThr, float, 0.7, "[Geometry] Create a new keyframe when the number of ICP inliers drops under this ratio of points in last frame's scan. Setting the value to 0 means that a keyframe is created for each processed frame.");
|
||||
RTABMAP_PARAM(Odom, ImageDecimation, int, 1, "Decimation of the images before registration.");
|
||||
RTABMAP_PARAM(Odom, ImageDecimation, int, 1, "Decimation of the images before registration. 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).");
|
||||
RTABMAP_PARAM(Odom, AlignWithGround, bool, false, "Align odometry with the ground on initialization.");
|
||||
|
||||
// Odometry Bag-of-words
|
||||
@@ -464,14 +464,14 @@ class RTABMAP_EXP Parameters
|
||||
|
||||
// Occupancy Grid
|
||||
RTABMAP_PARAM(Grid, FromDepth, bool, true, "Create occupancy grid from depth image(s), otherwise it is created from laser scan.");
|
||||
RTABMAP_PARAM(Grid, DepthDecimation, int, 4, uFormat("[%s=true] Decimation of the depth image before creating cloud.", kGridDepthDecimation().c_str()));
|
||||
RTABMAP_PARAM(Grid, DepthMin, float, 0.0, uFormat("[%s=true] Minimum cloud's depth from sensor.", kGridDepthDecimation().c_str()));
|
||||
RTABMAP_PARAM(Grid, DepthMax, float, 4.0, uFormat("[%s=true] Maximum cloud's depth from sensor. 0=inf.", kGridDepthDecimation().c_str()));
|
||||
RTABMAP_PARAM_STR(Grid, DepthRoiRatios, "0.0 0.0 0.0 0.0", uFormat("[%s=true] Region of interest ratios [left, right, top, bottom].", kGridDepthDecimation().c_str()));
|
||||
RTABMAP_PARAM(Grid, DepthDecimation, int, 4, uFormat("[%s=true] Decimation of the depth image before creating cloud. 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).", kGridDepthDecimation().c_str()));
|
||||
RTABMAP_PARAM(Grid, DepthMin, float, 0.0, uFormat("[%s=true] Minimum cloud's depth from sensor.", kGridFromDepth().c_str()));
|
||||
RTABMAP_PARAM(Grid, DepthMax, float, 4.0, uFormat("[%s=true] Maximum cloud's depth from sensor. 0=inf.", kGridFromDepth().c_str()));
|
||||
RTABMAP_PARAM_STR(Grid, DepthRoiRatios, "0.0 0.0 0.0 0.0", uFormat("[%s=true] Region of interest ratios [left, right, top, bottom].", kGridFromDepth().c_str()));
|
||||
RTABMAP_PARAM(Grid, FootprintLength, float, 0.0, "Footprint length used to filter points over the footprint of the robot.");
|
||||
RTABMAP_PARAM(Grid, FootprintWidth, float, 0.0, "Footprint width used to filter points over the footprint of the robot. Footprint length should be set.");
|
||||
RTABMAP_PARAM(Grid, FootprintHeight, float, 0.0, "Footprint height used to filter points over the footprint of the robot. Footprint length and width should be set.");
|
||||
RTABMAP_PARAM(Grid, ScanDecimation, int, 1, uFormat("[%s=false] Decimation of the laser scan before creating cloud.", kGridDepthDecimation().c_str()));
|
||||
RTABMAP_PARAM(Grid, ScanDecimation, int, 1, uFormat("[%s=false] Decimation of the laser scan before creating cloud.", kGridFromDepth().c_str()));
|
||||
RTABMAP_PARAM(Grid, CellSize, float, 0.05, "Resolution of the occupancy grid.");
|
||||
RTABMAP_PARAM(Grid, MapFrameProjection, bool, false, "Projection in map frame. On a 3D terrain and a fixed local camera transform (the cloud is created relative to ground), you may want to disable this to do the projection in robot frame instead.");
|
||||
RTABMAP_PARAM(Grid, NormalsSegmentation, bool, true, "Segment ground from obstacles using point normals, otherwise a fast passthrough is used.");
|
||||
|
||||
@@ -419,8 +419,14 @@ void Memory::parseParameters(const ParametersMap & parameters)
|
||||
UASSERT_MSG(_maxStMemSize >= 0, uFormat("value=%d", _maxStMemSize).c_str());
|
||||
UASSERT_MSG(_similarityThreshold >= 0.0f && _similarityThreshold <= 1.0f, uFormat("value=%f", _similarityThreshold).c_str());
|
||||
UASSERT_MSG(_recentWmRatio >= 0.0f && _recentWmRatio <= 1.0f, uFormat("value=%f", _recentWmRatio).c_str());
|
||||
UASSERT(_imagePreDecimation >= 1);
|
||||
UASSERT(_imagePostDecimation >= 1);
|
||||
if(_imagePreDecimation == 0)
|
||||
{
|
||||
_imagePreDecimation = 1;
|
||||
}
|
||||
if(_imagePostDecimation == 0)
|
||||
{
|
||||
_imagePostDecimation = 1;
|
||||
}
|
||||
UASSERT(_rehearsalMaxDistance >= 0.0f);
|
||||
UASSERT(_rehearsalMaxAngle >= 0.0f);
|
||||
|
||||
|
||||
@@ -74,6 +74,10 @@ void OccupancyGrid::parseParameters(const ParametersMap & parameters)
|
||||
{
|
||||
Parameters::parse(parameters, Parameters::kGridFromDepth(), occupancyFromCloud_);
|
||||
Parameters::parse(parameters, Parameters::kGridDepthDecimation(), cloudDecimation_);
|
||||
if(cloudDecimation_ == 0)
|
||||
{
|
||||
cloudDecimation_ = 1;
|
||||
}
|
||||
Parameters::parse(parameters, Parameters::kGridDepthMin(), cloudMinDepth_);
|
||||
Parameters::parse(parameters, Parameters::kGridDepthMax(), cloudMaxDepth_);
|
||||
Parameters::parse(parameters, Parameters::kGridFootprintLength(), footprintLength_);
|
||||
|
||||
@@ -108,7 +108,10 @@ Odometry::Odometry(const rtabmap::ParametersMap & parameters) :
|
||||
Parameters::parse(parameters, Parameters::kOdomKalmanMeasurementNoise(), _kalmanMeasurementNoise);
|
||||
Parameters::parse(parameters, Parameters::kOdomImageDecimation(), _imageDecimation);
|
||||
Parameters::parse(parameters, Parameters::kOdomAlignWithGround(), _alignWithGround);
|
||||
UASSERT(_imageDecimation>=1);
|
||||
if(_imageDecimation == 0)
|
||||
{
|
||||
_imageDecimation = 1;
|
||||
}
|
||||
|
||||
if(_filteringStrategy == 2)
|
||||
{
|
||||
|
||||
@@ -1224,7 +1224,7 @@ cv::Mat decimate(const cv::Mat & image, int decimation)
|
||||
|
||||
cv::Mat interpolate(const cv::Mat & image, int factor, float depthErrorRatio)
|
||||
{
|
||||
UASSERT(factor >= 1);
|
||||
UASSERT_MSG(factor >= 1, uFormat("factor=%d", factor).c_str());
|
||||
cv::Mat out;
|
||||
if(!image.empty())
|
||||
{
|
||||
|
||||
+96
-19
@@ -254,38 +254,72 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromDepth(
|
||||
}
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFromDepth(
|
||||
const cv::Mat & imageDepth,
|
||||
const cv::Mat & imageDepthIn,
|
||||
const CameraModel & model,
|
||||
int decimation,
|
||||
float maxDepth,
|
||||
float minDepth,
|
||||
std::vector<int> * validIndices)
|
||||
{
|
||||
if(decimation == 0)
|
||||
{
|
||||
decimation = 1;
|
||||
}
|
||||
float rgbToDepthFactorX = 1.0f;
|
||||
float rgbToDepthFactorY = 1.0f;
|
||||
|
||||
UASSERT(model.isValidForProjection());
|
||||
UASSERT(!imageDepth.empty() && (imageDepth.type() == CV_16UC1 || imageDepth.type() == CV_32FC1));
|
||||
UASSERT(!imageDepthIn.empty() && (imageDepthIn.type() == CV_16UC1 || imageDepthIn.type() == CV_32FC1));
|
||||
|
||||
cv::Mat imageDepth = imageDepthIn;
|
||||
if(model.imageHeight()>0 && model.imageWidth()>0)
|
||||
{
|
||||
UASSERT(model.imageHeight() % imageDepth.rows == 0 && model.imageWidth() % imageDepth.cols == 0);
|
||||
UASSERT_MSG(model.imageHeight() % decimation == 0, uFormat("model.imageHeight()=%d decimation=%d", model.imageHeight(), decimation).c_str());
|
||||
UASSERT_MSG(model.imageWidth() % decimation == 0, uFormat("model.imageWidth()=%d decimation=%d", model.imageWidth(), decimation).c_str());
|
||||
UASSERT(model.imageHeight() % imageDepthIn.rows == 0 && model.imageWidth() % imageDepthIn.cols == 0);
|
||||
|
||||
if(decimation < 0)
|
||||
{
|
||||
UDEBUG("Decimation from model (%d)", decimation);
|
||||
UASSERT_MSG(model.imageHeight() % decimation == 0, uFormat("model.imageHeight()=%d decimation=%d", model.imageHeight(), decimation).c_str());
|
||||
UASSERT_MSG(model.imageWidth() % decimation == 0, uFormat("model.imageWidth()=%d decimation=%d", model.imageWidth(), decimation).c_str());
|
||||
|
||||
// decimate from RGB image size, upsample depth if needed
|
||||
decimation = -1*decimation;
|
||||
|
||||
int targetSize = model.imageHeight() / decimation;
|
||||
if(targetSize > imageDepthIn.rows)
|
||||
{
|
||||
UDEBUG("Depth interpolation factor=%d", targetSize/imageDepthIn.rows);
|
||||
imageDepth = util2d::interpolate(imageDepthIn, targetSize/imageDepthIn.rows);
|
||||
decimation = 1;
|
||||
}
|
||||
else if(targetSize == imageDepthIn.rows)
|
||||
{
|
||||
decimation = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
UASSERT(imageDepthIn.rows % targetSize == 0);
|
||||
decimation = imageDepthIn.rows / targetSize;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UASSERT_MSG(imageDepthIn.rows % decimation == 0, uFormat("imageDepth.rows=%d decimation=%d", imageDepthIn.rows, decimation).c_str());
|
||||
UASSERT_MSG(imageDepthIn.cols % decimation == 0, uFormat("imageDepth.cols=%d decimation=%d", imageDepthIn.cols, decimation).c_str());
|
||||
}
|
||||
|
||||
rgbToDepthFactorX = 1.0f/float((model.imageWidth() / imageDepth.cols));
|
||||
rgbToDepthFactorY = 1.0f/float((model.imageHeight() / imageDepth.rows));
|
||||
}
|
||||
else
|
||||
{
|
||||
decimation = abs(decimation);
|
||||
UASSERT_MSG(imageDepth.rows % decimation == 0, uFormat("rows=%d decimation=%d", imageDepth.rows, decimation).c_str());
|
||||
UASSERT_MSG(imageDepth.cols % decimation == 0, uFormat("cols=%d decimation=%d", imageDepth.cols, decimation).c_str());
|
||||
}
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
if(decimation < 1)
|
||||
{
|
||||
return cloud;
|
||||
}
|
||||
|
||||
|
||||
//cloud.header = cameraInfo.header;
|
||||
cloud->height = imageDepth.rows/decimation;
|
||||
@@ -358,29 +392,62 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB(
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudFromDepthRGB(
|
||||
const cv::Mat & imageRgb,
|
||||
const cv::Mat & imageDepth,
|
||||
const cv::Mat & imageDepthIn,
|
||||
const CameraModel & model,
|
||||
int decimation,
|
||||
float maxDepth,
|
||||
float minDepth,
|
||||
std::vector<int> * validIndices)
|
||||
{
|
||||
if(decimation == 0)
|
||||
{
|
||||
decimation = 1;
|
||||
}
|
||||
UDEBUG("");
|
||||
UASSERT(model.isValidForProjection());
|
||||
UASSERT_MSG((model.imageHeight() == 0 && model.imageWidth() == 0) ||
|
||||
(model.imageHeight() == imageRgb.rows && model.imageWidth() == imageRgb.cols),
|
||||
uFormat("model=%dx%d rgb=%dx%d", model.imageWidth(), model.imageHeight(), imageRgb.cols, imageRgb.rows).c_str());
|
||||
UASSERT_MSG(imageRgb.rows % imageDepth.rows == 0 && imageRgb.cols % imageDepth.cols == 0,
|
||||
uFormat("rgb=%dx%d depth=%dx%d", imageRgb.cols, imageRgb.rows, imageDepth.cols, imageDepth.rows).c_str());
|
||||
UASSERT(!imageDepth.empty() && (imageDepth.type() == CV_16UC1 || imageDepth.type() == CV_32FC1));
|
||||
UASSERT_MSG(imageRgb.rows % decimation == 0, uFormat("imageDepth.rows=%d decimation=%d", imageRgb.rows, decimation).c_str());
|
||||
UASSERT_MSG(imageRgb.cols % decimation == 0, uFormat("imageDepth.cols=%d decimation=%d", imageRgb.cols, decimation).c_str());
|
||||
UASSERT_MSG(imageRgb.rows % imageDepthIn.rows == 0 && imageRgb.cols % imageDepthIn.cols == 0,
|
||||
uFormat("rgb=%dx%d depth=%dx%d", imageRgb.cols, imageRgb.rows, imageDepthIn.cols, imageDepthIn.rows).c_str());
|
||||
UASSERT(!imageDepthIn.empty() && (imageDepthIn.type() == CV_16UC1 || imageDepthIn.type() == CV_32FC1));
|
||||
if(decimation < 0)
|
||||
{
|
||||
UASSERT_MSG(imageRgb.rows % decimation == 0, uFormat("imageRgb.rows=%d decimation=%d", imageRgb.rows, decimation).c_str());
|
||||
UASSERT_MSG(imageRgb.cols % decimation == 0, uFormat("imageRgb.cols=%d decimation=%d", imageRgb.cols, decimation).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
UASSERT_MSG(imageDepthIn.rows % decimation == 0, uFormat("imageDepth.rows=%d decimation=%d", imageDepthIn.rows, decimation).c_str());
|
||||
UASSERT_MSG(imageDepthIn.cols % decimation == 0, uFormat("imageDepth.cols=%d decimation=%d", imageDepthIn.cols, decimation).c_str());
|
||||
}
|
||||
|
||||
cv::Mat imageDepth = imageDepthIn;
|
||||
if(decimation < 0)
|
||||
{
|
||||
UDEBUG("Decimation from RGB image (%d)", decimation);
|
||||
// decimate from RGB image size, upsample depth if needed
|
||||
decimation = -1*decimation;
|
||||
|
||||
int targetSize = imageRgb.rows / decimation;
|
||||
if(targetSize > imageDepthIn.rows)
|
||||
{
|
||||
UDEBUG("Depth interpolation factor=%d", targetSize/imageDepthIn.rows);
|
||||
imageDepth = util2d::interpolate(imageDepthIn, targetSize/imageDepthIn.rows);
|
||||
decimation = 1;
|
||||
}
|
||||
else if(targetSize == imageDepthIn.rows)
|
||||
{
|
||||
decimation = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
UASSERT(imageDepthIn.rows % targetSize == 0);
|
||||
decimation = imageDepthIn.rows / targetSize;
|
||||
}
|
||||
}
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||
if(decimation < 1)
|
||||
{
|
||||
return cloud;
|
||||
}
|
||||
|
||||
bool mono;
|
||||
if(imageRgb.channels() == 3) // BGR
|
||||
@@ -714,6 +781,11 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromSensorData(
|
||||
const ParametersMap & stereoParameters,
|
||||
const std::vector<float> & roiRatios)
|
||||
{
|
||||
if(decimation == 0)
|
||||
{
|
||||
decimation = 1;
|
||||
}
|
||||
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
|
||||
if(!sensorData.depthRaw().empty() && sensorData.cameraModels().size())
|
||||
@@ -857,6 +929,11 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudRGBFromSensorData(
|
||||
const ParametersMap & stereoParameters,
|
||||
const std::vector<float> & roiRatios)
|
||||
{
|
||||
if(decimation == 0)
|
||||
{
|
||||
decimation = 1;
|
||||
}
|
||||
|
||||
UASSERT(!sensorData.imageRaw().empty());
|
||||
UASSERT((!sensorData.depthRaw().empty() && sensorData.cameraModels().size()) ||
|
||||
(!sensorData.rightRaw().empty() && sensorData.stereoCameraModel().isValidForProjection()));
|
||||
|
||||
@@ -1706,7 +1706,11 @@ void DatabaseViewer::view3DMap()
|
||||
items.append("4");
|
||||
items.append("8");
|
||||
items.append("16");
|
||||
QString item = QInputDialog::getItem(this, tr("Decimation?"), tr("Image decimation"), items, 2, false, &ok);
|
||||
items.append("-2");
|
||||
items.append("-4");
|
||||
items.append("-8");
|
||||
items.append("-16");
|
||||
QString item = QInputDialog::getItem(this, tr("Decimation?"), tr("Image decimation. 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)."), items, 2, false, &ok);
|
||||
if(ok)
|
||||
{
|
||||
int decimation = item.toInt();
|
||||
@@ -1928,7 +1932,11 @@ void DatabaseViewer::generate3DMap()
|
||||
items.append("4");
|
||||
items.append("8");
|
||||
items.append("16");
|
||||
QString item = QInputDialog::getItem(this, tr("Decimation?"), tr("Image decimation"), items, 2, false, &ok);
|
||||
items.append("-2");
|
||||
items.append("-4");
|
||||
items.append("-8");
|
||||
items.append("-16");
|
||||
QString item = QInputDialog::getItem(this, tr("Decimation?"), tr("Image decimation. 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)."), items, 2, false, &ok);
|
||||
if(ok)
|
||||
{
|
||||
int decimation = item.toInt();
|
||||
@@ -4129,14 +4137,14 @@ void DatabaseViewer::refineConstraint(int from, int to, bool silent, bool update
|
||||
dataTo.uncompressData(&tmpC, &tmpD, 0);
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudFrom = util3d::cloudFromSensorData(
|
||||
dataFrom,
|
||||
ui_->spinBox_icp_decimation->value(),
|
||||
ui_->spinBox_icp_decimation->value()==0?1:ui_->spinBox_icp_decimation->value(),
|
||||
ui_->doubleSpinBox_icp_maxDepth->value(),
|
||||
ui_->doubleSpinBox_icp_minDepth->value(),
|
||||
0,
|
||||
ui_->parameters_toolbox->getParameters());
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloudTo = util3d::cloudFromSensorData(
|
||||
dataTo,
|
||||
ui_->spinBox_icp_decimation->value(),
|
||||
ui_->spinBox_icp_decimation->value()==0?1:ui_->spinBox_icp_decimation->value(),
|
||||
ui_->doubleSpinBox_icp_maxDepth->value(),
|
||||
ui_->doubleSpinBox_icp_minDepth->value(),
|
||||
0,
|
||||
|
||||
@@ -358,6 +358,7 @@ void ExportCloudsDialog::restoreDefaults()
|
||||
void ExportCloudsDialog::updateReconstructionFlavor()
|
||||
{
|
||||
_ui->groupBox_mls->setVisible(_ui->comboBox_pipeline->currentIndex() == 1);
|
||||
_ui->groupBox_mls->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
|
||||
_ui->groupBox_gp3->setVisible(_ui->comboBox_pipeline->currentIndex() == 1);
|
||||
_ui->groupBox_organized->setVisible(_ui->comboBox_pipeline->currentIndex() == 0);
|
||||
}
|
||||
@@ -818,7 +819,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
}
|
||||
|
||||
std::map<int, Transform> viewPoints = poses;
|
||||
if(_ui->groupBox_mls->isVisible() && _ui->groupBox_mls->isChecked())
|
||||
if(_ui->groupBox_mls->isEnabled() && _ui->groupBox_mls->isChecked())
|
||||
{
|
||||
_progressDialog->appendText(tr("Smoothing the surface using Moving Least Squares (MLS) algorithm... "
|
||||
"[search radius=%1m voxel=%2m]").arg(_ui->doubleSpinBox_mlsRadius->value()).arg(_ui->doubleSpinBox_voxelSize_assembled->value()));
|
||||
@@ -850,10 +851,10 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudWithNormals = iter->second.first;
|
||||
|
||||
if(_ui->groupBox_mls->isVisible() && _ui->groupBox_mls->isChecked())
|
||||
if(_ui->groupBox_mls->isEnabled() && _ui->groupBox_mls->isChecked())
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||
if(iter->second.first->isOrganized())
|
||||
if(iter->second.second->size())
|
||||
{
|
||||
pcl::copyPointCloud(*cloudWithNormals, *iter->second.second, *cloudWithoutNormals);
|
||||
}
|
||||
@@ -1244,65 +1245,70 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
int w = ster->second.width;
|
||||
int h = ster->second.height;
|
||||
UASSERT(w > 1 && h > 1);
|
||||
UASSERT(textureMesh->tex_polygons.size() && textureMesh->tex_polygons[0].size());
|
||||
|
||||
textureMesh->tex_coordinates.resize(1);
|
||||
if(!_ui->checkBox_mesh_quad->isEnabled()) // disabled -> we are exporting to file
|
||||
if(textureMesh->tex_polygons.size() && textureMesh->tex_polygons[0].size())
|
||||
{
|
||||
// When saving to file, tex_coordinates should be linked to polygon vertices, not points
|
||||
int polygonSize = textureMesh->tex_polygons[0][0].vertices.size();
|
||||
textureMesh->tex_coordinates[0].resize(polygonSize*textureMesh->tex_polygons[0].size());
|
||||
for(unsigned int i=0; i<textureMesh->tex_polygons[0].size(); ++i)
|
||||
textureMesh->tex_coordinates.resize(1);
|
||||
if(!_ui->checkBox_mesh_quad->isEnabled()) // disabled -> we are exporting to file
|
||||
{
|
||||
const pcl::Vertices & vertices = textureMesh->tex_polygons[0][i];
|
||||
UASSERT(polygonSize == (int)vertices.vertices.size());
|
||||
for(int k=0; k<polygonSize; ++k)
|
||||
// When saving to file, tex_coordinates should be linked to polygon vertices, not points
|
||||
int polygonSize = textureMesh->tex_polygons[0][0].vertices.size();
|
||||
textureMesh->tex_coordinates[0].resize(polygonSize*textureMesh->tex_polygons[0].size());
|
||||
for(unsigned int i=0; i<textureMesh->tex_polygons[0].size(); ++i)
|
||||
{
|
||||
const pcl::Vertices & vertices = textureMesh->tex_polygons[0][i];
|
||||
UASSERT(polygonSize == (int)vertices.vertices.size());
|
||||
for(int k=0; k<polygonSize; ++k)
|
||||
{
|
||||
//uv
|
||||
UASSERT(vertices.vertices[k] < oter->second.size());
|
||||
int originalVertex = oter->second[vertices.vertices[k]];
|
||||
textureMesh->tex_coordinates[0][i*polygonSize+k] = Eigen::Vector2f(
|
||||
float(originalVertex % w) / float(w), // u
|
||||
float(h - originalVertex / w) / float(h)); // v
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int nPoints = textureMesh->cloud.data.size()/textureMesh->cloud.point_step;
|
||||
textureMesh->tex_coordinates[0].resize(nPoints);
|
||||
for(int i=0; i<nPoints; ++i)
|
||||
{
|
||||
//uv
|
||||
UASSERT(vertices.vertices[k] < oter->second.size());
|
||||
int originalVertex = oter->second[vertices.vertices[k]];
|
||||
textureMesh->tex_coordinates[0][i*polygonSize+k] = Eigen::Vector2f(
|
||||
UASSERT(i < (int)oter->second.size());
|
||||
int originalVertex = oter->second[i];
|
||||
textureMesh->tex_coordinates[0][i] = Eigen::Vector2f(
|
||||
float(originalVertex % w) / float(w), // u
|
||||
float(h - originalVertex / w) / float(h)); // v
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int nPoints = textureMesh->cloud.data.size()/textureMesh->cloud.point_step;
|
||||
textureMesh->tex_coordinates[0].resize(nPoints);
|
||||
for(int i=0; i<nPoints; ++i)
|
||||
|
||||
pcl::TexMaterial mesh_material;
|
||||
mesh_material.tex_d = 1.0f;
|
||||
mesh_material.tex_Ns = 75.0f;
|
||||
mesh_material.tex_illum = 1;
|
||||
|
||||
std::stringstream tex_name;
|
||||
tex_name << "material_" << iter->first;
|
||||
tex_name >> mesh_material.tex_name;
|
||||
|
||||
std::string tmpDirectory = dir.filePath("tmp_textures").toStdString();
|
||||
mesh_material.tex_file = uFormat("%s/%s%d.png", tmpDirectory.c_str(), "texture_", iter->first);
|
||||
if(!cv::imwrite(mesh_material.tex_file, images.at(iter->first)))
|
||||
{
|
||||
//uv
|
||||
UASSERT(i < (int)oter->second.size());
|
||||
int originalVertex = oter->second[i];
|
||||
textureMesh->tex_coordinates[0][i] = Eigen::Vector2f(
|
||||
float(originalVertex % w) / float(w), // u
|
||||
float(h - originalVertex / w) / float(h)); // v
|
||||
UERROR("Cannot save texture of image %d", iter->first);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINFO("Saved temporary texture: \"%s\"", mesh_material.tex_file.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
pcl::TexMaterial mesh_material;
|
||||
mesh_material.tex_d = 1.0f;
|
||||
mesh_material.tex_Ns = 75.0f;
|
||||
mesh_material.tex_illum = 1;
|
||||
|
||||
std::stringstream tex_name;
|
||||
tex_name << "material_" << iter->first;
|
||||
tex_name >> mesh_material.tex_name;
|
||||
|
||||
std::string tmpDirectory = dir.filePath("tmp_textures").toStdString();
|
||||
mesh_material.tex_file = uFormat("%s/%s%d.png", tmpDirectory.c_str(), "texture_", iter->first);
|
||||
if(!cv::imwrite(mesh_material.tex_file, images.at(iter->first)))
|
||||
{
|
||||
UERROR("Cannot save texture of image %d", iter->first);
|
||||
textureMesh->tex_materials.push_back(mesh_material);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINFO("Saved temporary texture: \"%s\"", mesh_material.tex_file.c_str());
|
||||
UWARN("No polygons for mesh %d!?", iter->first);
|
||||
}
|
||||
|
||||
textureMesh->tex_materials.push_back(mesh_material);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1422,7 +1428,7 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
|
||||
cloudWithoutNormals = util3d::cloudRGBFromSensorData(
|
||||
d,
|
||||
_ui->spinBox_decimation->value(),
|
||||
_ui->spinBox_decimation->value() == 0?1:_ui->spinBox_decimation->value(),
|
||||
_ui->doubleSpinBox_maxDepth->value(),
|
||||
_ui->doubleSpinBox_minDepth->value(),
|
||||
indices.get(),
|
||||
|
||||
@@ -3888,7 +3888,7 @@ int PreferencesDialog::getCloudMeshingTriangleSize()
|
||||
int PreferencesDialog::getCloudDecimation(int index) const
|
||||
{
|
||||
UASSERT(index >= 0 && index <= 1);
|
||||
return _3dRenderingDecimation[index]->value();
|
||||
return _3dRenderingDecimation[index]->value()==0?1:_3dRenderingDecimation[index]->value();
|
||||
}
|
||||
double PreferencesDialog::getCloudMaxDepth(int index) const
|
||||
{
|
||||
|
||||
@@ -983,7 +983,7 @@
|
||||
<item>
|
||||
<widget class="QToolBox" name="toolBox">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_3">
|
||||
<property name="geometry">
|
||||
@@ -991,7 +991,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>324</width>
|
||||
<height>188</height>
|
||||
<height>210</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
@@ -1443,8 +1443,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>201</width>
|
||||
<height>126</height>
|
||||
<width>283</width>
|
||||
<height>225</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
@@ -1543,8 +1543,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>181</width>
|
||||
<height>200</height>
|
||||
<width>283</width>
|
||||
<height>225</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
@@ -1554,14 +1554,17 @@
|
||||
<item row="1" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_icp_decimation">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>-32</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Decimation</string>
|
||||
<string>Decimation. 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>
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-823</y>
|
||||
<y>0</y>
|
||||
<width>773</width>
|
||||
<height>1731</height>
|
||||
<height>1755</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
@@ -173,7 +173,7 @@
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_108">
|
||||
<property name="text">
|
||||
<string>3D cloud decimation (1-2-4-8-...).</string>
|
||||
<string>3D cloud 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>
|
||||
@@ -183,7 +183,7 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_decimation">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>-32</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
|
||||
@@ -63,25 +63,16 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-577</y>
|
||||
<width>678</width>
|
||||
<height>2417</height>
|
||||
<y>0</y>
|
||||
<width>673</width>
|
||||
<height>2520</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -95,7 +86,7 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>5</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_22">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||
@@ -776,7 +767,7 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_108">
|
||||
<property name="text">
|
||||
<string>3D cloud decimation (1-2-4-8-...).</string>
|
||||
<string>3D cloud 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>
|
||||
@@ -808,13 +799,13 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
<item row="2" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_decimation">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>-32</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>4</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -1099,13 +1090,13 @@ Show a yellow background when the number of odometry inliers goes under this thr
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_decimation_odom">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>-32</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -4290,16 +4281,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
<string>Directory of images (optional settings)</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_93">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -5713,7 +5695,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<item row="12" column="1">
|
||||
<widget class="QLabel" name="label_retrieved_13">
|
||||
<property name="text">
|
||||
<string>Image pre decimation. This option can be used to reduce image size before features extraction.</string>
|
||||
<string>Image pre decimation. This option can be used to reduce image size before features extraction. 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>
|
||||
@@ -5785,7 +5767,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<item row="13" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_imagePostDecimation">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>-16</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>16</number>
|
||||
@@ -5831,7 +5813,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<item row="13" column="1">
|
||||
<widget class="QLabel" name="label_retrieved_6">
|
||||
<property name="text">
|
||||
<string>Image post decimation. This option can be used to save images in lower resolution (size/decimation). It is done on the original image.</string>
|
||||
<string>Image post decimation. This option can be used to save images in lower resolution (size/decimation). It is done on the original image. 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>
|
||||
@@ -5880,7 +5862,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<item row="12" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_imagePreDecimation">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>-16</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>16</number>
|
||||
@@ -8516,7 +8498,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<item row="0" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_grid_decimation">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>-32</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
@@ -8529,7 +8511,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_322">
|
||||
<property name="text">
|
||||
<string>Image Decimation (1-2-4-8-...).</string>
|
||||
<string>Image 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>
|
||||
@@ -9352,7 +9334,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="label_248">
|
||||
<property name="text">
|
||||
<string>Decimation of images before features extraction.</string>
|
||||
<string>Decimation of images before features extraction. 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>
|
||||
@@ -9365,7 +9347,10 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<item row="7" column="0">
|
||||
<widget class="QSpinBox" name="odom_imageDecimation">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>-32</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -10376,16 +10361,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
<widget class="QWidget" name="page_54">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_85">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -10525,16 +10501,7 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_55">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_86">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -10692,16 +10659,7 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -10781,16 +10739,7 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
@@ -10902,16 +10851,7 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
|
||||
Reference in New Issue
Block a user