#pragma once
#include <g2o/core/base_binary_edge.h>
#include <g2o/types/sba/types_six_dof_expmap.h>
#include <Eigen/Core>
#include <string>
#include "../../common/include/ba_benchmark_utils.h"
class EdgeBALProjection : public g2o::BaseBinaryEdge<2, Eigen::Vector2d,
g2o::VertexPointXYZ,
g2o::VertexSE3Expmap> {
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
EdgeBALProjection() : focal_length_(1.0), k1_(0.0), k2_(0.0) {}
void setIntrinsics(double focal_length, double k1, double k2) {
focal_length_ = focal_length;
k1_ = k1;
k2_ = k2;
}
void computeError() override {
const g2o::VertexPointXYZ* point =
static_cast<const g2o::VertexPointXYZ*>(_vertices[0]);
const g2o::VertexSE3Expmap* camera =
static_cast<const g2o::VertexSE3Expmap*>(_vertices[1]);
Eigen::Vector3d p_cam = camera->estimate().map(point->estimate());
if (p_cam[2] >= 0.0) {
_error = Eigen::Vector2d(1e6, 1e6);
return;
}
double xp = -p_cam[0] / p_cam[2];
double yp = -p_cam[1] / p_cam[2];
double r2 = xp * xp + yp * yp;
double distortion = 1.0 + k1_ * r2 + k2_ * r2 * r2;
double predicted_x = focal_length_ * distortion * xp;
double predicted_y = focal_length_ * distortion * yp;
_error[0] = predicted_x - _measurement[0];
_error[1] = predicted_y - _measurement[1];
}
bool read(std::istream& ) override { return false; }
bool write(std::ostream& ) const override { return false; }
private:
double focal_length_;
double k1_;
double k2_;
};
benchmark_utils::BenchmarkResult BenchmarkG2O(const std::string& dataset_path);