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
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
3840using 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
320383bool 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