Skip to content

Commit dd8bc1b

Browse files
Scale from depth
1 parent 6cac705 commit dd8bc1b

File tree

3 files changed

+92
-15
lines changed

3 files changed

+92
-15
lines changed

meshroom/aliceVision/SfMTransform.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = "3.1"
1+
__version__ = "3.2"
22

33
from meshroom.core import desc
44
from meshroom.core.utils import DESCRIBER_TYPES, VERBOSE_LEVEL
@@ -23,6 +23,7 @@ class SfMTransform(desc.AVCommandLineNode):
2323
* from_gps: Align with the gps positions from the image metadata
2424
* align_ground: Detect ground level and align to it
2525
* from_lineup: Align using a camera pose (json line up file), tracks and a mesh
26+
* from_depthmaps: Rescale scene to match metric depth in tracks
2627
"""
2728

2829
inputs = [
@@ -47,9 +48,10 @@ class SfMTransform(desc.AVCommandLineNode):
4748
" - from_markers: Defines the coordinate system from markers specified by --markers.\n"
4849
" - from_gps: Defines coordinate system from GPS metadata.\n"
4950
" - from_lineup: Defines coordinate system using lineup json file.\n"
50-
" - align_ground: Defines ground level from the point cloud density. It assumes that the scene is oriented.",
51+
" - align_ground: Defines ground level from the point cloud density. It assumes that the scene is oriented.\n"
52+
" - from_depthmaps: Scale given depthmaps\n",
5153
value="auto",
52-
values=["transformation", "manual", "auto", "auto_from_cameras", "auto_from_cameras_x_axis", "auto_from_landmarks", "from_single_camera", "from_center_camera", "from_markers", "from_gps", "from_lineup", "align_ground"],
54+
values=["transformation", "manual", "auto", "auto_from_cameras", "auto_from_cameras_x_axis", "auto_from_landmarks", "from_single_camera", "from_center_camera", "from_markers", "from_gps", "from_lineup", "align_ground", "from_depthmaps"],
5355
),
5456
desc.File(
5557
name="lineUp",
@@ -63,7 +65,7 @@ class SfMTransform(desc.AVCommandLineNode):
6365
label="Tracks File",
6466
description="Tracks file for lineup.",
6567
value="",
66-
enabled=lambda node: node.method.value == "from_lineup"
68+
enabled=lambda node: node.method.value in ["from_lineup", "from_depthmaps"]
6769
),
6870
desc.File(
6971
name="objectFile",

src/aliceVision/sfm/pipeline/expanding/ExpansionProcess.hpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,21 @@ class ExpansionProcess{
6666
_postProcessHandler = std::move(expansionPostProcess);
6767
}
6868

69-
private:
70-
7169
/**
72-
* @brief Process sfmData if something exists inside (previous sfm)
70+
* @brief Remap the sfmData landmarks to id compatible with trackmap
7371
* @param[in] sfmData the object to update
7472
* @param[in] tracks the tracks for this scene
7573
*/
76-
bool prepareExisting(sfmData::SfMData & sfmData, const track::TracksHandler & tracksHandler);
74+
static void remapExistingLandmarks(sfmData::SfMData & sfmData, const track::TracksHandler & tracksHandler);
75+
76+
private:
7777

7878
/**
79-
* @brief Remap the sfmData landmarks to id compatible with trackmap
79+
* @brief Process sfmData if something exists inside (previous sfm)
8080
* @param[in] sfmData the object to update
8181
* @param[in] tracks the tracks for this scene
8282
*/
83-
void remapExistingLandmarks(sfmData::SfMData & sfmData, const track::TracksHandler & tracksHandler);
84-
83+
bool prepareExisting(sfmData::SfMData & sfmData, const track::TracksHandler & tracksHandler);
8584

8685

8786
private:

src/software/utils/main_sfmTransform.cpp

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <aliceVision/track/TracksHandler.hpp>
1515
#include <aliceVision/geometry/Pose3.hpp>
1616
#include <aliceVision/mesh/MeshIntersection.hpp>
17+
#include <aliceVision/sfm/pipeline/expanding/ExpansionProcess.hpp>
1718
#include <aliceVision/config.hpp>
1819
#include <fstream>
1920

@@ -30,10 +31,11 @@
3031

3132

3233

34+
3335
// These constants define the current software version.
3436
// They must be updated when the command line is changed.
35-
#define ALICEVISION_SOFTWARE_VERSION_MAJOR 1
36-
#define ALICEVISION_SOFTWARE_VERSION_MINOR 1
37+
#define ALICEVISION_SOFTWARE_VERSION_MAJOR 3
38+
#define ALICEVISION_SOFTWARE_VERSION_MINOR 2
3739

3840
using namespace aliceVision;
3941

@@ -57,7 +59,8 @@ enum class EAlignmentMethod : unsigned char
5759
FROM_MARKERS,
5860
FROM_GPS,
5961
FROM_LINEUP,
60-
ALIGN_GROUND
62+
ALIGN_GROUND,
63+
FROM_DEPTHMAPS
6164
};
6265

6366
/**
@@ -93,6 +96,8 @@ std::string EAlignmentMethod_enumToString(EAlignmentMethod alignmentMethod)
9396
return "from_lineup";
9497
case EAlignmentMethod::ALIGN_GROUND:
9598
return "align_ground";
99+
case EAlignmentMethod::FROM_DEPTHMAPS:
100+
return "from_depthmaps";
96101
}
97102
throw std::out_of_range("Invalid EAlignmentMethod enum");
98103
}
@@ -131,6 +136,8 @@ EAlignmentMethod EAlignmentMethod_stringToEnum(const std::string& alignmentMetho
131136
return EAlignmentMethod::FROM_LINEUP;
132137
if (method == "align_ground")
133138
return EAlignmentMethod::ALIGN_GROUND;
139+
if (method == "from_depthmaps")
140+
return EAlignmentMethod::FROM_DEPTHMAPS;
134141
throw std::out_of_range("Invalid SfM alignment method : " + alignmentMethod);
135142
}
136143

@@ -316,6 +323,62 @@ bool getPoseFromJson(const std::string & lineUpFilename, Eigen::Matrix4d & T, In
316323
return true;
317324
}
318325

326+
bool computeNewScaleFromDepths(const std::string & tracksFilename, sfmData::SfMData& sfmData, double & S)
327+
{
328+
// Load tracks
329+
ALICEVISION_LOG_INFO("Load tracks");
330+
track::TracksHandler tracksHandler;
331+
if (!tracksHandler.load(tracksFilename, sfmData.getValidViews()))
332+
{
333+
ALICEVISION_LOG_ERROR("The input tracks file '" + tracksFilename + "' cannot be read.");
334+
return false;
335+
}
336+
337+
sfm::ExpansionProcess::remapExistingLandmarks(sfmData, tracksHandler);
338+
339+
const track::TracksMap & tracks = tracksHandler.getAllTracks();
340+
341+
std::vector<double> ratios;
342+
for (const auto & [lid, landmark] : sfmData.getLandmarks())
343+
{
344+
const track::Track & track = tracks.at(lid);
345+
346+
for (const auto & [viewId, observation] : landmark.getObservations())
347+
{
348+
const sfmData::View & v = sfmData.getView(viewId);
349+
const sfmData::CameraPose cp = sfmData.getPose(v);
350+
351+
Vec3 pt = cp.getTransform()(landmark.X);
352+
if (pt.z() < 1e-12)
353+
{
354+
continue;
355+
}
356+
357+
double fz = track.featPerView.at(viewId).depth;
358+
if (fz < 1e-12)
359+
{
360+
continue;
361+
}
362+
363+
//Ratio between the depth from sfm, and the depth from depthmap
364+
double ratio = fz / pt.z();
365+
ratios.push_back(ratio);
366+
}
367+
}
368+
369+
if (ratios.size() == 0)
370+
{
371+
return false;
372+
}
373+
374+
// Compute median
375+
const auto medianIterator = ratios.begin() + ratios.size() / 2 - 1;
376+
std::nth_element(ratios.begin(), medianIterator, ratios.end());
377+
S = *medianIterator;
378+
379+
return true;
380+
}
381+
319382

320383
bool parseLineUp(const std::string & lineUpFilename, const std::string & tracksFilename, const std::string & objectFilename, sfmData::SfMData& sfmData, double & S, Eigen::Matrix3d & R, Eigen::Vector3d & t)
321384
{
@@ -478,7 +541,8 @@ int aliceVision_main(int argc, char** argv)
478541
"\t- from_single_camera: Refines the coordinate system from the camera specified by --tranformation.\n"
479542
"\t- from_markers: Refines the coordinate system from markers specified by --markers.\n"
480543
"\t- from_gps: Redefines coordinate system from GPS metadata.\n"
481-
"\t- align_ground: defines ground level from the point cloud density. It assumes that the scene is oriented.\n")
544+
"\t- align_ground: defines ground level from the point cloud density. It assumes that the scene is oriented.\n"
545+
"\t- from_depthmaps: Scale given injected depthmaps.\n")
482546
("transformation", po::value<std::string>(&transform)->default_value(transform),
483547
"Required only for 'transformation' and 'single camera' methods:\n"
484548
"Transformation: Align [X,Y,Z] to +Y-axis, rotate around Y by R deg, scale by S; syntax: X,Y,Z;R;S.\n"
@@ -687,6 +751,18 @@ int aliceVision_main(int argc, char** argv)
687751
}
688752
break;
689753
}
754+
case EAlignmentMethod::FROM_DEPTHMAPS:
755+
{
756+
R.setIdentity();
757+
t.fill(0.0);
758+
759+
if (!computeNewScaleFromDepths(tracksFilename, sfmData, S))
760+
{
761+
ALICEVISION_LOG_ERROR("Failed to use depths");
762+
return EXIT_FAILURE;
763+
}
764+
break;
765+
}
690766
case EAlignmentMethod::ALIGN_GROUND:
691767
{
692768
sfm::computeNewCoordinateSystemGroundAuto(sfmData, t);

0 commit comments

Comments
 (0)