00001
00002 #ifndef vpgl_affine_camera_txx_
00003 #define vpgl_affine_camera_txx_
00004
00005
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
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
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
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
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
00160 template <class T>
00161 vgl_homg_plane_3d<T> vpgl_affine_camera<T>::
00162 principal_plane() const
00163 {
00164
00165
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
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_