SRBA: Sparser Relative Bundle Adjustment
srba/models/observations_StereoCamera.h
00001 /* +---------------------------------------------------------------------------+
00002    |                     Mobile Robot Programming Toolkit (MRPT)               |
00003    |                          http://www.mrpt.org/                             |
00004    |                                                                           |
00005    | Copyright (c) 2005-2015, Individual contributors, see AUTHORS file        |
00006    | See: http://www.mrpt.org/Authors - All rights reserved.                   |
00007    | Released under BSD License. See details in http://www.mrpt.org/License    |
00008    +---------------------------------------------------------------------------+ */
00009 
00010 #pragma once
00011 
00015 #include "observations_MonocularCamera.h"
00016 
00017 
00018 #include <mrpt/utils/TCamera.h>
00019 #include <mrpt/utils/TStereoCamera.h>
00020 #include <mrpt/tfest.h>  // for use in landmark_matcher<>
00021 
00022 namespace srba {
00023 namespace observations {
00030     struct StereoCamera
00031     {
00032         static const size_t  OBS_DIMS = 4; 
00033         
00035         struct obs_data_t
00036         {
00037             mrpt::utils::TPixelCoordf  left_px, right_px;
00038 
00040             template <class ARRAY>
00041             inline void getAsArray(ARRAY &obs) const {
00042                 obs[0] = left_px.x;  obs[1] = left_px.y;
00043                 obs[2] = right_px.x; obs[3] = right_px.y;
00044             }
00045         };
00046 
00049         struct TObservationParams
00050         {
00051             mrpt::utils::TStereoCamera camera_calib;
00052         };
00053     };
00054 
00056     template <> struct landmark_matcher<StereoCamera>
00057     {
00058         template <class POSE>
00059         static bool find_relative_pose(
00060             const mrpt::aligned_containers<StereoCamera::obs_data_t>::vector_t & new_kf_obs,
00061             const mrpt::aligned_containers<StereoCamera::obs_data_t>::vector_t & old_kf_obs,
00062             const StereoCamera::TObservationParams &params,
00063             POSE &pose_new_kf_wrt_old_kf
00064             )
00065         {
00066             ASSERT_(new_kf_obs.size()==old_kf_obs.size())
00067             const size_t N=new_kf_obs.size();
00068             // project stereo points to 3D and use them to find out the relative pose:
00069             const double cx = params.camera_calib.leftCamera.cx(), cy = params.camera_calib.leftCamera.cy(), baseline = params.camera_calib.rightCameraPose.x(), f = params.camera_calib.leftCamera.fx();
00070             mrpt::utils::TMatchingPairList matches;
00071             matches.reserve(N);
00072             for (size_t i=0;i<N;i++)
00073             {
00074                 // Point 1:
00075                 const double disparity_old = old_kf_obs[i].left_px.x - old_kf_obs[i].right_px.x;
00076                 if (disparity_old<=.0) continue; // Invalid 3D point
00077                 const mrpt::math::TPoint3D pt_old(
00078                     ( old_kf_obs[i].left_px.x - cx )*baseline/disparity_old,
00079                     ( old_kf_obs[i].left_px.y - cy )*baseline/disparity_old,
00080                     f*baseline/disparity_old );
00081                 // Point 2:
00082                 const double disparity_new = new_kf_obs[i].left_px.x - new_kf_obs[i].right_px.x;
00083                 if (disparity_new<=.0) continue; // Invalid 3D point
00084                 const mrpt::math::TPoint3D pt_new(
00085                     ( new_kf_obs[i].left_px.x - cx )*baseline/disparity_new,
00086                     ( new_kf_obs[i].left_px.y - cy )*baseline/disparity_new,
00087                     f*baseline/disparity_new );
00088 
00089                 matches.push_back( mrpt::utils::TMatchingPair(i,i, pt_old.x,pt_old.y,pt_old.z, pt_new.x,pt_new.y,pt_new.z ) );
00090             }
00091             // Least-square optimal transformation:
00092             if (POSE::rotation_dimensions==2)
00093             { // SE(2)
00094                 mrpt::math::TPose2D found_pose;
00095                 if (!mrpt::tfest::se2_l2(matches,found_pose))
00096                     return false;
00097                 pose_new_kf_wrt_old_kf = POSE( mrpt::poses::CPose2D(found_pose));
00098             }
00099             else
00100             {  // SE(3)
00101                 mrpt::poses::CPose3DQuat found_pose;
00102                 double found_scale;
00103                 if (!mrpt::tfest::se3_l2(matches,found_pose,found_scale))
00104                     return false;
00105                 pose_new_kf_wrt_old_kf = POSE(found_pose);
00106             }
00107             return true;
00108         }
00109     };
00110 
00112 }
00113 } // end NS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends