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));
}
/* ************************************************************************* */