StereoCamera cleanup and improvements

release/4.3a0
Chris Beall 2011-09-12 12:37:10 +00:00
parent b456733cd0
commit 6da5127981
6 changed files with 39 additions and 45 deletions

View File

@ -30,6 +30,9 @@ namespace gtsam {
double b_; double b_;
public: public:
typedef boost::shared_ptr<Cal3_S2Stereo> shared_ptr; ///< shared pointer to stereo calibration object
/** /**
* default calibration leaves coordinates unchanged * default calibration leaves coordinates unchanged
*/ */

View File

@ -23,7 +23,7 @@ using namespace gtsam;
namespace gtsam { namespace gtsam {
/* ************************************************************************* */ /* ************************************************************************* */
StereoCamera::StereoCamera(const Pose3& leftCamPose, const Cal3_S2Stereo& K) : StereoCamera::StereoCamera(const Pose3& leftCamPose, const Cal3_S2Stereo::shared_ptr K) :
leftCamPose_(leftCamPose), K_(K) { leftCamPose_(leftCamPose), K_(K) {
} }
@ -32,49 +32,40 @@ StereoPoint2 StereoCamera::project(const Point3& point,
boost::optional<Matrix&> H1, boost::optional<Matrix&> H1,
boost::optional<Matrix&> H2) const { boost::optional<Matrix&> H2) const {
Point3 cameraPoint = leftCamPose_.transform_to(point); Point3 cameraPoint = leftCamPose_.transform_to(point, H1, H2);
if (H1) {
Matrix D_cameraPoint_pose;
Point3 cameraPoint = pose().transform_to(point, D_cameraPoint_pose,
boost::none);
if(H1 || H2) {
Matrix D_intrinsic_cameraPoint = Dproject_to_stereo_camera1(cameraPoint); // 3x3 Jacobian Matrix D_intrinsic_cameraPoint = Dproject_to_stereo_camera1(cameraPoint); // 3x3 Jacobian
Matrix D_intrinsic_pose = D_intrinsic_cameraPoint * D_cameraPoint_pose; Matrix D_projection_intrinsic = Duncalibrate2(K_); // 3x3
Matrix D_projection_intrinsic = Duncalibrate2(calibration()); // 3x3 if (H1) {
*H1 = D_projection_intrinsic * D_intrinsic_pose; //Matrix D_intrinsic_pose = D_intrinsic_cameraPoint * *H1;
} *H1 = D_projection_intrinsic * D_intrinsic_cameraPoint * *H1;
}
if (H2) { if (H2) {
Matrix D_cameraPoint_point; //Matrix D_intrinsic_point = D_intrinsic_cameraPoint * *H2;
Point3 cameraPoint = pose().transform_to(point, boost::none, *H2 = D_projection_intrinsic * D_intrinsic_cameraPoint * *H2;
D_cameraPoint_point); }
Matrix D_intrinsic_cameraPoint = Dproject_to_stereo_camera1(cameraPoint); // 3x3 Jacobian
Matrix D_intrinsic_point = D_intrinsic_cameraPoint * D_cameraPoint_point;
Matrix D_projection_intrinsic = Duncalibrate2(calibration()); // 3x3
*H2 = D_projection_intrinsic * D_intrinsic_point;
} }
double d = 1.0 / cameraPoint.z(); double d = 1.0 / cameraPoint.z();
double uL = K_.px() + d * K_.fx() * cameraPoint.x(); double uL = K_->px() + d * K_->fx() * cameraPoint.x();
double uR = K_.px() + d * K_.fx() * (cameraPoint.x() - K_.baseline()); double uR = K_->px() + d * K_->fx() * (cameraPoint.x() - K_->baseline());
double v = K_.py() + d * K_.fy() * cameraPoint.y(); double v = K_->py() + d * K_->fy() * cameraPoint.y();
return StereoPoint2(uL, uR, v); return StereoPoint2(uL, uR, v);
} }
/* ************************************************************************* */ /* ************************************************************************* */
Matrix StereoCamera::Dproject_to_stereo_camera1(const Point3& P) const { Matrix StereoCamera::Dproject_to_stereo_camera1(const Point3& P) const {
double d = 1.0 / P.z(), d2 = d * d; double d = 1.0 / P.z(), d2 = d * d;
return Matrix_(3, 3, d, 0.0, -P.x() * d2, d, 0.0, -(P.x() - K_.baseline()) * d2, return Matrix_(3, 3, d, 0.0, -P.x() * d2, d, 0.0, -(P.x() - K_->baseline()) * d2,
0.0, d, -P.y() * d2); 0.0, d, -P.y() * d2);
} }
/* ************************************************************************* */ /* ************************************************************************* */
Matrix StereoCamera::Duncalibrate2(const Cal3_S2& K) { Matrix StereoCamera::Duncalibrate2(const Cal3_S2Stereo::shared_ptr K) {
Vector calibration = K.vector(); Vector calibration = K->vector();
Vector calibration2(3); Vector calibration2(3);
calibration2(0) = calibration(0); calibration2(0) = calibration(0);
calibration2(1) = calibration(0); calibration2(1) = calibration(0);

View File

@ -32,15 +32,15 @@ namespace gtsam {
private: private:
Pose3 leftCamPose_; Pose3 leftCamPose_;
Cal3_S2Stereo K_; Cal3_S2Stereo::shared_ptr K_;
public: public:
StereoCamera() { StereoCamera() {
} }
StereoCamera(const Pose3& leftCamPose, const Cal3_S2Stereo& K); StereoCamera(const Pose3& leftCamPose, const Cal3_S2Stereo::shared_ptr K);
const Cal3_S2Stereo& calibration() const { const Cal3_S2Stereo::shared_ptr calibration() const {
return K_; return K_;
} }
@ -49,7 +49,7 @@ namespace gtsam {
} }
const double baseline() const { const double baseline() const {
return K_.baseline(); return K_->baseline();
} }
@ -75,16 +75,16 @@ namespace gtsam {
* i.e. does not rely on baseline * i.e. does not rely on baseline
*/ */
Point3 backproject(const Point2& projection, const double scale) const { Point3 backproject(const Point2& projection, const double scale) const {
Point2 intrinsic = K_.calibrate(projection); Point2 intrinsic = K_->calibrate(projection);
Point3 cameraPoint = Point3(intrinsic.x() * scale, intrinsic.y() * scale, scale);; Point3 cameraPoint = Point3(intrinsic.x() * scale, intrinsic.y() * scale, scale);;
return pose().transform_from(cameraPoint); return pose().transform_from(cameraPoint);
} }
Point3 backproject(const StereoPoint2& z) const { Point3 backproject(const StereoPoint2& z) const {
Vector measured = z.vector(); Vector measured = z.vector();
double Z = K_.baseline()*K_.fx()/(measured[0]-measured[1]); double Z = K_->baseline()*K_->fx()/(measured[0]-measured[1]);
double X = Z *(measured[0]- K_.px()) / K_.fx(); double X = Z *(measured[0]- K_->px()) / K_->fx();
double Y = Z *(measured[2]- K_.py()) / K_.fy(); double Y = Z *(measured[2]- K_->py()) / K_->fy();
Point3 world_point = leftCamPose_.transform_from(Point3(X, Y, Z)); Point3 world_point = leftCamPose_.transform_from(Point3(X, Y, Z));
return world_point; return world_point;
} }
@ -101,7 +101,7 @@ namespace gtsam {
/** Exponential map around p0 */ /** Exponential map around p0 */
inline StereoCamera expmap(const Vector& d) const { inline StereoCamera expmap(const Vector& d) const {
return StereoCamera(pose().expmap(d), calibration()); return StereoCamera(pose().expmap(d), K_);
} }
Vector logmap(const StereoCamera &camera) const { Vector logmap(const StereoCamera &camera) const {
@ -110,8 +110,8 @@ namespace gtsam {
} }
bool equals(const StereoCamera &camera, double tol = 1e-9) const { bool equals(const StereoCamera &camera, double tol = 1e-9) const {
return leftCamPose_.equals(camera.leftCamPose_, tol) && K_.equals( return leftCamPose_.equals(camera.leftCamPose_, tol) && K_->equals(
camera.K_, tol); *camera.K_, tol);
} }
Pose3 between(const StereoCamera &camera, Pose3 between(const StereoCamera &camera,
@ -122,13 +122,13 @@ namespace gtsam {
void print(const std::string& s = "") const { void print(const std::string& s = "") const {
leftCamPose_.print(s + ".camera."); leftCamPose_.print(s + ".camera.");
K_.print(s + ".calibration."); K_->print(s + ".calibration.");
} }
private: private:
/** utility functions */ /** utility functions */
Matrix Dproject_to_stereo_camera1(const Point3& P) const; Matrix Dproject_to_stereo_camera1(const Point3& P) const;
static Matrix Duncalibrate2(const Cal3_S2& K); static Matrix Duncalibrate2(const Cal3_S2Stereo::shared_ptr K);
friend class boost::serialization::access; friend class boost::serialization::access;
template<class Archive> template<class Archive>

View File

@ -36,7 +36,7 @@ TEST( StereoCamera, project)
{ {
// create a Stereo camera at the origin with focal length 1500, baseline 0.5m // create a Stereo camera at the origin with focal length 1500, baseline 0.5m
// and principal point 320, 240 (for a hypothetical 640x480 sensor) // and principal point 320, 240 (for a hypothetical 640x480 sensor)
Cal3_S2Stereo K(1500, 1500, 0, 320, 240, 0.5); Cal3_S2Stereo::shared_ptr K(new Cal3_S2Stereo(1500, 1500, 0, 320, 240, 0.5));
StereoCamera stereoCam(Pose3(), K); StereoCamera stereoCam(Pose3(), K);
// point X Y Z in meters // point X Y Z in meters
@ -77,7 +77,7 @@ Pose3 camera1(Matrix_(3,3,
), ),
Point3(0,0,6.25)); Point3(0,0,6.25));
Cal3_S2Stereo K(1500, 1500, 0, 320, 240, 0.5); Cal3_S2Stereo::shared_ptr K(new Cal3_S2Stereo(1500, 1500, 0, 320, 240, 0.5));
StereoCamera stereoCam(Pose3(), K); StereoCamera stereoCam(Pose3(), K);
// point X Y Z in meters // point X Y Z in meters
@ -115,7 +115,7 @@ TEST( StereoCamera, backproject2)
-0.804435942, -0.592650676, -0.0405925523, -0.804435942, -0.592650676, -0.0405925523,
0.0732045588, -0.0310882277, -0.996832359); 0.0732045588, -0.0310882277, -0.996832359);
Point3 t(53.5239823, 23.7866016, -4.42379876); Point3 t(53.5239823, 23.7866016, -4.42379876);
Cal3_S2Stereo K(1733.75, 1733.75, 0, 689.645, 508.835, 0.0699612); Cal3_S2Stereo::shared_ptr K(new Cal3_S2Stereo(1733.75, 1733.75, 0, 689.645, 508.835, 0.0699612));
StereoCamera camera(Pose3(R,t), K); StereoCamera camera(Pose3(R,t), K);
StereoPoint2 z(184.812, 129.068, 714.768); StereoPoint2 z(184.812, 129.068, 714.768);

View File

@ -86,7 +86,7 @@ public:
/** h(x)-z */ /** h(x)-z */
Vector evaluateError(const Pose3& pose, const Point3& point, Vector evaluateError(const Pose3& pose, const Point3& point,
boost::optional<Matrix&> H1, boost::optional<Matrix&> H2) const { boost::optional<Matrix&> H1, boost::optional<Matrix&> H2) const {
StereoCamera stereoCam(pose, *K_); StereoCamera stereoCam(pose, K_);
return (stereoCam.project(point, H1, H2) - z_).vector(); return (stereoCam.project(point, H1, H2) - z_).vector();
} }

View File

@ -40,7 +40,7 @@ Pose3 camera1(Matrix_(3,3,
), ),
Point3(0,0,6.25)); Point3(0,0,6.25));
Cal3_S2Stereo K(1500, 1500, 0, 320, 240, 0.5); Cal3_S2Stereo::shared_ptr K(new Cal3_S2Stereo(1500, 1500, 0, 320, 240, 0.5));
StereoCamera stereoCam(Pose3(), K); StereoCamera stereoCam(Pose3(), K);
// point X Y Z in meters // point X Y Z in meters