diff --git a/.cproject b/.cproject index 2f0f668ce..26815d331 100644 --- a/.cproject +++ b/.cproject @@ -1507,6 +1507,22 @@ true true + + make + -j2 + tests/timeCalibratedCamera.run + true + true + true + + + make + -j2 + tests/testPoint2.run + true + true + true + make -j2 diff --git a/gtsam/geometry/CalibratedCamera.cpp b/gtsam/geometry/CalibratedCamera.cpp index a442e9357..fa27f2f71 100644 --- a/gtsam/geometry/CalibratedCamera.cpp +++ b/gtsam/geometry/CalibratedCamera.cpp @@ -61,22 +61,42 @@ Point2 CalibratedCamera::project(const Point3& point, boost::optional H1, boost::optional H2) const { +#ifdef CALIBRATEDCAMERA_CHAIN_RULE Point3 q = pose_.transform_to(point, H1, H2); +#else + Point3 q = pose_.transform_to(point); +#endif + Point2 intrinsic = project_to_camera(q); // Check if point is in front of camera if(q.z() <= 0) throw CheiralityException(); if (H1 || H2) { - Matrix H; - Point2 intrinsic = project_to_camera(q,H); +#ifdef CALIBRATEDCAMERA_CHAIN_RULE // just implement chain rule + Matrix H; + project_to_camera(q,H); if (H1) *H1 = H * (*H1); - if (H1) *H2 = H * (*H2); - return intrinsic; + if (H2) *H2 = H * (*H2); +#else + // optimized version, see CalibratedCamera.nb + const double z = q.z(), d = 1.0/z; + const double u = intrinsic.x(), v = intrinsic.y(), uv = u*v; + if (H1) *H1 = Matrix_(2,6, + uv,-(1.+u*u), v, -d , 0., d*u, + (1.+v*v), -uv,-u, 0.,-d , d*v + ); + if (H2) { + const Matrix R(pose_.rotation().matrix()); + *H2 = d * Matrix_(2,3, + R(0,0) - u*R(0,2), R(1,0) - u*R(1,2), R(2,0) - u*R(2,2), + R(0,1) - v*R(0,2), R(1,1) - v*R(1,2), R(2,1) - v*R(2,2) + ); + } +#endif } - else - return project_to_camera(q); + return intrinsic; } /* ************************************************************************* */ diff --git a/gtsam/geometry/tests/testCalibratedCamera.cpp b/gtsam/geometry/tests/testCalibratedCamera.cpp index 4be47a4c0..5bb1ebe65 100644 --- a/gtsam/geometry/tests/testCalibratedCamera.cpp +++ b/gtsam/geometry/tests/testCalibratedCamera.cpp @@ -78,10 +78,10 @@ TEST( CalibratedCamera, level2) /* ************************************************************************* */ TEST( CalibratedCamera, project) { - CHECK(assert_equal( camera.project(point1), Point2(-.16, .16) )); - CHECK(assert_equal( camera.project(point2), Point2(-.16, -.16) )); - CHECK(assert_equal( camera.project(point3), Point2( .16, -.16) )); - CHECK(assert_equal( camera.project(point4), Point2( .16, .16) )); + CHECK(assert_equal( Point2(-.16, .16), camera.project(point1) )); + CHECK(assert_equal( Point2(-.16, -.16), camera.project(point2) )); + CHECK(assert_equal( Point2( .16, -.16), camera.project(point3) )); + CHECK(assert_equal( Point2( .16, .16), camera.project(point4) )); } /* ************************************************************************* */ @@ -105,9 +105,10 @@ TEST( CalibratedCamera, Dproject_point_pose) Point2 result = camera.project(point1, Dpose, Dpoint); Matrix numerical_pose = numericalDerivative21(project2, pose1, point1); Matrix numerical_point = numericalDerivative22(project2, pose1, point1); - CHECK(assert_equal(result, Point2(-.16, .16) )); - CHECK(assert_equal(Dpose, numerical_pose, 1e-7)); - CHECK(assert_equal(Dpoint, numerical_point,1e-7)); + CHECK(assert_equal(Point3(-0.08, 0.08, 0.5), camera.pose().transform_to(point1))); + CHECK(assert_equal(Point2(-.16, .16), result)); + CHECK(assert_equal(numerical_pose, Dpose, 1e-7)); + CHECK(assert_equal(numerical_point, Dpoint, 1e-7)); } /* ************************************************************************* */