core/vpgl/vpgl_calibration_matrix.txx
Go to the documentation of this file.
00001 // This is core/vpgl/vpgl_calibration_matrix.txx
00002 #ifndef vpgl_calibration_matrix_txx_
00003 #define vpgl_calibration_matrix_txx_
00004 //:
00005 // \file
00006 
00007 #include "vpgl_calibration_matrix.h"
00008 
00009 #include <vgl/vgl_point_2d.h>
00010 #include <vgl/io/vgl_io_point_2d.h>
00011 #include <vnl/vnl_inverse.h>
00012 #include <vnl/vnl_vector_fixed.h>
00013 #include <vnl/vnl_matrix_fixed.h>
00014 #include <vcl_cassert.h>
00015 
00016 //--------------------------------------
00017 template <class T>
00018 vpgl_calibration_matrix<T>::vpgl_calibration_matrix() :
00019   focal_length_( (T)1 ),
00020   principal_point_( vgl_point_2d<T>( (T)0, (T)0 ) ),
00021   x_scale_( (T)1 ),
00022   y_scale_( (T)1 ),
00023   skew_( (T)0 )
00024 {
00025 }
00026 
00027 
00028 //--------------------------------------
00029 template <class T>
00030 vpgl_calibration_matrix<T>::vpgl_calibration_matrix(
00031     T focal_length, const vgl_point_2d<T>& principal_point, T x_scale, T y_scale, T skew ) :
00032   focal_length_( focal_length ),
00033   principal_point_( principal_point ),
00034   x_scale_( x_scale ),
00035   y_scale_( y_scale ),
00036   skew_( skew )
00037 {
00038   // Make sure the inputs are valid.
00039   assert( focal_length != 0 );
00040   assert( x_scale > 0 );
00041   assert( y_scale > 0 );
00042 }
00043 
00044 
00045 //--------------------------------------
00046 template <class T>
00047 vpgl_calibration_matrix<T>::vpgl_calibration_matrix( const vnl_matrix_fixed<T,3,3>& K )
00048 {
00049   // Put the supplied matrix into canonical form and check that it could be a
00050   // calibration matrix.
00051   assert( K(2,2) != (T)0 && K(1,0) == (T)0 && K(2,0) == (T)0 && K(2,1) == (T)0 );
00052   double scale_factor = 1.0;
00053   if ( K(2,2) != (T)1 ) scale_factor /= (double)K(2,2);
00054 
00055   focal_length_ = (T)1;
00056   x_scale_ = T(scale_factor*K(0,0));
00057   y_scale_ = T(scale_factor*K(1,1));
00058   skew_    = T(scale_factor*K(0,1));
00059   principal_point_.set( T(scale_factor*K(0,2)), T(scale_factor*K(1,2)) );
00060 
00061   assert( ( x_scale_ > 0 && y_scale_ > 0 ) || ( x_scale_ < 0 && y_scale_ < 0 ) );
00062 }
00063 
00064 
00065 //--------------------------------------
00066 template <class T>
00067 vnl_matrix_fixed<T,3,3> vpgl_calibration_matrix<T>::get_matrix() const
00068 {
00069   // Construct the matrix as in H&Z.
00070   vnl_matrix_fixed<T,3,3> K( (T)0 );
00071   K(0,0) = focal_length_*x_scale_;
00072   K(1,1) = focal_length_*y_scale_;
00073   K(2,2) = (T)1;
00074   K(0,2) = principal_point_.x();
00075   K(1,2) = principal_point_.y();
00076   K(0,1) = skew_;
00077   return K;
00078 }
00079 
00080 
00081 //--------------------------------------
00082 template <class T>
00083 void vpgl_calibration_matrix<T>::set_focal_length( T new_focal_length )
00084 {
00085   assert( new_focal_length != (T)0 );
00086   focal_length_ = new_focal_length;
00087 }
00088 
00089 
00090 //--------------------------------------
00091 template <class T>
00092 void vpgl_calibration_matrix<T>::set_principal_point(
00093   const vgl_point_2d<T>& new_principal_point )
00094 {
00095   assert( !new_principal_point.ideal() );
00096   principal_point_ = new_principal_point;
00097 }
00098 
00099 
00100 //--------------------------------------
00101 template <class T>
00102 void vpgl_calibration_matrix<T>::set_x_scale( T new_x_scale )
00103 {
00104   assert( new_x_scale > 0 );
00105   x_scale_ = new_x_scale;
00106 }
00107 
00108 
00109 //--------------------------------------
00110 template <class T>
00111 void vpgl_calibration_matrix<T>::set_y_scale( T new_y_scale )
00112 {
00113   assert( new_y_scale > 0 );
00114   y_scale_ = new_y_scale;
00115 }
00116 
00117 
00118 //--------------------------------------
00119 template <class T>
00120 void vpgl_calibration_matrix<T>::set_skew( T new_skew )
00121 {
00122   skew_ = new_skew;
00123 }
00124 
00125 //: Equality test
00126 template <class T> bool vpgl_calibration_matrix<T>::
00127 operator==(vpgl_calibration_matrix<T> const &that) const
00128 {
00129   if (this == &that) // same object => equal.
00130     return true;
00131 
00132   return
00133     this->focal_length_ == that.focal_length_ &&
00134     this->principal_point_ == that.principal_point_ &&
00135     this->x_scale_ == that.x_scale_ && this->y_scale_ == that.y_scale_ &&
00136     this->skew_ == that.skew_;
00137 }
00138 
00139 //: Map from image to focal plane.
00140 // (Later may need to cache the inverse for efficiency)
00141 template <class T>
00142 vgl_point_2d<T> vpgl_calibration_matrix<T>::
00143 map_to_focal_plane(vgl_point_2d<T> const& p_image) const
00144 {
00145   vnl_vector_fixed<T,3> p(p_image.x(), p_image.y(), 1);
00146   vnl_matrix_fixed<T,3,3> Kinv = vnl_inverse(this->get_matrix());
00147   vnl_vector_fixed<T,3> pf = Kinv*p;
00148   return vgl_point_2d<T>(pf[0]/pf[2], pf[1]/pf[2]);
00149 }
00150 
00151 template <class T>
00152 vgl_point_2d<T> vpgl_calibration_matrix<T>::
00153 map_to_image(vgl_point_2d<T> const& p_focal_plane) const
00154 {
00155   vnl_vector_fixed<T,3> p(p_focal_plane.x(), p_focal_plane.y(), 1);
00156   vnl_matrix_fixed<T,3,3> K = this->get_matrix();
00157   vnl_vector_fixed<T,3> pf = K*p;
00158   return vgl_point_2d<T>(pf[0]/pf[2], pf[1]/pf[2]);
00159 }
00160 
00161 // Code for easy instantiation.
00162 #undef vpgl_CALIBRATION_MATRIX_INSTANTIATE
00163 #define vpgl_CALIBRATION_MATRIX_INSTANTIATE(T) \
00164 template class vpgl_calibration_matrix<T >
00165 
00166 #endif // vpgl_calibration_matrix_txx_