mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Export: added texture format option (jpg, png)
This commit is contained in:
@@ -597,7 +597,7 @@ pcl::texture_mapping::CameraVector createTextureCameras(
|
||||
cam.focal_length=modelIter->second.fx();
|
||||
cam.height=modelIter->second.imageHeight();
|
||||
cam.width=modelIter->second.imageWidth();
|
||||
cam.texture_file = uFormat("%d.png", poseIter->first);
|
||||
cam.texture_file = uFormat("%d", poseIter->first);
|
||||
cameras[oi++] = cam;
|
||||
}
|
||||
return cameras;
|
||||
@@ -654,7 +654,7 @@ pcl::TextureMesh::Ptr createTextureMesh(
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh_material.tex_file = "occluded.png";
|
||||
mesh_material.tex_file = "occluded";
|
||||
}
|
||||
|
||||
textureMesh->tex_materials[i] = mesh_material;
|
||||
|
||||
@@ -132,10 +132,12 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
||||
connect(_ui->doubleSpinBox_gp3Radius, 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, SLOT(updatePoissonOutputPolygonsAvailability()));
|
||||
connect(_ui->doubleSpinBox_transferColorRadius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->checkBox_cleanMesh, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SLOT(updateTexturingAvailability()));
|
||||
connect(_ui->comboBox_meshingTextureFormat, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
||||
|
||||
connect(_ui->checkBox_poisson_outputPolygons, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||
connect(_ui->checkBox_poisson_manifold, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||
@@ -186,6 +188,15 @@ void ExportCloudsDialog::updateTexturingAvailability(bool isExporting)
|
||||
{
|
||||
_ui->checkBox_textureMapping->setEnabled(!_ui->checkBox_assemble->isChecked() || isExporting);
|
||||
_ui->label_textureMapping->setEnabled(_ui->checkBox_textureMapping->isEnabled());
|
||||
_ui->comboBox_meshingTextureFormat->setEnabled(_ui->label_textureMapping->isEnabled());
|
||||
_ui->label_meshingTextureFormat->setEnabled(_ui->label_textureMapping->isEnabled());
|
||||
updatePoissonOutputPolygonsAvailability();
|
||||
}
|
||||
void ExportCloudsDialog::updatePoissonOutputPolygonsAvailability()
|
||||
{
|
||||
_ui->checkBox_poisson_outputPolygons->setDisabled(
|
||||
_ui->checkBox_binary->isEnabled() ||
|
||||
_ui->doubleSpinBox_meshDecimationFactor->value()!=0.0);
|
||||
}
|
||||
|
||||
void ExportCloudsDialog::cancel()
|
||||
@@ -257,6 +268,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
|
||||
settings.setValue("mesh_dense_strategy", _ui->comboBox_meshingApproach->currentIndex());
|
||||
|
||||
settings.setValue("mesh_texture", _ui->checkBox_textureMapping->isChecked());
|
||||
settings.setValue("mesh_textureFormat", _ui->comboBox_meshingTextureFormat->currentIndex());
|
||||
|
||||
settings.setValue("mesh_angle_tolerance", _ui->doubleSpinBox_mesh_angleTolerance->value());
|
||||
settings.setValue("mesh_quad", _ui->checkBox_mesh_quad->isChecked());
|
||||
@@ -342,6 +354,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
||||
_ui->comboBox_meshingApproach->setCurrentIndex(settings.value("mesh_dense_strategy", _ui->comboBox_meshingApproach->currentIndex()).toInt());
|
||||
|
||||
_ui->checkBox_textureMapping->setChecked(settings.value("mesh_texture", _ui->checkBox_textureMapping->isChecked()).toBool());
|
||||
_ui->comboBox_meshingTextureFormat->setCurrentIndex(settings.value("mesh_textureFormat", _ui->comboBox_meshingTextureFormat->currentIndex()).toInt());
|
||||
|
||||
_ui->doubleSpinBox_mesh_angleTolerance->setValue(settings.value("mesh_angle_tolerance", _ui->doubleSpinBox_mesh_angleTolerance->value()).toDouble());
|
||||
_ui->checkBox_mesh_quad->setChecked(settings.value("mesh_quad", _ui->checkBox_mesh_quad->isChecked()).toBool());
|
||||
@@ -425,6 +438,7 @@ void ExportCloudsDialog::restoreDefaults()
|
||||
_ui->comboBox_meshingApproach->setCurrentIndex(1);
|
||||
|
||||
_ui->checkBox_textureMapping->setChecked(false);
|
||||
_ui->comboBox_meshingTextureFormat->setCurrentIndex(0);
|
||||
|
||||
_ui->doubleSpinBox_mesh_angleTolerance->setValue(15.0);
|
||||
_ui->checkBox_mesh_quad->setChecked(false);
|
||||
@@ -650,13 +664,12 @@ void ExportCloudsDialog::viewClouds(
|
||||
if(!iter->second->tex_materials[i].tex_file.empty())
|
||||
{
|
||||
// absolute path
|
||||
QString fullPath = workingDirectory+QDir::separator()+prefix+QDir::separator()+QString(iter->second->tex_materials[i].tex_file.c_str());
|
||||
QString fullPath = workingDirectory+QDir::separator()+prefix+QDir::separator()+QString(iter->second->tex_materials[i].tex_file.c_str())+_ui->comboBox_meshingTextureFormat->currentText();
|
||||
if(!QFileInfo(fullPath).exists())
|
||||
{
|
||||
std::list<std::string> values = uSplit(iter->second->tex_materials[i].tex_file, '.');
|
||||
if(values.size() == 2 && uIsInteger(*values.begin(), false))
|
||||
if(uIsInteger(iter->second->tex_materials[i].tex_file, false))
|
||||
{
|
||||
int textureId = uStr2Int(*values.begin());
|
||||
int textureId = uStr2Int(iter->second->tex_materials[i].tex_file);
|
||||
UASSERT(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty());
|
||||
cv::Mat image;
|
||||
cachedSignatures.value(textureId).sensorData().uncompressDataConst(&image, 0);
|
||||
@@ -1354,7 +1367,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
else
|
||||
{
|
||||
pcl::Poisson<pcl::PointXYZRGBNormal> poisson;
|
||||
poisson.setOutputPolygons(_ui->checkBox_poisson_outputPolygons->isChecked());
|
||||
poisson.setOutputPolygons(_ui->checkBox_poisson_outputPolygons->isEnabled()?_ui->checkBox_poisson_outputPolygons->isChecked():false);
|
||||
poisson.setManifold(_ui->checkBox_poisson_manifold->isChecked());
|
||||
poisson.setSamplesPerNode(_ui->doubleSpinBox_poisson_samples->value());
|
||||
poisson.setDepth(_ui->spinBox_poisson_depth->value());
|
||||
@@ -1612,7 +1625,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
tex_name << "material_" << iter->first;
|
||||
tex_name >> mesh_material.tex_name;
|
||||
|
||||
mesh_material.tex_file = uFormat("%d.png", iter->first);
|
||||
mesh_material.tex_file = uFormat("%d", iter->first);
|
||||
textureMesh->tex_materials.push_back(mesh_material);
|
||||
}
|
||||
else
|
||||
@@ -1696,7 +1709,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
||||
{
|
||||
polygonSize = textureMesh->tex_polygons[t][0].vertices.size();
|
||||
|
||||
UASSERT(filteredCoordinates.size() == textureMesh->tex_polygons[t].size()*polygonSize);
|
||||
UASSERT_MSG(filteredCoordinates.size() == textureMesh->tex_polygons[t].size()*polygonSize, uFormat("%d vs %d (polygon size=%d)", (int)filteredCoordinates.size(), (int)textureMesh->tex_polygons[t].size(), (int)polygonSize).c_str());
|
||||
for(unsigned int i=0; i<textureMesh->tex_polygons[t].size(); ++i)
|
||||
{
|
||||
if(validPolygons.find(allPolygonsIndex) != validPolygons.end())
|
||||
@@ -2350,14 +2363,13 @@ void ExportCloudsDialog::saveTextureMeshes(
|
||||
if(!mesh->tex_materials[i].tex_file.empty())
|
||||
{
|
||||
// absolute path
|
||||
QString fullPath = QFileInfo(path).absoluteDir().absolutePath()+QDir::separator()+QFileInfo(path).baseName()+QDir::separator()+QString(mesh->tex_materials[i].tex_file.c_str());
|
||||
QString fullPath = QFileInfo(path).absoluteDir().absolutePath()+QDir::separator()+QFileInfo(path).baseName()+QDir::separator()+QString(mesh->tex_materials[i].tex_file.c_str())+_ui->comboBox_meshingTextureFormat->currentText();
|
||||
|
||||
if(!QFileInfo(fullPath).exists())
|
||||
{
|
||||
std::list<std::string> values = uSplit(mesh->tex_materials[i].tex_file, '.');
|
||||
if(values.size() == 2 && uIsInteger(*values.begin(), false))
|
||||
if(uIsInteger(mesh->tex_materials[i].tex_file, false))
|
||||
{
|
||||
int textureId = uStr2Int(*values.begin());
|
||||
int textureId = uStr2Int(mesh->tex_materials[i].tex_file);
|
||||
UASSERT(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty());
|
||||
cv::Mat image;
|
||||
cachedSignatures.value(textureId).sensorData().uncompressDataConst(&image, 0);
|
||||
@@ -2387,7 +2399,7 @@ void ExportCloudsDialog::saveTextureMeshes(
|
||||
}
|
||||
}
|
||||
// relative path
|
||||
mesh->tex_materials[i].tex_file=(QFileInfo(path).baseName()+QDir::separator()+QString(mesh->tex_materials[i].tex_file.c_str())).toStdString();
|
||||
mesh->tex_materials[i].tex_file=(QFileInfo(path).baseName()+QDir::separator()+QString(mesh->tex_materials[i].tex_file.c_str())+_ui->comboBox_meshingTextureFormat->currentText()).toStdString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2435,13 +2447,12 @@ void ExportCloudsDialog::saveTextureMeshes(
|
||||
if(!mesh->tex_materials[i].tex_file.empty())
|
||||
{
|
||||
// absolute path
|
||||
QString fullPath = path+QDir::separator()+currentPrefix+QDir::separator()+QString(mesh->tex_materials[i].tex_file.c_str());
|
||||
QString fullPath = path+QDir::separator()+currentPrefix+QDir::separator()+QString(mesh->tex_materials[i].tex_file.c_str())+_ui->comboBox_meshingTextureFormat->currentText();
|
||||
if(!QFileInfo(fullPath).exists())
|
||||
{
|
||||
std::list<std::string> values = uSplit(mesh->tex_materials[i].tex_file, '.');
|
||||
if(values.size() == 2 && uIsInteger(*values.begin(), false))
|
||||
if(uIsInteger(mesh->tex_materials[i].tex_file, false))
|
||||
{
|
||||
int textureId = uStr2Int(*values.begin());
|
||||
int textureId = uStr2Int(mesh->tex_materials[i].tex_file);
|
||||
UASSERT(cachedSignatures.contains(textureId) && !cachedSignatures.value(textureId).sensorData().imageCompressed().empty());
|
||||
cv::Mat image;
|
||||
cachedSignatures.value(textureId).sensorData().uncompressDataConst(&image, 0);
|
||||
@@ -2471,7 +2482,7 @@ void ExportCloudsDialog::saveTextureMeshes(
|
||||
}
|
||||
}
|
||||
// relative path
|
||||
mesh->tex_materials[i].tex_file=(currentPrefix+QDir::separator()+QString(mesh->tex_materials[i].tex_file.c_str())).toStdString();
|
||||
mesh->tex_materials[i].tex_file=(currentPrefix+QDir::separator()+QString(mesh->tex_materials[i].tex_file.c_str())+_ui->comboBox_meshingTextureFormat->currentText()).toStdString();
|
||||
}
|
||||
}
|
||||
pcl::PointCloud<pcl::PointNormal>::Ptr tmp(new pcl::PointCloud<pcl::PointNormal>);
|
||||
|
||||
@@ -92,6 +92,7 @@ private slots:
|
||||
void selectDistortionModel();
|
||||
void updateMLSGrpVisibility();
|
||||
void updateTexturingAvailability();
|
||||
void updatePoissonOutputPolygonsAvailability();
|
||||
void cancel();
|
||||
|
||||
private:
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<y>-1430</y>
|
||||
<width>773</width>
|
||||
<height>2728</height>
|
||||
<height>2774</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||
@@ -1105,14 +1105,14 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_15">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_10" columnstretch="0,1">
|
||||
<item row="5" column="0">
|
||||
<item row="6" column="0">
|
||||
<widget class="QSpinBox" name="spinBox_mesh_minClusterSize">
|
||||
<property name="maximum">
|
||||
<number>999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_meshDecimation">
|
||||
<property name="text">
|
||||
<string>Mesh quadric decimation factor (0=no decimation). Used to reduce the number of polygons. Higher the factor, lower the output resolution (less polygons). Can be used only when dense reconstruction flavor is selected.</string>
|
||||
@@ -1122,6 +1122,43 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_denseReconstruction">
|
||||
<property name="text">
|
||||
<string>Surface reconstruction approach. Can be used only when dense reconstruction flavor is selected. Poisson is available only when clouds are assembled.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_meshDecimation_2">
|
||||
<property name="text">
|
||||
<string>Radius used to transfer color from original cloud to resampled reconstructed surface (e.g., Poisson or mesh decimation). 0 means disabled.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_textureMapping">
|
||||
<property name="text">
|
||||
<string>Texture mapping. Images of the cameras will be projected on the mesh(es). Output is a *.obj format. Only available on Export or when clouds are not assembled.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Min polygon cluster size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_textureMapping">
|
||||
<property name="text">
|
||||
@@ -1143,27 +1180,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_denseReconstruction">
|
||||
<property name="text">
|
||||
<string>Surface reconstruction approach. Can be used only when dense reconstruction flavor is selected. Poisson is available only when clouds are assembled.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_meshDecimation_2">
|
||||
<property name="text">
|
||||
<string>Radius used to transfer color from original cloud to resampled reconstructed surface (e.g., Poisson or mesh decimation). 0 means disabled.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_transferColorRadius">
|
||||
<property name="suffix">
|
||||
<string> m</string>
|
||||
@@ -1185,7 +1202,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_meshDecimationFactor">
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
@@ -1204,24 +1221,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_textureMapping">
|
||||
<property name="text">
|
||||
<string>Texture mapping. Images of the cameras will be projected on the mesh(es). Output is a *.obj format. Only available on Export or when clouds are not assembled.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Min polygon cluster size</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_meshDecimation_3">
|
||||
<property name="text">
|
||||
<string>Clean mesh from polygons without color or texture.</string>
|
||||
@@ -1231,13 +1231,37 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="checkBox_cleanMesh">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_meshingTextureFormat">
|
||||
<property name="text">
|
||||
<string>Texture format.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QComboBox" name="comboBox_meshingTextureFormat">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>.jpg</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>.png</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -1461,9 +1485,9 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_173">
|
||||
<widget class="QLabel" name="label_outputPolygons">
|
||||
<property name="text">
|
||||
<string>Output polygons flag. Enabling this flag tells the reconstructor to output a polygon mesh (rather than triangulating of the results of Marching Cubes).</string>
|
||||
<string>Output polygons flag. Enabling this flag tells the reconstructor to output a polygon mesh (rather than triangulating of the results of Marching Cubes). Disabled when exporting to file or if mesh decimation is set.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
||||
Reference in New Issue
Block a user