mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-03 10:00:23 +08:00
MainWindow: Added statistics about how much size the created clouds take in RAM. Avoid caching data on small movements. Export: Fixed meshing checkbox and pipeline combo box not saved/loaded. PreferencesDialog: Added option to disable caching the point clouds. computeNormals(): added viewpoint parameter. mls(): making sure that all returned normals are normalized.
This commit is contained in:
@@ -194,6 +194,8 @@ public:
|
|||||||
void setGroundTruth(const Transform & pose) {groundTruth_ = pose;}
|
void setGroundTruth(const Transform & pose) {groundTruth_ = pose;}
|
||||||
const Transform & groundTruth() const {return groundTruth_;}
|
const Transform & groundTruth() const {return groundTruth_;}
|
||||||
|
|
||||||
|
long getMemoryUsed() const; // Return memory usage in Bytes
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _id;
|
int _id;
|
||||||
double _stamp;
|
double _stamp;
|
||||||
|
|||||||
@@ -126,28 +126,34 @@ pcl::TextureMesh::Ptr RTABMAP_EXP createTextureMesh(
|
|||||||
|
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
|
||||||
int normalKSearch = 20);
|
int normalKSearch = 20,
|
||||||
|
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
int normalKSearch = 20);
|
int normalKSearch = 20,
|
||||||
|
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices,
|
const pcl::IndicesPtr & indices,
|
||||||
int normalKSearch = 20);
|
int normalKSearch = 20,
|
||||||
|
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr RTABMAP_EXP computeNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices,
|
const pcl::IndicesPtr & indices,
|
||||||
int normalKSearch = 20);
|
int normalKSearch = 20,
|
||||||
|
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
|
||||||
|
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
float maxDepthChangeFactor = 0.02f,
|
float maxDepthChangeFactor = 0.02f,
|
||||||
float normalSmoothingSize = 10.0f);
|
float normalSmoothingSize = 10.0f,
|
||||||
|
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices,
|
const pcl::IndicesPtr & indices,
|
||||||
float maxDepthChangeFactor = 0.02f,
|
float maxDepthChangeFactor = 0.02f,
|
||||||
float normalSmoothingSize = 10.0f);
|
float normalSmoothingSize = 10.0f,
|
||||||
|
const Eigen::Vector3f & viewPoint = Eigen::Vector3f(0,0,0));
|
||||||
|
|
||||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr RTABMAP_EXP mls(
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr RTABMAP_EXP mls(
|
||||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
|
|||||||
@@ -193,7 +193,21 @@ void CameraThread::mainLoop()
|
|||||||
cv::Mat scan;
|
cv::Mat scan;
|
||||||
if(_scanNormalsK>0)
|
if(_scanNormalsK>0)
|
||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, _scanNormalsK);
|
// view point
|
||||||
|
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
|
||||||
|
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
|
||||||
|
{
|
||||||
|
viewPoint[0] = data.cameraModels()[0].localTransform().x();
|
||||||
|
viewPoint[1] = data.cameraModels()[0].localTransform().y();
|
||||||
|
viewPoint[2] = data.cameraModels()[0].localTransform().z();
|
||||||
|
}
|
||||||
|
else if(!data.stereoCameraModel().localTransform().isNull())
|
||||||
|
{
|
||||||
|
viewPoint[0] = data.stereoCameraModel().localTransform().x();
|
||||||
|
viewPoint[1] = data.stereoCameraModel().localTransform().y();
|
||||||
|
viewPoint[2] = data.stereoCameraModel().localTransform().z();
|
||||||
|
}
|
||||||
|
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, _scanNormalsK, viewPoint);
|
||||||
pcl::PointCloud<pcl::PointNormal>::Ptr cloudNormals(new pcl::PointCloud<pcl::PointNormal>);
|
pcl::PointCloud<pcl::PointNormal>::Ptr cloudNormals(new pcl::PointCloud<pcl::PointNormal>);
|
||||||
pcl::concatenateFields(*cloud, *normals, *cloudNormals);
|
pcl::concatenateFields(*cloud, *normals, *cloudNormals);
|
||||||
scan = util3d::laserScanFromPointCloud(*cloudNormals);
|
scan = util3d::laserScanFromPointCloud(*cloudNormals);
|
||||||
|
|||||||
@@ -448,7 +448,6 @@ void SensorData::setUserDataRaw(const cv::Mat & userDataRaw)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_userDataRaw = userDataRaw;
|
_userDataRaw = userDataRaw;
|
||||||
_userDataCompressed = cv::Mat();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SensorData::setUserData(const cv::Mat & userData)
|
void SensorData::setUserData(const cv::Mat & userData)
|
||||||
@@ -607,5 +606,17 @@ void SensorData::uncompressDataConst(cv::Mat * imageRaw, cv::Mat * depthRaw, cv:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long SensorData::getMemoryUsed() const // Return memory usage in Bytes
|
||||||
|
{
|
||||||
|
return _imageCompressed.total()*_imageCompressed.elemSize() +
|
||||||
|
_imageRaw.total()*_imageRaw.elemSize() +
|
||||||
|
_depthOrRightCompressed.total()*_depthOrRightCompressed.elemSize() +
|
||||||
|
_depthOrRightRaw.total()*_depthOrRightRaw.elemSize() +
|
||||||
|
_userDataCompressed.total()*_userDataCompressed.elemSize() +
|
||||||
|
_userDataRaw.total()*_userDataRaw.elemSize() +
|
||||||
|
_laserScanCompressed.total()*_laserScanCompressed.elemSize() +
|
||||||
|
_laserScanRaw.total()*_laserScanRaw.elemSize();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace rtabmap
|
} // namespace rtabmap
|
||||||
|
|
||||||
|
|||||||
@@ -596,15 +596,17 @@ pcl::TextureMesh::Ptr createTextureMesh(
|
|||||||
|
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
|
||||||
int normalKSearch)
|
int normalKSearch,
|
||||||
|
const Eigen::Vector3f & viewPoint)
|
||||||
{
|
{
|
||||||
pcl::IndicesPtr indices(new std::vector<int>);
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
return computeNormals(cloud, indices, normalKSearch);
|
return computeNormals(cloud, indices, normalKSearch, viewPoint);
|
||||||
}
|
}
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices,
|
const pcl::IndicesPtr & indices,
|
||||||
int normalKSearch)
|
int normalKSearch,
|
||||||
|
const Eigen::Vector3f & viewPoint)
|
||||||
{
|
{
|
||||||
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
|
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
|
||||||
if(indices->size())
|
if(indices->size())
|
||||||
@@ -627,6 +629,7 @@ pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
|||||||
//}
|
//}
|
||||||
n.setSearchMethod (tree);
|
n.setSearchMethod (tree);
|
||||||
n.setKSearch (normalKSearch);
|
n.setKSearch (normalKSearch);
|
||||||
|
n.setViewPoint(viewPoint[0], viewPoint[1], viewPoint[2]);
|
||||||
n.compute (*normals);
|
n.compute (*normals);
|
||||||
|
|
||||||
return normals;
|
return normals;
|
||||||
@@ -634,15 +637,17 @@ pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
|||||||
|
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
int normalKSearch)
|
int normalKSearch,
|
||||||
|
const Eigen::Vector3f & viewPoint)
|
||||||
{
|
{
|
||||||
pcl::IndicesPtr indices(new std::vector<int>);
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
return computeNormals(cloud, indices, normalKSearch);
|
return computeNormals(cloud, indices, normalKSearch, viewPoint);
|
||||||
}
|
}
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices,
|
const pcl::IndicesPtr & indices,
|
||||||
int normalKSearch)
|
int normalKSearch,
|
||||||
|
const Eigen::Vector3f & viewPoint)
|
||||||
{
|
{
|
||||||
pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB>);
|
pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB>);
|
||||||
if(indices->size())
|
if(indices->size())
|
||||||
@@ -665,6 +670,7 @@ pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
|||||||
//}
|
//}
|
||||||
n.setSearchMethod (tree);
|
n.setSearchMethod (tree);
|
||||||
n.setKSearch (normalKSearch);
|
n.setKSearch (normalKSearch);
|
||||||
|
n.setViewPoint(viewPoint[0], viewPoint[1], viewPoint[2]);
|
||||||
n.compute (*normals);
|
n.compute (*normals);
|
||||||
|
|
||||||
return normals;
|
return normals;
|
||||||
@@ -673,16 +679,18 @@ pcl::PointCloud<pcl::Normal>::Ptr computeNormals(
|
|||||||
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
float maxDepthChangeFactor,
|
float maxDepthChangeFactor,
|
||||||
float normalSmoothingSize)
|
float normalSmoothingSize,
|
||||||
|
const Eigen::Vector3f & viewPoint)
|
||||||
{
|
{
|
||||||
pcl::IndicesPtr indices(new std::vector<int>);
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
return computeFastOrganizedNormals(cloud, indices, maxDepthChangeFactor, normalSmoothingSize);
|
return computeFastOrganizedNormals(cloud, indices, maxDepthChangeFactor, normalSmoothingSize, viewPoint);
|
||||||
}
|
}
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
|
pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
|
||||||
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices,
|
const pcl::IndicesPtr & indices,
|
||||||
float maxDepthChangeFactor,
|
float maxDepthChangeFactor,
|
||||||
float normalSmoothingSize)
|
float normalSmoothingSize,
|
||||||
|
const Eigen::Vector3f & viewPoint)
|
||||||
{
|
{
|
||||||
UASSERT(cloud->isOrganized());
|
UASSERT(cloud->isOrganized());
|
||||||
|
|
||||||
@@ -698,6 +706,7 @@ pcl::PointCloud<pcl::Normal>::Ptr computeFastOrganizedNormals(
|
|||||||
//{
|
//{
|
||||||
// ne.setIndices(indices);
|
// ne.setIndices(indices);
|
||||||
//}
|
//}
|
||||||
|
ne.setViewPoint(viewPoint[0], viewPoint[1], viewPoint[2]);
|
||||||
ne.compute(*normals);
|
ne.compute(*normals);
|
||||||
|
|
||||||
return normals;
|
return normals;
|
||||||
@@ -783,6 +792,16 @@ pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mls(
|
|||||||
mls.setSearchMethod (tree);
|
mls.setSearchMethod (tree);
|
||||||
mls.process (*cloud_with_normals);
|
mls.process (*cloud_with_normals);
|
||||||
|
|
||||||
|
// It seems that returned normals are not normalized!? FIXME: Is it a bug only in PCL 1.7.1?
|
||||||
|
for(unsigned int i=0; i<cloud_with_normals->size(); ++i)
|
||||||
|
{
|
||||||
|
Eigen::Vector3f normal(cloud_with_normals->at(i).normal_x, cloud_with_normals->at(i).normal_y, cloud_with_normals->at(i).normal_z);
|
||||||
|
normal.normalize();
|
||||||
|
cloud_with_normals->at(i).normal_x = normal[0];
|
||||||
|
cloud_with_normals->at(i).normal_y = normal[1];
|
||||||
|
cloud_with_normals->at(i).normal_z = normal[2];
|
||||||
|
}
|
||||||
|
|
||||||
return cloud_with_normals;
|
return cloud_with_normals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -281,12 +281,14 @@ private:
|
|||||||
int _waypointsIndex;
|
int _waypointsIndex;
|
||||||
|
|
||||||
QMap<int, Signature> _cachedSignatures;
|
QMap<int, Signature> _cachedSignatures;
|
||||||
|
long _cachedMemoryUsage;
|
||||||
std::map<int, Transform> _currentPosesMap; // <nodeId, pose>
|
std::map<int, Transform> _currentPosesMap; // <nodeId, pose>
|
||||||
std::map<int, Transform> _currentGTPosesMap; // <nodeId, pose>
|
std::map<int, Transform> _currentGTPosesMap; // <nodeId, pose>
|
||||||
std::multimap<int, Link> _currentLinksMap; // <nodeFromId, link>
|
std::multimap<int, Link> _currentLinksMap; // <nodeFromId, link>
|
||||||
std::map<int, int> _currentMapIds; // <nodeId, mapId>
|
std::map<int, int> _currentMapIds; // <nodeId, mapId>
|
||||||
std::map<int, std::string> _currentLabels; // <nodeId, label>
|
std::map<int, std::string> _currentLabels; // <nodeId, label>
|
||||||
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > _createdClouds;
|
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > _cachedClouds;
|
||||||
|
long _createdCloudsMemoryUsage;
|
||||||
std::pair<int, std::pair<std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>, pcl::IndicesPtr> > _previousCloud; // used for subtraction
|
std::pair<int, std::pair<std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>, pcl::IndicesPtr> > _previousCloud; // used for subtraction
|
||||||
|
|
||||||
std::map<int, cv::Mat> _createdScans;
|
std::map<int, cv::Mat> _createdScans;
|
||||||
|
|||||||
@@ -224,6 +224,7 @@ public:
|
|||||||
|
|
||||||
//
|
//
|
||||||
bool isImagesKept() const;
|
bool isImagesKept() const;
|
||||||
|
bool isCloudsKept() const;
|
||||||
float getTimeLimit() const;
|
float getTimeLimit() const;
|
||||||
float getDetectionRate() const;
|
float getDetectionRate() const;
|
||||||
bool isSLAMMode() const;
|
bool isSLAMMode() const;
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
|||||||
connect(_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMLSGrpVisibility()));
|
connect(_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMLSGrpVisibility()));
|
||||||
updateMLSGrpVisibility();
|
updateMLSGrpVisibility();
|
||||||
|
|
||||||
connect(_ui->groupBox_gp3, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
|
connect(_ui->groupBox_meshing, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_gp3Radius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_gp3Radius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_gp3Mu, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_gp3Mu, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
@@ -138,6 +138,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
|
|||||||
{
|
{
|
||||||
settings.beginGroup(group);
|
settings.beginGroup(group);
|
||||||
}
|
}
|
||||||
|
settings.setValue("pipeline", _ui->comboBox_pipeline->currentIndex());
|
||||||
settings.setValue("binary", _ui->checkBox_binary->isChecked());
|
settings.setValue("binary", _ui->checkBox_binary->isChecked());
|
||||||
settings.setValue("normals_k", _ui->spinBox_normalKSearch->value());
|
settings.setValue("normals_k", _ui->spinBox_normalKSearch->value());
|
||||||
|
|
||||||
@@ -169,7 +170,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
|
|||||||
settings.setValue("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value());
|
settings.setValue("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value());
|
||||||
settings.setValue("mls_dilation_iterations", _ui->spinBox_dilationSteps->value());
|
settings.setValue("mls_dilation_iterations", _ui->spinBox_dilationSteps->value());
|
||||||
|
|
||||||
settings.setValue("mesh", _ui->groupBox_gp3->isChecked());
|
settings.setValue("mesh", _ui->groupBox_meshing->isChecked());
|
||||||
settings.setValue("mesh_radius", _ui->doubleSpinBox_gp3Radius->value());
|
settings.setValue("mesh_radius", _ui->doubleSpinBox_gp3Radius->value());
|
||||||
settings.setValue("mesh_mu", _ui->doubleSpinBox_gp3Mu->value());
|
settings.setValue("mesh_mu", _ui->doubleSpinBox_gp3Mu->value());
|
||||||
settings.setValue("mesh_decimation_factor", _ui->doubleSpinBox_meshDecimationFactor->value());
|
settings.setValue("mesh_decimation_factor", _ui->doubleSpinBox_meshDecimationFactor->value());
|
||||||
@@ -193,6 +194,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
|||||||
settings.beginGroup(group);
|
settings.beginGroup(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ui->comboBox_pipeline->setCurrentIndex(settings.value("pipeline", _ui->comboBox_pipeline->currentIndex()).toInt());
|
||||||
_ui->checkBox_binary->setChecked(settings.value("binary", _ui->checkBox_binary->isChecked()).toBool());
|
_ui->checkBox_binary->setChecked(settings.value("binary", _ui->checkBox_binary->isChecked()).toBool());
|
||||||
_ui->spinBox_normalKSearch->setValue(settings.value("normals_k", _ui->spinBox_normalKSearch->value()).toInt());
|
_ui->spinBox_normalKSearch->setValue(settings.value("normals_k", _ui->spinBox_normalKSearch->value()).toInt());
|
||||||
|
|
||||||
@@ -223,7 +225,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
|||||||
_ui->doubleSpinBox_dilationVoxelSize->setValue(settings.value("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value()).toDouble());
|
_ui->doubleSpinBox_dilationVoxelSize->setValue(settings.value("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value()).toDouble());
|
||||||
_ui->spinBox_dilationSteps->setValue(settings.value("mls_dilation_iterations", _ui->spinBox_dilationSteps->value()).toInt());
|
_ui->spinBox_dilationSteps->setValue(settings.value("mls_dilation_iterations", _ui->spinBox_dilationSteps->value()).toInt());
|
||||||
|
|
||||||
_ui->groupBox_gp3->setChecked(settings.value("mesh", _ui->groupBox_gp3->isChecked()).toBool());
|
_ui->groupBox_meshing->setChecked(settings.value("mesh", _ui->groupBox_meshing->isChecked()).toBool());
|
||||||
_ui->doubleSpinBox_gp3Radius->setValue(settings.value("mesh_radius", _ui->doubleSpinBox_gp3Radius->value()).toDouble());
|
_ui->doubleSpinBox_gp3Radius->setValue(settings.value("mesh_radius", _ui->doubleSpinBox_gp3Radius->value()).toDouble());
|
||||||
_ui->doubleSpinBox_gp3Mu->setValue(settings.value("mesh_mu", _ui->doubleSpinBox_gp3Mu->value()).toDouble());
|
_ui->doubleSpinBox_gp3Mu->setValue(settings.value("mesh_mu", _ui->doubleSpinBox_gp3Mu->value()).toDouble());
|
||||||
_ui->doubleSpinBox_meshDecimationFactor->setValue(settings.value("mesh_decimation_factor",_ui->doubleSpinBox_meshDecimationFactor->value()).toDouble());
|
_ui->doubleSpinBox_meshDecimationFactor->setValue(settings.value("mesh_decimation_factor",_ui->doubleSpinBox_meshDecimationFactor->value()).toDouble());
|
||||||
@@ -272,7 +274,7 @@ void ExportCloudsDialog::restoreDefaults()
|
|||||||
_ui->doubleSpinBox_dilationVoxelSize->setValue(0.01);
|
_ui->doubleSpinBox_dilationVoxelSize->setValue(0.01);
|
||||||
_ui->spinBox_dilationSteps->setValue(0);
|
_ui->spinBox_dilationSteps->setValue(0);
|
||||||
|
|
||||||
_ui->groupBox_gp3->setChecked(false);
|
_ui->groupBox_meshing->setChecked(false);
|
||||||
_ui->doubleSpinBox_gp3Radius->setValue(0.04);
|
_ui->doubleSpinBox_gp3Radius->setValue(0.04);
|
||||||
_ui->doubleSpinBox_gp3Mu->setValue(2.5);
|
_ui->doubleSpinBox_gp3Mu->setValue(2.5);
|
||||||
_ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
|
_ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
|
||||||
@@ -336,7 +338,7 @@ void ExportCloudsDialog::exportClouds(
|
|||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::map<int, int> & mapIds,
|
const std::map<int, int> & mapIds,
|
||||||
const QMap<int, Signature> & cachedSignatures,
|
const QMap<int, Signature> & cachedSignatures,
|
||||||
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
|
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
|
||||||
const QString & workingDirectory,
|
const QString & workingDirectory,
|
||||||
const ParametersMap & parameters)
|
const ParametersMap & parameters)
|
||||||
{
|
{
|
||||||
@@ -350,7 +352,7 @@ void ExportCloudsDialog::exportClouds(
|
|||||||
poses,
|
poses,
|
||||||
mapIds,
|
mapIds,
|
||||||
cachedSignatures,
|
cachedSignatures,
|
||||||
createdClouds,
|
cachedClouds,
|
||||||
workingDirectory,
|
workingDirectory,
|
||||||
parameters,
|
parameters,
|
||||||
clouds,
|
clouds,
|
||||||
@@ -388,7 +390,7 @@ void ExportCloudsDialog::viewClouds(
|
|||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::map<int, int> & mapIds,
|
const std::map<int, int> & mapIds,
|
||||||
const QMap<int, Signature> & cachedSignatures,
|
const QMap<int, Signature> & cachedSignatures,
|
||||||
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
|
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
|
||||||
const QString & workingDirectory,
|
const QString & workingDirectory,
|
||||||
const ParametersMap & parameters)
|
const ParametersMap & parameters)
|
||||||
{
|
{
|
||||||
@@ -402,7 +404,7 @@ void ExportCloudsDialog::viewClouds(
|
|||||||
poses,
|
poses,
|
||||||
mapIds,
|
mapIds,
|
||||||
cachedSignatures,
|
cachedSignatures,
|
||||||
createdClouds,
|
cachedClouds,
|
||||||
workingDirectory,
|
workingDirectory,
|
||||||
parameters,
|
parameters,
|
||||||
clouds,
|
clouds,
|
||||||
@@ -519,7 +521,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::map<int, int> & mapIds,
|
const std::map<int, int> & mapIds,
|
||||||
const QMap<int, Signature> & cachedSignatures,
|
const QMap<int, Signature> & cachedSignatures,
|
||||||
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
|
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
|
||||||
const QString & workingDirectory,
|
const QString & workingDirectory,
|
||||||
const ParametersMap & parameters,
|
const ParametersMap & parameters,
|
||||||
std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & cloudsWithNormals,
|
std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & cloudsWithNormals,
|
||||||
@@ -555,7 +557,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds = this->getClouds(
|
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds = this->getClouds(
|
||||||
poses,
|
poses,
|
||||||
cachedSignatures,
|
cachedSignatures,
|
||||||
createdClouds,
|
cachedClouds,
|
||||||
parameters);
|
parameters);
|
||||||
|
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr rawAssembledCloud(new pcl::PointCloud<pcl::PointXYZ>);
|
pcl::PointCloud<pcl::PointXYZ>::Ptr rawAssembledCloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||||
@@ -608,10 +610,30 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
clouds.insert(std::make_pair(0, std::make_pair(assembledCloud, pcl::IndicesPtr(new std::vector<int>))));
|
clouds.insert(std::make_pair(0, std::make_pair(assembledCloud, pcl::IndicesPtr(new std::vector<int>))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<int, Transform> viewPoints = poses;
|
||||||
if(_ui->groupBox_mls->isChecked())
|
if(_ui->groupBox_mls->isChecked())
|
||||||
{
|
{
|
||||||
_progressDialog->appendText(tr("Smoothing the surface using Moving Least Squares (MLS) algorithm... "
|
_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()));
|
"[search radius=%1m voxel=%2m]").arg(_ui->doubleSpinBox_mlsRadius->value()).arg(_ui->doubleSpinBox_voxelSize_assembled->value()));
|
||||||
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
|
// Adjust view points with local transforms
|
||||||
|
for(std::map<int, Transform>::iterator iter= viewPoints.begin(); iter!=viewPoints.end(); ++iter)
|
||||||
|
{
|
||||||
|
if(cachedSignatures.contains(iter->first))
|
||||||
|
{
|
||||||
|
const SensorData & data = cachedSignatures.find(iter->first)->sensorData();
|
||||||
|
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
|
||||||
|
{
|
||||||
|
iter->second *= data.cameraModels()[0].localTransform();
|
||||||
|
}
|
||||||
|
else if(!data.stereoCameraModel().localTransform().isNull())
|
||||||
|
{
|
||||||
|
iter->second *= data.stereoCameraModel().localTransform();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//fill cloudWithNormals
|
//fill cloudWithNormals
|
||||||
@@ -661,10 +683,11 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
cloudWithNormals,
|
cloudWithNormals,
|
||||||
_ui->doubleSpinBox_voxelSize_assembled->value());
|
_ui->doubleSpinBox_voxelSize_assembled->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
_progressDialog->appendText(tr("Update %1 normals with %2 camera views...").arg(cloudWithNormals->size()).arg(poses.size()));
|
_progressDialog->appendText(tr("Update %1 normals with %2 camera views...").arg(cloudWithNormals->size()).arg(poses.size()));
|
||||||
|
|
||||||
util3d::adjustNormalsToViewPoints(
|
util3d::adjustNormalsToViewPoints(
|
||||||
poses,
|
viewPoints,
|
||||||
rawAssembledCloud,
|
rawAssembledCloud,
|
||||||
rawCameraIndices,
|
rawCameraIndices,
|
||||||
cloudWithNormals);
|
cloudWithNormals);
|
||||||
@@ -692,6 +715,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
{
|
{
|
||||||
_progressDialog->appendText(tr("Organized fast mesh... "));
|
_progressDialog->appendText(tr("Organized fast mesh... "));
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
|
||||||
std::vector<pcl::Vertices> mergedPolygons;
|
std::vector<pcl::Vertices> mergedPolygons;
|
||||||
@@ -839,6 +863,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
{
|
{
|
||||||
_progressDialog->appendText(tr("Greedy projection triangulation... [radius=%1m]").arg(_ui->doubleSpinBox_gp3Radius->value()));
|
_progressDialog->appendText(tr("Greedy projection triangulation... [radius=%1m]").arg(_ui->doubleSpinBox_gp3Radius->value()));
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
|
QApplication::processEvents();
|
||||||
|
|
||||||
int i=0;
|
int i=0;
|
||||||
for(std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::iterator iter=cloudsWithNormals.begin();
|
for(std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::iterator iter=cloudsWithNormals.begin();
|
||||||
@@ -1018,7 +1043,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > ExportCloudsDialog::getClouds(
|
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > ExportCloudsDialog::getClouds(
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const QMap<int, Signature> & cachedSignatures,
|
const QMap<int, Signature> & cachedSignatures,
|
||||||
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
|
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
|
||||||
const ParametersMap & parameters) const
|
const ParametersMap & parameters) const
|
||||||
{
|
{
|
||||||
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
|
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
|
||||||
@@ -1065,7 +1090,22 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value());
|
// view point
|
||||||
|
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
|
||||||
|
if(d.cameraModels().size() && !d.cameraModels()[0].localTransform().isNull())
|
||||||
|
{
|
||||||
|
viewPoint[0] = d.cameraModels()[0].localTransform().x();
|
||||||
|
viewPoint[1] = d.cameraModels()[0].localTransform().y();
|
||||||
|
viewPoint[2] = d.cameraModels()[0].localTransform().z();
|
||||||
|
}
|
||||||
|
else if(!d.stereoCameraModel().localTransform().isNull())
|
||||||
|
{
|
||||||
|
viewPoint[0] = d.stereoCameraModel().localTransform().x();
|
||||||
|
viewPoint[1] = d.stereoCameraModel().localTransform().y();
|
||||||
|
viewPoint[2] = d.stereoCameraModel().localTransform().z();
|
||||||
|
}
|
||||||
|
|
||||||
|
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), viewPoint);
|
||||||
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
|
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
|
||||||
|
|
||||||
if(_ui->groupBox_subtraction->isChecked() &&
|
if(_ui->groupBox_subtraction->isChecked() &&
|
||||||
@@ -1117,15 +1157,15 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
|||||||
UERROR("Cloud %d not found in cache!", iter->first);
|
UERROR("Cloud %d not found in cache!", iter->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(uContains(createdClouds, iter->first))
|
else if(uContains(cachedClouds, iter->first))
|
||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
|
||||||
if(!_ui->groupBox_meshing->isChecked() &&
|
if(!_ui->groupBox_meshing->isChecked() &&
|
||||||
_ui->doubleSpinBox_voxelSize_assembled->value() > 0.0)
|
_ui->doubleSpinBox_voxelSize_assembled->value() > 0.0)
|
||||||
{
|
{
|
||||||
cloudWithoutNormals = util3d::voxelize(
|
cloudWithoutNormals = util3d::voxelize(
|
||||||
createdClouds.at(iter->first).first,
|
cachedClouds.at(iter->first).first,
|
||||||
createdClouds.at(iter->first).second,
|
cachedClouds.at(iter->first).second,
|
||||||
_ui->doubleSpinBox_voxelSize_assembled->value());
|
_ui->doubleSpinBox_voxelSize_assembled->value());
|
||||||
|
|
||||||
//generate indices for all points (they are all valid)
|
//generate indices for all points (they are all valid)
|
||||||
@@ -1137,12 +1177,41 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cloudWithoutNormals = createdClouds.at(iter->first).first;
|
cloudWithoutNormals = cachedClouds.at(iter->first).first;
|
||||||
indices = createdClouds.at(iter->first).second;
|
indices = cachedClouds.at(iter->first).second;
|
||||||
}
|
}
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value());
|
|
||||||
|
// view point
|
||||||
|
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
|
||||||
|
if(cachedSignatures.contains(iter->first))
|
||||||
|
{
|
||||||
|
const Signature & s = cachedSignatures.find(iter->first).value();
|
||||||
|
SensorData d = s.sensorData();
|
||||||
|
if(d.cameraModels().size() && !d.cameraModels()[0].localTransform().isNull())
|
||||||
|
{
|
||||||
|
viewPoint[0] = d.cameraModels()[0].localTransform().x();
|
||||||
|
viewPoint[1] = d.cameraModels()[0].localTransform().y();
|
||||||
|
viewPoint[2] = d.cameraModels()[0].localTransform().z();
|
||||||
|
}
|
||||||
|
else if(!d.stereoCameraModel().localTransform().isNull())
|
||||||
|
{
|
||||||
|
viewPoint[0] = d.stereoCameraModel().localTransform().x();
|
||||||
|
viewPoint[1] = d.stereoCameraModel().localTransform().y();
|
||||||
|
viewPoint[2] = d.stereoCameraModel().localTransform().z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("Cached cloud %1 is not found in cached data, the view point for normal computation will not be set (%2/%3).").arg(iter->first).arg(++i).arg(poses.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), viewPoint);
|
||||||
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
|
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("Cached cloud %1 not found. You may want to regenerate the clouds (%2/%3).").arg(iter->first).arg(++i).arg(poses.size()));
|
||||||
|
}
|
||||||
|
|
||||||
if(indices->size())
|
if(indices->size())
|
||||||
{
|
{
|
||||||
@@ -1165,8 +1234,16 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
|||||||
|
|
||||||
if(points>0)
|
if(points>0)
|
||||||
{
|
{
|
||||||
_progressDialog->appendText(tr("Generated cloud %1 with %2 points and %3 indices (%4/%5).")
|
if(_ui->groupBox_regenerate->isChecked())
|
||||||
.arg(iter->first).arg(points).arg(totalIndices).arg(++i).arg(poses.size()));
|
{
|
||||||
|
_progressDialog->appendText(tr("Generated cloud %1 with %2 points and %3 indices (%4/%5).")
|
||||||
|
.arg(iter->first).arg(points).arg(totalIndices).arg(++i).arg(poses.size()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_progressDialog->appendText(tr("Copied cloud %1 from cache with %2 points and %3 indices (%4/%5).")
|
||||||
|
.arg(iter->first).arg(points).arg(totalIndices).arg(++i).arg(poses.size()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::map<int, int> & mapIds,
|
const std::map<int, int> & mapIds,
|
||||||
const QMap<int, Signature> & cachedSignatures,
|
const QMap<int, Signature> & cachedSignatures,
|
||||||
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
|
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
|
||||||
const QString & workingDirectory,
|
const QString & workingDirectory,
|
||||||
const ParametersMap & parameters);
|
const ParametersMap & parameters);
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ public:
|
|||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::map<int, int> & mapIds,
|
const std::map<int, int> & mapIds,
|
||||||
const QMap<int, Signature> & cachedSignatures,
|
const QMap<int, Signature> & cachedSignatures,
|
||||||
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
|
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
|
||||||
const QString & workingDirectory,
|
const QString & workingDirectory,
|
||||||
const ParametersMap & parameters);
|
const ParametersMap & parameters);
|
||||||
|
|
||||||
@@ -89,13 +89,13 @@ private:
|
|||||||
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > getClouds(
|
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > getClouds(
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const QMap<int, Signature> & cachedSignatures,
|
const QMap<int, Signature> & cachedSignatures,
|
||||||
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
|
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
|
||||||
const ParametersMap & parameters) const;
|
const ParametersMap & parameters) const;
|
||||||
bool getExportedClouds(
|
bool getExportedClouds(
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::map<int, int> & mapIds,
|
const std::map<int, int> & mapIds,
|
||||||
const QMap<int, Signature> & cachedSignatures,
|
const QMap<int, Signature> & cachedSignatures,
|
||||||
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
|
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
|
||||||
const QString & workingDirectory,
|
const QString & workingDirectory,
|
||||||
const ParametersMap & parameters,
|
const ParametersMap & parameters,
|
||||||
std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds,
|
std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds,
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
|||||||
_odomImageDepthShow(false),
|
_odomImageDepthShow(false),
|
||||||
_savedMaximized(false),
|
_savedMaximized(false),
|
||||||
_waypointsIndex(0),
|
_waypointsIndex(0),
|
||||||
|
_cachedMemoryUsage(0),
|
||||||
|
_createdCloudsMemoryUsage(0),
|
||||||
_odometryCorrection(Transform::getIdentity()),
|
_odometryCorrection(Transform::getIdentity()),
|
||||||
_processingOdometry(false),
|
_processingOdometry(false),
|
||||||
_oneSecondTimer(0),
|
_oneSecondTimer(0),
|
||||||
@@ -552,6 +554,8 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
|||||||
_ui->statsToolBox->updateStat("GUI/RGB-D cloud/ms", 0.0f);
|
_ui->statsToolBox->updateStat("GUI/RGB-D cloud/ms", 0.0f);
|
||||||
_ui->statsToolBox->updateStat("GUI/RGB-D closure_view/ms", 0.0f);
|
_ui->statsToolBox->updateStat("GUI/RGB-D closure_view/ms", 0.0f);
|
||||||
_ui->statsToolBox->updateStat("GUI/Refresh stats/ms", 0.0f);
|
_ui->statsToolBox->updateStat("GUI/Refresh stats/ms", 0.0f);
|
||||||
|
_ui->statsToolBox->updateStat("GUI/Cache Data Size/MB", 0.0f);
|
||||||
|
_ui->statsToolBox->updateStat("GUI/Cache Clouds Size/MB", 0.0f);
|
||||||
|
|
||||||
this->loadFigures();
|
this->loadFigures();
|
||||||
connect(_ui->statsToolBox, SIGNAL(figuresSetupChanged()), this, SLOT(configGUIModified()));
|
connect(_ui->statsToolBox, SIGNAL(figuresSetupChanged()), this, SLOT(configGUIModified()));
|
||||||
@@ -1307,13 +1311,26 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
bool highestHypothesisIsSaved = (bool)uValue(stat.data(), Statistics::kLoopHypothesis_reactivated(), 0.0f);
|
bool highestHypothesisIsSaved = (bool)uValue(stat.data(), Statistics::kLoopHypothesis_reactivated(), 0.0f);
|
||||||
|
|
||||||
|
bool smallMovement = (bool)uValue(stat.data(), Statistics::kMemorySmall_movement(), 0.0f);
|
||||||
|
|
||||||
// update cache
|
// update cache
|
||||||
Signature signature;
|
Signature signature;
|
||||||
if(uContains(stat.getSignatures(), stat.refImageId()))
|
if(uContains(stat.getSignatures(), stat.refImageId()))
|
||||||
{
|
{
|
||||||
signature = stat.getSignatures().at(stat.refImageId());
|
signature = stat.getSignatures().at(stat.refImageId());
|
||||||
signature.sensorData().uncompressData(); // make sure data are uncompressed
|
signature.sensorData().uncompressData(); // make sure data are uncompressed
|
||||||
_cachedSignatures.insert(signature.id(), signature);
|
|
||||||
|
if(!smallMovement)
|
||||||
|
{
|
||||||
|
// keep in cache only compressed data
|
||||||
|
Signature signatureWithoutRawData = signature;
|
||||||
|
signatureWithoutRawData.sensorData().setImageRaw(cv::Mat());
|
||||||
|
signatureWithoutRawData.sensorData().setDepthOrRightRaw(cv::Mat());
|
||||||
|
signatureWithoutRawData.sensorData().setUserDataRaw(cv::Mat());
|
||||||
|
signatureWithoutRawData.sensorData().setLaserScanRaw(cv::Mat(), 0, 0);
|
||||||
|
_cachedSignatures.insert(signature.id(), signatureWithoutRawData);
|
||||||
|
_cachedMemoryUsage += signatureWithoutRawData.sensorData().getMemoryUsed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For intermediate empty nodes, keep latest image shown
|
// For intermediate empty nodes, keep latest image shown
|
||||||
@@ -1332,7 +1349,6 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
bool rehearsedSimilarity = (float)uValue(stat.data(), Statistics::kMemoryRehearsal_id(), 0.0f) != 0.0f;
|
bool rehearsedSimilarity = (float)uValue(stat.data(), Statistics::kMemoryRehearsal_id(), 0.0f) != 0.0f;
|
||||||
int proximityTimeDetections = (int)uValue(stat.data(), Statistics::kProximityTime_detections(), 0.0f);
|
int proximityTimeDetections = (int)uValue(stat.data(), Statistics::kProximityTime_detections(), 0.0f);
|
||||||
bool scanMatchingSuccess = (bool)uValue(stat.data(), Statistics::kNeighborLinkRefiningAccepted(), 0.0f);
|
bool scanMatchingSuccess = (bool)uValue(stat.data(), Statistics::kNeighborLinkRefiningAccepted(), 0.0f);
|
||||||
bool smallMovement = (bool)uValue(stat.data(), Statistics::kMemorySmall_movement(), 0.0f);
|
|
||||||
_ui->label_stats_imageNumber->setText(QString("%1 [%2]").arg(stat.refImageId()).arg(refMapId));
|
_ui->label_stats_imageNumber->setText(QString("%1 [%2]").arg(stat.refImageId()).arg(refMapId));
|
||||||
|
|
||||||
if(rehearsalMerged > 0)
|
if(rehearsalMerged > 0)
|
||||||
@@ -1437,8 +1453,9 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
QMap<int, Signature>::iterator iter = _cachedSignatures.find(shownLoopId);
|
QMap<int, Signature>::iterator iter = _cachedSignatures.find(shownLoopId);
|
||||||
if(iter != _cachedSignatures.end())
|
if(iter != _cachedSignatures.end())
|
||||||
{
|
{
|
||||||
iter.value().sensorData().uncompressData();
|
// uncompress after copy to avoid keeping uncompressed data in memory
|
||||||
loopSignature = iter.value();
|
loopSignature = iter.value();
|
||||||
|
loopSignature.sensorData().uncompressData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1764,7 +1781,11 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
if(!_preferencesDialog->isImagesKept())
|
if(!_preferencesDialog->isImagesKept())
|
||||||
{
|
{
|
||||||
_cachedSignatures.clear();
|
_cachedSignatures.clear();
|
||||||
|
_cachedMemoryUsage = 0;
|
||||||
}
|
}
|
||||||
|
_ui->statsToolBox->updateStat("GUI/Cache Data Size/MB", stat.refImageId(), _cachedMemoryUsage/(1024*1024));
|
||||||
|
_ui->statsToolBox->updateStat("GUI/Cache Clouds Size/MB", stat.refImageId(), _createdCloudsMemoryUsage/(1024*1024));
|
||||||
|
|
||||||
if(_state != kMonitoring && _state != kDetecting)
|
if(_state != kMonitoring && _state != kDetecting)
|
||||||
{
|
{
|
||||||
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
|
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
|
||||||
@@ -1889,13 +1910,13 @@ void MainWindow::updateMapCloud(
|
|||||||
_cloudViewer->setCloudOpacity(cloudName, _preferencesDialog->getCloudOpacity(0));
|
_cloudViewer->setCloudOpacity(cloudName, _preferencesDialog->getCloudOpacity(0));
|
||||||
_cloudViewer->setCloudPointSize(cloudName, _preferencesDialog->getCloudPointSize(0));
|
_cloudViewer->setCloudPointSize(cloudName, _preferencesDialog->getCloudPointSize(0));
|
||||||
}
|
}
|
||||||
else if(_createdClouds.find(iter->first) == _createdClouds.end() && _cachedSignatures.contains(iter->first))
|
else if(_cachedClouds.find(iter->first) == _cachedClouds.end() && _cachedSignatures.contains(iter->first))
|
||||||
{
|
{
|
||||||
if((_cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0)) ||
|
if((_cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0)) ||
|
||||||
_projectionLocalMaps.find(iter->first) == _projectionLocalMaps.end())
|
_projectionLocalMaps.find(iter->first) == _projectionLocalMaps.end())
|
||||||
{
|
{
|
||||||
this->createAndAddCloudToMap(iter->first, iter->second, uValue(mapIds, iter->first, -1));
|
this->createAndAddCloudToMap(iter->first, iter->second, uValue(mapIds, iter->first, -1));
|
||||||
if(_createdClouds.find(iter->first) != _createdClouds.end())
|
if(viewerClouds.contains(cloudName))
|
||||||
{
|
{
|
||||||
_cloudViewer->setCloudVisibility(cloudName.c_str(), _cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0));
|
_cloudViewer->setCloudVisibility(cloudName.c_str(), _cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0));
|
||||||
}
|
}
|
||||||
@@ -1992,8 +2013,8 @@ void MainWindow::updateMapCloud(
|
|||||||
// activate actions
|
// activate actions
|
||||||
if(_state != kMonitoring && _state != kDetecting)
|
if(_state != kMonitoring && _state != kDetecting)
|
||||||
{
|
{
|
||||||
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty());
|
_ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
|
||||||
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty());
|
_ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
|
||||||
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
|
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
|
||||||
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
|
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
|
||||||
_ui->actionView_scans->setEnabled(!_createdScans.empty());
|
_ui->actionView_scans->setEnabled(!_createdScans.empty());
|
||||||
@@ -2223,11 +2244,7 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_createdClouds.find(nodeId) != _createdClouds.end())
|
UASSERT(_cachedClouds.find(nodeId) == _cachedClouds.end());
|
||||||
{
|
|
||||||
UDEBUG("Cloud %d already created.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((!iter->sensorData().imageCompressed().empty() || !iter->sensorData().imageRaw().empty()) &&
|
if((!iter->sensorData().imageCompressed().empty() || !iter->sensorData().imageRaw().empty()) &&
|
||||||
(!iter->sensorData().depthOrRightCompressed().empty() || !iter->sensorData().depthOrRightRaw().empty()))
|
(!iter->sensorData().depthOrRightCompressed().empty() || !iter->sensorData().depthOrRightRaw().empty()))
|
||||||
@@ -2259,6 +2276,21 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
|
|||||||
indices.get(),
|
indices.get(),
|
||||||
_preferencesDialog->getAllParameters());
|
_preferencesDialog->getAllParameters());
|
||||||
|
|
||||||
|
// view point
|
||||||
|
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
|
||||||
|
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
|
||||||
|
{
|
||||||
|
viewPoint[0] = data.cameraModels()[0].localTransform().x();
|
||||||
|
viewPoint[1] = data.cameraModels()[0].localTransform().y();
|
||||||
|
viewPoint[2] = data.cameraModels()[0].localTransform().z();
|
||||||
|
}
|
||||||
|
else if(!data.stereoCameraModel().localTransform().isNull())
|
||||||
|
{
|
||||||
|
viewPoint[0] = data.stereoCameraModel().localTransform().x();
|
||||||
|
viewPoint[1] = data.stereoCameraModel().localTransform().y();
|
||||||
|
viewPoint[2] = data.stereoCameraModel().localTransform().z();
|
||||||
|
}
|
||||||
|
|
||||||
// filtering pipeline
|
// filtering pipeline
|
||||||
if(indices->size() && _preferencesDialog->getMapVoxel() > 0.0)
|
if(indices->size() && _preferencesDialog->getMapVoxel() > 0.0)
|
||||||
{
|
{
|
||||||
@@ -2353,7 +2385,7 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
|
|||||||
//normals required
|
//normals required
|
||||||
if(_preferencesDialog->getNormalKSearch() > 0)
|
if(_preferencesDialog->getNormalKSearch() > 0)
|
||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch());
|
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch(), viewPoint);
|
||||||
pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
|
pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2411,25 +2443,12 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
|
|||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output;
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output;
|
||||||
// we need to extract indices as pcl::OrganizedFastMesh doesn't take indices
|
// we need to extract indices as pcl::OrganizedFastMesh doesn't take indices
|
||||||
output = util3d::extractIndices(cloud, indices, false, true);
|
output = util3d::extractIndices(cloud, indices, false, true);
|
||||||
Eigen::Vector3f viewpoint(0.0f,0.0f,0.0f);
|
|
||||||
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
|
|
||||||
{
|
|
||||||
viewpoint[0] = data.cameraModels()[0].localTransform().x();
|
|
||||||
viewpoint[1] = data.cameraModels()[0].localTransform().y();
|
|
||||||
viewpoint[2] = data.cameraModels()[0].localTransform().z();
|
|
||||||
}
|
|
||||||
else if(!data.stereoCameraModel().localTransform().isNull())
|
|
||||||
{
|
|
||||||
viewpoint[0] = data.stereoCameraModel().localTransform().x();
|
|
||||||
viewpoint[1] = data.stereoCameraModel().localTransform().y();
|
|
||||||
viewpoint[2] = data.stereoCameraModel().localTransform().z();
|
|
||||||
}
|
|
||||||
std::vector<pcl::Vertices> polygons = util3d::organizedFastMesh(
|
std::vector<pcl::Vertices> polygons = util3d::organizedFastMesh(
|
||||||
output,
|
output,
|
||||||
_preferencesDialog->getCloudMeshingAngle(),
|
_preferencesDialog->getCloudMeshingAngle(),
|
||||||
_preferencesDialog->isCloudMeshingQuad(),
|
_preferencesDialog->isCloudMeshingQuad(),
|
||||||
_preferencesDialog->getCloudMeshingTriangleSize(),
|
_preferencesDialog->getCloudMeshingTriangleSize(),
|
||||||
viewpoint);
|
viewPoint);
|
||||||
if(polygons.size())
|
if(polygons.size())
|
||||||
{
|
{
|
||||||
// remove unused vertices to save memory
|
// remove unused vertices to save memory
|
||||||
@@ -2440,9 +2459,10 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
|
|||||||
{
|
{
|
||||||
UERROR("Adding mesh cloud %d to viewer failed!", nodeId);
|
UERROR("Adding mesh cloud %d to viewer failed!", nodeId);
|
||||||
}
|
}
|
||||||
else
|
else if(_preferencesDialog->isCloudsKept())
|
||||||
{
|
{
|
||||||
_createdClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
|
_cachedClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
|
||||||
|
_createdCloudsMemoryUsage += output->size() * sizeof(pcl::PointXYZRGB) + indices->size()*sizeof(int);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2457,7 +2477,7 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
|
|||||||
|
|
||||||
if(_preferencesDialog->getNormalKSearch() > 0 && cloudWithNormals->size() == 0)
|
if(_preferencesDialog->getNormalKSearch() > 0 && cloudWithNormals->size() == 0)
|
||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch());
|
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch(), viewPoint);
|
||||||
pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
|
pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2479,9 +2499,10 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
|
|||||||
{
|
{
|
||||||
UERROR("Adding cloud %d to viewer failed!", nodeId);
|
UERROR("Adding cloud %d to viewer failed!", nodeId);
|
||||||
}
|
}
|
||||||
else
|
else if(_preferencesDialog->isCloudsKept())
|
||||||
{
|
{
|
||||||
_createdClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
|
_cachedClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
|
||||||
|
_createdCloudsMemoryUsage += output->size() * sizeof(pcl::PointXYZRGB) + indices->size()*sizeof(int);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2491,9 +2512,10 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
|
|||||||
{
|
{
|
||||||
UERROR("Adding cloud %d to viewer failed!", nodeId);
|
UERROR("Adding cloud %d to viewer failed!", nodeId);
|
||||||
}
|
}
|
||||||
else
|
else if(_preferencesDialog->isCloudsKept())
|
||||||
{
|
{
|
||||||
_createdClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
|
_cachedClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
|
||||||
|
_createdCloudsMemoryUsage += output->size() * sizeof(pcl::PointXYZRGB) + indices->size()*sizeof(int);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2965,6 +2987,7 @@ void MainWindow::processRtabmapEvent3DMap(const rtabmap::RtabmapEvent3DMap & eve
|
|||||||
(_cachedSignatures.value(iter->first).sensorData().imageCompressed().empty() && !iter->second.sensorData().imageCompressed().empty()))
|
(_cachedSignatures.value(iter->first).sensorData().imageCompressed().empty() && !iter->second.sensorData().imageCompressed().empty()))
|
||||||
{
|
{
|
||||||
_cachedSignatures.insert(iter->first, iter->second);
|
_cachedSignatures.insert(iter->first, iter->second);
|
||||||
|
_cachedMemoryUsage += iter->second.sensorData().getMemoryUsed();
|
||||||
++addedSignatures;
|
++addedSignatures;
|
||||||
}
|
}
|
||||||
_initProgressDialog->incrementStep();
|
_initProgressDialog->incrementStep();
|
||||||
@@ -2997,6 +3020,7 @@ void MainWindow::processRtabmapEvent3DMap(const rtabmap::RtabmapEvent3DMap & eve
|
|||||||
if(!_preferencesDialog->isImagesKept())
|
if(!_preferencesDialog->isImagesKept())
|
||||||
{
|
{
|
||||||
_cachedSignatures.clear();
|
_cachedSignatures.clear();
|
||||||
|
_cachedMemoryUsage = 0;
|
||||||
}
|
}
|
||||||
if(_state != kMonitoring && _state != kDetecting)
|
if(_state != kMonitoring && _state != kDetecting)
|
||||||
{
|
{
|
||||||
@@ -4842,7 +4866,9 @@ void MainWindow::anchorCloudsToGroundTruth()
|
|||||||
void MainWindow::clearTheCache()
|
void MainWindow::clearTheCache()
|
||||||
{
|
{
|
||||||
_cachedSignatures.clear();
|
_cachedSignatures.clear();
|
||||||
_createdClouds.clear();
|
_cachedMemoryUsage = 0;
|
||||||
|
_cachedClouds.clear();
|
||||||
|
_createdCloudsMemoryUsage = 0;
|
||||||
_previousCloud.first = 0;
|
_previousCloud.first = 0;
|
||||||
_previousCloud.second.first.first.reset();
|
_previousCloud.second.first.first.reset();
|
||||||
_previousCloud.second.first.second.reset();
|
_previousCloud.second.first.second.reset();
|
||||||
@@ -5250,7 +5276,7 @@ void MainWindow::exportClouds()
|
|||||||
_ui->widget_mapVisibility->getVisiblePoses(),
|
_ui->widget_mapVisibility->getVisiblePoses(),
|
||||||
_currentMapIds,
|
_currentMapIds,
|
||||||
_cachedSignatures,
|
_cachedSignatures,
|
||||||
_createdClouds,
|
_cachedClouds,
|
||||||
_preferencesDialog->getWorkingDirectory(),
|
_preferencesDialog->getWorkingDirectory(),
|
||||||
_preferencesDialog->getAllParameters());
|
_preferencesDialog->getAllParameters());
|
||||||
}
|
}
|
||||||
@@ -5266,7 +5292,7 @@ void MainWindow::viewClouds()
|
|||||||
_currentPosesMap,
|
_currentPosesMap,
|
||||||
_currentMapIds,
|
_currentMapIds,
|
||||||
_cachedSignatures,
|
_cachedSignatures,
|
||||||
_createdClouds,
|
_cachedClouds,
|
||||||
_preferencesDialog->getWorkingDirectory(),
|
_preferencesDialog->getWorkingDirectory(),
|
||||||
_preferencesDialog->getAllParameters());
|
_preferencesDialog->getAllParameters());
|
||||||
|
|
||||||
@@ -5713,8 +5739,8 @@ void MainWindow::changeState(MainWindow::State newState)
|
|||||||
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
|
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
|
||||||
_ui->actionGenerate_map->setEnabled(false);
|
_ui->actionGenerate_map->setEnabled(false);
|
||||||
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
|
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
|
||||||
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty());
|
_ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
|
||||||
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty());
|
_ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
|
||||||
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
|
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
|
||||||
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
|
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
|
||||||
_ui->actionView_scans->setEnabled(!_createdScans.empty());
|
_ui->actionView_scans->setEnabled(!_createdScans.empty());
|
||||||
@@ -5769,8 +5795,8 @@ void MainWindow::changeState(MainWindow::State newState)
|
|||||||
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
|
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
|
||||||
_ui->actionGenerate_map->setEnabled(true);
|
_ui->actionGenerate_map->setEnabled(true);
|
||||||
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
|
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
|
||||||
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty());
|
_ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
|
||||||
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty());
|
_ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
|
||||||
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
|
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
|
||||||
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
|
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
|
||||||
_ui->actionView_scans->setEnabled(!_createdScans.empty());
|
_ui->actionView_scans->setEnabled(!_createdScans.empty());
|
||||||
@@ -5895,8 +5921,8 @@ void MainWindow::changeState(MainWindow::State newState)
|
|||||||
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
|
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
|
||||||
_ui->actionGenerate_map->setEnabled(true);
|
_ui->actionGenerate_map->setEnabled(true);
|
||||||
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
|
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
|
||||||
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty());
|
_ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
|
||||||
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty());
|
_ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
|
||||||
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
|
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
|
||||||
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
|
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
|
||||||
_ui->actionView_scans->setEnabled(!_createdScans.empty());
|
_ui->actionView_scans->setEnabled(!_createdScans.empty());
|
||||||
@@ -5959,8 +5985,8 @@ void MainWindow::changeState(MainWindow::State newState)
|
|||||||
_ui->actionPost_processing->setEnabled(_cachedSignatures.size() >= 2 && _currentPosesMap.size() >= 2 && _currentLinksMap.size() >= 1);
|
_ui->actionPost_processing->setEnabled(_cachedSignatures.size() >= 2 && _currentPosesMap.size() >= 2 && _currentLinksMap.size() >= 1);
|
||||||
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
|
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
|
||||||
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
|
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
|
||||||
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty());
|
_ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
|
||||||
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty());
|
_ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
|
||||||
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
|
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
|
||||||
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
|
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
|
||||||
_ui->actionView_scans->setEnabled(!_createdScans.empty());
|
_ui->actionView_scans->setEnabled(!_createdScans.empty());
|
||||||
|
|||||||
@@ -270,6 +270,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
|
|
||||||
// General panel
|
// General panel
|
||||||
connect(_ui->general_checkBox_imagesKept, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
connect(_ui->general_checkBox_imagesKept, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||||
|
connect(_ui->general_checkBox_cloudsKept, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||||
connect(_ui->checkBox_verticalLayoutUsed, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
connect(_ui->checkBox_verticalLayoutUsed, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||||
connect(_ui->checkBox_imageRejectedShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
connect(_ui->checkBox_imageRejectedShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||||
connect(_ui->checkBox_imageHighestHypShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
connect(_ui->checkBox_imageHighestHypShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||||
@@ -1150,6 +1151,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
|||||||
if(groupBox->objectName() == _ui->groupBox_generalSettingsGui0->objectName())
|
if(groupBox->objectName() == _ui->groupBox_generalSettingsGui0->objectName())
|
||||||
{
|
{
|
||||||
_ui->general_checkBox_imagesKept->setChecked(true);
|
_ui->general_checkBox_imagesKept->setChecked(true);
|
||||||
|
_ui->general_checkBox_cloudsKept->setChecked(true);
|
||||||
_ui->checkBox_beep->setChecked(false);
|
_ui->checkBox_beep->setChecked(false);
|
||||||
_ui->checkBox_notifyWhenNewGlobalPathIsReceived->setChecked(false);
|
_ui->checkBox_notifyWhenNewGlobalPathIsReceived->setChecked(false);
|
||||||
_ui->checkBox_verticalLayoutUsed->setChecked(true);
|
_ui->checkBox_verticalLayoutUsed->setChecked(true);
|
||||||
@@ -1448,7 +1450,9 @@ void PreferencesDialog::loadConfigFrom()
|
|||||||
QString path = QFileDialog::getOpenFileName(this, tr("Load settings..."), this->getWorkingDirectory(), "*.ini");
|
QString path = QFileDialog::getOpenFileName(this, tr("Load settings..."), this->getWorkingDirectory(), "*.ini");
|
||||||
if(!path.isEmpty())
|
if(!path.isEmpty())
|
||||||
{
|
{
|
||||||
|
_ui->checkBox_useOdomFeatures->blockSignals(true);
|
||||||
this->readSettings(path);
|
this->readSettings(path);
|
||||||
|
_ui->checkBox_useOdomFeatures->blockSignals(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1501,6 +1505,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
|
|||||||
settings.beginGroup("Gui");
|
settings.beginGroup("Gui");
|
||||||
settings.beginGroup("General");
|
settings.beginGroup("General");
|
||||||
_ui->general_checkBox_imagesKept->setChecked(settings.value("imagesKept", _ui->general_checkBox_imagesKept->isChecked()).toBool());
|
_ui->general_checkBox_imagesKept->setChecked(settings.value("imagesKept", _ui->general_checkBox_imagesKept->isChecked()).toBool());
|
||||||
|
_ui->general_checkBox_cloudsKept->setChecked(settings.value("cloudsKept", _ui->general_checkBox_cloudsKept->isChecked()).toBool());
|
||||||
_ui->comboBox_loggerLevel->setCurrentIndex(settings.value("loggerLevel", _ui->comboBox_loggerLevel->currentIndex()).toInt());
|
_ui->comboBox_loggerLevel->setCurrentIndex(settings.value("loggerLevel", _ui->comboBox_loggerLevel->currentIndex()).toInt());
|
||||||
_ui->comboBox_loggerEventLevel->setCurrentIndex(settings.value("loggerEventLevel", _ui->comboBox_loggerEventLevel->currentIndex()).toInt());
|
_ui->comboBox_loggerEventLevel->setCurrentIndex(settings.value("loggerEventLevel", _ui->comboBox_loggerEventLevel->currentIndex()).toInt());
|
||||||
_ui->comboBox_loggerPauseLevel->setCurrentIndex(settings.value("loggerPauseLevel", _ui->comboBox_loggerPauseLevel->currentIndex()).toInt());
|
_ui->comboBox_loggerPauseLevel->setCurrentIndex(settings.value("loggerPauseLevel", _ui->comboBox_loggerPauseLevel->currentIndex()).toInt());
|
||||||
@@ -1904,6 +1909,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
|
|||||||
settings.beginGroup("General");
|
settings.beginGroup("General");
|
||||||
settings.remove("");
|
settings.remove("");
|
||||||
settings.setValue("imagesKept", _ui->general_checkBox_imagesKept->isChecked());
|
settings.setValue("imagesKept", _ui->general_checkBox_imagesKept->isChecked());
|
||||||
|
settings.setValue("cloudsKept", _ui->general_checkBox_cloudsKept->isChecked());
|
||||||
settings.setValue("loggerLevel", _ui->comboBox_loggerLevel->currentIndex());
|
settings.setValue("loggerLevel", _ui->comboBox_loggerLevel->currentIndex());
|
||||||
settings.setValue("loggerEventLevel", _ui->comboBox_loggerEventLevel->currentIndex());
|
settings.setValue("loggerEventLevel", _ui->comboBox_loggerEventLevel->currentIndex());
|
||||||
settings.setValue("loggerPauseLevel", _ui->comboBox_loggerPauseLevel->currentIndex());
|
settings.setValue("loggerPauseLevel", _ui->comboBox_loggerPauseLevel->currentIndex());
|
||||||
@@ -3440,8 +3446,8 @@ void PreferencesDialog::useOdomFeatures()
|
|||||||
if(this->isVisible() && _ui->checkBox_useOdomFeatures->isChecked())
|
if(this->isVisible() && _ui->checkBox_useOdomFeatures->isChecked())
|
||||||
{
|
{
|
||||||
int r = QMessageBox::question(this, tr("Using odometry features for vocabulary..."),
|
int r = QMessageBox::question(this, tr("Using odometry features for vocabulary..."),
|
||||||
tr("Do you want to match feature parameters "
|
tr("Do you want to match vocabulary feature parameters "
|
||||||
"below with corresponding ones used for odometry?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
|
"with corresponding ones used for odometry?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
|
||||||
|
|
||||||
if(r == QMessageBox::Yes)
|
if(r == QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
@@ -4270,6 +4276,10 @@ bool PreferencesDialog::isImagesKept() const
|
|||||||
{
|
{
|
||||||
return _ui->general_checkBox_imagesKept->isChecked();
|
return _ui->general_checkBox_imagesKept->isChecked();
|
||||||
}
|
}
|
||||||
|
bool PreferencesDialog::isCloudsKept() const
|
||||||
|
{
|
||||||
|
return _ui->general_checkBox_cloudsKept->isChecked();
|
||||||
|
}
|
||||||
float PreferencesDialog::getTimeLimit() const
|
float PreferencesDialog::getTimeLimit() const
|
||||||
{
|
{
|
||||||
return _ui->general_doubleSpinBox_timeThr->value();
|
return _ui->general_doubleSpinBox_timeThr->value();
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>-847</y>
|
<y>0</y>
|
||||||
<width>686</width>
|
<width>686</width>
|
||||||
<height>2023</height>
|
<height>2023</height>
|
||||||
</rect>
|
</rect>
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_22">
|
<widget class="QWidget" name="page_22">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||||
@@ -121,14 +121,14 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_beep">
|
<widget class="QCheckBox" name="checkBox_beep">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QLabel" name="label_88">
|
<widget class="QLabel" name="label_88">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Beep! on special events (finished processing the data set, an error has occured, ...).</string>
|
<string>Beep! on special events (finished processing the data set, an error has occured, ...).</string>
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QLabel" name="label_102">
|
<widget class="QLabel" name="label_102">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Notify when a new global path is received.</string>
|
<string>Notify when a new global path is received.</string>
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_notifyWhenNewGlobalPathIsReceived">
|
<widget class="QCheckBox" name="checkBox_notifyWhenNewGlobalPathIsReceived">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
@@ -164,6 +164,29 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_313">
|
||||||
|
<property name="text">
|
||||||
|
<string>Insert created clouds in the GUI cache to avoid regenerating clouds on export.</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="0">
|
||||||
|
<widget class="QCheckBox" name="general_checkBox_cloudsKept">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|||||||
Reference in New Issue
Block a user