moved Stereo camera and StereoPoint to gtsam
parent
62c63f9452
commit
6694b395c5
|
|
@ -14,6 +14,10 @@ check_PROGRAMS += tests/testPoint2 tests/testRot2 tests/testPose2 tests/testPoin
|
||||||
sources += Cal3_S2.cpp CalibratedCamera.cpp SimpleCamera.cpp
|
sources += Cal3_S2.cpp CalibratedCamera.cpp SimpleCamera.cpp
|
||||||
check_PROGRAMS += tests/testCal3_S2 tests/testCalibratedCamera tests/testSimpleCamera
|
check_PROGRAMS += tests/testCal3_S2 tests/testCalibratedCamera tests/testSimpleCamera
|
||||||
|
|
||||||
|
# Stereo
|
||||||
|
sources += StereoPoint2.cpp StereoCamera.cpp
|
||||||
|
check_PROGRAMS += tests/testStereoCamera
|
||||||
|
|
||||||
# Tensors
|
# Tensors
|
||||||
headers += tensors.h Tensor1.h Tensor2.h Tensor3.h Tensor4.h Tensor5.h
|
headers += tensors.h Tensor1.h Tensor2.h Tensor3.h Tensor4.h Tensor5.h
|
||||||
headers += Tensor1Expression.h Tensor2Expression.h Tensor3Expression.h Tensor5Expression.h
|
headers += Tensor1Expression.h Tensor2Expression.h Tensor3Expression.h Tensor5Expression.h
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
/**
|
||||||
|
* @file StereoCamera.h
|
||||||
|
* @brief A Stereo Camera based on two Simple Cameras
|
||||||
|
* @author Chris Beall
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StereoCamera.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace gtsam;
|
||||||
|
|
||||||
|
namespace gtsam{
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
StereoCamera::StereoCamera(const Pose3& leftCamPose, const Cal3_S2& K, double baseline) :
|
||||||
|
leftCamPose_(leftCamPose), K_(K), baseline_(baseline) {
|
||||||
|
Vector calibration = K_.vector();
|
||||||
|
fx_ = calibration(0);
|
||||||
|
fy_ = calibration(1);
|
||||||
|
cx_ = calibration(3);
|
||||||
|
cy_ = calibration(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
StereoPoint2 StereoCamera::project(const Point3& point) const {
|
||||||
|
|
||||||
|
Point3 cameraPoint = transform_to(leftCamPose_, point);
|
||||||
|
|
||||||
|
double d = 1.0 / cameraPoint.z();
|
||||||
|
double uL = cx_ + d * fx_ * cameraPoint.x();
|
||||||
|
double uR = cx_ + d * fx_ * (cameraPoint.x() - baseline_);
|
||||||
|
double v = cy_ + d * fy_ * cameraPoint.y();
|
||||||
|
return StereoPoint2(uL,uR,v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
Matrix Dproject_to_stereo_camera1(const StereoCamera& camera, const Point3& P) {
|
||||||
|
double d = 1.0 / P.z(), d2 = d * d;
|
||||||
|
//return Matrix_(2, 3, d, 0.0, -P.x() * d2, 0.0, d, -P.y() * d2);
|
||||||
|
return Matrix_(3, 3, d, 0.0, -P.x() * d2, d, 0.0, -(P.x()-camera.baseline()) * d2, 0.0, d, -P.y() * d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
Matrix Duncalibrate2(const Cal3_S2& K) {
|
||||||
|
Vector calibration = K.vector(); // I want fx, fx, fy
|
||||||
|
Vector calibration2(3);
|
||||||
|
calibration2(0) = calibration(0);
|
||||||
|
calibration2(1) = calibration(0);
|
||||||
|
calibration2(2) = calibration(1);
|
||||||
|
return diag(calibration2);
|
||||||
|
//return Matrix_(2, 2, K.fx_, K.s_, 0.000, K.fy_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
Matrix Dproject_stereo_pose(const StereoCamera& camera, const Point3& point) {
|
||||||
|
//Point2 intrinsic = project(camera.calibrated_, point); // unused
|
||||||
|
|
||||||
|
//Matrix D_intrinsic_pose = Dproject_pose(camera.calibrated_, point);
|
||||||
|
//**** above function call inlined
|
||||||
|
Point3 cameraPoint = transform_to(camera.pose(), point);
|
||||||
|
Matrix D_cameraPoint_pose = Dtransform_to1(camera.pose(), point); // 3x6
|
||||||
|
//cout << "D_cameraPoint_pose" << endl;
|
||||||
|
//print(D_cameraPoint_pose);
|
||||||
|
|
||||||
|
//Point2 intrinsic = project_to_camera(cameraPoint); // unused
|
||||||
|
Matrix D_intrinsic_cameraPoint = Dproject_to_stereo_camera1(camera, cameraPoint); // 3x3 Jacobian
|
||||||
|
//cout << "myJacobian" << endl;
|
||||||
|
//print(D_intrinsic_cameraPoint);
|
||||||
|
|
||||||
|
Matrix D_intrinsic_pose = D_intrinsic_cameraPoint * D_cameraPoint_pose;
|
||||||
|
|
||||||
|
//****
|
||||||
|
//Matrix D_projection_intrinsic = Duncalibrate2(camera.K_, intrinsic);
|
||||||
|
Matrix D_projection_intrinsic = Duncalibrate2(camera.K()); // 3x3
|
||||||
|
|
||||||
|
Matrix D_projection_pose = D_projection_intrinsic * D_intrinsic_pose;
|
||||||
|
return D_projection_pose;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
Matrix Dproject_stereo_point(const StereoCamera& camera, const Point3& point) {
|
||||||
|
//Point2 intrinsic = project(camera.calibrated_, point); // unused
|
||||||
|
|
||||||
|
//Matrix D_intrinsic_point = Dproject_point(camera.calibrated_, point);
|
||||||
|
//**** above function call inlined
|
||||||
|
Point3 cameraPoint = transform_to(camera.pose(), point);
|
||||||
|
Matrix D_cameraPoint_point = Dtransform_to2(camera.pose(), point);
|
||||||
|
|
||||||
|
//Point2 intrinsic = project_to_camera(cameraPoint); // unused
|
||||||
|
Matrix D_intrinsic_cameraPoint = Dproject_to_stereo_camera1(camera, cameraPoint); // 3x3 Jacobian
|
||||||
|
|
||||||
|
Matrix D_intrinsic_point = D_intrinsic_cameraPoint * D_cameraPoint_point;
|
||||||
|
|
||||||
|
//****
|
||||||
|
//Matrix D_projection_intrinsic = Duncalibrate2(camera.K_, intrinsic);
|
||||||
|
Matrix D_projection_intrinsic = Duncalibrate2(camera.K()); // 3x3
|
||||||
|
|
||||||
|
Matrix D_projection_point = D_projection_intrinsic * D_intrinsic_point;
|
||||||
|
return D_projection_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// calibrated cameras
|
||||||
|
/*
|
||||||
|
Matrix Dproject_pose(const CalibratedCamera& camera, const Point3& point) {
|
||||||
|
Point3 cameraPoint = transform_to(camera.pose(), point);
|
||||||
|
Matrix D_cameraPoint_pose = Dtransform_to1(camera.pose(), point);
|
||||||
|
|
||||||
|
Point2 intrinsic = project_to_camera(cameraPoint);
|
||||||
|
Matrix D_intrinsic_cameraPoint = Dproject_to_camera1(cameraPoint);
|
||||||
|
|
||||||
|
Matrix D_intrinsic_pose = D_intrinsic_cameraPoint * D_cameraPoint_pose;
|
||||||
|
return D_intrinsic_pose;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Dproject_point(const CalibratedCamera& camera, const Point3& point) {
|
||||||
|
Point3 cameraPoint = transform_to(camera.pose(), point);
|
||||||
|
Matrix D_cameraPoint_point = Dtransform_to2(camera.pose());
|
||||||
|
|
||||||
|
Point2 intrinsic = project_to_camera(cameraPoint);
|
||||||
|
Matrix D_intrinsic_cameraPoint = Dproject_to_camera1(cameraPoint);
|
||||||
|
|
||||||
|
Matrix D_intrinsic_point = D_intrinsic_cameraPoint * D_cameraPoint_point;
|
||||||
|
return D_intrinsic_point;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
/**
|
||||||
|
* @file StereoCamera.h
|
||||||
|
* @brief A Stereo Camera based on two Simple Cameras
|
||||||
|
* @author Chris Beall
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "boost/tuple/tuple.hpp"
|
||||||
|
#include <Cal3_S2.h>
|
||||||
|
#include <Pose3.h>
|
||||||
|
#include <Lie.h>
|
||||||
|
#include "StereoPoint2.h"
|
||||||
|
|
||||||
|
namespace gtsam {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A stereo camera class
|
||||||
|
*/
|
||||||
|
class StereoCamera {
|
||||||
|
|
||||||
|
private:
|
||||||
|
Pose3 leftCamPose_;
|
||||||
|
Cal3_S2 K_;
|
||||||
|
double baseline_;
|
||||||
|
double fx_, fy_;
|
||||||
|
double cx_, cy_;
|
||||||
|
public:
|
||||||
|
StereoCamera() {
|
||||||
|
}
|
||||||
|
|
||||||
|
StereoCamera(const Pose3& leftCamPose, const Cal3_S2& K, double baseline);
|
||||||
|
|
||||||
|
const Cal3_S2& K() const {
|
||||||
|
return K_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Pose3& pose() const {
|
||||||
|
return leftCamPose_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double baseline() const {
|
||||||
|
return baseline_;
|
||||||
|
}
|
||||||
|
|
||||||
|
StereoPoint2 project(const Point3& point) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Dimensionality of the tangent space */
|
||||||
|
inline size_t dim(const StereoCamera& obj) {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Exponential map around p0 */
|
||||||
|
template<> inline StereoCamera expmap<StereoCamera>(const StereoCamera& p0, const Vector& d) {
|
||||||
|
return StereoCamera(expmap(p0.pose(),d),p0.K(),p0.baseline());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline StereoPoint2 project(const StereoCamera& camera, const Point3& point) {
|
||||||
|
return camera.project(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Dproject_stereo_pose(const StereoCamera& camera, const Point3& point);
|
||||||
|
Matrix Dproject_stereo_point(const StereoCamera& camera, const Point3& point);
|
||||||
|
|
||||||
|
Matrix
|
||||||
|
Dproject_to_stereo_camera1(const StereoCamera& camera, const Point3& P);
|
||||||
|
Matrix Duncalibrate2(const Cal3_S2& K);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*
|
||||||
|
* StereoPoint2.cpp
|
||||||
|
*
|
||||||
|
* Created on: Jan 26, 2010
|
||||||
|
* Author: dellaert
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StereoPoint2.h"
|
||||||
|
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* StereoPoint2.h
|
||||||
|
*
|
||||||
|
* Created on: Jan 26, 2010
|
||||||
|
* Author: dellaert
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef STEREOPOINT2_H_
|
||||||
|
#define STEREOPOINT2_H_
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <Vector.h>
|
||||||
|
#include <Testable.h>
|
||||||
|
#include <Lie.h>
|
||||||
|
#include <Point2.h>
|
||||||
|
|
||||||
|
namespace gtsam {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 2D stereo point, v will be same for rectified images
|
||||||
|
*/
|
||||||
|
class StereoPoint2: Testable<StereoPoint2>, Lie<StereoPoint2> {
|
||||||
|
private:
|
||||||
|
double uL_, uR_, v_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** default constructor */
|
||||||
|
StereoPoint2() :
|
||||||
|
uL_(0), uR_(0), v_(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** constructor */
|
||||||
|
StereoPoint2(double uL, double uR, double v) :
|
||||||
|
uL_(uL), uR_(uR), v_(v) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/** print */
|
||||||
|
void print(const std::string& s) const {
|
||||||
|
std::cout << s << "(" << uL_ << ", " << uR_ << ", " << v_ << ")"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** equals */
|
||||||
|
bool equals(const StereoPoint2& q, double tol) const {
|
||||||
|
return (fabs(uL_ - q.uL_) < tol && fabs(uR_ - q.uR_) < tol && fabs(v_
|
||||||
|
- q.v_) < tol);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** convert to vector */
|
||||||
|
Vector vector() const {
|
||||||
|
return Vector_(3, uL_, uR_, v_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** add two stereo points */
|
||||||
|
StereoPoint2 operator+(const StereoPoint2& b) const {
|
||||||
|
return StereoPoint2(uL_ + b.uL_, uR_ + b.uR_, v_ + b.v_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** subtract two stereo points */
|
||||||
|
StereoPoint2 operator-(const StereoPoint2& b) const {
|
||||||
|
return StereoPoint2(uL_ - b.uL_, uR_ - b.uR_, v_ - b.v_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convenient function to get a Point2 from the left image
|
||||||
|
*/
|
||||||
|
inline Point2 point2(){
|
||||||
|
return Point2(uL_, v_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Dimensionality of the tangent space */
|
||||||
|
inline size_t dim(const StereoPoint2& obj) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Exponential map around identity - just create a Point2 from a vector */
|
||||||
|
template<> inline StereoPoint2 expmap(const Vector& d) {
|
||||||
|
return StereoPoint2(d(0), d(1), d(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Log map around identity - just return the Point2 as a vector */
|
||||||
|
inline Vector logmap(const StereoPoint2& p) {
|
||||||
|
return p.vector();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** "Compose", just adds the coordinates of two points. */
|
||||||
|
inline StereoPoint2 compose(const StereoPoint2& p1, const StereoPoint2& p0) {
|
||||||
|
return p0 + p1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** inverse */
|
||||||
|
inline StereoPoint2 inverse(const StereoPoint2& p) {
|
||||||
|
return StereoPoint2()-p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* STEREOPOINT2_H_ */
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
/**
|
||||||
|
* @file testStereoCamera.cpp
|
||||||
|
* @brief Unit test for StereoCamera
|
||||||
|
* single camera
|
||||||
|
* @author Chris Beall
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <CppUnitLite/TestHarness.h>
|
||||||
|
#include <numericalDerivative.h>
|
||||||
|
#include "StereoCamera.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace gtsam;
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST( StereoCamera, operators)
|
||||||
|
{
|
||||||
|
StereoPoint2 a(1, 2, 3), b(4, 5, 6), c(5, 7, 9), d(3, 3, 3);
|
||||||
|
CHECK(assert_equal(c,a+b));
|
||||||
|
CHECK(assert_equal(d,b-a));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST( StereoCamera, project)
|
||||||
|
{
|
||||||
|
double uL, uR, v;
|
||||||
|
// create a Stereo camera at the origin with focal length 1500, baseline 0.5m
|
||||||
|
// and principal point 320, 240 (for a hypothetical 640x480 sensor)
|
||||||
|
Cal3_S2 K(1500, 1500, 0, 320, 240);
|
||||||
|
StereoCamera stereoCam(Pose3(), K, 0.5);
|
||||||
|
|
||||||
|
// point X Y Z in meters
|
||||||
|
Point3 p(0, 0, 5);
|
||||||
|
StereoPoint2 result = stereoCam.project(p);
|
||||||
|
CHECK(assert_equal(StereoPoint2(320,320-150,240),result));
|
||||||
|
|
||||||
|
// point X Y Z in meters
|
||||||
|
Point3 p2(1, 1, 5);
|
||||||
|
StereoPoint2 result2 = stereoCam.project(p2);
|
||||||
|
CHECK(assert_equal(StereoPoint2(320.0+300.0,320.0+150.0,240.0+300),result2));
|
||||||
|
|
||||||
|
// move forward 1 meter and try the same thing
|
||||||
|
// point X Y Z in meters
|
||||||
|
Point3 p3(1, 1, 6);
|
||||||
|
Rot3 unit = Rot3();
|
||||||
|
Point3 one_meter_z(0, 0, 1);
|
||||||
|
Pose3 camPose3(unit, one_meter_z);
|
||||||
|
StereoCamera stereoCam3(camPose3, K, 0.5);
|
||||||
|
StereoPoint2 result3 = stereoCam3.project(p3);
|
||||||
|
CHECK(assert_equal(StereoPoint2(320.0+300.0, 320.0+150.0, 240.0+300),result3));
|
||||||
|
|
||||||
|
// camera at (0,0,1) looking right (90deg)
|
||||||
|
Point3 p4(5, 1, 0);
|
||||||
|
Rot3 right = Rot3(0, 0, 1, 0, 1, 0, -1, 0, 0);
|
||||||
|
Pose3 camPose4(right, one_meter_z);
|
||||||
|
StereoCamera stereoCam4(camPose4, K, 0.5);
|
||||||
|
StereoPoint2 result4 = stereoCam4.project(p4);
|
||||||
|
CHECK(assert_equal(StereoPoint2(320.0+300.0,320.0+150.0,240.0+300),result4));
|
||||||
|
|
||||||
|
// cout << "(uL,uR,v): ("<<result4(0)<<","<<result4(1)<<","<<result4(2)<<")" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
|
||||||
|
Pose3 camera1(Matrix_(3,3,
|
||||||
|
1., 0., 0.,
|
||||||
|
0.,-1., 0.,
|
||||||
|
0., 0.,-1.
|
||||||
|
),
|
||||||
|
Point3(0,0,6.25));
|
||||||
|
|
||||||
|
Cal3_S2 K(1500, 1500, 0, 320, 240);
|
||||||
|
StereoCamera stereoCam(Pose3(), K, 0.5);
|
||||||
|
|
||||||
|
// point X Y Z in meters
|
||||||
|
Point3 p(0, 0, 5);
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST( StereoCamera, Dproject_stereo_pose)
|
||||||
|
{
|
||||||
|
Matrix expected = numericalDerivative21<StereoPoint2,StereoCamera,Point3>(project,stereoCam, p);
|
||||||
|
Matrix actual = Dproject_stereo_pose(stereoCam, p);
|
||||||
|
CHECK(assert_equal(expected,actual,1e-7));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST( StereoCamera, Dproject_stereo_point)
|
||||||
|
{
|
||||||
|
Matrix expected = numericalDerivative22<StereoPoint2,StereoCamera,Point3>(project,stereoCam, p);
|
||||||
|
Matrix actual = Dproject_stereo_point(stereoCam, p);
|
||||||
|
CHECK(assert_equal(expected,actual,1e-8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
int main() { TestResult tr; return TestRegistry::runAllTests(tr);}
|
||||||
|
/* ************************************************************************* */
|
||||||
Loading…
Reference in New Issue