project2 of point at infinity

release/4.3a0
dellaert 2015-03-05 22:10:30 -08:00
parent f3f09b17a7
commit 3f94791b3b
3 changed files with 71 additions and 4 deletions

View File

@ -136,6 +136,33 @@ Point2 PinholeBase::project2(const Point3& point, OptionalJacobian<2, 6> Dpose,
return pn; return pn;
} }
/* ************************************************************************* */
Point2 PinholeBase::project2(const Unit3& pw, OptionalJacobian<2, 6> Dpose,
OptionalJacobian<2, 2> Dpoint) const {
// world to camera coordinate
Matrix23 Dpc_rot;
Matrix2 Dpc_point;
const Unit3 pc = pose().rotation().unrotate(pw, Dpose ? &Dpc_rot : 0,
Dpose ? &Dpc_point : 0);
// camera to normalized image coordinate
Matrix2 Dpn_pc;
const Point2 pn = PinholeBase::project_to_camera(pc,
Dpose || Dpoint ? &Dpn_pc : 0);
// chain the Jacobian matrices
if (Dpose) {
// only rotation is important
Matrix26 Dpc_pose;
Dpc_pose.setZero();
Dpc_pose.leftCols<3>() = Dpc_rot;
*Dpose = Dpn_pc * Dpc_pose; // 2x2 * 2x6
}
if (Dpoint)
*Dpoint = Dpn_pc * Dpc_point; // 2x2 * 2*2
return pn;
}
/* ************************************************************************* */ /* ************************************************************************* */
Point3 PinholeBase::backproject_from_camera(const Point2& p, Point3 PinholeBase::backproject_from_camera(const Point2& p,
const double depth) { const double depth) {

View File

@ -187,6 +187,15 @@ public:
Point2 project2(const Point3& point, OptionalJacobian<2, 6> Dpose = Point2 project2(const Point3& point, OptionalJacobian<2, 6> Dpose =
boost::none, OptionalJacobian<2, 3> Dpoint = boost::none) const; boost::none, OptionalJacobian<2, 3> Dpoint = boost::none) const;
/**
* Project point at infinity into the image
* Throws a CheiralityException if point behind image plane iff GTSAM_THROW_CHEIRALITY_EXCEPTION
* @param point 3D point in world coordinates
* @return the intrinsic coordinates of the projected point
*/
Point2 project2(const Unit3& point, OptionalJacobian<2, 6> Dpose =
boost::none, OptionalJacobian<2, 2> Dpoint = boost::none) const;
/// backproject a 2-dimensional point to a 3-dimensional point at given depth /// backproject a 2-dimensional point to a 3-dimensional point at given depth
static Point3 backproject_from_camera(const Point2& p, const double depth); static Point3 backproject_from_camera(const Point2& p, const double depth);

View File

@ -105,11 +105,12 @@ static Point2 project_to_camera2(const Unit3& point) {
return PinholeBase::project_to_camera(point); return PinholeBase::project_to_camera(point);
} }
Unit3 pointAtInfinity(0, 0, 1000);
TEST( CalibratedCamera, Dproject_to_cameraInfinity) { TEST( CalibratedCamera, Dproject_to_cameraInfinity) {
Unit3 pp(0, 0, 1000);
Matrix test1; Matrix test1;
CalibratedCamera::project_to_camera(pp, test1); CalibratedCamera::project_to_camera(pointAtInfinity, test1);
Matrix test2 = numericalDerivative11<Point2, Unit3>(project_to_camera2, pp); Matrix test2 = numericalDerivative11<Point2, Unit3>(project_to_camera2,
pointAtInfinity);
CHECK(assert_equal(test1, test2)); CHECK(assert_equal(test1, test2));
} }
@ -144,6 +145,36 @@ TEST( CalibratedCamera, Dproject_point_pose2)
CHECK(assert_equal(numerical_point, Dpoint, 1e-7)); CHECK(assert_equal(numerical_point, Dpoint, 1e-7));
} }
/* ************************************************************************* */
static Point2 projectAtInfinity(const CalibratedCamera& camera, const Unit3& point) {
return camera.project2(point);
}
TEST( CalibratedCamera, Dproject_point_pose_infinity)
{
Matrix Dpose, Dpoint;
Point2 result = camera.project2(pointAtInfinity, Dpose, Dpoint);
Matrix numerical_pose = numericalDerivative21(projectAtInfinity, camera, pointAtInfinity);
Matrix numerical_point = numericalDerivative22(projectAtInfinity, camera, pointAtInfinity);
CHECK(assert_equal(Point2(), result));
CHECK(assert_equal(numerical_pose, Dpose, 1e-7));
CHECK(assert_equal(numerical_point, Dpoint, 1e-7));
}
/* ************************************************************************* */
// Add a test with more arbitrary rotation
TEST( CalibratedCamera, Dproject_point_pose2_infinity)
{
static const Pose3 pose1(Rot3::ypr(0.1, -0.1, 0.4), Point3(0, 0, -10));
static const CalibratedCamera camera(pose1);
Matrix Dpose, Dpoint;
camera.project2(pointAtInfinity, Dpose, Dpoint);
Matrix numerical_pose = numericalDerivative21(projectAtInfinity, camera, pointAtInfinity);
Matrix numerical_point = numericalDerivative22(projectAtInfinity, camera, pointAtInfinity);
CHECK(assert_equal(numerical_pose, Dpose, 1e-7));
CHECK(assert_equal(numerical_point, Dpoint, 1e-7));
}
/* ************************************************************************* */ /* ************************************************************************* */
int main() { TestResult tr; return TestRegistry::runAllTests(tr); } int main() { TestResult tr; return TestRegistry::runAllTests(tr); }
/* ************************************************************************* */ /* ************************************************************************* */