Go to the documentation of this file.00001
00026 #ifndef VSLAM_CAMERA_MODEL_H_INCLUDED
00027 #define VSLAM_CAMERA_MODEL_H_INCLUDED
00028 #include "utils.h"
00029
00030
00031
00032
00033
00034 namespace vslam {
00035
00040
00041
00042
00044 inline Vector2d two3dLinesAngle(const Vector3d vec1, const Vector3d& vec2){
00045 assert(false);
00046 }
00047
00048 struct SphericalCoord{
00049 double azimuth;
00050 double elevation;
00051 };
00052
00054 template<class ImageCoordT, class RayCoordT> class CameraModel{
00055 public:
00057 bool canProject(const RayCoordT& ray) const { return true; }
00058
00059 ImageCoordT project(const RayCoordT& ray) const { assert(false); }
00060
00062 bool canBackProject(const ImageCoordT& im_coord) const {
00063 return canProject(BackProject(im_coord));
00064 }
00065
00066 RayCoordT backProject(const ImageCoordT& im_coord) const { assert(false); }
00067 };
00068
00069 template<class ImageCoordT> class ConcentricCameraModel :
00070 public CameraModel<ImageCoordT, Vector3d>{
00071 };
00072
00073
00074
00075 class FieldOfViewCCM{
00076 bool canProject(const Vector3d& ray) const { return true; }
00077 };
00078
00079
00081 class SphericalCM : ConcentricCameraModel<Vector3d>{
00082 protected:
00083 double hfov;
00084 double vfov;
00085
00086 public:
00087 static const double IGNORE = -1;
00088
00089 SphericalCM(double _hfov = IGNORE, double _vfov = IGNORE) :
00090 hfov(_hfov), vfov(_vfov) {}
00091
00092
00093 bool canProject(const Vector3d& ray_coord) const{
00094 Vector2d hv_angles = two3dLinesAngle(ray_coord, Vector3d::Zero());
00095 return (hfov < 0 || hv_angles(0) <= hfov) && (vfov < 0 || hv_angles(1) <= vfov);
00096 }
00097
00098 Vector3d project(const Vector3d& ray_coord) const{
00099 return ray_coord.normalized();
00100 }
00101
00102 bool canBackProject(const Vector3d& im_coord) const{
00103 return canProject(im_coord);
00104 }
00105
00106 Vector3d backProject(const Vector3d& im_coord) const{
00107 return im_coord;
00108 }
00109
00110 };
00111
00112
00134 class CylindricalCCMSphRays : CameraModel<Vector2d, SphericalCoord>{
00135 protected:
00136 int pan_width;
00137 int pan_height;
00138 public:
00139 CylindricalCCMSphRays(int _pan_width, int _pan_height) :
00140 pan_width(_pan_width), pan_height(_pan_height) {}
00141
00142 SphericalCoord backProject(Eigen::Vector2d pixel) const{
00143 SphericalCoord sc;
00144 sc.azimuth = linspace_idx(
00145 (double)0,
00146 (double)(pan_width - 1) / (double)pan_width* (-2.0)*M_PI,
00147 pan_width,
00148 pixel(0) - (double)(((int)pan_width) / 2));
00149 sc.elevation = -linspace_idx(-M_PI / 2.0, M_PI / 2.0, pan_height, pixel(1));
00150 return sc;
00151 }
00152
00153 Vector2d project(SphericalCoord sc) const{
00154 Eigen::Vector2d t;
00155 t(0) = inv_linspace_idx(
00156 (double)0,
00157 (double)(pan_width - 1) / (double)pan_width * (-2.0)*M_PI,
00158 pan_width,
00159 sc.azimuth) + (double)(((int)pan_width) / 2);
00160 t(1) = inv_linspace_idx(-M_PI / 2.0, M_PI / 2.0, pan_height, -sc.elevation);
00161 return t;
00162 }
00163 };
00164
00165
00174 class CylindricalCCMCartRays : CameraModel<Vector2d, Vector3d>{
00175 private:
00176 int pan_width;
00177 int pan_height;
00178 CylindricalCCMSphRays sccm;
00179
00180 public:
00181 CylindricalCCMCartRays(int _w, int _h) :
00182 pan_width(_w), pan_height(_h), sccm(pan_width, pan_height) {}
00183
00184
00185 Vector2d project(const Vector3d& dir_vec) const{
00186 SphericalCoord sc;
00187
00188 Vector3d dir_vec2 = dir_vec.normalized();
00189 double x = dir_vec2(0);
00190 double y = dir_vec2(1);
00191 double z = dir_vec2(2);
00192
00193 double r_xz = std::sqrt(x*x + z*z);
00194 sc.azimuth = std::atan2(-x, z);
00195 sc.elevation = std::atan2(y, r_xz);
00196 return sccm.project(sc);
00197 }
00198
00199 Vector3d backProject(Vector2d& im_coord) const{
00200 SphericalCoord sc = sccm.backProject(im_coord);
00201 Eigen::Vector3d direction;
00202 direction(0) = -std::sin( sc.azimuth ) * std::cos( sc.elevation );
00203 direction(1) = std::sin( sc.elevation );
00204 direction(2) = std::cos( sc.azimuth ) * std::cos( sc.elevation );
00205 return direction;
00206 }
00207 };
00208
00209
00211 template<class CameraModelRayIntermediate, class CameraModelIntermediateImage>
00212 projectionCoordinateAdaptorCM : public CameraModel<NewImageCoordT, CameraModelT::RayCoordT>{
00213 CameraModelT cm_ray_to_intermed;
00214 CameraModelT cm_intermed_to_image;
00215 project(const CameraModelT::RayCoordT ray_coord){
00216 return cm_intermed_to_image(cm_ray_to_intermed(ray_coord));
00217 }
00218
00219 backProject(const CameraModelT::
00220
00221 }
00222
00223
00225 template<class T> struct MCRCoord{
00226 int id;
00227 T coord;
00228
00229 MCRCoord<T>(int _id, T _coord) : id(_id), coord(_coord) {}
00230 };
00231
00232
00233
00235 template<class CCMT> class MultiCameraRigFromCCM :
00236 CameraModel<MCRCoord< typename CCMT::ImageCoordT>,
00237 MCRCoord< typename CCMT::RayCoordT> >{
00238 private:
00239 vector<CCMT> cameras;
00240 vector<SE3> camera_transforms;
00241
00242 public:
00243
00244 bool canProject(const Vector3d& point){
00245 for(size_t i=0; i<cameras.size(); i++){
00246 if(cameras[i].canProject(point)){
00247 return true;
00248 }
00249 }
00250 return false;
00251 }
00252
00253 MCRCoord<typename CCMT::ImageCoordT> project(Vector3d point){
00254 for(size_t i=0; i<cameras.size(); i++){
00255 if(cameras[i].canProject(point)){
00256 return MCRCoord<typename CCMT::ImageCoordT>(
00257 i, makepair(cameras[i].getProjectionCenter(), cameras[i].project(point)));
00258 }
00259 }
00260 assert(false);
00261 }
00262 };
00263
00265 template<class CCMT> class MultiCameraRigFromCCM :
00266 CameraModel<MCRCoord< typename CCMT::ImageCoordT>,
00267 MCRCoord< typename CCMT::RayCoordT> >{
00268 private:
00269 vector<CCMT> cameras;
00270 vector<SE3> camera_transforms;
00271 sph_approx_backprojection = false;
00272
00273 public:
00274 bool canProject(const Vector3d& point){
00275 MCRCoord<typename CCMT::ImageCoordT> coord = project(point);
00276 return coord != INVALID_PROJECTION;
00277 }
00278
00279 MCRCoord<typename CCMT::ImageCoordT> project(Vector3d point){
00280 for(size_t i=0; i<cameras.size(); i++){
00281 if(cameras[i].canProject(point)){
00282 Vector3d bproji = vector3dAngle(cameras[i].backProjectionFromPoint(point));
00283 if(camIdWithMinOpticalAxisAngleToVector3d(bproji)==i){
00284 return cameras[i].project(point);
00285 }
00286 }
00287 }
00288 return INVALID_PROJECTION;
00289 }
00290
00291 bool canBackProject(){
00292 MCRCoord<typename CCMT::ImageCoordT> coord = backProject(point);
00293 return coord != MCRCoord<typename CCMT::ImageCoordT>::INVALID_COORD_IDX;
00294 }
00295
00296 backProject(){
00297 for(size_t i=0; i<cameras.size(); i++){
00298 if(cameras[i].canBackProject(point)){
00299 Vector3d bproji = vector3dAngle(cameras[i].backProject(point));
00300 if(camIdWithMinOpticalAxisAngleToVector3d(bproji)==i){
00301 if(sph_approx_backprojection){
00302 return bproji;
00303 } else{
00304 return MCRCoord<typename CCMT::ImageCoordT>(
00305 i, makepair(cameras[i].getProjectionCenter(), bproji));
00306 }
00307 }
00308 }
00309 }
00310 return MCRCoord<typename CCMT::ImageCoordT>(
00311 MCRCoord<typename CCMT::ImageCoordT>::INVALID_COORD_IDX);
00312 }
00313
00314
00315 };
00316
00317
00318
00319
00320
00321
00322
00323
00324
00326 }
00327
00328
00329 #endif