Export: added texture format option (jpg, png)

This commit is contained in:
matlabbe
2017-01-17 14:57:50 -05:00
parent 4c7d46c8a0
commit 0a98df922e
4 changed files with 101 additions and 65 deletions

View File

@@ -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;

View File

@@ -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>);

View File

@@ -92,6 +92,7 @@ private slots:
void selectDistortionModel();
void updateMLSGrpVisibility();
void updateTexturingAvailability();
void updatePoissonOutputPolygonsAvailability();
void cancel();
private:

View File

@@ -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>