mirror of
https://github.com/introlab/rtabmap_ros.git
synced 2026-10-04 00:37:46 +08:00
Export: added rgb/gray gain compensation option, added maximum outout textures option (can be useful for #189).
This commit is contained in:
@@ -73,18 +73,22 @@ public:
|
|||||||
|
|
||||||
void apply(
|
void apply(
|
||||||
int id,
|
int id,
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud) const;
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
|
bool rgb = true) const;
|
||||||
void apply(
|
void apply(
|
||||||
int id,
|
int id,
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices) const;
|
const pcl::IndicesPtr & indices,
|
||||||
|
bool rgb = true) const;
|
||||||
void apply(
|
void apply(
|
||||||
int id,
|
int id,
|
||||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud,
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices) const;
|
const pcl::IndicesPtr & indices,
|
||||||
|
bool rgb = true) const;
|
||||||
void apply(
|
void apply(
|
||||||
int id,
|
int id,
|
||||||
cv::Mat & image) const;
|
cv::Mat & image,
|
||||||
|
bool rgb = true) const;
|
||||||
|
|
||||||
double getGain(int id, double * r=0, double * g=0, double * b=0) const;
|
double getGain(int id, double * r=0, double * g=0, double * b=0) const;
|
||||||
int getIndex(int id) const;
|
int getIndex(int id) const;
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ pcl::TextureMesh::Ptr RTABMAP_EXP concatenateTextureMeshes(
|
|||||||
const std::list<pcl::TextureMesh::Ptr> & meshes);
|
const std::list<pcl::TextureMesh::Ptr> & meshes);
|
||||||
|
|
||||||
void RTABMAP_EXP concatenateTextureMaterials(
|
void RTABMAP_EXP concatenateTextureMaterials(
|
||||||
pcl::TextureMesh & mesh, const cv::Size & imageSize, int textureSize, float & scale, std::vector<bool> * materialsKept=0);
|
pcl::TextureMesh & mesh, const cv::Size & imageSize, int textureSize, int maxTextures, float & scale, std::vector<bool> * materialsKept=0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Concatenate a vector of indices to a single vector.
|
* @brief Concatenate a vector of indices to a single vector.
|
||||||
|
|||||||
@@ -394,11 +394,12 @@ void applyImpl(
|
|||||||
int index,
|
int index,
|
||||||
typename pcl::PointCloud<PointT>::Ptr & cloud,
|
typename pcl::PointCloud<PointT>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices,
|
const pcl::IndicesPtr & indices,
|
||||||
const cv::Mat_<double> & gains)
|
const cv::Mat_<double> & gains,
|
||||||
|
bool rgb)
|
||||||
{
|
{
|
||||||
double gainR = gains(index, 1);
|
double gainR = gains(index, rgb?1:0);
|
||||||
double gainG = gains(index, 2);
|
double gainG = gains(index, rgb?2:0);
|
||||||
double gainB = gains(index, 3);
|
double gainB = gains(index, rgb?3:0);
|
||||||
UDEBUG("index=%d gain=%f (%f,%f,%f)", index, gains(index, 0), gainR, gainG, gainB);
|
UDEBUG("index=%d gain=%f (%f,%f,%f)", index, gains(index, 0), gainR, gainG, gainB);
|
||||||
if(indices->size())
|
if(indices->size())
|
||||||
{
|
{
|
||||||
@@ -424,34 +425,38 @@ void applyImpl(
|
|||||||
|
|
||||||
void GainCompensator::apply(
|
void GainCompensator::apply(
|
||||||
int id,
|
int id,
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud) const
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
|
bool rgb) const
|
||||||
{
|
{
|
||||||
pcl::IndicesPtr indices(new std::vector<int>);
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
apply(id, cloud, indices);
|
apply(id, cloud, indices, rgb);
|
||||||
}
|
}
|
||||||
void GainCompensator::apply(
|
void GainCompensator::apply(
|
||||||
int id,
|
int id,
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices) const
|
const pcl::IndicesPtr & indices,
|
||||||
|
bool rgb) const
|
||||||
{
|
{
|
||||||
UASSERT_MSG(uContains(idToIndex_, id), uFormat("id=%d idToIndex_.size()=%d", id, (int)idToIndex_.size()).c_str());
|
UASSERT_MSG(uContains(idToIndex_, id), uFormat("id=%d idToIndex_.size()=%d", id, (int)idToIndex_.size()).c_str());
|
||||||
applyImpl<pcl::PointXYZRGB>(idToIndex_.at(id), cloud, indices, gains_);
|
applyImpl<pcl::PointXYZRGB>(idToIndex_.at(id), cloud, indices, gains_, rgb);
|
||||||
}
|
}
|
||||||
void GainCompensator::apply(
|
void GainCompensator::apply(
|
||||||
int id,
|
int id,
|
||||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud,
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud,
|
||||||
const pcl::IndicesPtr & indices) const
|
const pcl::IndicesPtr & indices,
|
||||||
|
bool rgb) const
|
||||||
{
|
{
|
||||||
UASSERT_MSG(uContains(idToIndex_, id), uFormat("id=%d idToIndex_.size()=%d", id, (int)idToIndex_.size()).c_str());
|
UASSERT_MSG(uContains(idToIndex_, id), uFormat("id=%d idToIndex_.size()=%d", id, (int)idToIndex_.size()).c_str());
|
||||||
applyImpl<pcl::PointXYZRGBNormal>(idToIndex_.at(id), cloud, indices, gains_);
|
applyImpl<pcl::PointXYZRGBNormal>(idToIndex_.at(id), cloud, indices, gains_, rgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GainCompensator::apply(
|
void GainCompensator::apply(
|
||||||
int id,
|
int id,
|
||||||
cv::Mat & image) const
|
cv::Mat & image,
|
||||||
|
bool rgb) const
|
||||||
{
|
{
|
||||||
UASSERT_MSG(uContains(idToIndex_, id), uFormat("id=%d idToIndex_.size()=%d", id, (int)idToIndex_.size()).c_str());
|
UASSERT_MSG(uContains(idToIndex_, id), uFormat("id=%d idToIndex_.size()=%d", id, (int)idToIndex_.size()).c_str());
|
||||||
if(image.channels() == 1)
|
if(image.channels() == 1 || !rgb)
|
||||||
{
|
{
|
||||||
cv::multiply(image, gains_(idToIndex_.at(id), 0), image);
|
cv::multiply(image, gains_(idToIndex_.at(id), 0), image);
|
||||||
}
|
}
|
||||||
|
|||||||
+53
-22
@@ -1988,9 +1988,13 @@ int gcd(int a, int b) {
|
|||||||
return b == 0 ? a : gcd(b, a % b);
|
return b == 0 ? a : gcd(b, a % b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void concatenateTextureMaterials(pcl::TextureMesh & mesh, const cv::Size & imageSize, int textureSize, float & scale, std::vector<bool> * materialsKept)
|
void concatenateTextureMaterials(pcl::TextureMesh & mesh, const cv::Size & imageSize, int textureSize, int maxTextures, float & scale, std::vector<bool> * materialsKept)
|
||||||
{
|
{
|
||||||
UASSERT(textureSize>0 && imageSize.width>0 && imageSize.height>0);
|
UASSERT(textureSize>0 && imageSize.width>0 && imageSize.height>0);
|
||||||
|
if(maxTextures < 1)
|
||||||
|
{
|
||||||
|
maxTextures = 1;
|
||||||
|
}
|
||||||
int materials = 0;
|
int materials = 0;
|
||||||
for(unsigned int i=0; i<mesh.tex_materials.size(); ++i)
|
for(unsigned int i=0; i<mesh.tex_materials.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -2012,7 +2016,7 @@ void concatenateTextureMaterials(pcl::TextureMesh & mesh, const cv::Size & image
|
|||||||
float factor = 0.1f;
|
float factor = 0.1f;
|
||||||
float epsilon = 0.001f;
|
float epsilon = 0.001f;
|
||||||
scale = 1.0f;
|
scale = 1.0f;
|
||||||
while(colCount*rowCount < materials || (factor == 0.1f || scale > 1.0f))
|
while((colCount*rowCount)*maxTextures < materials || (factor == 0.1f || scale > 1.0f))
|
||||||
{
|
{
|
||||||
// first run try scale = 1 (no scaling)
|
// first run try scale = 1 (no scaling)
|
||||||
if(factor!=0.1f)
|
if(factor!=0.1f)
|
||||||
@@ -2023,28 +2027,30 @@ void concatenateTextureMaterials(pcl::TextureMesh & mesh, const cv::Size & image
|
|||||||
rowCount = float(textureSize)/(scale*float(h));
|
rowCount = float(textureSize)/(scale*float(h));
|
||||||
factor+=epsilon; // search the maximum perfect fit
|
factor+=epsilon; // search the maximum perfect fit
|
||||||
}
|
}
|
||||||
UDEBUG("materials=%d col=%d row=%d factor=%f scale=%f", materials, colCount, rowCount, factor-epsilon, scale);
|
int outputTextures = (materials / (colCount*rowCount))+1;
|
||||||
|
UDEBUG("materials=%d col=%d row=%d output textures=%d factor=%f scale=%f", materials, colCount, rowCount, outputTextures, factor-epsilon, scale);
|
||||||
|
|
||||||
UASSERT(mesh.tex_coordinates.size() == mesh.tex_materials.size() && mesh.tex_polygons.size() == mesh.tex_materials.size());
|
UASSERT(mesh.tex_coordinates.size() == mesh.tex_materials.size() && mesh.tex_polygons.size() == mesh.tex_materials.size());
|
||||||
|
|
||||||
// prepare size
|
// prepare size
|
||||||
int totalPolygons = 0;
|
std::vector<int> totalPolygons(outputTextures, 0);
|
||||||
int totalCoordinates = 0;
|
std::vector<int> totalCoordinates(outputTextures, 0);
|
||||||
|
int count = 0;
|
||||||
for(unsigned int i=0; i<mesh.tex_materials.size(); ++i)
|
for(unsigned int i=0; i<mesh.tex_materials.size(); ++i)
|
||||||
{
|
{
|
||||||
if(mesh.tex_polygons[i].size())
|
if(mesh.tex_polygons[i].size())
|
||||||
{
|
{
|
||||||
totalPolygons+=mesh.tex_polygons[i].size();
|
int indexMaterial = count / (colCount*rowCount);
|
||||||
totalCoordinates+=mesh.tex_coordinates[i].size();
|
UASSERT(indexMaterial < outputTextures);
|
||||||
|
|
||||||
|
totalPolygons[indexMaterial]+=mesh.tex_polygons[i].size();
|
||||||
|
totalCoordinates[indexMaterial]+=mesh.tex_coordinates[i].size();
|
||||||
|
|
||||||
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<pcl::Vertices> newPolygons(totalPolygons);
|
pcl::TextureMesh outputMesh;
|
||||||
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
|
||||||
std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > newCoordinates(totalCoordinates); // UV coordinates
|
|
||||||
#else
|
|
||||||
std::vector<Eigen::Vector2f> newCoordinates(totalCoordinates); // UV coordinates
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int pi = 0;
|
int pi = 0;
|
||||||
int ci = 0;
|
int ci = 0;
|
||||||
@@ -2061,7 +2067,24 @@ void concatenateTextureMaterials(pcl::TextureMesh & mesh, const cv::Size & image
|
|||||||
{
|
{
|
||||||
if(mesh.tex_polygons[t].size())
|
if(mesh.tex_polygons[t].size())
|
||||||
{
|
{
|
||||||
int row = ti/colCount;
|
int indexMaterial = ti / (colCount*rowCount);
|
||||||
|
UASSERT(indexMaterial < outputTextures);
|
||||||
|
if(outputMesh.tex_polygons.size() <= indexMaterial)
|
||||||
|
{
|
||||||
|
std::vector<pcl::Vertices> newPolygons(totalPolygons[indexMaterial]);
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > newCoordinates(totalCoordinates[indexMaterial]); // UV coordinates
|
||||||
|
#else
|
||||||
|
std::vector<Eigen::Vector2f> newCoordinates(totalCoordinates[indexMaterial]); // UV coordinates
|
||||||
|
#endif
|
||||||
|
outputMesh.tex_polygons.push_back(newPolygons);
|
||||||
|
outputMesh.tex_coordinates.push_back(newCoordinates);
|
||||||
|
|
||||||
|
pi=0;
|
||||||
|
ci=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int row = (ti/colCount) % rowCount;
|
||||||
int col = ti%colCount;
|
int col = ti%colCount;
|
||||||
float offsetU = scaledWidth * float(col);
|
float offsetU = scaledWidth * float(col);
|
||||||
float offsetV = scaledHeight * float((rowCount - 1) - row) + lowerBorderSize;
|
float offsetV = scaledHeight * float((rowCount - 1) - row) + lowerBorderSize;
|
||||||
@@ -2069,7 +2092,8 @@ void concatenateTextureMaterials(pcl::TextureMesh & mesh, const cv::Size & image
|
|||||||
|
|
||||||
for(unsigned int i=0; i<mesh.tex_polygons[t].size(); ++i)
|
for(unsigned int i=0; i<mesh.tex_polygons[t].size(); ++i)
|
||||||
{
|
{
|
||||||
newPolygons[pi++] = mesh.tex_polygons[t].at(i);
|
UASSERT(pi < (int)outputMesh.tex_polygons[indexMaterial].size());
|
||||||
|
outputMesh.tex_polygons[indexMaterial][pi++] = mesh.tex_polygons[t].at(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(unsigned int i=0; i<mesh.tex_coordinates[t].size(); ++i)
|
for(unsigned int i=0; i<mesh.tex_coordinates[t].size(); ++i)
|
||||||
@@ -2077,12 +2101,12 @@ void concatenateTextureMaterials(pcl::TextureMesh & mesh, const cv::Size & image
|
|||||||
const Eigen::Vector2f & v = mesh.tex_coordinates[t].at(i);
|
const Eigen::Vector2f & v = mesh.tex_coordinates[t].at(i);
|
||||||
if(v[0] >= 0 && v[1] >=0)
|
if(v[0] >= 0 && v[1] >=0)
|
||||||
{
|
{
|
||||||
newCoordinates[ci][0] = v[0]*scaledWidth + offsetU;
|
outputMesh.tex_coordinates[indexMaterial][ci][0] = v[0]*scaledWidth + offsetU;
|
||||||
newCoordinates[ci][1] = v[1]*scaledHeight + offsetV;
|
outputMesh.tex_coordinates[indexMaterial][ci][1] = v[1]*scaledHeight + offsetV;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newCoordinates[ci] = v;
|
outputMesh.tex_coordinates[indexMaterial][ci] = v;
|
||||||
}
|
}
|
||||||
++ci;
|
++ci;
|
||||||
}
|
}
|
||||||
@@ -2095,13 +2119,20 @@ void concatenateTextureMaterials(pcl::TextureMesh & mesh, const cv::Size & image
|
|||||||
}
|
}
|
||||||
pcl::TexMaterial m = mesh.tex_materials.front();
|
pcl::TexMaterial m = mesh.tex_materials.front();
|
||||||
mesh.tex_materials.clear();
|
mesh.tex_materials.clear();
|
||||||
|
for(int i=0; i<outputTextures; ++i)
|
||||||
|
{
|
||||||
m.tex_file = "texture";
|
m.tex_file = "texture";
|
||||||
m.tex_name = "material";
|
m.tex_name = "material";
|
||||||
|
if(outputTextures > 1)
|
||||||
|
{
|
||||||
|
m.tex_file += uNumber2Str(i);
|
||||||
|
m.tex_name += uNumber2Str(i);
|
||||||
|
}
|
||||||
|
|
||||||
mesh.tex_materials.push_back(m);
|
mesh.tex_materials.push_back(m);
|
||||||
mesh.tex_coordinates.clear();
|
}
|
||||||
mesh.tex_coordinates.push_back(newCoordinates);
|
mesh.tex_coordinates = outputMesh.tex_coordinates;
|
||||||
mesh.tex_polygons.clear();
|
mesh.tex_polygons = outputMesh.tex_polygons;
|
||||||
mesh.tex_polygons.push_back(newPolygons);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
|||||||
connect(_ui->doubleSpinBox_gainRadius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_gainRadius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_gainOverlap, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_gainOverlap, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_gainBeta, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_gainBeta, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->checkBox_gainRGB, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->checkBox_gainFull, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->checkBox_gainFull, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->spinBox_textureBrightnessContrastRatioLow, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->spinBox_textureBrightnessContrastRatioLow, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->spinBox_textureBrightnessContrastRatioHigh, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->spinBox_textureBrightnessContrastRatioHigh, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
||||||
@@ -167,6 +168,7 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
|||||||
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor()));
|
connect(_ui->checkBox_textureMapping, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor()));
|
||||||
connect(_ui->comboBox_meshingTextureFormat, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->comboBox_meshingTextureFormat, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->comboBox_meshingTextureSize, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->comboBox_meshingTextureSize, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->spinBox_mesh_maxTextures, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_meshingTextureMaxDistance, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_meshingTextureMaxDistance, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->spinBox_mesh_minTextureClusterSize, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->spinBox_mesh_minTextureClusterSize, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->lineEdit_meshingTextureRoiRatios, SIGNAL(textChanged(const QString &)), this, SIGNAL(configChanged()));
|
connect(_ui->lineEdit_meshingTextureRoiRatios, SIGNAL(textChanged(const QString &)), this, SIGNAL(configChanged()));
|
||||||
@@ -289,6 +291,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
|
|||||||
settings.setValue("gain_radius", _ui->doubleSpinBox_gainRadius->value());
|
settings.setValue("gain_radius", _ui->doubleSpinBox_gainRadius->value());
|
||||||
settings.setValue("gain_overlap", _ui->doubleSpinBox_gainOverlap->value());
|
settings.setValue("gain_overlap", _ui->doubleSpinBox_gainOverlap->value());
|
||||||
settings.setValue("gain_beta", _ui->doubleSpinBox_gainBeta->value());
|
settings.setValue("gain_beta", _ui->doubleSpinBox_gainBeta->value());
|
||||||
|
settings.setValue("gain_rgb", _ui->checkBox_gainRGB->isChecked());
|
||||||
settings.setValue("gain_full", _ui->checkBox_gainFull->isChecked());
|
settings.setValue("gain_full", _ui->checkBox_gainFull->isChecked());
|
||||||
|
|
||||||
settings.setValue("mesh", _ui->checkBox_meshing->isChecked());
|
settings.setValue("mesh", _ui->checkBox_meshing->isChecked());
|
||||||
@@ -305,6 +308,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
|
|||||||
settings.setValue("mesh_texture", _ui->checkBox_textureMapping->isChecked());
|
settings.setValue("mesh_texture", _ui->checkBox_textureMapping->isChecked());
|
||||||
settings.setValue("mesh_textureFormat", _ui->comboBox_meshingTextureFormat->currentIndex());
|
settings.setValue("mesh_textureFormat", _ui->comboBox_meshingTextureFormat->currentIndex());
|
||||||
settings.setValue("mesh_textureSize", _ui->comboBox_meshingTextureSize->currentIndex());
|
settings.setValue("mesh_textureSize", _ui->comboBox_meshingTextureSize->currentIndex());
|
||||||
|
settings.setValue("mesh_textureMaxCount", _ui->spinBox_mesh_maxTextures->value());
|
||||||
settings.setValue("mesh_textureMaxDistance", _ui->doubleSpinBox_meshingTextureMaxDistance->value());
|
settings.setValue("mesh_textureMaxDistance", _ui->doubleSpinBox_meshingTextureMaxDistance->value());
|
||||||
settings.setValue("mesh_textureMinCluster", _ui->spinBox_mesh_minTextureClusterSize->value());
|
settings.setValue("mesh_textureMinCluster", _ui->spinBox_mesh_minTextureClusterSize->value());
|
||||||
settings.setValue("mesh_textureRoiRatios", _ui->lineEdit_meshingTextureRoiRatios->text());
|
settings.setValue("mesh_textureRoiRatios", _ui->lineEdit_meshingTextureRoiRatios->text());
|
||||||
@@ -398,6 +402,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
|||||||
_ui->doubleSpinBox_gainRadius->setValue(settings.value("gain_radius", _ui->doubleSpinBox_gainRadius->value()).toDouble());
|
_ui->doubleSpinBox_gainRadius->setValue(settings.value("gain_radius", _ui->doubleSpinBox_gainRadius->value()).toDouble());
|
||||||
_ui->doubleSpinBox_gainOverlap->setValue(settings.value("gain_overlap", _ui->doubleSpinBox_gainOverlap->value()).toDouble());
|
_ui->doubleSpinBox_gainOverlap->setValue(settings.value("gain_overlap", _ui->doubleSpinBox_gainOverlap->value()).toDouble());
|
||||||
_ui->doubleSpinBox_gainBeta->setValue(settings.value("gain_beta", _ui->doubleSpinBox_gainBeta->value()).toDouble());
|
_ui->doubleSpinBox_gainBeta->setValue(settings.value("gain_beta", _ui->doubleSpinBox_gainBeta->value()).toDouble());
|
||||||
|
_ui->checkBox_gainRGB->setChecked(settings.value("gain_rgb", _ui->checkBox_gainRGB->isChecked()).toBool());
|
||||||
_ui->checkBox_gainFull->setChecked(settings.value("gain_full", _ui->checkBox_gainFull->isChecked()).toBool());
|
_ui->checkBox_gainFull->setChecked(settings.value("gain_full", _ui->checkBox_gainFull->isChecked()).toBool());
|
||||||
|
|
||||||
_ui->checkBox_meshing->setChecked(settings.value("mesh", _ui->checkBox_meshing->isChecked()).toBool());
|
_ui->checkBox_meshing->setChecked(settings.value("mesh", _ui->checkBox_meshing->isChecked()).toBool());
|
||||||
@@ -414,6 +419,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
|||||||
_ui->checkBox_textureMapping->setChecked(settings.value("mesh_texture", _ui->checkBox_textureMapping->isChecked()).toBool());
|
_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->comboBox_meshingTextureFormat->setCurrentIndex(settings.value("mesh_textureFormat", _ui->comboBox_meshingTextureFormat->currentIndex()).toInt());
|
||||||
_ui->comboBox_meshingTextureSize->setCurrentIndex(settings.value("mesh_textureSize", _ui->comboBox_meshingTextureSize->currentIndex()).toInt());
|
_ui->comboBox_meshingTextureSize->setCurrentIndex(settings.value("mesh_textureSize", _ui->comboBox_meshingTextureSize->currentIndex()).toInt());
|
||||||
|
_ui->spinBox_mesh_maxTextures->setValue(settings.value("mesh_textureMaxCount", _ui->spinBox_mesh_maxTextures->value()).toInt());
|
||||||
_ui->doubleSpinBox_meshingTextureMaxDistance->setValue(settings.value("mesh_textureMaxDistance", _ui->doubleSpinBox_meshingTextureMaxDistance->value()).toDouble());
|
_ui->doubleSpinBox_meshingTextureMaxDistance->setValue(settings.value("mesh_textureMaxDistance", _ui->doubleSpinBox_meshingTextureMaxDistance->value()).toDouble());
|
||||||
_ui->spinBox_mesh_minTextureClusterSize->setValue(settings.value("mesh_textureMinCluster", _ui->spinBox_mesh_minTextureClusterSize->value()).toDouble());
|
_ui->spinBox_mesh_minTextureClusterSize->setValue(settings.value("mesh_textureMinCluster", _ui->spinBox_mesh_minTextureClusterSize->value()).toDouble());
|
||||||
_ui->lineEdit_meshingTextureRoiRatios->setText(settings.value("mesh_textureRoiRatios", _ui->lineEdit_meshingTextureRoiRatios->text()).toString());
|
_ui->lineEdit_meshingTextureRoiRatios->setText(settings.value("mesh_textureRoiRatios", _ui->lineEdit_meshingTextureRoiRatios->text()).toString());
|
||||||
@@ -507,6 +513,7 @@ void ExportCloudsDialog::restoreDefaults()
|
|||||||
_ui->doubleSpinBox_gainRadius->setValue(0.02);
|
_ui->doubleSpinBox_gainRadius->setValue(0.02);
|
||||||
_ui->doubleSpinBox_gainOverlap->setValue(0.0);
|
_ui->doubleSpinBox_gainOverlap->setValue(0.0);
|
||||||
_ui->doubleSpinBox_gainBeta->setValue(10);
|
_ui->doubleSpinBox_gainBeta->setValue(10);
|
||||||
|
_ui->checkBox_gainRGB->setChecked(true);
|
||||||
_ui->checkBox_gainFull->setChecked(false);
|
_ui->checkBox_gainFull->setChecked(false);
|
||||||
|
|
||||||
_ui->checkBox_meshing->setChecked(false);
|
_ui->checkBox_meshing->setChecked(false);
|
||||||
@@ -523,6 +530,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(5); // 4096
|
||||||
|
_ui->spinBox_mesh_maxTextures->setValue(1);
|
||||||
_ui->doubleSpinBox_meshingTextureMaxDistance->setValue(3.0);
|
_ui->doubleSpinBox_meshingTextureMaxDistance->setValue(3.0);
|
||||||
_ui->spinBox_mesh_minTextureClusterSize->setValue(50);
|
_ui->spinBox_mesh_minTextureClusterSize->setValue(50);
|
||||||
_ui->lineEdit_meshingTextureRoiRatios->setText("0.0 0.0 0.0 0.0");
|
_ui->lineEdit_meshingTextureRoiRatios->setText("0.0 0.0 0.0 0.0");
|
||||||
@@ -834,7 +842,12 @@ void ExportCloudsDialog::viewClouds(
|
|||||||
cv::Mat globalTexture;
|
cv::Mat globalTexture;
|
||||||
if (mesh->tex_materials.size() > 1)
|
if (mesh->tex_materials.size() > 1)
|
||||||
{
|
{
|
||||||
globalTexture = mergeTextures(*mesh, cachedSignatures, textureVertexToPixels);
|
std::vector<cv::Mat> globalTextures;
|
||||||
|
globalTextures = mergeTextures(*mesh, cachedSignatures, textureVertexToPixels, 1);
|
||||||
|
if(globalTextures.size() == 1)
|
||||||
|
{
|
||||||
|
globalTexture = globalTextures[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_progressDialog->appendText(tr("Viewing the mesh %1 (%2 polygons)...").arg(iter->first).arg(mesh->tex_polygons.size()?mesh->tex_polygons[0].size():0));
|
_progressDialog->appendText(tr("Viewing the mesh %1 (%2 polygons)...").arg(iter->first).arg(mesh->tex_polygons.size()?mesh->tex_polygons[0].size():0));
|
||||||
@@ -902,7 +915,7 @@ void ExportCloudsDialog::viewClouds(
|
|||||||
UASSERT(!globalTexture.empty());
|
UASSERT(!globalTexture.empty());
|
||||||
if (_ui->checkBox_gainCompensation->isChecked() && _compensator && _compensator->getIndex(textureId) >= 0)
|
if (_ui->checkBox_gainCompensation->isChecked() && _compensator && _compensator->getIndex(textureId) >= 0)
|
||||||
{
|
{
|
||||||
_compensator->apply(textureId, globalTexture);
|
_compensator->apply(textureId, globalTexture, _ui->checkBox_gainRGB->isChecked());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1155,7 +1168,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
if(jter!=clouds.end())
|
if(jter!=clouds.end())
|
||||||
{
|
{
|
||||||
double gain = _compensator->getGain(jter->first);;
|
double gain = _compensator->getGain(jter->first);;
|
||||||
_compensator->apply(jter->first, jter->second.first, jter->second.second);
|
_compensator->apply(jter->first, jter->second.first, jter->second.second, _ui->checkBox_gainRGB->isChecked());
|
||||||
|
|
||||||
_progressDialog->appendText(tr("Cloud %1 has gain %2").arg(jter->first).arg(gain));
|
_progressDialog->appendText(tr("Cloud %1 has gain %2").arg(jter->first).arg(gain));
|
||||||
_progressDialog->incrementStep();
|
_progressDialog->incrementStep();
|
||||||
@@ -2988,10 +3001,11 @@ double sqr(uchar v)
|
|||||||
return double(v)*double(v);
|
return double(v)*double(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat ExportCloudsDialog::mergeTextures(
|
std::vector<cv::Mat> ExportCloudsDialog::mergeTextures(
|
||||||
pcl::TextureMesh & mesh,
|
pcl::TextureMesh & mesh,
|
||||||
const QMap<int, Signature> & cachedSignatures,
|
const QMap<int, Signature> & cachedSignatures,
|
||||||
const std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels) const
|
const std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels,
|
||||||
|
int maxTextures) const
|
||||||
{
|
{
|
||||||
//get texture size, if disabled use default 1024
|
//get texture size, if disabled use default 1024
|
||||||
int textureSize = 1024;
|
int textureSize = 1024;
|
||||||
@@ -3000,7 +3014,7 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
textureSize = 128 << _ui->comboBox_meshingTextureSize->currentIndex(); // start at 256
|
textureSize = 128 << _ui->comboBox_meshingTextureSize->currentIndex(); // start at 256
|
||||||
}
|
}
|
||||||
UDEBUG("textureSize = %d", textureSize);
|
UDEBUG("textureSize = %d", textureSize);
|
||||||
cv::Mat globalTexture;
|
std::vector<cv::Mat> globalTextures;
|
||||||
if(mesh.tex_materials.size() > 1)
|
if(mesh.tex_materials.size() > 1)
|
||||||
{
|
{
|
||||||
std::vector<std::pair<int, int> > textures(mesh.tex_materials.size(), std::pair<int, int>(-1,-1));
|
std::vector<std::pair<int, int> > textures(mesh.tex_materials.size(), std::pair<int, int>(-1,-1));
|
||||||
@@ -3094,13 +3108,20 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
float scale = 0.0f;
|
float scale = 0.0f;
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
std::vector<bool> materialsKept;
|
std::vector<bool> materialsKept;
|
||||||
util3d::concatenateTextureMaterials(mesh, imageSize, textureSize, scale, &materialsKept);
|
util3d::concatenateTextureMaterials(mesh, imageSize, textureSize, maxTextures, scale, &materialsKept);
|
||||||
if(scale && mesh.tex_materials.size()==1)
|
if(scale && mesh.tex_materials.size())
|
||||||
{
|
{
|
||||||
|
int materials = (int)mesh.tex_materials.size();
|
||||||
int cols = float(textureSize)/(scale*imageSize.width);
|
int cols = float(textureSize)/(scale*imageSize.width);
|
||||||
|
int rows = float(textureSize)/(scale*imageSize.height);
|
||||||
|
|
||||||
globalTexture = cv::Mat(textureSize, textureSize, imageType, cv::Scalar::all(255));
|
std::vector<cv::Mat> globalTextureMasks(materials);
|
||||||
cv::Mat globalTextureMask = cv::Mat(textureSize, textureSize, CV_8UC1, cv::Scalar::all(0));
|
globalTextures.resize(materials);
|
||||||
|
for(int i=0; i<materials; ++i)
|
||||||
|
{
|
||||||
|
globalTextures[i] = cv::Mat(textureSize, textureSize, imageType, cv::Scalar::all(255));
|
||||||
|
globalTextureMasks[i] = cv::Mat(textureSize, textureSize, CV_8UC1, cv::Scalar::all(0));
|
||||||
|
}
|
||||||
|
|
||||||
// used for multi camera texturing, to avoid reloading same texture for sub cameras
|
// used for multi camera texturing, to avoid reloading same texture for sub cameras
|
||||||
cv::Mat previousImage;
|
cv::Mat previousImage;
|
||||||
@@ -3117,9 +3138,12 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
{
|
{
|
||||||
if(materialsKept.at(t))
|
if(materialsKept.at(t))
|
||||||
{
|
{
|
||||||
|
int indexMaterial = oi / (cols*rows);
|
||||||
|
UASSERT(indexMaterial < materials);
|
||||||
|
|
||||||
newCamIndex[t] = oi;
|
newCamIndex[t] = oi;
|
||||||
int u = oi%cols * emptyImage.cols;
|
int u = oi%cols * emptyImage.cols;
|
||||||
int v = oi/cols * emptyImage.rows;
|
int v = ((oi/cols) % rows ) * emptyImage.rows;
|
||||||
UASSERT(u < textureSize-emptyImage.cols);
|
UASSERT(u < textureSize-emptyImage.cols);
|
||||||
UASSERT(v < textureSize-emptyImage.rows);
|
UASSERT(v < textureSize-emptyImage.rows);
|
||||||
imageOrigin[t].x = u;
|
imageOrigin[t].x = u;
|
||||||
@@ -3176,15 +3200,15 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
}
|
}
|
||||||
if(_ui->checkBox_gainCompensation->isChecked() && _compensator && _compensator->getIndex(textures[t].first) >= 0)
|
if(_ui->checkBox_gainCompensation->isChecked() && _compensator && _compensator->getIndex(textures[t].first) >= 0)
|
||||||
{
|
{
|
||||||
_compensator->apply(textures[t].first, resizedImage);
|
_compensator->apply(textures[t].first, resizedImage, _ui->checkBox_gainRGB->isChecked());
|
||||||
}
|
}
|
||||||
UASSERT(resizedImage.type() == globalTexture.type());
|
UASSERT(resizedImage.type() == globalTextures[indexMaterial].type());
|
||||||
resizedImage.copyTo(globalTexture(cv::Rect(u, v, resizedImage.cols, resizedImage.rows)));
|
resizedImage.copyTo(globalTextures[indexMaterial](cv::Rect(u, v, resizedImage.cols, resizedImage.rows)));
|
||||||
emptyImageMask.copyTo(globalTextureMask(cv::Rect(u, v, resizedImage.cols, resizedImage.rows)));
|
emptyImageMask.copyTo(globalTextureMasks[indexMaterial](cv::Rect(u, v, resizedImage.cols, resizedImage.rows)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emptyImage.copyTo(globalTexture(cv::Rect(u, v, emptyImage.cols, emptyImage.rows)));
|
emptyImage.copyTo(globalTextures[indexMaterial](cv::Rect(u, v, emptyImage.cols, emptyImage.rows)));
|
||||||
}
|
}
|
||||||
++oi;
|
++oi;
|
||||||
}
|
}
|
||||||
@@ -3227,13 +3251,15 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
N(i, j) += 1;
|
N(i, j) += 1;
|
||||||
N(j, i) += 1;
|
N(j, i) += 1;
|
||||||
|
|
||||||
|
int indexMaterial = i / (cols*rows);
|
||||||
|
|
||||||
// uv in globalTexture
|
// uv in globalTexture
|
||||||
int ui = iter->second.x*emptyImage.cols + imageOrigin[iter->first].x;
|
int ui = iter->second.x*emptyImage.cols + imageOrigin[iter->first].x;
|
||||||
int vi = (1.0-iter->second.y)*emptyImage.rows + imageOrigin[iter->first].y;
|
int vi = (1.0-iter->second.y)*emptyImage.rows + imageOrigin[iter->first].y;
|
||||||
int uj = jter->second.x*emptyImage.cols + imageOrigin[jter->first].x;
|
int uj = jter->second.x*emptyImage.cols + imageOrigin[jter->first].x;
|
||||||
int vj = (1.0-jter->second.y)*emptyImage.rows + imageOrigin[jter->first].y;
|
int vj = (1.0-jter->second.y)*emptyImage.rows + imageOrigin[jter->first].y;
|
||||||
cv::Vec3b * pt1 = globalTexture.ptr<cv::Vec3b>(vi,ui);
|
cv::Vec3b * pt1 = globalTextures[indexMaterial].ptr<cv::Vec3b>(vi,ui);
|
||||||
cv::Vec3b * pt2 = globalTexture.ptr<cv::Vec3b>(vj,uj);
|
cv::Vec3b * pt2 = globalTextures[indexMaterial].ptr<cv::Vec3b>(vj,uj);
|
||||||
|
|
||||||
I(i, j) += std::sqrt(static_cast<double>(sqr(pt1->val[0]) + sqr(pt1->val[1]) + sqr(pt1->val[2])));
|
I(i, j) += std::sqrt(static_cast<double>(sqr(pt1->val[0]) + sqr(pt1->val[1]) + sqr(pt1->val[2])));
|
||||||
I(j, i) += std::sqrt(static_cast<double>(sqr(pt2->val[0]) + sqr(pt2->val[1]) + sqr(pt2->val[2])));
|
I(j, i) += std::sqrt(static_cast<double>(sqr(pt2->val[0]) + sqr(pt2->val[1]) + sqr(pt2->val[2])));
|
||||||
@@ -3323,14 +3349,17 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
|
|
||||||
UDEBUG("Gain cam%d = %f", newCamIndex[t], gainsGray(newCamIndex[t], 0));
|
UDEBUG("Gain cam%d = %f", newCamIndex[t], gainsGray(newCamIndex[t], 0));
|
||||||
|
|
||||||
cv::Mat roi = globalTexture(cv::Rect(u, v, emptyImage.cols, emptyImage.rows));
|
int indexMaterial = newCamIndex[t] / (cols*rows);
|
||||||
|
cv::Mat roi = globalTextures[indexMaterial](cv::Rect(u, v, emptyImage.cols, emptyImage.rows));
|
||||||
|
|
||||||
std::vector<cv::Mat> channels;
|
std::vector<cv::Mat> channels;
|
||||||
cv::split(roi, channels);
|
cv::split(roi, channels);
|
||||||
|
|
||||||
// assuming BGR
|
// assuming BGR
|
||||||
cv::multiply(channels[0], gains(newCamIndex[t], 3), channels[0]);
|
cv::multiply(channels[0], gains(newCamIndex[t], _ui->checkBox_gainRGB->isChecked()?3:0), channels[0]);
|
||||||
cv::multiply(channels[1], gains(newCamIndex[t], 2), channels[1]);
|
cv::multiply(channels[1], gains(newCamIndex[t], _ui->checkBox_gainRGB->isChecked()?2:0), channels[1]);
|
||||||
cv::multiply(channels[2], gains(newCamIndex[t], 1), channels[2]);
|
cv::multiply(channels[2], gains(newCamIndex[t], _ui->checkBox_gainRGB->isChecked()?1:0), channels[2]);
|
||||||
|
|
||||||
cv::merge(channels, roi);
|
cv::merge(channels, roi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3352,17 +3381,20 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
int polygonSize = mesh.tex_polygons[0][0].vertices.size();
|
int polygonSize = mesh.tex_polygons[0][0].vertices.size();
|
||||||
UDEBUG("polygon size=%d", polygonSize);
|
UDEBUG("polygon size=%d", polygonSize);
|
||||||
|
|
||||||
for(unsigned int i=0; i<mesh.tex_coordinates[0].size(); i+=polygonSize)
|
for(unsigned int k=0; k<mesh.tex_coordinates.size(); ++k)
|
||||||
|
{
|
||||||
|
for(unsigned int i=0; i<mesh.tex_coordinates[k].size(); i+=polygonSize)
|
||||||
{
|
{
|
||||||
for(int j=0; j<polygonSize; ++j)
|
for(int j=0; j<polygonSize; ++j)
|
||||||
{
|
{
|
||||||
const Eigen::Vector2f & uc1 = mesh.tex_coordinates[0][i + j];
|
const Eigen::Vector2f & uc1 = mesh.tex_coordinates[k][i + j];
|
||||||
const Eigen::Vector2f & uc2 = mesh.tex_coordinates[0][i + (j+1)%polygonSize];
|
const Eigen::Vector2f & uc2 = mesh.tex_coordinates[k][i + (j+1)%polygonSize];
|
||||||
Eigen::Vector2f edge = (uc1-uc2)*textureSize;
|
Eigen::Vector2f edge = (uc1-uc2)*textureSize;
|
||||||
edgeLengths.push_back(fabs(edge[0]));
|
edgeLengths.push_back(fabs(edge[0]));
|
||||||
edgeLengths.push_back(fabs(edge[1]));
|
edgeLengths.push_back(fabs(edge[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
float edgeLength = 0.0f;
|
float edgeLength = 0.0f;
|
||||||
if(edgeLengths.size())
|
if(edgeLengths.size())
|
||||||
{
|
{
|
||||||
@@ -3390,7 +3422,12 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
UDEBUG("decimation=%d", decimation);
|
UDEBUG("decimation=%d", decimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat blendGains(globalTexture.rows/decimation, globalTexture.cols/decimation, CV_32FC3, cv::Scalar::all(1.0f));
|
std::vector<cv::Mat> blendGains(materials);
|
||||||
|
for(int i=0; i<materials;++i)
|
||||||
|
{
|
||||||
|
blendGains[i] = cv::Mat(globalTextures[i].rows/decimation, globalTextures[i].cols/decimation, CV_32FC3, cv::Scalar::all(1.0f));
|
||||||
|
}
|
||||||
|
|
||||||
for(unsigned int p=0; p<textureVertexToPixels.size(); ++p)
|
for(unsigned int p=0; p<textureVertexToPixels.size(); ++p)
|
||||||
{
|
{
|
||||||
if(textureVertexToPixels[p].size() > 1)
|
if(textureVertexToPixels[p].size() > 1)
|
||||||
@@ -3413,7 +3450,8 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
{
|
{
|
||||||
weight = 0.0f;
|
weight = 0.0f;
|
||||||
}
|
}
|
||||||
cv::Vec3b * pt = globalTexture.ptr<cv::Vec3b>(v,u);
|
int indexMaterial = newCamIndex[iter->first] / (cols*rows);
|
||||||
|
cv::Vec3b * pt = globalTextures[indexMaterial].ptr<cv::Vec3b>(v,u);
|
||||||
gainsB[k] = static_cast<double>(pt->val[0]) * weight;
|
gainsB[k] = static_cast<double>(pt->val[0]) * weight;
|
||||||
gainsG[k] = static_cast<double>(pt->val[1]) * weight;
|
gainsG[k] = static_cast<double>(pt->val[1]) * weight;
|
||||||
gainsR[k] = static_cast<double>(pt->val[2]) * weight;
|
gainsR[k] = static_cast<double>(pt->val[2]) * weight;
|
||||||
@@ -3437,11 +3475,12 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
{
|
{
|
||||||
int u = iter->second.x*emptyImage.cols + imageOrigin[iter->first].x;
|
int u = iter->second.x*emptyImage.cols + imageOrigin[iter->first].x;
|
||||||
int v = (1.0-iter->second.y)*emptyImage.rows + imageOrigin[iter->first].y;
|
int v = (1.0-iter->second.y)*emptyImage.rows + imageOrigin[iter->first].y;
|
||||||
cv::Vec3b * pt = globalTexture.ptr<cv::Vec3b>(v,u);
|
int indexMaterial = newCamIndex[iter->first] / (cols*rows);
|
||||||
|
cv::Vec3b * pt = globalTextures[indexMaterial].ptr<cv::Vec3b>(v,u);
|
||||||
float gB = targetColor[0]/(pt->val[0]==0?1.0f:pt->val[0]);
|
float gB = targetColor[0]/(pt->val[0]==0?1.0f:pt->val[0]);
|
||||||
float gG = targetColor[1]/(pt->val[1]==0?1.0f:pt->val[1]);
|
float gG = targetColor[1]/(pt->val[1]==0?1.0f:pt->val[1]);
|
||||||
float gR = targetColor[2]/(pt->val[2]==0?1.0f:pt->val[2]);
|
float gR = targetColor[2]/(pt->val[2]==0?1.0f:pt->val[2]);
|
||||||
cv::Vec3f * ptr = blendGains.ptr<cv::Vec3f>(v/decimation, u/decimation);
|
cv::Vec3f * ptr = blendGains[indexMaterial].ptr<cv::Vec3f>(v/decimation, u/decimation);
|
||||||
ptr->val[0] = (gB>1.3f)?1.3f:(gB<0.7f)?0.7f:gB;
|
ptr->val[0] = (gB>1.3f)?1.3f:(gB<0.7f)?0.7f:gB;
|
||||||
ptr->val[1] = (gG>1.3f)?1.3f:(gG<0.7f)?0.7f:gG;
|
ptr->val[1] = (gG>1.3f)?1.3f:(gG<0.7f)?0.7f:gG;
|
||||||
ptr->val[2] = (gR>1.3f)?1.3f:(gR<0.7f)?0.7f:gR;
|
ptr->val[2] = (gR>1.3f)?1.3f:(gR<0.7f)?0.7f:gR;
|
||||||
@@ -3451,6 +3490,8 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<materials; ++i)
|
||||||
|
{
|
||||||
/*std::vector<cv::Mat> channels;
|
/*std::vector<cv::Mat> channels;
|
||||||
cv::split(blendGains, channels);
|
cv::split(blendGains, channels);
|
||||||
cv::Mat img;
|
cv::Mat img;
|
||||||
@@ -3462,8 +3503,8 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
cv::imwrite("blendSmallR.png", img);*/
|
cv::imwrite("blendSmallR.png", img);*/
|
||||||
|
|
||||||
cv::Mat dst;
|
cv::Mat dst;
|
||||||
cv::blur(blendGains, dst, cv::Size(3,3));
|
cv::blur(blendGains[i], dst, cv::Size(3,3));
|
||||||
cv::resize(dst, blendGains, globalTexture.size(), 0, 0, cv::INTER_LINEAR);
|
cv::resize(dst, blendGains[i], globalTextures[i].size(), 0, 0, cv::INTER_LINEAR);
|
||||||
|
|
||||||
/*cv::split(blendGains, channels);
|
/*cv::split(blendGains, channels);
|
||||||
channels[0].convertTo(img,CV_8U,128.0,0);
|
channels[0].convertTo(img,CV_8U,128.0,0);
|
||||||
@@ -3473,43 +3514,46 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
channels[2].convertTo(img,CV_8U,128.0,0);
|
channels[2].convertTo(img,CV_8U,128.0,0);
|
||||||
cv::imwrite("blendFullR.png", img);*/
|
cv::imwrite("blendFullR.png", img);*/
|
||||||
|
|
||||||
cv::multiply(globalTexture, blendGains, globalTexture, 1.0, CV_8UC3);
|
cv::multiply(globalTextures[i], blendGains[i], globalTextures[i], 1.0, CV_8UC3);
|
||||||
|
|
||||||
//UWARN("Saving blending.png", globalTexture);
|
//UWARN("Saving blending.png", globalTexture);
|
||||||
//cv::imwrite("blending.png", globalTexture);
|
//cv::imwrite("blending.png", globalTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(_ui->spinBox_textureBrightnessContrastRatioLow->value() > 0 || _ui->spinBox_textureBrightnessContrastRatioHigh->value() > 0)
|
if(_ui->spinBox_textureBrightnessContrastRatioLow->value() > 0 || _ui->spinBox_textureBrightnessContrastRatioHigh->value() > 0)
|
||||||
|
{
|
||||||
|
for(int i=0; i<materials; ++i)
|
||||||
{
|
{
|
||||||
if(_ui->checkBox_exposureFusion->isEnabled() && _ui->checkBox_exposureFusion->isChecked())
|
if(_ui->checkBox_exposureFusion->isEnabled() && _ui->checkBox_exposureFusion->isChecked())
|
||||||
{
|
{
|
||||||
std::vector<cv::Mat> images;
|
std::vector<cv::Mat> images;
|
||||||
images.push_back(globalTexture);
|
images.push_back(globalTextures[i]);
|
||||||
if (_ui->spinBox_textureBrightnessContrastRatioLow->value() > 0)
|
if (_ui->spinBox_textureBrightnessContrastRatioLow->value() > 0)
|
||||||
{
|
{
|
||||||
images.push_back(util2d::brightnessAndContrastAuto(
|
images.push_back(util2d::brightnessAndContrastAuto(
|
||||||
globalTexture,
|
globalTextures[i],
|
||||||
globalTextureMask,
|
globalTextureMasks[i],
|
||||||
(float)_ui->spinBox_textureBrightnessContrastRatioLow->value(),
|
(float)_ui->spinBox_textureBrightnessContrastRatioLow->value(),
|
||||||
0.0f));
|
0.0f));
|
||||||
}
|
}
|
||||||
if (_ui->spinBox_textureBrightnessContrastRatioHigh->value() > 0)
|
if (_ui->spinBox_textureBrightnessContrastRatioHigh->value() > 0)
|
||||||
{
|
{
|
||||||
images.push_back(util2d::brightnessAndContrastAuto(
|
images.push_back(util2d::brightnessAndContrastAuto(
|
||||||
globalTexture,
|
globalTextures[i],
|
||||||
globalTextureMask,
|
globalTextureMasks[i],
|
||||||
0.0f,
|
0.0f,
|
||||||
(float)_ui->spinBox_textureBrightnessContrastRatioHigh->value()));
|
(float)_ui->spinBox_textureBrightnessContrastRatioHigh->value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
globalTexture = util2d::exposureFusion(images);
|
globalTextures[i] = util2d::exposureFusion(images);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
globalTexture = util2d::brightnessAndContrastAuto(
|
globalTextures[i] = util2d::brightnessAndContrastAuto(
|
||||||
globalTexture,
|
globalTextures[i],
|
||||||
globalTextureMask,
|
globalTextureMasks[i],
|
||||||
(float)_ui->spinBox_textureBrightnessContrastRatioLow->value(),
|
(float)_ui->spinBox_textureBrightnessContrastRatioLow->value(),
|
||||||
(float)_ui->spinBox_textureBrightnessContrastRatioHigh->value());
|
(float)_ui->spinBox_textureBrightnessContrastRatioHigh->value());
|
||||||
}
|
}
|
||||||
@@ -3517,7 +3561,8 @@ cv::Mat ExportCloudsDialog::mergeTextures(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return globalTexture;
|
}
|
||||||
|
return globalTextures;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportCloudsDialog::saveTextureMeshes(
|
void ExportCloudsDialog::saveTextureMeshes(
|
||||||
@@ -3547,11 +3592,11 @@ void ExportCloudsDialog::saveTextureMeshes(
|
|||||||
|
|
||||||
pcl::TextureMesh::Ptr mesh = meshes.begin()->second;
|
pcl::TextureMesh::Ptr mesh = meshes.begin()->second;
|
||||||
|
|
||||||
cv::Mat globalTexture;
|
std::vector<cv::Mat> globalTextures;
|
||||||
bool texturesMerged = _ui->comboBox_meshingTextureSize->isEnabled() && _ui->comboBox_meshingTextureSize->currentIndex() > 0;
|
bool texturesMerged = _ui->comboBox_meshingTextureSize->isEnabled() && _ui->comboBox_meshingTextureSize->currentIndex() > 0;
|
||||||
if(texturesMerged && mesh->tex_materials.size()>1)
|
if(texturesMerged && mesh->tex_materials.size()>1)
|
||||||
{
|
{
|
||||||
globalTexture = mergeTextures(*mesh, cachedSignatures, textureVertexToPixels);
|
globalTextures = mergeTextures(*mesh, cachedSignatures, textureVertexToPixels, _ui->spinBox_mesh_maxTextures->value());
|
||||||
}
|
}
|
||||||
bool singleTexture = mesh->tex_materials.size() == 1;
|
bool singleTexture = mesh->tex_materials.size() == 1;
|
||||||
if(!singleTexture)
|
if(!singleTexture)
|
||||||
@@ -3631,7 +3676,7 @@ void ExportCloudsDialog::saveTextureMeshes(
|
|||||||
}
|
}
|
||||||
if(_ui->checkBox_gainCompensation->isChecked() && _compensator && _compensator->getIndex(textureId) >= 0)
|
if(_ui->checkBox_gainCompensation->isChecked() && _compensator && _compensator->getIndex(textureId) >= 0)
|
||||||
{
|
{
|
||||||
_compensator->apply(textureId, image);
|
_compensator->apply(textureId, image, _ui->checkBox_gainRGB->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!cv::imwrite(fullPath.toStdString(), image))
|
if(!cv::imwrite(fullPath.toStdString(), image))
|
||||||
@@ -3647,9 +3692,9 @@ void ExportCloudsDialog::saveTextureMeshes(
|
|||||||
cv::Mat image = cv::Mat::ones(imageSize, CV_8UC1)*255;
|
cv::Mat image = cv::Mat::ones(imageSize, CV_8UC1)*255;
|
||||||
cv::imwrite(fullPath.toStdString(), image);
|
cv::imwrite(fullPath.toStdString(), image);
|
||||||
}
|
}
|
||||||
else if(!globalTexture.empty())
|
else if(!globalTextures[i].empty())
|
||||||
{
|
{
|
||||||
if(!cv::imwrite(fullPath.toStdString(), globalTexture))
|
if(!cv::imwrite(fullPath.toStdString(), globalTextures[i]))
|
||||||
{
|
{
|
||||||
_progressDialog->appendText(tr("Failed saving texture \"%1\" to \"%2\".")
|
_progressDialog->appendText(tr("Failed saving texture \"%1\" to \"%2\".")
|
||||||
.arg(mesh->tex_materials[i].tex_file.c_str()).arg(fullPath), Qt::darkRed);
|
.arg(mesh->tex_materials[i].tex_file.c_str()).arg(fullPath), Qt::darkRed);
|
||||||
@@ -3713,11 +3758,11 @@ void ExportCloudsDialog::saveTextureMeshes(
|
|||||||
if(iter->second->tex_materials.size())
|
if(iter->second->tex_materials.size())
|
||||||
{
|
{
|
||||||
pcl::TextureMesh::Ptr mesh = iter->second;
|
pcl::TextureMesh::Ptr mesh = iter->second;
|
||||||
cv::Mat globalTexture;
|
std::vector<cv::Mat> globalTextures;
|
||||||
bool texturesMerged = _ui->comboBox_meshingTextureSize->isEnabled() && _ui->comboBox_meshingTextureSize->currentIndex() > 0;
|
bool texturesMerged = _ui->comboBox_meshingTextureSize->isEnabled() && _ui->comboBox_meshingTextureSize->currentIndex() > 0;
|
||||||
if(texturesMerged && mesh->tex_materials.size()>1)
|
if(texturesMerged && mesh->tex_materials.size()>1)
|
||||||
{
|
{
|
||||||
globalTexture = mergeTextures(*mesh, cachedSignatures, textureVertexToPixels);
|
globalTextures = mergeTextures(*mesh, cachedSignatures, textureVertexToPixels, _ui->spinBox_mesh_maxTextures->value());
|
||||||
}
|
}
|
||||||
bool singleTexture = mesh->tex_materials.size() == 1;
|
bool singleTexture = mesh->tex_materials.size() == 1;
|
||||||
if(!singleTexture)
|
if(!singleTexture)
|
||||||
@@ -3802,7 +3847,7 @@ void ExportCloudsDialog::saveTextureMeshes(
|
|||||||
}
|
}
|
||||||
if(_ui->checkBox_gainCompensation->isChecked() && _compensator && _compensator->getIndex(textureId) >= 0)
|
if(_ui->checkBox_gainCompensation->isChecked() && _compensator && _compensator->getIndex(textureId) >= 0)
|
||||||
{
|
{
|
||||||
_compensator->apply(textureId, image);
|
_compensator->apply(textureId, image, _ui->checkBox_gainRGB->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!cv::imwrite(fullPath.toStdString(), image))
|
if(!cv::imwrite(fullPath.toStdString(), image))
|
||||||
@@ -3818,9 +3863,9 @@ void ExportCloudsDialog::saveTextureMeshes(
|
|||||||
cv::Mat image = cv::Mat::ones(imageSize, CV_8UC1)*255;
|
cv::Mat image = cv::Mat::ones(imageSize, CV_8UC1)*255;
|
||||||
cv::imwrite(fullPath.toStdString(), image);
|
cv::imwrite(fullPath.toStdString(), image);
|
||||||
}
|
}
|
||||||
else if(!globalTexture.empty())
|
else if(!globalTextures[i].empty())
|
||||||
{
|
{
|
||||||
if(!cv::imwrite(fullPath.toStdString(), globalTexture))
|
if(!cv::imwrite(fullPath.toStdString(), globalTextures[i]))
|
||||||
{
|
{
|
||||||
_progressDialog->appendText(tr("Failed saving texture \"%1\" to \"%2\".")
|
_progressDialog->appendText(tr("Failed saving texture \"%1\" to \"%2\".")
|
||||||
.arg(mesh->tex_materials[i].tex_file.c_str()).arg(fullPath), Qt::darkRed);
|
.arg(mesh->tex_materials[i].tex_file.c_str()).arg(fullPath), Qt::darkRed);
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ private:
|
|||||||
void saveClouds(const QString & workingDirectory, const std::map<int, Transform> & poses, const std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds, bool binaryMode = true);
|
void saveClouds(const QString & workingDirectory, const std::map<int, Transform> & poses, const std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds, bool binaryMode = true);
|
||||||
void saveMeshes(const QString & workingDirectory, const std::map<int, Transform> & poses, const std::map<int, pcl::PolygonMesh::Ptr> & meshes, bool binaryMode = true);
|
void saveMeshes(const QString & workingDirectory, const std::map<int, Transform> & poses, const std::map<int, pcl::PolygonMesh::Ptr> & meshes, bool binaryMode = true);
|
||||||
void saveTextureMeshes(const QString & workingDirectory, const std::map<int, Transform> & poses, std::map<int, pcl::TextureMesh::Ptr> & textureMeshes, const QMap<int, Signature> & cachedSignatures, const std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels);
|
void saveTextureMeshes(const QString & workingDirectory, const std::map<int, Transform> & poses, std::map<int, pcl::TextureMesh::Ptr> & textureMeshes, const QMap<int, Signature> & cachedSignatures, const std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels);
|
||||||
cv::Mat mergeTextures(pcl::TextureMesh & mesh, const QMap<int, Signature> & cachedSignatures, const std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels) const;
|
std::vector<cv::Mat> mergeTextures(pcl::TextureMesh & mesh, const QMap<int, Signature> & cachedSignatures, const std::vector<std::map<int, pcl::PointXY> > & textureVertexToPixels, int maxTextures) const;
|
||||||
|
|
||||||
void setSaveButton();
|
void setSaveButton();
|
||||||
void setOkButton();
|
void setOkButton();
|
||||||
|
|||||||
+161
-124
@@ -23,9 +23,9 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>-1412</y>
|
||||||
<width>773</width>
|
<width>773</width>
|
||||||
<height>3895</height>
|
<height>3953</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||||
@@ -1151,6 +1151,38 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_12" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout_12" columnstretch="0,1">
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainBeta">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>1000.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>100.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLabel" name="label_binaryFile_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Do full compensation between all locations (longer to do but quality is better). Otherwise, compensation is done only between linked locations.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainOverlap">
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainOverlap">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
@@ -1173,35 +1205,13 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_gainFull">
|
<widget class="QCheckBox" name="checkBox_gainFull">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_gainBeta">
|
|
||||||
<property name="suffix">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<double>0.100000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>1000.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>1.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>100.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="label_binaryFile_3">
|
<widget class="QLabel" name="label_binaryFile_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -1255,15 +1265,22 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QLabel" name="label_binaryFile_7">
|
<widget class="QLabel" name="label_binaryFile_8">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Do full compensation between all locations (longer to do but quality is better). Otherwise, compensation is done only between linked locations.</string>
|
<string>Gain on each RGB channel separatly.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_gainRGB">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -1469,51 +1486,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_15" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout_15" columnstretch="0,1">
|
||||||
<item row="7" column="0">
|
<item row="7" column="1">
|
||||||
<widget class="QComboBox" name="comboBox_blendingDecimation">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Auto</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>1</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>2</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>4</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>8</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>16</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>32</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>64</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="QLabel" name="label_exposureFusion_2">
|
<widget class="QLabel" name="label_exposureFusion_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Blending. Only used with dense reconstruction flavor and if clouds are assembled.</string>
|
<string>Blending. Only used with dense reconstruction flavor and if clouds are assembled.</string>
|
||||||
@@ -1523,7 +1496,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_2">
|
<widget class="QLabel" name="label_meshingTextureSize_2">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Maximum distance from the camera for polygons to be textured by this camera (0 means infinite). Only used with dense reconstruction flavor.</string>
|
<string>Maximum distance from the camera for polygons to be textured by this camera (0 means infinite). Only used with dense reconstruction flavor.</string>
|
||||||
@@ -1533,7 +1506,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_meshingTextureMaxDistance">
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_meshingTextureMaxDistance">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string> m</string>
|
<string> m</string>
|
||||||
@@ -1555,7 +1528,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="1">
|
<item row="9" column="1">
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_5">
|
<widget class="QLabel" name="label_meshingTextureSize_5">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Brightness and contrast balance low ratio. Only used when textures are merged.</string>
|
<string>Brightness and contrast balance low ratio. Only used when textures are merged.</string>
|
||||||
@@ -1589,17 +1562,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="10" column="0">
|
||||||
<widget class="QLabel" name="label_meshingTextureSize">
|
|
||||||
<property name="text">
|
|
||||||
<string>Output texture size. If not set or when clouds are not assembled, all textures are saved separately. Warning: values higher than 2048 may not be compatible with all GPUs.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="0">
|
|
||||||
<widget class="QSpinBox" name="spinBox_textureBrightnessContrastRatioHigh">
|
<widget class="QSpinBox" name="spinBox_textureBrightnessContrastRatioHigh">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string> %</string>
|
<string> %</string>
|
||||||
@@ -1612,21 +1575,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="10" column="1">
|
||||||
<widget class="QCheckBox" name="checkBox_blending">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QCheckBox" name="checkBox_cameraFilter">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="1">
|
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_6">
|
<widget class="QLabel" name="label_meshingTextureSize_6">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Brightness and contrast balance high ratio. Only used when textures are merged.</string>
|
<string>Brightness and contrast balance high ratio. Only used when textures are merged.</string>
|
||||||
@@ -1685,7 +1634,95 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="12" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_exposureFusion">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLabel" name="label_meshingTextureSize_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Minimum polygon cluster size for texturing. This removes textures applied on sparse polygons. Only used with dense reconstruction flavor.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_meshingTextureRoiRatios"/>
|
||||||
|
</item>
|
||||||
<item row="8" column="0">
|
<item row="8" column="0">
|
||||||
|
<widget class="QComboBox" name="comboBox_blendingDecimation">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Auto</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>1</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>2</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>4</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>8</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>16</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>32</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>64</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_meshingTextureSize">
|
||||||
|
<property name="text">
|
||||||
|
<string>Output texture size. If not set or when clouds are not assembled, all textures are saved separately. Warning: values higher than 2048 may not be compatible with all GPUs.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_blending">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_cameraFilter">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="0">
|
||||||
<widget class="QSpinBox" name="spinBox_textureBrightnessContrastRatioLow">
|
<widget class="QSpinBox" name="spinBox_textureBrightnessContrastRatioLow">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string> %</string>
|
<string> %</string>
|
||||||
@@ -1698,14 +1735,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_exposureFusion">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QSpinBox" name="spinBox_mesh_minTextureClusterSize">
|
<widget class="QSpinBox" name="spinBox_mesh_minTextureClusterSize">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
@@ -1715,7 +1745,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="QLabel" name="label_exposureFusion_3">
|
<widget class="QLabel" name="label_exposureFusion_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Blending decimation. </string>
|
<string>Blending decimation. </string>
|
||||||
@@ -1725,17 +1755,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Minimum polygon cluster size for texturing. This removes textures applied on sparse polygons. Only used with dense reconstruction flavor.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_3">
|
<widget class="QLabel" name="label_meshingTextureSize_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Camera filtering. By comparing poses in the same area, only one camera in a fixed radius and angle is used for texturing.</string>
|
<string>Camera filtering. By comparing poses in the same area, only one camera in a fixed radius and angle is used for texturing.</string>
|
||||||
@@ -1745,7 +1765,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="1">
|
<item row="12" column="1">
|
||||||
<widget class="QLabel" name="label_exposureFusion">
|
<widget class="QLabel" name="label_exposureFusion">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Exposure fusion. Only used when textures are merged and brightness/contrast balance ratios are used (merging original texture + 1 for each ratios).</string>
|
<string>Exposure fusion. Only used when textures are merged and brightness/contrast balance ratios are used (merging original texture + 1 for each ratios).</string>
|
||||||
@@ -1755,7 +1775,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_7">
|
<widget class="QLabel" name="label_meshingTextureSize_7">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>ROI ratios [left right top bottom] between 0 and 1. This can be used to ignore black borders of RGB images caused by calibration. </string>
|
<string>ROI ratios [left right top bottom] between 0 and 1. This can be used to ignore black borders of RGB images caused by calibration. </string>
|
||||||
@@ -1766,7 +1786,24 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLineEdit" name="lineEdit_meshingTextureRoiRatios"/>
|
<widget class="QSpinBox" name="spinBox_mesh_maxTextures">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="label_meshingTextureSize_8">
|
||||||
|
<property name="text">
|
||||||
|
<string>Maximum output textures.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user