#ifndef CERES_EXAMPLES_SNAVELY_REPROJECTION_ERROR_H_
#define CERES_EXAMPLES_SNAVELY_REPROJECTION_ERROR_H_
#include "ceres/rotation.h"
namespace ceres {
namespace examples {
struct SnavelyReprojectionError {
SnavelyReprojectionError(double observed_x, double observed_y)
: observed_x(observed_x), observed_y(observed_y) {}
template <typename T>
bool operator()(const T* const camera,
const T* const point,
T* residuals) const {
T p[3];
AngleAxisRotatePoint(camera, point, p);
p[0] += camera[3];
p[1] += camera[4];
p[2] += camera[5];
const T xp = - p[0] / p[2];
const T yp = - p[1] / p[2];
const T& l1 = camera[7];
const T& l2 = camera[8];
const T r2 = xp*xp + yp*yp;
const T distortion = T(1.0) + r2 * (l1 + l2 * r2);
const T& focal = camera[6];
const T predicted_x = focal * distortion * xp;
const T predicted_y = focal * distortion * yp;
residuals[0] = predicted_x - T(observed_x);
residuals[1] = predicted_y - T(observed_y);
return true;
}
static ceres::CostFunction* Create(const double observed_x,
const double observed_y) {
return (new ceres::AutoDiffCostFunction<SnavelyReprojectionError, 2, 9, 3>(
new SnavelyReprojectionError(observed_x, observed_y)));
}
double observed_x;
double observed_y;
};
struct SnavelyReprojectionErrorWithQuaternions {
SnavelyReprojectionErrorWithQuaternions(double observed_x, double observed_y)
: observed_x(observed_x), observed_y(observed_y) {}
template <typename T>
bool operator()(const T* const camera,
const T* const point,
T* residuals) const {
T p[3];
QuaternionRotatePoint(camera, point, p);
p[0] += camera[4];
p[1] += camera[5];
p[2] += camera[6];
const T xp = - p[0] / p[2];
const T yp = - p[1] / p[2];
const T& l1 = camera[8];
const T& l2 = camera[9];
const T r2 = xp*xp + yp*yp;
const T distortion = T(1.0) + r2 * (l1 + l2 * r2);
const T& focal = camera[7];
const T predicted_x = focal * distortion * xp;
const T predicted_y = focal * distortion * yp;
residuals[0] = predicted_x - T(observed_x);
residuals[1] = predicted_y - T(observed_y);
return true;
}
static ceres::CostFunction* Create(const double observed_x,
const double observed_y) {
return (new ceres::AutoDiffCostFunction<
SnavelyReprojectionErrorWithQuaternions, 2, 10, 3>(
new SnavelyReprojectionErrorWithQuaternions(observed_x,
observed_y)));
}
double observed_x;
double observed_y;
};
} }
#endif