Added more options for multiband texturing

This commit is contained in:
matlabbe
2021-08-16 13:14:02 -04:00
parent 6fb553a5e7
commit ed68fe777b
5 changed files with 436 additions and 21 deletions

View File

@@ -253,7 +253,7 @@ cv::Mat RTABMAP_EXP mergeTextures(
void RTABMAP_EXP fixTextureMeshForVisualization(pcl::TextureMesh & textureMesh); void RTABMAP_EXP fixTextureMeshForVisualization(pcl::TextureMesh & textureMesh);
bool RTABMAP_EXP multiBandTexturing( RTABMAP_DEPRECATED(bool RTABMAP_EXP multiBandTexturing(
const std::string & outputOBJPath, const std::string & outputOBJPath,
const pcl::PCLPointCloud2 & cloud, const pcl::PCLPointCloud2 & cloud,
const std::vector<pcl::Vertices> & polygons, const std::vector<pcl::Vertices> & polygons,
@@ -268,7 +268,56 @@ bool RTABMAP_EXP multiBandTexturing(
const std::map<int, std::map<int, cv::Vec4d> > & gains = std::map<int, std::map<int, cv::Vec4d> >(), // optional output of util3d::mergeTextures() const std::map<int, std::map<int, cv::Vec4d> > & gains = std::map<int, std::map<int, cv::Vec4d> >(), // optional output of util3d::mergeTextures()
const std::map<int, std::map<int, cv::Mat> > & blendingGains = std::map<int, std::map<int, cv::Mat> >(), // optional output of util3d::mergeTextures() const std::map<int, std::map<int, cv::Mat> > & blendingGains = std::map<int, std::map<int, cv::Mat> >(), // optional output of util3d::mergeTextures()
const std::pair<float, float> & contrastValues = std::pair<float, float>(0,0), // optional output of util3d::mergeTextures() const std::pair<float, float> & contrastValues = std::pair<float, float>(0,0), // optional output of util3d::mergeTextures()
bool gainRGB = true); bool gainRGB = true), "Use the same method with 22 parameters instead.");
/**
* Texture mesh with AliceVision's multiband texturing approach. See also https://meshroom-manual.readthedocs.io/en/bibtex1/node-reference/nodes/Texturing.html.
* @param outputOBJPath Output OBJ path
* @param cloud input Cloud of the mesh.
* @param polygons Input polygons of the mesh.
* @param cameraPoses Poses of the cameras.
* @param vertexToPixels Output from {@link #createTextureMesh()}.
* @param images Images corresponding to cameraPoses, raw or compressed, can be empty if memory or dbDriver should be used.
* @param cameraModels Camera calibrations corresponding to cameraPoses.
* @param memory Should be set if images and dbDriver are not set.
* @param dbDriver Should be set if images and memory are not set.
* @param textureSize Output texture size 1024, 2048, 4096, 8192, 16384.
* @param textureDownscale Downscaling to 4 or 8 will reduce the texture quality but speed up the computation time. Set Texture Downscale to 1 instead of 2 to get the maximum possible resolution with the resolution of your images. The output texture size will be divided by this value, e.g., with texture size of 8192 and downscale value of 2, the output will be 4096.
* @param textureFormat Output texture format: "png" or "jpg".
* @param gains Optional output of {@link #mergeTextures()}.
* @param blendingGains Optional output of {@link #mergeTextures()}.
* @param contrastValues Optional output of {@link #mergeTextures()}.
* @param gainRGB Apply gain compensation on each RGB channels separately, otherwise it is apply equally to all channels.
* @param unwrapMethod Method to unwrap input mesh if it does not have UV coordinates Basic (> 600k faces) fast and simple. Can generate multiple atlases LSCM (<= 600k faces): optimize space. Generates one atlas ABF (<= 300k faces): optimize space and stretch. Generates one atlas.
* @param fillHoles Fill Texture holes with plausible values True/False.
* @param padding Texture edge padding size in pixel (0-100).
* @param bestScoreThreshold 0.0 to disable filtering based on threshold to relative best score (0.0-1.0).
* @param angleHardThreshold 0.0 to disable angle hard threshold filtering (0.0, 180.0).
* @param forceVisibleByAllVertices Triangle visibility is based on the union of vertices visibility.
*/
bool RTABMAP_EXP multiBandTexturing(
const std::string & outputOBJPath,
const pcl::PCLPointCloud2 & cloud,
const std::vector<pcl::Vertices> & polygons,
const std::map<int, Transform> & cameraPoses,
const std::vector<std::map<int, pcl::PointXY> > & vertexToPixels,
const std::map<int, cv::Mat> & images,
const std::map<int, std::vector<CameraModel> > & cameraModels,
const Memory * memory = 0,
const DBDriver * dbDriver = 0,
unsigned int textureSize = 8192,
unsigned int textureDownscale = 2,
const std::string & textureFormat = "jpg",
const std::map<int, std::map<int, cv::Vec4d> > & gains = std::map<int, std::map<int, cv::Vec4d> >(),
const std::map<int, std::map<int, cv::Mat> > & blendingGains = std::map<int, std::map<int, cv::Mat> >(),
const std::pair<float, float> & contrastValues = std::pair<float, float>(0,0),
bool gainRGB = true,
unsigned int unwrapMethod = 0,
bool fillHoles = false,
unsigned int padding = 5,
double bestScoreThreshold = 0.1,
double angleHardThreshold = 90.0,
bool forceVisibleByAllVertices = false);
cv::Mat RTABMAP_EXP computeNormals( cv::Mat RTABMAP_EXP computeNormals(
const cv::Mat & laserScan, const cv::Mat & laserScan,

View File

@@ -2231,6 +2231,50 @@ bool multiBandTexturing(
const std::pair<float, float> & contrastValues, // optional output of util3d::mergeTextures() const std::pair<float, float> & contrastValues, // optional output of util3d::mergeTextures()
bool gainRGB) bool gainRGB)
{ {
return multiBandTexturing(
outputOBJPath,
cloud,
polygons,
cameraPoses,
vertexToPixels,
images,
cameraModels,
memory,
dbDriver,
textureSize,
2,
textureFormat,
gains,
blendingGains,
contrastValues,
gainRGB);
}
bool multiBandTexturing(
const std::string & outputOBJPath,
const pcl::PCLPointCloud2 & cloud,
const std::vector<pcl::Vertices> & polygons,
const std::map<int, Transform> & cameraPoses,
const std::vector<std::map<int, pcl::PointXY> > & vertexToPixels,
const std::map<int, cv::Mat> & images,
const std::map<int, std::vector<CameraModel> > & cameraModels,
const Memory * memory,
const DBDriver * dbDriver,
unsigned int textureSize,
unsigned int textureDownScale,
const std::string & textureFormat,
const std::map<int, std::map<int, cv::Vec4d> > & gains,
const std::map<int, std::map<int, cv::Mat> > & blendingGains,
const std::pair<float, float> & contrastValues,
bool gainRGB,
unsigned int unwrapMethod,
bool fillHoles,
unsigned int padding,
double bestScoreThreshold,
double angleHardThreshold,
bool forceVisibleByAllVertices)
{
#ifdef RTABMAP_ALICE_VISION #ifdef RTABMAP_ALICE_VISION
if(ULogger::level() == ULogger::kDebug) if(ULogger::level() == ULogger::kDebug)
{ {
@@ -2265,8 +2309,14 @@ bool multiBandTexturing(
texturing.pointsVisibilities = new mesh::PointsVisibility(); texturing.pointsVisibilities = new mesh::PointsVisibility();
texturing.pointsVisibilities->reserve(cloud2.size()); texturing.pointsVisibilities->reserve(cloud2.size());
#endif #endif
texturing.texParams.textureSide = 8192; texturing.texParams.textureSide = textureSize;
texturing.texParams.downscale = 8192/textureSize; texturing.texParams.downscale = textureDownScale;
texturing.texParams.padding = padding;
texturing.texParams.fillHoles = fillHoles;
texturing.texParams.bestScoreThreshold = bestScoreThreshold;
texturing.texParams.angleHardThreshold = angleHardThreshold;
texturing.texParams.forceVisibleByAllVertices = forceVisibleByAllVertices;
for(size_t i=0;i<cloud2.size();++i) for(size_t i=0;i<cloud2.size();++i)
{ {
@@ -2457,7 +2507,7 @@ bool multiBandTexturing(
mvsUtils::MultiViewParams mp(sfmData); mvsUtils::MultiViewParams mp(sfmData);
UINFO("Unwrapping..."); UINFO("Unwrapping...");
texturing.unwrap(mp, mesh::EUnwrapMethod::Basic); texturing.unwrap(mp, (mesh::EUnwrapMethod)unwrapMethod);
UINFO("Unwrapping done. %fs", timer.ticks()); UINFO("Unwrapping done. %fs", timer.ticks());
// save final obj file // save final obj file

View File

@@ -230,6 +230,15 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
connect(_ui->doubleSpinBox_cameraFilterVel, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); connect(_ui->doubleSpinBox_cameraFilterVel, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_cameraFilterVelRad, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); connect(_ui->doubleSpinBox_cameraFilterVelRad, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_laplacianVariance, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged())); connect(_ui->doubleSpinBox_laplacianVariance, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_multiband, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_multiband, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor()));
connect(_ui->spinBox_multiband_downscale, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->comboBox_multiband_unwrap, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_multiband_fillholes, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->spinBox_multiband_padding, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_multiband_bestscore, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_multiband_angle, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_multiband_forcevisible, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
connect(_ui->checkBox_poisson_outputPolygons, SIGNAL(stateChanged(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())); connect(_ui->checkBox_poisson_manifold, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
@@ -440,6 +449,13 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
settings.setValue("mesh_textureBlending", _ui->checkBox_blending->isChecked()); settings.setValue("mesh_textureBlending", _ui->checkBox_blending->isChecked());
settings.setValue("mesh_textureBlendingDecimation", _ui->comboBox_blendingDecimation->currentIndex()); settings.setValue("mesh_textureBlendingDecimation", _ui->comboBox_blendingDecimation->currentIndex());
settings.setValue("mesh_textureMultiband", _ui->checkBox_multiband->isChecked()); settings.setValue("mesh_textureMultiband", _ui->checkBox_multiband->isChecked());
settings.setValue("mesh_textureMultibandDownScale", _ui->spinBox_multiband_downscale->value());
settings.setValue("mesh_textureMultibandUnwrap", _ui->comboBox_multiband_unwrap->currentIndex());
settings.setValue("mesh_textureMultibandFillHoles", _ui->checkBox_multiband_fillholes->isChecked());
settings.setValue("mesh_textureMultibandPadding", _ui->spinBox_multiband_padding->value());
settings.setValue("mesh_textureMultibandBestScoreThr", _ui->doubleSpinBox_multiband_bestscore->value());
settings.setValue("mesh_textureMultibandAngleHardThr", _ui->doubleSpinBox_multiband_angle->value());
settings.setValue("mesh_textureMultibandForceVisible", _ui->checkBox_multiband_forcevisible->isChecked());
settings.setValue("mesh_angle_tolerance", _ui->doubleSpinBox_mesh_angleTolerance->value()); settings.setValue("mesh_angle_tolerance", _ui->doubleSpinBox_mesh_angleTolerance->value());
@@ -607,6 +623,13 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
_ui->checkBox_blending->setChecked(settings.value("mesh_textureBlending", _ui->checkBox_blending->isChecked()).toBool()); _ui->checkBox_blending->setChecked(settings.value("mesh_textureBlending", _ui->checkBox_blending->isChecked()).toBool());
_ui->comboBox_blendingDecimation->setCurrentIndex(settings.value("mesh_textureBlendingDecimation", _ui->comboBox_blendingDecimation->currentIndex()).toInt()); _ui->comboBox_blendingDecimation->setCurrentIndex(settings.value("mesh_textureBlendingDecimation", _ui->comboBox_blendingDecimation->currentIndex()).toInt());
_ui->checkBox_multiband->setChecked(settings.value("mesh_textureMultiband", _ui->checkBox_multiband->isChecked()).toBool()); _ui->checkBox_multiband->setChecked(settings.value("mesh_textureMultiband", _ui->checkBox_multiband->isChecked()).toBool());
_ui->spinBox_multiband_downscale->setValue(settings.value("mesh_textureMultibandDownScale", _ui->spinBox_multiband_downscale->value()).toInt());
_ui->comboBox_multiband_unwrap->setCurrentIndex(settings.value("mesh_textureMultibandUnwrap", _ui->comboBox_multiband_unwrap->currentIndex()).toInt());
_ui->checkBox_multiband_fillholes->setChecked(settings.value("mesh_textureMultibandFillHoles", _ui->checkBox_multiband_fillholes->isChecked()).toBool());
_ui->spinBox_multiband_padding->setValue(settings.value("mesh_textureMultibandPadding", _ui->spinBox_multiband_padding->value()).toInt());
_ui->doubleSpinBox_multiband_bestscore->setValue(settings.value("mesh_textureMultibandBestScoreThr", _ui->doubleSpinBox_multiband_bestscore->value()).toDouble());
_ui->doubleSpinBox_multiband_angle->setValue(settings.value("mesh_textureMultibandAngleHardThr", _ui->doubleSpinBox_multiband_angle->value()).toDouble());
_ui->checkBox_multiband_forcevisible->setChecked(settings.value("mesh_textureMultibandForceVisible", _ui->checkBox_multiband_forcevisible->isChecked()).toBool());
_ui->doubleSpinBox_mesh_angleTolerance->setValue(settings.value("mesh_angle_tolerance", _ui->doubleSpinBox_mesh_angleTolerance->value()).toDouble()); _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()); _ui->checkBox_mesh_quad->setChecked(settings.value("mesh_quad", _ui->checkBox_mesh_quad->isChecked()).toBool());
@@ -745,7 +768,7 @@ void ExportCloudsDialog::restoreDefaults()
_ui->checkBox_textureMapping->setChecked(false); _ui->checkBox_textureMapping->setChecked(false);
_ui->comboBox_meshingTextureFormat->setCurrentIndex(0); _ui->comboBox_meshingTextureFormat->setCurrentIndex(0);
_ui->comboBox_meshingTextureSize->setCurrentIndex(5); // 4096 _ui->comboBox_meshingTextureSize->setCurrentIndex(6); // 8192
_ui->spinBox_mesh_maxTextures->setValue(1); _ui->spinBox_mesh_maxTextures->setValue(1);
_ui->doubleSpinBox_meshingTextureMaxDistance->setValue(3.0); _ui->doubleSpinBox_meshingTextureMaxDistance->setValue(3.0);
_ui->doubleSpinBox_meshingTextureMaxDepthError->setValue(0.0); _ui->doubleSpinBox_meshingTextureMaxDepthError->setValue(0.0);
@@ -765,6 +788,14 @@ void ExportCloudsDialog::restoreDefaults()
_ui->checkBox_blending->setChecked(true); _ui->checkBox_blending->setChecked(true);
_ui->comboBox_blendingDecimation->setCurrentIndex(0); _ui->comboBox_blendingDecimation->setCurrentIndex(0);
_ui->checkBox_multiband->setChecked(false); _ui->checkBox_multiband->setChecked(false);
_ui->spinBox_multiband_downscale->setValue(2);
_ui->comboBox_multiband_unwrap->setCurrentIndex(0);
_ui->checkBox_multiband_fillholes->setChecked(false);
_ui->spinBox_multiband_padding->setValue(5);
_ui->doubleSpinBox_multiband_bestscore->setValue(0.1);
_ui->doubleSpinBox_multiband_angle->setValue(90.0);
_ui->checkBox_multiband_forcevisible->setChecked(false);
_ui->doubleSpinBox_mesh_angleTolerance->setValue(15.0); _ui->doubleSpinBox_mesh_angleTolerance->setValue(15.0);
_ui->checkBox_mesh_quad->setChecked(false); _ui->checkBox_mesh_quad->setChecked(false);
@@ -891,6 +922,7 @@ void ExportCloudsDialog::updateReconstructionFlavor()
_ui->groupBox_subtraction->setVisible(_ui->checkBox_subtraction->isChecked()); _ui->groupBox_subtraction->setVisible(_ui->checkBox_subtraction->isChecked());
_ui->groupBox_textureMapping->setVisible(_ui->checkBox_textureMapping->isChecked()); _ui->groupBox_textureMapping->setVisible(_ui->checkBox_textureMapping->isChecked());
_ui->groupBox_cameraFilter->setVisible(_ui->checkBox_cameraFilter->isChecked()); _ui->groupBox_cameraFilter->setVisible(_ui->checkBox_cameraFilter->isChecked());
_ui->groupBox_multiband->setVisible(_ui->checkBox_multiband->isChecked());
// dense texturing options // dense texturing options
if(_ui->checkBox_meshing->isChecked()) if(_ui->checkBox_meshing->isChecked())
@@ -3713,7 +3745,6 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
float h = _ui->doubleSpinBox_footprintHeight->value(); float h = _ui->doubleSpinBox_footprintHeight->value();
float w = _ui->doubleSpinBox_footprintWidth->value(); float w = _ui->doubleSpinBox_footprintWidth->value();
float l = _ui->doubleSpinBox_footprintLength->value(); float l = _ui->doubleSpinBox_footprintLength->value();
int before= indices->size();
indices = util3d::cropBox( indices = util3d::cropBox(
cloud, cloud,
indices, indices,
@@ -4444,10 +4475,18 @@ void ExportCloudsDialog::saveTextureMeshes(
0, 0,
_dbDriver, _dbDriver,
textureSize, textureSize,
_ui->spinBox_multiband_downscale->value(),
_ui->comboBox_meshingTextureFormat->currentText().toStdString(), _ui->comboBox_meshingTextureFormat->currentText().toStdString(),
gains, gains,
blendingGains, blendingGains,
contrastValues); contrastValues,
true,
_ui->comboBox_multiband_unwrap->currentIndex(),
_ui->checkBox_multiband_fillholes->isChecked(),
_ui->spinBox_multiband_padding->value(),
_ui->doubleSpinBox_multiband_bestscore->value(),
_ui->doubleSpinBox_multiband_angle->value(),
_ui->checkBox_multiband_forcevisible->isChecked());
if(success) if(success)
{ {
_progressDialog->incrementStep(); _progressDialog->incrementStep();

View File

@@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>814</width> <width>1032</width>
<height>680</height> <height>869</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -23,9 +23,9 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>-1225</y> <y>-3479</y>
<width>780</width> <width>998</width>
<height>5739</height> <height>5642</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_13"> <layout class="QVBoxLayout" name="verticalLayout_13">
@@ -2751,6 +2751,182 @@ By Node ID and Camera Index: NodeID*10+CameraIndex</string>
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QGroupBox" name="groupBox_multiband">
<property name="title">
<string>MultiBand Texturing</string>
</property>
<layout class="QGridLayout" name="gridLayout_22" columnstretch="0,1">
<item row="0" column="1">
<widget class="QLabel" name="label_49">
<property name="text">
<string>Downscaling to 4 or 8 will reduce the texture quality but speed up the computation time. Set Texture Downscale to 1 instead of 2 to get the maximum possible resolution with the resolution of your images. The output texture size will be divided by this value, e.g., with texture size of 8192 and downscale value of 2, the output will be 4096.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBox_multiband_fillholes">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_50">
<property name="text">
<string>Unwrap method. Method to unwrap input mesh if it does not have UV coordinates Basic (&gt; 600k faces) fast and simple. Can generate multiple atlases LSCM (&lt;= 600k faces): optimize space. Generates one atlas ABF (&lt;= 300k faces): optimize space and stretch. Generates one atlas.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QSpinBox" name="spinBox_multiband_downscale">
<property name="maximum">
<number>16</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_52">
<property name="text">
<string>Texture edge padding size in pixel.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_54">
<property name="text">
<string>Angle hard threshold. 0 to disable angle hard threshold filtering.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_multiband_angle">
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>180.000000000000000</double>
</property>
<property name="value">
<double>90.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_53">
<property name="text">
<string>Best score threshold. 0 to disable filtering based on threshold to relative best score.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_multiband_bestscore">
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QSpinBox" name="spinBox_multiband_padding">
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_51">
<property name="text">
<string>Fill Texture holes with plausible values.</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="QComboBox" name="comboBox_multiband_unwrap">
<item>
<property name="text">
<string>Basic</string>
</property>
</item>
<item>
<property name="text">
<string>LSCM</string>
</property>
</item>
<item>
<property name="text">
<string>ABF</string>
</property>
</item>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_55">
<property name="text">
<string>Force visible by all vertices. Triangle visibility is based on the union of vertices visibility.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_multiband_forcevisible">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@@ -62,7 +62,7 @@ void showUsage()
" --las Export cloud in LAS instead of PLY (PDAL dependency required).\n" " --las Export cloud in LAS instead of PLY (PDAL dependency required).\n"
" --mesh Create a mesh.\n" " --mesh Create a mesh.\n"
" --texture Create a mesh with texture.\n" " --texture Create a mesh with texture.\n"
" --texture_size # Texture size (default 4096).\n" " --texture_size # Texture size 1024, 2048, 4096, 8192, 16384 (default 8192).\n"
" --texture_count # Maximum textures generated (default 1).\n" " --texture_count # Maximum textures generated (default 1).\n"
" --texture_range # Maximum camera range for texturing a polygon (default 0 meters: no limit).\n" " --texture_range # Maximum camera range for texturing a polygon (default 0 meters: no limit).\n"
" --texture_depth_error # Maximum depth error between reprojected mesh and depth image to texture a face (-1=disabled, 0=edge length is used, default=0).\n" " --texture_depth_error # Maximum depth error between reprojected mesh and depth image to texture a face (-1=disabled, 0=edge length is used, default=0).\n"
@@ -89,10 +89,17 @@ void showUsage()
" --no_clean Disable cleaning colorless polygons.\n" " --no_clean Disable cleaning colorless polygons.\n"
" --low_gain # Low brightness gain 0-100 (default 0).\n" " --low_gain # Low brightness gain 0-100 (default 0).\n"
" --high_gain # High brightness gain 0-100 (default 10).\n" " --high_gain # High brightness gain 0-100 (default 10).\n"
" --multiband Enable multiband texturing (AliceVision dependency required).\n" " --multiband Enable multiband texturing (AliceVision dependency required).\n"
" --multiband_downscale # Downscaling reduce the texture quality but speed up the computation time (default 2).\n"
" --multiband_unwrap # Method to unwrap input mesh: 0=basic (default, >600k faces, fast), 1=LSCM (<=600k faces, optimize space), 2=ABF (<=300k faces, generate 1 atlas).\n"
" --multiband_fillholes Fill Texture holes with plausible values.\n"
" --multiband_padding # Texture edge padding size in pixel (0-100) (default 5).\n"
" --multiband_scorethr # 0 to disable filtering based on threshold to relative best score (0.0-1.0). (default 0.1).\n"
" --multiband_anglethr # 0 to disable angle hard threshold filtering (0.0, 180.0) (default 90.0).\n"
" --multiband_forcevisible Triangle visibility is based on the union of vertices visibility.\n"
" --poisson_depth # Set Poisson depth for mesh reconstruction.\n" " --poisson_depth # Set Poisson depth for mesh reconstruction.\n"
" --poisson_size # Set target polygon size when computing Poisson's depth for mesh reconstruction (default 0.03 m).\n" " --poisson_size # Set target polygon size when computing Poisson's depth for mesh reconstruction (default 0.03 m).\n"
" --max_polygons # Maximum polygons when creating a mesh (default 500000, set 0 for no limit).\n" " --max_polygons # Maximum polygons when creating a mesh (default 300000, set 0 for no limit).\n"
" --max_range # Maximum range of the created clouds (default 4 m, 0 m with --scan).\n" " --max_range # Maximum range of the created clouds (default 4 m, 0 m with --scan).\n"
" --decimation # Depth image decimation before creating the clouds (default 4, 1 with --scan).\n" " --decimation # Depth image decimation before creating the clouds (default 4, 1 with --scan).\n"
" --voxel # Voxel size of the created clouds (default 0.01 m, 0 m with --scan).\n" " --voxel # Voxel size of the created clouds (default 0.01 m, 0 m with --scan).\n"
@@ -133,18 +140,25 @@ int main(int argc, char * argv[])
bool doClean = true; bool doClean = true;
int poissonDepth = 0; int poissonDepth = 0;
float poissonSize = 0.03; float poissonSize = 0.03;
int maxPolygons = 500000; int maxPolygons = 300000;
int decimation = -1; int decimation = -1;
float maxRange = -1.0f; float maxRange = -1.0f;
float voxelSize = -1.0f; float voxelSize = -1.0f;
float noiseRadius = 0.0f; float noiseRadius = 0.0f;
int noiseMinNeighbors = 5; int noiseMinNeighbors = 5;
int textureSize = 4096; int textureSize = 8192;
int textureCount = 1; int textureCount = 1;
int textureRange = 0; int textureRange = 0;
float textureDepthError = 0; float textureDepthError = 0;
bool distanceToCamPolicy = false; bool distanceToCamPolicy = false;
bool multiband = false; bool multiband = false;
int multibandDownScale = 2;
int multibandUnwrap = 0;
bool multibandFillHoles = false;
int multibandPadding = 5;
double multibandBestScoreThr = 0.1;
double multibandAngleHardthr = 90;
bool multibandForceVisible = false;
float colorRadius = -1.0f; float colorRadius = -1.0f;
bool cloudFromScan = false; bool cloudFromScan = false;
bool saveInDb = false; bool saveInDb = false;
@@ -343,6 +357,74 @@ int main(int argc, char * argv[])
printf("\"--multiband\" option cannot be used because RTAB-Map is not built with AliceVision support. Ignoring multiband...\n"); printf("\"--multiband\" option cannot be used because RTAB-Map is not built with AliceVision support. Ignoring multiband...\n");
#endif #endif
} }
else if(std::strcmp(argv[i], "--multiband_fillholes") == 0)
{
multibandFillHoles = true;
}
else if(std::strcmp(argv[i], "--multiband_downscale") == 0)
{
++i;
if(i<argc-1)
{
multibandDownScale = uStr2Int(argv[i]);
}
else
{
showUsage();
}
}
else if(std::strcmp(argv[i], "--multiband_unwrap") == 0)
{
++i;
if(i<argc-1)
{
multibandUnwrap = uStr2Int(argv[i]);
}
else
{
showUsage();
}
}
else if(std::strcmp(argv[i], "--multiband_padding") == 0)
{
++i;
if(i<argc-1)
{
multibandPadding = uStr2Int(argv[i]);
}
else
{
showUsage();
}
}
else if(std::strcmp(argv[i], "--multiband_forcevisible") == 0)
{
multibandForceVisible = true;
}
else if(std::strcmp(argv[i], "--multiband_scorethr") == 0)
{
++i;
if(i<argc-1)
{
multibandBestScoreThr = uStr2Float(argv[i]);
}
else
{
showUsage();
}
}
else if(std::strcmp(argv[i], "--multiband_anglethr") == 0)
{
++i;
if(i<argc-1)
{
multibandAngleHardthr = uStr2Float(argv[i]);
}
else
{
showUsage();
}
}
else if(std::strcmp(argv[i], "--poisson_depth") == 0) else if(std::strcmp(argv[i], "--poisson_depth") == 0)
{ {
++i; ++i;
@@ -1166,7 +1248,10 @@ int main(int argc, char * argv[])
if(mesh->polygons.size()) if(mesh->polygons.size())
{ {
printf("Mesh color transfer...\n"); printf("Mesh color transfer (max polygons=%d, color radius=%f, clean=%s)...\n",
maxPolygons,
colorRadius,
doClean?"true":"false");
rtabmap::util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>( rtabmap::util3d::denseMeshPostProcessing<pcl::PointXYZRGBNormal>(
mesh, mesh,
0.0f, 0.0f,
@@ -1313,7 +1398,16 @@ int main(int argc, char * argv[])
{ {
timer.restart(); timer.restart();
std::string outputPath=outputDirectory+"/"+baseName+"_mesh_multiband.obj"; std::string outputPath=outputDirectory+"/"+baseName+"_mesh_multiband.obj";
printf("MultiBand texturing... \"%s\"\n", outputPath.c_str()); printf("MultiBand texturing (size=%d, downscale=%d, unwrap method=%s, fill holes=%s, padding=%d, best score thr=%f, angle thr=%f, force visible=%s)... \"%s\"\n",
textureSize,
multibandDownScale,
multibandUnwrap==2?"ABF":multibandUnwrap==1?"LSCM":"Basic",
multibandFillHoles?"true":"false",
multibandPadding,
multibandBestScoreThr,
multibandAngleHardthr,
multibandForceVisible?"false":"true",
outputPath.c_str());
if(util3d::multiBandTexturing(outputPath, if(util3d::multiBandTexturing(outputPath,
textureMesh->cloud, textureMesh->cloud,
textureMesh->tex_polygons[0], textureMesh->tex_polygons[0],
@@ -1324,11 +1418,18 @@ int main(int argc, char * argv[])
rtabmap.getMemory(), rtabmap.getMemory(),
0, 0,
textureSize, textureSize,
multibandDownScale,
"jpg", "jpg",
gains, gains,
blendingGains, blendingGains,
contrastValues, contrastValues,
doGainCompensationRGB)) doGainCompensationRGB,
multibandUnwrap,
multibandFillHoles,
multibandPadding,
multibandBestScoreThr,
multibandAngleHardthr,
multibandForceVisible))
{ {
printf("MultiBand texturing...done (%fs).\n", timer.ticks()); printf("MultiBand texturing...done (%fs).\n", timer.ticks());
} }