core/vpgl/vpgl_affine_camera.txx
Go to the documentation of this file.
00001 // This is core/vpgl/vpgl_affine_camera.txx
00002 #ifndef vpgl_affine_camera_txx_
00003 #define vpgl_affine_camera_txx_
00004 //:
00005 // \file
00006 
00007 #include "vpgl_affine_camera.h"
00008 #include <vnl/vnl_vector_fixed.h>
00009 #include <vnl/vnl_matrix_fixed.h>
00010 #include <vgl/algo/vgl_rotation_3d.h>
00011 #include <vgl/vgl_closest_point.h>
00012 #include <vgl/vgl_tolerance.h>
00013 #include <vcl_cassert.h>
00014 
00015 //-------------------------------------------
00016 template <class T>
00017 vpgl_affine_camera<T>::vpgl_affine_camera()
00018 {
00019   vnl_matrix_fixed<T,3,4> C( (T)0 );
00020   C(0,0) = C(1,1) = C(2,3) = (T)1;
00021   vpgl_proj_camera<T>::set_matrix( C );
00022   view_distance_ = (T)0;
00023   vgl_homg_point_3d<T> cc = vpgl_proj_camera<T>::camera_center();
00024   ray_dir_.set(cc.x(), cc.y(), cc.z());
00025   ray_dir_ = normalize(ray_dir_);
00026 }
00027 
00028 
00029 //-------------------------------------------
00030 template <class T>
00031 vpgl_affine_camera<T>::vpgl_affine_camera( const vnl_vector_fixed<T,4>& row1,
00032                                            const vnl_vector_fixed<T,4>& row2 )
00033 {
00034   set_rows( row1, row2 );
00035   view_distance_ = (T)0;
00036   vgl_homg_point_3d<T> cc = vpgl_proj_camera<T>::camera_center();
00037   ray_dir_.set(cc.x(), cc.y(), cc.z());
00038   ray_dir_ = normalize(ray_dir_);
00039 }
00040 
00041 
00042 //------------------------------------------
00043 template <class T>
00044 vpgl_affine_camera<T>::vpgl_affine_camera( const vnl_matrix_fixed<T,3,4>& camera_matrix )
00045 {
00046   assert( camera_matrix(2,3) != 0 );
00047   vnl_matrix_fixed<T,3,4> C( camera_matrix );
00048   C = C/C(2,3);
00049   C(2,0) = (T)0; C(2,1) = (T)0; C(2,2) = (T)0;
00050   vpgl_proj_camera<T>::set_matrix( C );
00051   view_distance_ = (T)0;
00052   vgl_homg_point_3d<T> cc = vpgl_proj_camera<T>::camera_center();
00053   ray_dir_.set(cc.x(), cc.y(), cc.z());
00054   ray_dir_ = normalize(ray_dir_);
00055 }
00056 
00057 template <class T>
00058 vpgl_affine_camera<T>::
00059 vpgl_affine_camera(vgl_vector_3d<T> ray, vgl_vector_3d<T> up,
00060                    vgl_point_3d<T> stare_pt,
00061                    T u0, T v0, T su, T sv) {
00062 
00063   vgl_vector_3d<T> uvec = normalized(up), rvec = normalized(ray);
00064   vnl_matrix_fixed<T,3,3> R;
00065   if (vcl_fabs(dot_product<T>(uvec,rvec)-T(1))<1e-5)
00066   {
00067     T r[] = { 1, 0, 0,
00068               0, 1, 0,
00069               0, 0, 1 };
00070 
00071     R = vnl_matrix_fixed<T,3,3>(r);
00072   }
00073   else if (vcl_fabs(dot_product<T>(uvec,rvec)-T(-1))<1e-5)
00074   {
00075       T r[] = { 1, 0, 0,
00076               0, 1, 0,
00077               0, 0, -1 };
00078 
00079       R = vnl_matrix_fixed<T,3,3>(r);
00080   }
00081   else
00082   {
00083     vgl_vector_3d<T> x = cross_product(-uvec,rvec);
00084     vgl_vector_3d<T> y = cross_product(rvec,x);
00085     normalize(x);
00086     normalize(y);
00087 
00088     T r[] = { x.x(), x.y(), x.z(),
00089               y.x(), y.y(), y.z(),
00090               rvec.x(), rvec.y(), rvec.z() };
00091 
00092     R = vnl_matrix_fixed<T,3,3>(r);
00093   }
00094 
00095   //form affine camera
00096   vnl_vector_fixed<T, 4> r0, r1;
00097   for (unsigned i = 0; i<3; ++i) {
00098     r0[i] = su*R[0][i];
00099     r1[i] = sv*R[1][i];
00100   }
00101   r0[3]= 0.0;   r1[3]= 0.0;
00102   this->set_rows(r0, r1);
00103   T u, v;
00104   this->project(stare_pt.x(), stare_pt.y(), stare_pt.z(), u, v);
00105   T tu = (u0-u);
00106   T tv = (v0-v);
00107   r0[3]=tu; r1[3]=tv;
00108   this->set_rows(r0, r1);
00109   view_distance_ = (T)0;
00110   ray_dir_.set(rvec.x(), rvec.y(), rvec.z());
00111 }
00112 
00113 
00114 //------------------------------------------
00115 template <class T>
00116 void vpgl_affine_camera<T>::set_rows(
00117   const vnl_vector_fixed<T,4>& row1,
00118   const vnl_vector_fixed<T,4>& row2 )
00119 {
00120   vnl_matrix_fixed<T,3,4> C( (T)0 );
00121   for ( unsigned int i = 0; i < 4; ++i ) {
00122     C(0,i) = row1(i);
00123     C(1,i) = row2(i);
00124   }
00125   C(2,3) = (T)1;
00126   vpgl_proj_camera<T>::set_matrix( C );
00127 }
00128 
00129 //: Find the 3d coordinates of the center of the camera. Will be an ideal point with the sense of the ray direction.
00130 template <class T>
00131 vgl_homg_point_3d<T> vpgl_affine_camera<T>::camera_center() const
00132 {
00133   vgl_homg_point_3d<T> temp(ray_dir_.x(), ray_dir_.y(), ray_dir_.z(), (T)0);
00134   return temp;
00135 }
00136 
00137 //: Find the 3d ray that goes through the camera center and the provided image point.
00138 template <class T>
00139 vgl_homg_line_3d_2_points<T> vpgl_affine_camera<T>::
00140 backproject( const vgl_homg_point_2d<T>& image_point ) const
00141 {
00142   vgl_homg_line_3d_2_points<T> ret;
00143   //get line from projective camera
00144   vgl_homg_line_3d_2_points<T> line =
00145     vpgl_proj_camera<T>::backproject(image_point);
00146   vgl_homg_point_3d<T> cph = vgl_closest_point_origin(line);
00147   if (!is_ideal(cph, vgl_tolerance<T>::position)) {
00148   vgl_point_3d<T> cp(cph);
00149   vgl_point_3d<T> eye_pt = cp-(view_distance_*ray_dir_);
00150   vgl_homg_point_3d<T> pt_fin(eye_pt.x(), eye_pt.y(), eye_pt.z());
00151   vgl_homg_point_3d<T> pinf(ray_dir_.x(), ray_dir_.y(), ray_dir_.z(), (T)0);
00152   ret = vgl_homg_line_3d_2_points<T>(pt_fin, pinf);
00153   }
00154   else
00155     vcl_cout << "Warning vpgl_affine_camera::backproject produced line at infinity\n";
00156   return ret;
00157 }
00158 
00159 //: Find the world plane parallel to the image plane intersecting the camera center.
00160 template <class T>
00161 vgl_homg_plane_3d<T> vpgl_affine_camera<T>::
00162 principal_plane() const
00163 {
00164   //note that d = view_distance_ not -view_distance_,
00165   //since dir points towards the origin
00166   vgl_homg_plane_3d<T> ret(ray_dir_.x(), ray_dir_.y(),
00167                            ray_dir_.z(), view_distance_);
00168   return ret;
00169 }
00170 
00171 
00172 // Code for easy instantiation.
00173 #undef vpgl_AFFINE_CAMERA_INSTANTIATE
00174 #define vpgl_AFFINE_CAMERA_INSTANTIATE(T) \
00175 template class vpgl_affine_camera<T >
00176 
00177 
00178 #endif // vpgl_affine_camera_txx_