Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[multiview] Addition of 10 points relative pose solver #474

Merged
merged 43 commits into from
May 17, 2020
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
0d35aa4
Addition of 10 points relative pose solver
gregoire-dl Oct 23, 2018
71666d7
[software] WIP: Use F10 Solver in `FeatureMatching`
gregoire-dl Jan 8, 2019
09dacfa
[multiview] Reformatting relative pose and resection solvers / kernels
gregoire-dl Apr 12, 2019
d666022
[multiview] Remove empty `EssentialError`
gregoire-dl Apr 15, 2019
58a5364
[multiview] Remove unused `P3P_ResectionKernel_K`
gregoire-dl Apr 15, 2019
7e9e6f7
[software] `featureMatching` Fix error : in some case`geometricErrorM…
gregoire-dl Apr 15, 2019
bf14eb0
[multiview] Formatting comments and functions typography
gregoire-dl Apr 16, 2019
4ba7108
[multiview] Resolve cross dependency with `robustEstimation`
gregoire-dl Apr 16, 2019
7a0dce7
[multiview] FIx codacy issues
gregoire-dl Apr 24, 2019
445d33b
[robustEstimation] Fix codacy issues
gregoire-dl Apr 24, 2019
31bad06
[aliceVision] Formatting code
gregoire-dl Apr 25, 2019
5aeaa8d
[robustEstimaation] Rename `FittingKernel` to `PointFittingKernel`
gregoire-dl Apr 25, 2019
71a7a8c
[travis] Update dependencies
gregoire-dl Apr 26, 2019
c5ba23d
Merge branch 'develop' of https://github.com/alicevision/AliceVision …
fabiencastan Sep 18, 2019
0412d7b
[sfm] bugfix: ceres::AngleAxisRotatePoint cannot by used in-place
fabiencastan Sep 19, 2019
b87b7a8
[samples] added a sample to test F10
simogasp Mar 1, 2019
5f596ba
Merge branch 'develop' into dev_F10
fabiencastan Apr 10, 2020
613361c
Merge develop into dev_F10
fabiencastan Apr 27, 2020
d8d475c
[robustEstimation] build fix: missing include with MSVC
fabiencastan Apr 29, 2020
a7e724f
[feature] remove unused
simogasp May 2, 2020
6056cd8
[multiview] reduce scope
simogasp May 2, 2020
f954abe
[robust] const
simogasp May 2, 2020
962f206
[multiview] remove duplicated file
fabiencastan May 3, 2020
0573b90
[multiview] tests: use a fixed translate value
fabiencastan May 3, 2020
392763e
[multiview] tests: more checks
fabiencastan May 3, 2020
7c995c3
[numeric] add cheirality test functions
simogasp May 4, 2020
0ef5272
[cmake] add unit test for cheirality functions
simogasp May 4, 2020
a392bf4
[numeric] typedef --> using
simogasp May 4, 2020
3947752
[test] add safeguard to generate points in front of the camera
simogasp May 4, 2020
4d8a5ed
[test] add more trials
simogasp May 4, 2020
cccac2e
[cmake] add explicit boost test define
fabiencastan May 5, 2020
24667bd
[sfm] lossFunction as a ceres options
fabiencastan May 8, 2020
e684381
Merge remote-tracking branch 'origin/develop' into dev_F10
fabiencastan May 11, 2020
a284fcf
[ci] travis: update SfM_quality_evaluation
fabiencastan May 15, 2020
fd21b32
[multiview] typos
simogasp May 16, 2020
015b916
[multiview] missing override
simogasp May 16, 2020
6b4d6b1
[robustEstimation] no virtual when override
simogasp May 16, 2020
ffb6d2c
[multiview] const
simogasp May 16, 2020
5ce4113
[sample] fix
simogasp May 16, 2020
47244f7
[refactoring] move guidedMatching and supportEstimation in matching
simogasp May 16, 2020
c76bc69
[matching] split cpp hpp supportEstimation
simogasp May 16, 2020
a7de74d
[matching] split cpp hpp guidedMatching
simogasp May 16, 2020
ec1f0ed
[multiview] doc
simogasp May 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ script:
git clone --branch master https://github.com/alicevision/SfM_quality_evaluation.git $GT_TEST_SOURCE;
fi
cd $GT_TEST_SOURCE
git checkout 1828a5076ccca86fd523c92a768f1d518dfdbb91 # checkout a specific commit to ensure repeatability
python EvaluationLauncher.py -s "$ALICEVISION_BUILD/$BUILD_SYSTEM-$BUILD_PROCESSOR" -i Benchmarking_Camera_Calibration_2008/ -o ${GT_TEST_OUTPUT} -r ${GT_TEST_RESULTS} --limit 3
git checkout a78109bfb8343ce867fca5a7064bb49963c6615a # checkout a specific commit to ensure repeatability
python EvaluationLauncher.py -s "$ALICEVISION_BUILD/$BUILD_SYSTEM-$BUILD_PROCESSOR" -i Benchmarking_Camera_Calibration_2008/ -o ${GT_TEST_OUTPUT} -r ${GT_TEST_RESULTS} -v --limit 3
cat ${GT_TEST_RESULTS}
# Return to root and remove GT huge files to avoid cache problems
cd $TRAVIS_BUILD_DIR
Expand Down
16 changes: 8 additions & 8 deletions ci/install-dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ downloadFromAliceVisionDependencies()

set -x

downloadFromAliceVisionDependencies boost-1.61.0 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies eigen-3.3.4 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies ceres-1.13.0 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies boost-1.66.0 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies eigen-3.3.7 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies ceres-1.14.0 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies opencv-3.4.2 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies opengv-2018.02.26 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies openexr-2.2.1 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies openimageio-master ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies alembic-1.7.5 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies geogram-1.6.0 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies opengv-2019.04.25 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies openexr-2.3.0 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies openimageio-1.8.9 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies alembic-1.7.10 ${DEPS_INSTALL_PATH}
downloadFromAliceVisionDependencies geogram-1.6.11 ${DEPS_INSTALL_PATH}
23 changes: 11 additions & 12 deletions src/aliceVision/camera/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
# Headers
set(camera_files_headers
camera.hpp
cameraCommon.hpp
cameraUndistortImage.hpp
IntrinsicBase.hpp
IntrinsicInitMode.hpp
Pinhole.hpp
PinholeBrown.hpp
PinholeFisheye.hpp
PinholeFisheye1.hpp
PinholeRadial.hpp
camera.hpp
cameraCommon.hpp
cameraUndistortImage.hpp
IntrinsicBase.hpp
IntrinsicInitMode.hpp
Pinhole.hpp
PinholeBrown.hpp
PinholeFisheye.hpp
PinholeFisheye1.hpp
PinholeRadial.hpp
)

alicevision_add_interface(aliceVision_camera
SOURCES ${camera_files_headers}
LINKS
aliceVision_numeric
aliceVision_geometry
aliceVision_multiview
aliceVision_image
aliceVision_numeric
aliceVision_stl
aliceVision_system
)
Expand Down
6 changes: 3 additions & 3 deletions src/aliceVision/camera/Pinhole.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
#pragma once

#include <aliceVision/numeric/numeric.hpp>
#include <aliceVision/numeric/projection.hpp>
#include <aliceVision/geometry/Pose3.hpp>
#include <aliceVision/camera/cameraCommon.hpp>
#include <aliceVision/camera/IntrinsicBase.hpp>
#include <aliceVision/geometry/Pose3.hpp>
#include <aliceVision/multiview/projection.hpp>

#include <vector>
#include <sstream>
Expand Down Expand Up @@ -106,7 +106,7 @@ class Pinhole : public IntrinsicBase
virtual Mat34 get_projective_equivalent(const geometry::Pose3 & pose) const
{
Mat34 P;
P_From_KRt(K(), pose.rotation(), pose.translation(), &P);
P_from_KRt(K(), pose.rotation(), pose.translation(), &P);
return P;
}

Expand Down
2 changes: 1 addition & 1 deletion src/aliceVision/geometry/frustumIntersection_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "aliceVision/geometry/Frustum.hpp"

#include "aliceVision/multiview/NViewDataSet.hpp"
#include "aliceVision/multiview/projection.hpp"
#include "aliceVision/numeric/projection.hpp"

#include <iostream>

Expand Down
32 changes: 15 additions & 17 deletions src/aliceVision/geometry/rigidTransformation3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,13 @@ void Refine_RTS(const Mat &x1,
}
}

bool ACRansac_FindRTS(const Mat &x1,
const Mat &x2,
double &S,
Vec3 &t,
Mat3 &R,
std::vector<std::size_t> &vec_inliers,
bool refine)
bool ACRansac_FindRTS(const Mat& x1,
const Mat& x2,
double& S,
Vec3& t,
Mat3& R,
std::vector<std::size_t>& vec_inliers,
bool refine)
{
assert(3 == x1.rows());
assert(3 <= x1.cols());
Expand All @@ -142,19 +142,17 @@ bool ACRansac_FindRTS(const Mat &x1,
const std::size_t numIterations = 1024;
const double dPrecision = std::numeric_limits<double>::infinity();

Mat4 RTS;
using SolverT = geometry::RTSSolver;
using KernelT = ACKernelAdaptor_PointsRegistrationSRT<SolverT, geometry::RTSSquaredResidualError>;

typedef geometry::RTSSolver SolverType;
typedef ACKernelAdaptor_PointsRegistrationSRT<
SolverType,
geometry::RTSSquaredResidualError> KernelType;
const KernelT kernel = KernelT(x1, x2);

KernelType kernel = KernelType(x1, x2);
// Robust estimation of the Projection matrix and its precision
const std::pair<double, double> ACRansacOut =
robustEstimation::ACRANSAC(kernel, vec_inliers, numIterations, &RTS, dPrecision);
robustEstimation::MatrixModel<Mat4> RTS;

const bool good = decomposeRTS(RTS, S, t, R);
// robust estimation of the Projection matrix and its precision
const std::pair<double, double> ACRansacOut = robustEstimation::ACRANSAC(kernel, vec_inliers, numIterations, &RTS, dPrecision);

const bool good = decomposeRTS(RTS.getMatrix(), S, t, R);

// return if it is not good or refine is not required
if(!good || !refine)
Expand Down
126 changes: 78 additions & 48 deletions src/aliceVision/geometry/rigidTransformation3D.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <aliceVision/numeric/numeric.hpp>
#include <aliceVision/numeric/LMFunctor.hpp>
#include <aliceVision/robustEstimation/ISolver.hpp>

namespace aliceVision {
namespace geometry {
Expand Down Expand Up @@ -149,31 +150,46 @@ void Refine_RTS(const Mat &x1,
/**
* @brief the Solver to use for ACRansac
*/
struct RTSSolver
class RTSSolver : public robustEstimation::ISolver<robustEstimation::MatrixModel<Mat4>>
{
public:

enum
/**
* @brief Return the minimum number of required samples
* @return minimum number of required samples
*/
inline std::size_t getMinimumNbRequiredSamples() const override
{
MINIMUM_SAMPLES = 3
};
return 3;
}

enum
/**
* @brief Return the maximum number of models
* @return maximum number of models
*/
inline std::size_t getMaximumNbModels() const override
{
MAX_MODELS = 1
};

// Solve the RTS problem
static void Solve(const Mat &pts1, const Mat &pts2, std::vector<Mat4> *models)
return 1;
}

// solve the RTS problem
inline void solve(const Mat& pts1, const Mat& pts2, std::vector<robustEstimation::MatrixModel<Mat4>>& models) const
{
models.push_back( robustEstimation::MatrixModel<Mat4>(Eigen::umeyama(pts1, pts2, true)) );
}

void solve(const Mat& x1, const Mat& x2, std::vector<robustEstimation::MatrixModel<Mat4>>& models, const std::vector<double>& weights) const override
{
models->push_back(Eigen::umeyama(pts1, pts2, true));
throw std::logic_error("RTSSolver does not support problem solving with weights.");
}

// Compute the residual of the transformation
static double Error(const Mat4 &RTS, const Vec3 & pt1, const Vec3 & pt2)
// compute the residual of the transformation
inline double error(const robustEstimation::MatrixModel<Mat4>& RTS, const Vec3& pt1, const Vec3& pt2)
{
const Mat3 &RS = RTS.topLeftCorner<3, 3>();
const Vec3 &t = RTS.topRightCorner<3, 1>();
return (pt2 - (RS*pt1 + t)).norm();
const Mat4& matrixRTS = RTS.getMatrix();
const Mat3& RS = matrixRTS.topLeftCorner<3, 3>();
const Vec3& t = matrixRTS.topRightCorner<3, 1>();
return(pt2 - (RS*pt1 + t)).norm();
}
};

Expand All @@ -183,31 +199,31 @@ struct RTSSolver
*/
struct RTSSquaredResidualError
{
// Return the squared error
static double Error(const Mat4 &RTS, const Vec3 & pt1, const Vec3 & pt2)
// return the squared error
inline double error(const robustEstimation::MatrixModel<Mat4>& RTS, const Vec3& pt1, const Vec3& pt2) const
{
const Mat3 &RS = RTS.topLeftCorner<3, 3>();
const Vec3 &t = RTS.topRightCorner<3, 1>();
const Mat4& matrixRTS = RTS.getMatrix();
const Mat3& RS = matrixRTS.topLeftCorner<3, 3>();
const Vec3& t = matrixRTS.topRightCorner<3, 1>();
return (pt2 - (RS*pt1 + t)).squaredNorm();
}
};

/**
* @brief The kernel to use for ACRansac
*/
template <typename SolverArg,
typename ErrorArg,
typename ModelArg = Mat4>
template <typename SolverT_, typename ErrorT_, typename ModelT_ = robustEstimation::MatrixModel<Mat4>>
class ACKernelAdaptor_PointsRegistrationSRT
{
public:
typedef SolverArg Solver;
typedef ModelArg Model;
typedef ErrorArg ErrorT;

ACKernelAdaptor_PointsRegistrationSRT(const Mat & xA,
const Mat & xB) :
x1_(xA), x2_(xB), logalpha0_(log10(M_PI)) //@todo WTF?
using SolverT = SolverT_;
using ModelT = ModelT_;
using ErrorT = ErrorT_;

ACKernelAdaptor_PointsRegistrationSRT(const Mat& xA, const Mat& xB)
: x1_(xA)
, x2_(xB)
, _logalpha0(log10(M_PI)) //@todo WTF?
{
assert(3 == x1_.rows());
assert(x1_.rows() == x2_.rows());
Expand All @@ -216,40 +232,51 @@ class ACKernelAdaptor_PointsRegistrationSRT
// @todo normalize points?
}

enum
/**
* @brief Return the minimum number of required samples
* @return minimum number of required samples
*/
inline std::size_t getMinimumNbRequiredSamples() const
{
MINIMUM_SAMPLES = Solver::MINIMUM_SAMPLES
};
return _kernelSolver.getMinimumNbRequiredSamples();
}

enum
/**
* @brief Return the maximum number of models
* @return maximum number of models
*/
inline std::size_t getMaximumNbModels() const
{
MAX_MODELS = Solver::MAX_MODELS
};
return _kernelSolver.getMaximumNbModels();
}

void Fit(const std::vector<size_t> &samples, std::vector<Model> *models) const
void fit(const std::vector<std::size_t>& samples, std::vector<ModelT>& models) const
{
const Mat x1 = ExtractColumns(x1_, samples);
const Mat x2 = ExtractColumns(x2_, samples);
Solver::Solve(x1, x2, models);
_kernelSolver.solve(x1, x2, models);
}

double Error(size_t sample, const Model &model) const
double error(std::size_t sample, const ModelT& model) const
{
return Square(ErrorT::Error(model, x1_.col(sample), x2_.col(sample)));
return Square(_errorEstimator.error(model, x1_.col(sample), x2_.col(sample)));
}

void Errors(const Model & model, std::vector<double> & vec_errors) const
void errors(const ModelT& model, std::vector<double> & vec_errors) const
{
vec_errors.resize(x1_.cols());
for(size_t sample = 0; sample < x1_.cols(); ++sample)
vec_errors[sample] = Square(ErrorT::Error(model, x1_.col(sample), x2_.col(sample)));
for(std::size_t sample = 0; sample < x1_.cols(); ++sample)
vec_errors[sample] = error(sample,model);
}

size_t NumSamples() const { return static_cast<size_t> (x1_.cols()); }
std::size_t nbSamples() const
{
return static_cast<std::size_t> (x1_.cols());
}

void Unnormalize(Model * model) const { } //-- Do nothing, no normalization
void unnormalize(ModelT& model) const { } //-- Do nothing, no normalization

double logalpha0() const { return logalpha0_; }
double logalpha0() const { return _logalpha0; }

double multError() const { return 1.;}

Expand All @@ -260,8 +287,11 @@ class ACKernelAdaptor_PointsRegistrationSRT
double unormalizeError(double val) const { return sqrt(val); }

private:
Mat x1_, x2_; // Normalized input data
double logalpha0_; // Alpha0 is used to make the error scale invariant
Mat x1_, x2_; // normalized input data
double _logalpha0; // alpha0 is used to make the error scale invariant

SolverT _kernelSolver;
ErrorT _errorEstimator;
};

/**
Expand Down
Loading