diff --git a/gtsam/geometry/Cal3Bundler.cpp b/gtsam/geometry/Cal3Bundler.cpp index 587d0ea63..95b61c2b0 100644 --- a/gtsam/geometry/Cal3Bundler.cpp +++ b/gtsam/geometry/Cal3Bundler.cpp @@ -64,6 +64,45 @@ bool Cal3Bundler::equals(const Cal3Bundler& K, double tol) const { return true; } +/* ************************************************************************* */ +Point2 Cal3Bundler::uncalibrate(const Point2& p) const { + // r = x^2 + y^2; + // g = (1 + k(1)*r + k(2)*r^2); + // pi(:,i) = g * pn(:,i) + const double x = p.x(), y = p.y(); + const double r = x * x + y * y; + const double g = 1. + (k1_ + k2_ * r) * r; + const double u = g * x, v = g * y; + return Point2(u0_ + f_ * u, v0_ + f_ * v); +} + +/* ************************************************************************* */ +Point2 Cal3Bundler::uncalibrate(const Point2& p, // + boost::optional Dcal, boost::optional Dp) const { + // r = x^2 + y^2; + // g = (1 + k(1)*r + k(2)*r^2); + // pi(:,i) = g * pn(:,i) + const double x = p.x(), y = p.y(); + const double r = x * x + y * y; + const double g = 1. + (k1_ + k2_ * r) * r; + const double u = g * x, v = g * y; + + // Derivatives make use of intermediate variables above + if (Dcal) { + double rx = r * x, ry = r * y; + *Dcal << u, f_ * rx, f_ * r * rx, v, f_ * ry, f_ * r * ry; + } + + if (Dp) { + const double a = 2. * (k1_ + 2. * k2_ * r); + const double axx = a * x * x, axy = a * x * y, ayy = a * y * y; + *Dp << g + axx, axy, axy, g + ayy; + *Dp *= f_; + } + + return Point2(u0_ + f_ * u, v0_ + f_ * v); +} + /* ************************************************************************* */ Point2 Cal3Bundler::uncalibrate(const Point2& p, // boost::optional Dcal, boost::optional Dp) const { diff --git a/gtsam/geometry/Cal3Bundler.h b/gtsam/geometry/Cal3Bundler.h index 2de5a808d..454435c66 100644 --- a/gtsam/geometry/Cal3Bundler.h +++ b/gtsam/geometry/Cal3Bundler.h @@ -106,12 +106,29 @@ public: /** * convert intrinsic coordinates xy to image coordinates uv * @param p point in intrinsic coordinates + * @return point in image coordinates + */ + Point2 uncalibrate(const Point2& p) const; + + /** + * Version of uncalibrate with fixed derivatives + * @param p point in intrinsic coordinates * @param Dcal optional 2*3 Jacobian wrpt CalBundler parameters * @param Dp optional 2*2 Jacobian wrpt intrinsic coordinates * @return point in image coordinates */ - Point2 uncalibrate(const Point2& p, boost::optional Dcal = - boost::none, boost::optional Dp = boost::none) const; + Point2 uncalibrate(const Point2& p, boost::optional Dcal, + boost::optional Dp) const; + + /** + * Version of uncalibrate with dynamic derivatives + * @param p point in intrinsic coordinates + * @param Dcal optional 2*3 Jacobian wrpt CalBundler parameters + * @param Dp optional 2*2 Jacobian wrpt intrinsic coordinates + * @return point in image coordinates + */ + Point2 uncalibrate(const Point2& p, boost::optional Dcal, + boost::optional Dp) const; /// Conver a pixel coordinate to ideal coordinate Point2 calibrate(const Point2& pi, const double tol = 1e-5) const;