48 typedef LORANSAC<P3PEstimator, EPNPEstimator> AbsolutePoseRANSAC;
50 void EstimateAbsolutePoseKernel(
const Camera& camera,
51 const double focal_length_factor,
52 const std::vector<Eigen::Vector2d>& points2D,
53 const std::vector<Eigen::Vector3d>& points3D,
54 const RANSACOptions& options,
55 AbsolutePoseRANSAC::Report* report) {
57 Camera scaled_camera = camera;
58 const std::vector<size_t>& focal_length_idxs = camera.FocalLengthIdxs();
59 for (
const size_t idx : focal_length_idxs) {
60 scaled_camera.Params(idx) *= focal_length_factor;
64 std::vector<Eigen::Vector2d> points2D_N(points2D.size());
65 for (
size_t i = 0; i < points2D.size(); ++i) {
66 points2D_N[i] = scaled_camera.ImageToWorld(points2D[i]);
70 auto custom_options = options;
71 custom_options.max_error =
72 scaled_camera.ImageToWorldThreshold(options.max_error);
73 AbsolutePoseRANSAC ransac(custom_options);
74 *report = ransac.Estimate(points2D_N, points3D);
80 const std::vector<Eigen::Vector2d>& points2D,
81 const std::vector<Eigen::Vector3d>& points3D,
82 Eigen::Vector4d* qvec,
83 Eigen::Vector3d* tvec,
86 std::vector<char>* inlier_mask) {
89 std::vector<double> focal_length_factors;
97 for (
double f = 0; f <= 1.0; f += fstep) {
102 focal_length_factors.reserve(1);
103 focal_length_factors.push_back(1);
106 std::vector<std::future<void>> futures;
107 futures.resize(focal_length_factors.size());
108 std::vector<
typename AbsolutePoseRANSAC::Report,
109 Eigen::aligned_allocator<typename AbsolutePoseRANSAC::Report>>
111 reports.resize(focal_length_factors.size());
115 static_cast<int>(focal_length_factors.size())));
117 for (
size_t i = 0; i < focal_length_factors.size(); ++i) {
118 futures[i] = thread_pool.
AddTask(
119 EstimateAbsolutePoseKernel, *camera, focal_length_factors[i],
123 double focal_length_factor = 0;
126 inlier_mask->clear();
129 for (
size_t i = 0; i < focal_length_factors.size(); ++i) {
131 const auto report = reports[i];
132 if (report.success && report.support.num_inliers > *num_inliers) {
133 *num_inliers = report.support.num_inliers;
134 proj_matrix = report.model;
135 *inlier_mask = report.inlier_mask;
136 focal_length_factor = focal_length_factors[i];
140 if (*num_inliers == 0) {
146 const std::vector<size_t>& focal_length_idxs =
148 for (
const size_t idx : focal_length_idxs) {
149 camera->
Params(idx) *= focal_length_factor;
155 *tvec = proj_matrix.rightCols<1>();
165 const std::vector<Eigen::Vector2d>& points1,
166 const std::vector<Eigen::Vector2d>& points2,
167 Eigen::Vector4d* qvec,
168 Eigen::Vector3d* tvec) {
170 const auto report = ransac.
Estimate(points1, points2);
172 if (!report.success) {
176 std::vector<Eigen::Vector2d> inliers1(report.support.num_inliers);
177 std::vector<Eigen::Vector2d> inliers2(report.support.num_inliers);
180 for (
size_t i = 0; i < points1.size(); ++i) {
181 if (report.inlier_mask[i]) {
182 inliers1[j] = points1[i];
183 inliers2[j] = points2[i];
190 std::vector<Eigen::Vector3d> points3D;
200 return points3D.size();
204 const std::vector<char>& inlier_mask,
205 const std::vector<Eigen::Vector2d>& points2D,
206 const std::vector<Eigen::Vector3d>& points3D,
207 Eigen::Vector4d* qvec,
208 Eigen::Vector3d* tvec,
210 CHECK_EQ(inlier_mask.size(), points2D.size());
211 CHECK_EQ(points2D.size(), points3D.size());
214 ceres::LossFunction* loss_function =
217 double* camera_params_data = camera->
ParamsData();
218 double* qvec_data = qvec->data();
219 double* tvec_data = tvec->data();
221 std::vector<Eigen::Vector3d> points3D_copy = points3D;
223 ceres::Problem problem;
225 for (
size_t i = 0; i < points2D.size(); ++i) {
227 if (!inlier_mask[i]) {
231 ceres::CostFunction* cost_function =
nullptr;
234 #define CAMERA_MODEL_CASE(CameraModel) \
235 case CameraModel::kModelId: \
236 cost_function = BundleAdjustmentCostFunction<CameraModel>::Create( \
242 #undef CAMERA_MODEL_CASE
245 problem.AddResidualBlock(cost_function, loss_function, qvec_data,
246 tvec_data, points3D_copy[i].
data(),
248 problem.SetParameterBlockConstant(points3D_copy[i].
data());
251 if (problem.NumResiduals() > 0) {
261 problem.SetParameterBlockConstant(camera->
ParamsData());
264 std::vector<int> camera_params_const;
265 const std::vector<size_t>& principal_point_idxs =
267 camera_params_const.insert(camera_params_const.end(),
268 principal_point_idxs.begin(),
269 principal_point_idxs.end());
272 const std::vector<size_t>& focal_length_idxs =
274 camera_params_const.insert(camera_params_const.end(),
275 focal_length_idxs.begin(),
276 focal_length_idxs.end());
280 const std::vector<size_t>& extra_params_idxs =
282 camera_params_const.insert(camera_params_const.end(),
283 extra_params_idxs.begin(),
284 extra_params_idxs.end());
287 if (camera_params_const.size() == camera->
NumParams()) {
288 problem.SetParameterBlockConstant(camera->
ParamsData());
291 camera_params_const, &problem,
304 ceres::Solver::Options solver_options;
307 solver_options.linear_solver_type = ceres::DENSE_QR;
310 solver_options.num_threads = 1;
311 #if CERES_VERSION_MAJOR < 2
312 solver_options.num_linear_solver_threads = 1;
315 ceres::Solver::Summary summary;
318 if (solver_options.minimizer_progress_to_stdout) {
327 return summary.IsSolutionUsable();
331 const std::vector<Eigen::Vector2d>& points1,
332 const std::vector<Eigen::Vector2d>& points2,
333 Eigen::Vector4d* qvec,
334 Eigen::Vector3d* tvec) {
335 CHECK_EQ(points1.size(), points2.size());
340 const double kMaxL2Error = 1.0;
341 ceres::LossFunction* loss_function =
new ceres::CauchyLoss(kMaxL2Error);
343 ceres::Problem problem;
345 for (
size_t i = 0; i < points1.size(); ++i) {
346 ceres::CostFunction* cost_function =
348 problem.AddResidualBlock(cost_function, loss_function, qvec->data(),
361 SetSphereManifold<3>(&problem, tvec->data());
363 ceres::Solver::Summary summary;
366 return summary.IsSolutionUsable();
#define CAMERA_MODEL_SWITCH_CASES
const std::vector< double > & Params() const
const std::vector< size_t > & PrincipalPointIdxs() const
const std::vector< size_t > & ExtraParamsIdxs() const
const std::vector< size_t > & FocalLengthIdxs() const
const double * ParamsData() const
Report Estimate(const std::vector< typename Estimator::X_t > &X, const std::vector< typename Estimator::Y_t > &Y)
static ceres::CostFunction * Create(const Eigen::Vector2d &x1, const Eigen::Vector2d &x2)
auto AddTask(func_t &&f, args_t &&... args) -> std::future< typename std::result_of< func_t(args_t...)>::type >
Matrix< double, 3, 4 > Matrix3x4d
QTextStream & endl(QTextStream &stream)
void Solve(const Tensor &A, const Tensor &B, Tensor &X)
Solve AX = B with LU decomposition. A is a square matrix.
void PrintHeading2(const std::string &heading)
size_t EstimateRelativePose(const RANSACOptions &ransac_options, const std::vector< Eigen::Vector2d > &points1, const std::vector< Eigen::Vector2d > &points2, Eigen::Vector4d *qvec, Eigen::Vector3d *tvec)
Eigen::Vector4d NormalizeQuaternion(const Eigen::Vector4d &qvec)
void PrintSolverSummary(const ceres::Solver::Summary &summary)
bool EstimateAbsolutePose(const AbsolutePoseEstimationOptions &options, const std::vector< Eigen::Vector2d > &points2D, const std::vector< Eigen::Vector3d > &points3D, Eigen::Vector4d *qvec, Eigen::Vector3d *tvec, Camera *camera, size_t *num_inliers, std::vector< char > *inlier_mask)
Eigen::Vector4d RotationMatrixToQuaternion(const Eigen::Matrix3d &rot_mat)
void SetQuaternionManifold(ceres::Problem *problem, double *quat_xyzw)
bool RefineRelativePose(const ceres::Solver::Options &options, const std::vector< Eigen::Vector2d > &points1, const std::vector< Eigen::Vector2d > &points2, Eigen::Vector4d *qvec, Eigen::Vector3d *tvec)
bool RefineAbsolutePose(const AbsolutePoseRefinementOptions &options, const std::vector< char > &inlier_mask, const std::vector< Eigen::Vector2d > &points2D, const std::vector< Eigen::Vector3d > &points3D, Eigen::Vector4d *qvec, Eigen::Vector3d *tvec, Camera *camera)
bool IsNaN(const float x)
void PoseFromEssentialMatrix(const Eigen::Matrix3d &E, const std::vector< Eigen::Vector2d > &points1, const std::vector< Eigen::Vector2d > &points2, Eigen::Matrix3d *R, Eigen::Vector3d *t, std::vector< Eigen::Vector3d > *points3D)
void SetSubsetManifold(int size, const std::vector< int > &constant_params, ceres::Problem *problem, double *params)
bool estimate_focal_length
RANSACOptions ransac_options
size_t num_focal_length_samples
double min_focal_length_ratio
double max_focal_length_ratio
double loss_function_scale
double gradient_tolerance