Export clouds/poses: frame reference can be selected when clouds are not assembled

This commit is contained in:
matlabbe
2017-05-10 15:53:02 -04:00
parent ee04ad500a
commit 98184c31de
4 changed files with 324 additions and 170 deletions
+1
View File
@@ -326,6 +326,7 @@ private:
LoopClosureViewer * _loopClosureViewer; LoopClosureViewer * _loopClosureViewer;
QString _graphSavingFileName; QString _graphSavingFileName;
bool _exportPosesFrame;
QMap<int, QString> _exportPosesFileName; QMap<int, QString> _exportPosesFileName;
bool _autoScreenCaptureOdomSync; bool _autoScreenCaptureOdomSync;
bool _autoScreenCaptureRAM; bool _autoScreenCaptureRAM;
+70 -38
View File
@@ -115,6 +115,8 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
connect(_ui->checkBox_assemble, SIGNAL(clicked(bool)), this, SIGNAL(configChanged())); connect(_ui->checkBox_assemble, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_assemble, SIGNAL(clicked(bool)), this, SLOT(updateReconstructionFlavor())); connect(_ui->checkBox_assemble, SIGNAL(clicked(bool)), this, SLOT(updateReconstructionFlavor()));
connect(_ui->doubleSpinBox_voxelSize_assembled, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); connect(_ui->doubleSpinBox_voxelSize_assembled, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->comboBox_frame, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->comboBox_frame, SIGNAL(currentIndexChanged(int)), this, SLOT(updateReconstructionFlavor()));
connect(_ui->checkBox_subtraction, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged())); connect(_ui->checkBox_subtraction, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_subtraction, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor())); connect(_ui->checkBox_subtraction, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor()));
@@ -263,6 +265,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
settings.setValue("assemble", _ui->checkBox_assemble->isChecked()); settings.setValue("assemble", _ui->checkBox_assemble->isChecked());
settings.setValue("assemble_voxel",_ui->doubleSpinBox_voxelSize_assembled->value()); settings.setValue("assemble_voxel",_ui->doubleSpinBox_voxelSize_assembled->value());
settings.setValue("frame",_ui->comboBox_frame->currentIndex());
settings.setValue("subtract",_ui->checkBox_subtraction->isChecked()); settings.setValue("subtract",_ui->checkBox_subtraction->isChecked());
settings.setValue("subtract_point_radius",_ui->doubleSpinBox_subtractPointFilteringRadius->value()); settings.setValue("subtract_point_radius",_ui->doubleSpinBox_subtractPointFilteringRadius->value());
@@ -370,6 +373,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
_ui->checkBox_assemble->setChecked(settings.value("assemble", _ui->checkBox_assemble->isChecked()).toBool()); _ui->checkBox_assemble->setChecked(settings.value("assemble", _ui->checkBox_assemble->isChecked()).toBool());
_ui->doubleSpinBox_voxelSize_assembled->setValue(settings.value("assemble_voxel", _ui->doubleSpinBox_voxelSize_assembled->value()).toDouble()); _ui->doubleSpinBox_voxelSize_assembled->setValue(settings.value("assemble_voxel", _ui->doubleSpinBox_voxelSize_assembled->value()).toDouble());
_ui->comboBox_frame->setCurrentIndex(settings.value("frame", _ui->comboBox_frame->currentIndex()).toInt());
_ui->checkBox_subtraction->setChecked(settings.value("subtract",_ui->checkBox_subtraction->isChecked()).toBool()); _ui->checkBox_subtraction->setChecked(settings.value("subtract",_ui->checkBox_subtraction->isChecked()).toBool());
_ui->doubleSpinBox_subtractPointFilteringRadius->setValue(settings.value("subtract_point_radius",_ui->doubleSpinBox_subtractPointFilteringRadius->value()).toDouble()); _ui->doubleSpinBox_subtractPointFilteringRadius->setValue(settings.value("subtract_point_radius",_ui->doubleSpinBox_subtractPointFilteringRadius->value()).toDouble());
@@ -477,6 +481,7 @@ void ExportCloudsDialog::restoreDefaults()
_ui->checkBox_assemble->setChecked(true); _ui->checkBox_assemble->setChecked(true);
_ui->doubleSpinBox_voxelSize_assembled->setValue(0.0); _ui->doubleSpinBox_voxelSize_assembled->setValue(0.0);
_ui->comboBox_frame->setCurrentIndex(0);
_ui->checkBox_subtraction->setChecked(false); _ui->checkBox_subtraction->setChecked(false);
_ui->doubleSpinBox_subtractPointFilteringRadius->setValue(0.02); _ui->doubleSpinBox_subtractPointFilteringRadius->setValue(0.02);
@@ -558,10 +563,17 @@ void ExportCloudsDialog::updateReconstructionFlavor()
_ui->checkBox_smoothing->setVisible(_ui->comboBox_pipeline->currentIndex() == 1); _ui->checkBox_smoothing->setVisible(_ui->comboBox_pipeline->currentIndex() == 1);
_ui->checkBox_smoothing->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1); _ui->checkBox_smoothing->setEnabled(_ui->comboBox_pipeline->currentIndex() == 1);
_ui->comboBox_frame->setEnabled(!_ui->checkBox_assemble->isChecked() && _ui->checkBox_binary->isEnabled());
_ui->comboBox_frame->setVisible(_ui->comboBox_frame->isEnabled());
_ui->label_frame->setVisible(_ui->comboBox_frame->isEnabled());
_ui->checkBox_gainCompensation->setEnabled(!(_ui->comboBox_frame->isEnabled() && _ui->comboBox_frame->currentIndex() == 2));
_ui->checkBox_gainCompensation->setVisible(_ui->checkBox_gainCompensation->isEnabled());
_ui->label_gainCompensation->setVisible(_ui->checkBox_gainCompensation->isEnabled());
_ui->groupBox_regenerate->setVisible(_ui->checkBox_regenerate->isChecked()); _ui->groupBox_regenerate->setVisible(_ui->checkBox_regenerate->isChecked());
_ui->groupBox_bilateral->setVisible(_ui->checkBox_bilateral->isChecked()); _ui->groupBox_bilateral->setVisible(_ui->checkBox_bilateral->isChecked());
_ui->groupBox_filtering->setVisible(_ui->checkBox_filtering->isChecked()); _ui->groupBox_filtering->setVisible(_ui->checkBox_filtering->isChecked());
_ui->groupBox_gain->setVisible(_ui->checkBox_gainCompensation->isChecked()); _ui->groupBox_gain->setVisible(_ui->checkBox_gainCompensation->isEnabled() && _ui->checkBox_gainCompensation->isChecked());
_ui->groupBox_mls->setVisible(_ui->checkBox_smoothing->isEnabled() && _ui->checkBox_smoothing->isChecked()); _ui->groupBox_mls->setVisible(_ui->checkBox_smoothing->isEnabled() && _ui->checkBox_smoothing->isChecked());
_ui->groupBox_meshing->setVisible(_ui->checkBox_meshing->isChecked()); _ui->groupBox_meshing->setVisible(_ui->checkBox_meshing->isChecked());
_ui->groupBox_subtraction->setVisible(_ui->checkBox_subtraction->isChecked()); _ui->groupBox_subtraction->setVisible(_ui->checkBox_subtraction->isChecked());
@@ -1060,7 +1072,9 @@ bool ExportCloudsDialog::getExportedClouds(
_ui->comboBox_pipeline->currentIndex()==1 && _ui->comboBox_pipeline->currentIndex()==1 &&
_ui->checkBox_assemble->isChecked() && _ui->checkBox_assemble->isChecked() &&
_ui->comboBox_meshingTextureSize->isEnabled() && _ui->comboBox_meshingTextureSize->isEnabled() &&
_ui->comboBox_meshingTextureSize->currentIndex() > 0)) _ui->comboBox_meshingTextureSize->currentIndex() > 0) &&
// Don't do compensation if clouds are in camera frame
!(_ui->comboBox_frame->isEnabled() && _ui->comboBox_frame->currentIndex()==2))
{ {
UASSERT(_compensator == 0); UASSERT(_compensator == 0);
_compensator = new GainCompensator(_ui->doubleSpinBox_gainRadius->value(), _ui->doubleSpinBox_gainOverlap->value(), 0.01, _ui->doubleSpinBox_gainBeta->value()); _compensator = new GainCompensator(_ui->doubleSpinBox_gainRadius->value(), _ui->doubleSpinBox_gainOverlap->value(), 0.01, _ui->doubleSpinBox_gainBeta->value());
@@ -1196,7 +1210,7 @@ bool ExportCloudsDialog::getExportedClouds(
return false; return false;
} }
std::map<int, Transform> viewPoints = poses; std::map<int, Transform> mlsViewPoints = poses;
if(_ui->checkBox_smoothing->isEnabled() && _ui->checkBox_smoothing->isChecked()) if(_ui->checkBox_smoothing->isEnabled() && _ui->checkBox_smoothing->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... "
@@ -1205,29 +1219,32 @@ bool ExportCloudsDialog::getExportedClouds(
uSleep(100); uSleep(100);
QApplication::processEvents(); QApplication::processEvents();
// Adjust view points with local transforms if(_ui->checkBox_assemble->isChecked())
for(std::map<int, Transform>::iterator iter= viewPoints.begin(); iter!=viewPoints.end(); ++iter)
{ {
std::vector<CameraModel> models; // Adjust view points with local transforms
StereoCameraModel stereoModel; for(std::map<int, Transform>::iterator iter= mlsViewPoints.begin(); iter!=mlsViewPoints.end(); ++iter)
if(cachedSignatures.contains(iter->first))
{ {
const SensorData & data = cachedSignatures.find(iter->first)->sensorData(); std::vector<CameraModel> models;
models = data.cameraModels(); StereoCameraModel stereoModel;
stereoModel = data.stereoCameraModel(); if(cachedSignatures.contains(iter->first))
} {
else if(_dbDriver) const SensorData & data = cachedSignatures.find(iter->first)->sensorData();
{ models = data.cameraModels();
_dbDriver->getCalibration(iter->first, models, stereoModel); stereoModel = data.stereoCameraModel();
} }
else if(_dbDriver)
{
_dbDriver->getCalibration(iter->first, models, stereoModel);
}
if(models.size() && !models[0].localTransform().isNull()) if(models.size() && !models[0].localTransform().isNull())
{ {
iter->second *= models[0].localTransform(); iter->second *= models[0].localTransform();
} }
else if(!stereoModel.localTransform().isNull()) else if(!stereoModel.localTransform().isNull())
{ {
iter->second *= stereoModel.localTransform(); iter->second *= stereoModel.localTransform();
}
} }
} }
} }
@@ -1289,7 +1306,7 @@ bool ExportCloudsDialog::getExportedClouds(
_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(
viewPoints, mlsViewPoints,
rawAssembledCloud, rawAssembledCloud,
rawCameraIndices, rawCameraIndices,
cloudWithNormals); cloudWithNormals);
@@ -1422,17 +1439,21 @@ bool ExportCloudsDialog::getExportedClouds(
else else
#endif #endif
{ {
if(models.size() && !models[0].localTransform().isNull()) if((_ui->comboBox_frame->isEnabled() && _ui->comboBox_frame->currentIndex() != 2) ||
!iter->second->isOrganized())
{ {
viewpoint[0] = models[0].localTransform().x(); if(models.size() && !models[0].localTransform().isNull())
viewpoint[1] = models[0].localTransform().y(); {
viewpoint[2] = models[0].localTransform().z(); viewpoint[0] = models[0].localTransform().x();
} viewpoint[1] = models[0].localTransform().y();
else if(!stereoModel.localTransform().isNull()) viewpoint[2] = models[0].localTransform().z();
{ }
viewpoint[0] = stereoModel.localTransform().x(); else if(!stereoModel.localTransform().isNull())
viewpoint[1] = stereoModel.localTransform().y(); {
viewpoint[2] = stereoModel.localTransform().z(); viewpoint[0] = stereoModel.localTransform().x();
viewpoint[1] = stereoModel.localTransform().y();
viewpoint[2] = stereoModel.localTransform().z();
}
} }
std::vector<pcl::Vertices> polygons = util3d::organizedFastMesh( std::vector<pcl::Vertices> polygons = util3d::organizedFastMesh(
@@ -2184,6 +2205,7 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
{ {
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBNormal>); pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
pcl::IndicesPtr indices(new std::vector<int>); pcl::IndicesPtr indices(new std::vector<int>);
Transform localTransform = Transform::getIdentity();
if(_ui->checkBox_regenerate->isChecked()) if(_ui->checkBox_regenerate->isChecked())
{ {
SensorData data; SensorData data;
@@ -2267,12 +2289,14 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f); Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull()) if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
{ {
localTransform = data.cameraModels()[0].localTransform();
viewPoint[0] = data.cameraModels()[0].localTransform().x(); viewPoint[0] = data.cameraModels()[0].localTransform().x();
viewPoint[1] = data.cameraModels()[0].localTransform().y(); viewPoint[1] = data.cameraModels()[0].localTransform().y();
viewPoint[2] = data.cameraModels()[0].localTransform().z(); viewPoint[2] = data.cameraModels()[0].localTransform().z();
} }
else if(!data.stereoCameraModel().localTransform().isNull()) else if(!data.stereoCameraModel().localTransform().isNull())
{ {
localTransform = data.stereoCameraModel().localTransform();
viewPoint[0] = data.stereoCameraModel().localTransform().x(); viewPoint[0] = data.stereoCameraModel().localTransform().x();
viewPoint[1] = data.stereoCameraModel().localTransform().y(); viewPoint[1] = data.stereoCameraModel().localTransform().y();
viewPoint[2] = data.stereoCameraModel().localTransform().z(); viewPoint[2] = data.stereoCameraModel().localTransform().z();
@@ -2362,12 +2386,14 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
if(models.size() && !models[0].localTransform().isNull()) if(models.size() && !models[0].localTransform().isNull())
{ {
localTransform = models[0].localTransform();
viewPoint[0] = models[0].localTransform().x(); viewPoint[0] = models[0].localTransform().x();
viewPoint[1] = models[0].localTransform().y(); viewPoint[1] = models[0].localTransform().y();
viewPoint[2] = models[0].localTransform().z(); viewPoint[2] = models[0].localTransform().z();
} }
else if(!stereoModel.localTransform().isNull()) else if(!stereoModel.localTransform().isNull())
{ {
localTransform = stereoModel.localTransform();
viewPoint[0] = stereoModel.localTransform().x(); viewPoint[0] = stereoModel.localTransform().x();
viewPoint[1] = stereoModel.localTransform().y(); viewPoint[1] = stereoModel.localTransform().y();
viewPoint[2] = stereoModel.localTransform().z(); viewPoint[2] = stereoModel.localTransform().z();
@@ -2393,6 +2419,12 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
{ {
indices = util3d::radiusFiltering(cloud, indices, _ui->doubleSpinBox_filteringRadius->value(), _ui->spinBox_filteringMinNeighbors->value()); indices = util3d::radiusFiltering(cloud, indices, _ui->doubleSpinBox_filteringRadius->value(), _ui->spinBox_filteringMinNeighbors->value());
} }
if((_ui->comboBox_frame->isEnabled() && _ui->comboBox_frame->currentIndex()==2) && cloud->isOrganized())
{
cloud = util3d::transformPointCloud(cloud, localTransform.inverse()); // put back in camera frame
}
clouds.insert(std::make_pair(iter->first, std::make_pair(cloud, indices))); clouds.insert(std::make_pair(iter->first, std::make_pair(cloud, indices)));
points = (int)cloud->size(); points = (int)cloud->size();
totalIndices = (int)indices->size(); totalIndices = (int)indices->size();
@@ -2502,7 +2534,7 @@ void ExportCloudsDialog::saveClouds(
if(iter->second->size()) if(iter->second->size())
{ {
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr transformedCloud; pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr transformedCloud;
transformedCloud = util3d::transformPointCloud(iter->second, poses.at(iter->first)); transformedCloud = util3d::transformPointCloud(iter->second, !_ui->comboBox_frame->isEnabled()||_ui->comboBox_frame->currentIndex()==0?poses.at(iter->first):Transform::getIdentity());
QString pathFile = path+QDir::separator()+QString("%1%2.%3").arg(prefix).arg(iter->first).arg(suffix); QString pathFile = path+QDir::separator()+QString("%1%2.%3").arg(prefix).arg(iter->first).arg(suffix);
bool success =false; bool success =false;
@@ -2642,14 +2674,14 @@ void ExportCloudsDialog::saveMeshes(
{ {
pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp(new pcl::PointCloud<pcl::PointXYZRGB>); pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmp(new pcl::PointCloud<pcl::PointXYZRGB>);
pcl::fromPCLPointCloud2(iter->second->cloud, *tmp); pcl::fromPCLPointCloud2(iter->second->cloud, *tmp);
tmp = util3d::transformPointCloud(tmp, poses.at(iter->first)); tmp = util3d::transformPointCloud(tmp, !_ui->comboBox_frame->isEnabled()||_ui->comboBox_frame->currentIndex()==0?poses.at(iter->first):Transform::getIdentity());
pcl::toPCLPointCloud2(*tmp, mesh.cloud); pcl::toPCLPointCloud2(*tmp, mesh.cloud);
} }
else else
{ {
pcl::PointCloud<pcl::PointXYZ>::Ptr tmp(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr tmp(new pcl::PointCloud<pcl::PointXYZ>);
pcl::fromPCLPointCloud2(iter->second->cloud, *tmp); pcl::fromPCLPointCloud2(iter->second->cloud, *tmp);
tmp = util3d::transformPointCloud(tmp, poses.at(iter->first)); tmp = util3d::transformPointCloud(tmp, !_ui->comboBox_frame->isEnabled()||_ui->comboBox_frame->currentIndex()==0?poses.at(iter->first):Transform::getIdentity());
pcl::toPCLPointCloud2(*tmp, mesh.cloud); pcl::toPCLPointCloud2(*tmp, mesh.cloud);
} }
@@ -3564,7 +3596,7 @@ void ExportCloudsDialog::saveTextureMeshes(
} }
pcl::PointCloud<pcl::PointNormal>::Ptr tmp(new pcl::PointCloud<pcl::PointNormal>); pcl::PointCloud<pcl::PointNormal>::Ptr tmp(new pcl::PointCloud<pcl::PointNormal>);
pcl::fromPCLPointCloud2(mesh->cloud, *tmp); pcl::fromPCLPointCloud2(mesh->cloud, *tmp);
tmp = util3d::transformPointCloud(tmp, poses.at(iter->first)); tmp = util3d::transformPointCloud(tmp, !_ui->comboBox_frame->isEnabled()||_ui->comboBox_frame->currentIndex()==0?poses.at(iter->first):Transform::getIdentity());
pcl::toPCLPointCloud2(*tmp, mesh->cloud); pcl::toPCLPointCloud2(*tmp, mesh->cloud);
QString pathFile = path+QDir::separator()+QString("%1.%3").arg(currentPrefix).arg(suffix); QString pathFile = path+QDir::separator()+QString("%1.%3").arg(currentPrefix).arg(suffix);
+96 -4
View File
@@ -163,6 +163,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
_posteriorCurve(0), _posteriorCurve(0),
_likelihoodCurve(0), _likelihoodCurve(0),
_rawLikelihoodCurve(0), _rawLikelihoodCurve(0),
_exportPosesFrame(0),
_autoScreenCaptureOdomSync(false), _autoScreenCaptureOdomSync(false),
_autoScreenCaptureRAM(false), _autoScreenCaptureRAM(false),
_firstCall(true), _firstCall(true),
@@ -4737,20 +4738,94 @@ void MainWindow::exportPoses(int format)
{ {
if(_currentPosesMap.size()) if(_currentPosesMap.size())
{ {
std::map<int, Transform> poses;
QStringList items;
items.push_back("Robot");
items.push_back("Camera");
items.push_back("Scan");
QString item = QInputDialog::getItem(this, tr("Export Poses"), tr("Frame: "), items, _exportPosesFrame, false);
if(item.isEmpty())
{
return;
}
if(item.compare("Robot") != 0)
{
bool cameraFrame = item.compare("Camera") == 0;
_exportPosesFrame = cameraFrame?1:2;
for(std::map<int, Transform>::iterator iter=_currentPosesMap.begin(); iter!=_currentPosesMap.end(); ++iter)
{
if(_cachedSignatures.contains(iter->first))
{
Transform localTransform;
if(cameraFrame)
{
if((_cachedSignatures[iter->first].sensorData().cameraModels().size() == 1 &&
!_cachedSignatures[iter->first].sensorData().cameraModels().at(0).localTransform().isNull()))
{
localTransform = _cachedSignatures[iter->first].sensorData().cameraModels().at(0).localTransform();
}
else if(!_cachedSignatures[iter->first].sensorData().stereoCameraModel().localTransform().isNull())
{
localTransform = _cachedSignatures[iter->first].sensorData().stereoCameraModel().localTransform();
}
else if(_cachedSignatures[iter->first].sensorData().cameraModels().size()>1)
{
UWARN("Multi-camera is not supported (node %d)", iter->first);
}
else
{
UWARN("Missing calibration for node %d", iter->first);
}
}
else
{
if(!_cachedSignatures[iter->first].sensorData().laserScanInfo().localTransform().isNull())
{
localTransform = _cachedSignatures[iter->first].sensorData().laserScanInfo().localTransform();
}
else
{
UWARN("Missing scan info for node %d", iter->first);
}
}
if(!localTransform.isNull())
{
poses.insert(std::make_pair(iter->first, iter->second * localTransform));
}
}
else
{
UWARN("Did not find node %d in cache", iter->first);
}
}
if(poses.empty())
{
QMessageBox::warning(this,
tr("Export Poses"),
tr("Could not find any \"%1\" frame, exporting in Robot frame instead.").arg(item));
poses = _currentPosesMap;
}
}
else
{
_exportPosesFrame = 0;
poses = _currentPosesMap;
}
std::map<int, double> stamps; std::map<int, double> stamps;
if(format == 1) if(format == 1)
{ {
for(std::map<int, Transform>::iterator iter=_currentPosesMap.begin(); iter!=_currentPosesMap.end(); ++iter) for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
{ {
if(_cachedSignatures.contains(iter->first)) if(_cachedSignatures.contains(iter->first))
{ {
stamps.insert(std::make_pair(iter->first, _cachedSignatures.value(iter->first).getStamp())); stamps.insert(std::make_pair(iter->first, _cachedSignatures.value(iter->first).getStamp()));
} }
} }
if(stamps.size()!=_currentPosesMap.size()) if(stamps.size()!=poses.size())
{ {
QMessageBox::warning(this, tr("Export poses..."), tr("RGB-D SLAM format: Poses (%1) and stamps (%2) have not the same size! Try again after updating the cache.") QMessageBox::warning(this, tr("Export poses..."), tr("RGB-D SLAM format: Poses (%1) and stamps (%2) have not the same size! Try again after updating the cache.")
.arg(_currentPosesMap.size()).arg(stamps.size())); .arg(poses.size()).arg(stamps.size()));
return; return;
} }
} }
@@ -4770,7 +4845,24 @@ void MainWindow::exportPoses(int format)
{ {
_exportPosesFileName[format] = path; _exportPosesFileName[format] = path;
bool saved = graph::exportPoses(path.toStdString(), format, _currentPosesMap, _currentLinksMap, stamps); std::multimap<int, Link> links;
if(poses.size() != _currentPosesMap.size())
{
for(std::multimap<int, Link>::iterator iter=_currentLinksMap.begin(); iter!=_currentLinksMap.end(); ++iter)
{
if(uContains(poses, iter->second.from()) && uContains(poses, iter->second.to()))
{
links.insert(*iter);
}
}
}
else
{
links = _currentLinksMap;
}
bool saved = graph::exportPoses(path.toStdString(), format, poses, links, stamps);
if(saved) if(saved)
{ {
+157 -128
View File
@@ -23,89 +23,25 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>-3080</y> <y>0</y>
<width>778</width> <width>773</width>
<height>3701</height> <height>3795</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_13"> <layout class="QVBoxLayout" name="verticalLayout_13">
<item> <item>
<layout class="QGridLayout" name="gridLayout_8" columnstretch="0,1"> <layout class="QGridLayout" name="gridLayout_8" columnstretch="0,1">
<item row="2" column="0"> <item row="10" column="1">
<widget class="QCheckBox" name="checkBox_assemble"> <widget class="QLabel" name="label_binaryFile_12">
<property name="text"> <property name="text">
<string/> <string>Meshing.</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_binaryFile_2">
<property name="text">
<string>Assemble clouds/meshes to a single output cloud/mesh.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_binary">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_normal">
<property name="text">
<string>Set the number of k nearest neighbors to use for the normal estimation.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QCheckBox" name="checkBox_gainCompensation">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="1"> <item row="5" column="1">
<widget class="QLabel" name="label_binaryFile_8">
<property name="text">
<string>Regenerate clouds. This can be used to regenerate the point clouds at higher density than those used for online visualization.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="label_binaryFile_11">
<property name="text">
<string>Gain compensation. Normalize brightness of images.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QSpinBox" name="spinBox_normalKSearch">
<property name="minimum">
<number>3</number>
</property>
<property name="value">
<number>20</number>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_voxel"> <widget class="QLabel" name="label_voxel">
<property name="text"> <property name="text">
<string>Voxel size. Set 0 to disable. When organized meshes are assembled, this is the radius in which the vertices of the polygons are merged.</string> <string>Voxel size. Set 0 to disable. When organized meshes are assembled, this is the radius in which the vertices of the polygons are merged.</string>
@@ -115,38 +51,65 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="4" column="0">
<widget class="QLabel" name="label_binaryFile"> <widget class="QSpinBox" name="spinBox_normalKSearch">
<property name="minimum">
<number>3</number>
</property>
<property name="value">
<number>20</number>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QCheckBox" name="checkBox_meshing">
<property name="text"> <property name="text">
<string>Binary file.</string> <string/>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="label_binaryFile_9">
<property name="text">
<string>Cloud filtering. Remove sparse points that are far from surfaces.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="8" column="0">
<widget class="QComboBox" name="comboBox_pipeline"> <widget class="QCheckBox" name="checkBox_smoothing">
<item>
<property name="text">
<string>Organized Point Cloud</string>
</property>
</item>
<item>
<property name="text">
<string>Dense Point Cloud</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_12">
<property name="text"> <property name="text">
<string>Reconstruction flavor.</string> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="7" column="0">
<widget class="QCheckBox" name="checkBox_filtering">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_regenerate">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="label_binaryFile_10">
<property name="text">
<string>Cloud smoothing using Moving Least Squares algorithm (MLS).</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSize_assembled"> <widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSize_assembled">
<property name="suffix"> <property name="suffix">
<string> m</string> <string> m</string>
@@ -165,51 +128,41 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="0" column="1">
<widget class="QLabel" name="label_binaryFile_10"> <widget class="QLabel" name="label_12">
<property name="text"> <property name="text">
<string>Cloud smoothing using Moving Least Squares algorithm (MLS).</string> <string>Reconstruction flavor.</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="comboBox_pipeline">
<item>
<property name="text">
<string>Organized Point Cloud</string>
</property>
</item>
<item>
<property name="text">
<string>Dense Point Cloud</string>
</property>
</item>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_binaryFile">
<property name="text">
<string>Binary file.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item row="5" column="0">
<widget class="QCheckBox" name="checkBox_regenerate">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_filtering">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="checkBox_smoothing">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="1"> <item row="6" column="1">
<widget class="QLabel" name="label_binaryFile_9"> <widget class="QLabel" name="label_binaryFile_8">
<property name="text"> <property name="text">
<string>Cloud filtering. Remove sparse points that are far from surfaces.</string> <string>Regenerate clouds. This can be used to regenerate the point clouds at higher density than those used for online visualization.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="label_binaryFile_12">
<property name="text">
<string>Meshing.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>
@@ -217,12 +170,88 @@
</widget> </widget>
</item> </item>
<item row="9" column="0"> <item row="9" column="0">
<widget class="QCheckBox" name="checkBox_meshing"> <widget class="QCheckBox" name="checkBox_gainCompensation">
<property name="text"> <property name="text">
<string/> <string/>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1">
<widget class="QLabel" name="label_normal">
<property name="text">
<string>Set the number of k nearest neighbors to use for the normal estimation.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_binary">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_binaryFile_2">
<property name="text">
<string>Assemble clouds/meshes to a single output cloud/mesh.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBox_assemble">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="label_gainCompensation">
<property name="text">
<string>Gain compensation. Normalize brightness of images.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_frame">
<property name="text">
<string>Output frame.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QComboBox" name="comboBox_frame">
<item>
<property name="text">
<string>Map</string>
</property>
</item>
<item>
<property name="text">
<string>Robot</string>
</property>
</item>
<item>
<property name="text">
<string>Camera</string>
</property>
</item>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>