Snavely tested

release/4.3a0
dellaert 2014-10-18 13:16:44 +02:00
parent bdf12b14b9
commit 4c33444415
1 changed files with 55 additions and 19 deletions

View File

@ -262,12 +262,14 @@ struct Projective {
} }
return false; return false;
} }
// Adapt to eigen types
Vector2 operator()(const MatrixRowMajor& P, const Vector4& X) const { Vector2 operator()(const MatrixRowMajor& P, const Vector4& X) const {
Vector2 x; Vector2 x;
if (operator()(P.data(), X.data(), x.data())) if (operator()(P.data(), X.data(), x.data()))
return x; return x;
else else
throw std::runtime_error("Projective fails"); throw std::runtime_error("Projective fail");
} }
}; };
@ -276,13 +278,10 @@ struct Projective {
// focal length and 2 for radial distortion. The principal point is not modeled // focal length and 2 for radial distortion. The principal point is not modeled
// (i.e. it is assumed be located at the image center). // (i.e. it is assumed be located at the image center).
struct SnavelyReprojectionError { struct SnavelyReprojectionError {
SnavelyReprojectionError(double observed_x, double observed_y) :
observed_x(observed_x), observed_y(observed_y) {
}
template<typename T> template<typename T>
bool operator()(const T* const camera, const T* const point, bool operator()(const T* const camera, const T* const point,
T* residuals) const { T* predicted) const {
// camera[0,1,2] are the angle-axis rotation. // camera[0,1,2] are the angle-axis rotation.
T p[3]; T p[3];
ceres::AngleAxisRotatePoint(camera, point, p); ceres::AngleAxisRotatePoint(camera, point, p);
@ -306,26 +305,21 @@ struct SnavelyReprojectionError {
// Compute final projected point position. // Compute final projected point position.
const T& focal = camera[6]; const T& focal = camera[6];
T predicted_x = focal * distortion * xp; predicted[0] = focal * distortion * xp;
T predicted_y = focal * distortion * yp; predicted[1] = focal * distortion * yp;
// The error is the difference between the predicted and observed position.
residuals[0] = predicted_x - T(observed_x);
residuals[1] = predicted_y - T(observed_y);
return true; return true;
} }
// Factory to hide the construction of the CostFunction object from // Adapt to GTSAM types
// the client code. Vector2 operator()(const Vector9& P, const Vector3& X) const {
static ceres::CostFunction* Create(const double observed_x, Vector2 x;
const double observed_y) { if (operator()(P.data(), X.data(), x.data()))
return (new ceres::AutoDiffCostFunction<SnavelyReprojectionError, 2, 9, 3>( return x;
new SnavelyReprojectionError(observed_x, observed_y))); else
throw std::runtime_error("Snavely fail");
} }
double observed_x;
double observed_y;
}; };
/* ************************************************************************* */ /* ************************************************************************* */
@ -438,6 +432,48 @@ TEST(Expression, AutoDiff) {
EXPECT(assert_equal(E2,H2,1e-8)); EXPECT(assert_equal(E2,H2,1e-8));
} }
/* ************************************************************************* */
// Test Ceres AutoDiff on Snavely
TEST(Expression, AutoDiff2) {
using ceres::internal::AutoDiff;
// Instantiate function
SnavelyReprojectionError snavely;
// Make arguments
Vector9 P;
P << 0, 0, 0, 0, 5, 0, 1, 0, 0;
Vector3 X(10, 0, -5);
// Apply the mapping, to get image point b_x.
Vector expected = Vector2(2, 1);
Vector2 actual = snavely(P, X);
EXPECT(assert_equal(expected,actual,1e-9));
// Get expected derivatives
Matrix E1 = numericalDerivative21<Vector2, Vector9, Vector3>(
SnavelyReprojectionError(), P, X);
Matrix E2 = numericalDerivative22<Vector2, Vector9, Vector3>(
SnavelyReprojectionError(), P, X);
// Get derivatives with AutoDiff
Vector2 actual2;
MatrixRowMajor H1(2, 9), H2(2, 3);
double *parameters[] = { P.data(), X.data() };
double *jacobians[] = { H1.data(), H2.data() };
CHECK(
(AutoDiff<SnavelyReprojectionError, double, 9, 3>::Differentiate( snavely, parameters, 2, actual2.data(), jacobians)));
EXPECT(assert_equal(E1,H1,1e-8));
EXPECT(assert_equal(E2,H2,1e-8));
}
/* ************************************************************************* */
// keys
TEST(Expression, SnavelyKeys) {
// Expression<Vector2> expression(1);
// set<Key> expected = list_of(1)(2);
// EXPECT(expected == expression.keys());
}
/* ************************************************************************* */ /* ************************************************************************* */
int main() { int main() {
TestResult tr; TestResult tr;