00001
00002 #ifndef vpgl_calibration_matrix_txx_
00003 #define vpgl_calibration_matrix_txx_
00004
00005
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/algo/vnl_svd.h>
00012 #include <vcl_cassert.h>
00013
00014
00015 template <class T>
00016 vpgl_calibration_matrix<T>::vpgl_calibration_matrix() :
00017 focal_length_( (T)1 ),
00018 principal_point_( vgl_point_2d<T>( (T)0, (T)0 ) ),
00019 x_scale_( (T)1 ),
00020 y_scale_( (T)1 ),
00021 skew_( (T)0 )
00022 {
00023 }
00024
00025
00026
00027 template <class T>
00028 vpgl_calibration_matrix<T>::vpgl_calibration_matrix(
00029 T focal_length, const vgl_point_2d<T>& principal_point, T x_scale, T y_scale, T skew ) :
00030 focal_length_( focal_length ),
00031 principal_point_( principal_point ),
00032 x_scale_( x_scale ),
00033 y_scale_( y_scale ),
00034 skew_( skew )
00035 {
00036
00037 assert( focal_length != 0 );
00038 assert( x_scale > 0 );
00039 assert( y_scale > 0 );
00040 }
00041
00042
00043
00044 template <class T>
00045 vpgl_calibration_matrix<T>::vpgl_calibration_matrix( const vnl_matrix_fixed<T,3,3>& K )
00046 {
00047
00048
00049 assert( K(2,2) != (T)0 && K(1,0) == (T)0 && K(2,0) == (T)0 && K(2,1) == (T)0 );
00050 double scale_factor = (T)1;
00051 if ( K(2,2) != (T)1 ) scale_factor = ((T)1)/K(2,2);
00052
00053 focal_length_ = (T)1;
00054 x_scale_ = scale_factor*K(0,0);
00055 y_scale_ = scale_factor*K(1,1);
00056 skew_ = scale_factor*K(0,1);
00057 principal_point_.set( scale_factor*K(0,2), scale_factor*K(1,2) );
00058
00059 assert( ( x_scale_ > 0 && y_scale_ > 0 ) || ( x_scale_ < 0 && y_scale_ < 0 ) );
00060 }
00061
00062
00063
00064 template <class T>
00065 vnl_matrix_fixed<T,3,3> vpgl_calibration_matrix<T>::get_matrix() const
00066 {
00067
00068 vnl_matrix_fixed<T,3,3> K( (T)0 );
00069 K(0,0) = focal_length_*x_scale_;
00070 K(1,1) = focal_length_*y_scale_;
00071 K(2,2) = (T)1;
00072 K(0,2) = principal_point_.x();
00073 K(1,2) = principal_point_.y();
00074 K(0,1) = skew_;
00075 return K;
00076 }
00077
00078
00079
00080 template <class T>
00081 void vpgl_calibration_matrix<T>::set_focal_length( T new_focal_length )
00082 {
00083 assert( new_focal_length != (T)0 );
00084 focal_length_ = new_focal_length;
00085 }
00086
00087
00088
00089 template <class T>
00090 void vpgl_calibration_matrix<T>::set_principal_point(
00091 const vgl_point_2d<T>& new_principal_point )
00092 {
00093 assert( !new_principal_point.ideal() );
00094 principal_point_ = new_principal_point;
00095 }
00096
00097
00098
00099 template <class T>
00100 void vpgl_calibration_matrix<T>::set_x_scale( T new_x_scale )
00101 {
00102 assert( new_x_scale > 0 );
00103 x_scale_ = new_x_scale;
00104 }
00105
00106
00107
00108 template <class T>
00109 void vpgl_calibration_matrix<T>::set_y_scale( T new_y_scale )
00110 {
00111 assert( new_y_scale > 0 );
00112 y_scale_ = new_y_scale;
00113 }
00114
00115
00116
00117 template <class T>
00118 void vpgl_calibration_matrix<T>::set_skew( T new_skew )
00119 {
00120 skew_ = new_skew;
00121 }
00122
00123
00124 template <class T> bool vpgl_calibration_matrix<T>::
00125 operator==(vpgl_calibration_matrix<T> const &that) const
00126 {
00127 if (this == &that)
00128 return true;
00129
00130 return
00131 this->focal_length_ == that.focal_length_ &&
00132 this->principal_point_ == that.principal_point_ &&
00133 this->x_scale_ == that.x_scale_ && this->y_scale_ == that.y_scale_ &&
00134 this->skew_ == that.skew_;
00135 }
00136
00137
00138
00139 template <class T>
00140 vgl_point_2d<T> vpgl_calibration_matrix<T>::
00141 map_to_focal_plane(vgl_point_2d<T> const& p_image) const
00142 {
00143 vnl_vector<T> p(3);
00144 p[0]=p_image.x(); p[1]=p_image.y(); p[2]=1;
00145 vnl_svd<T> svd(this->get_matrix());
00146 vnl_matrix<T> Kinv = svd.inverse();
00147 vnl_vector<T> 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<T> p(3);
00156 p[0]=p_focal_plane.x(); p[1]=p_focal_plane.y(); p[2]=1;
00157 vnl_matrix_fixed<T,3,3> K = this->get_matrix();
00158 vnl_vector<T> pf = K*p;
00159 return vgl_point_2d<T>(pf[0]/pf[2], pf[1]/pf[2]);
00160 }
00161
00162
00163
00164
00165
00166 template <class T> void vpgl_calibration_matrix<T>::
00167 b_read(vsl_b_istream &is)
00168 {
00169 if (!is) return;
00170
00171 short ver;
00172 vsl_b_read(is, ver);
00173 switch (ver)
00174 {
00175 case 1:
00176 vsl_b_read(is, focal_length_);
00177 vsl_b_read(is, principal_point_);
00178 vsl_b_read(is, x_scale_);
00179 vsl_b_read(is, y_scale_);
00180 vsl_b_read(is, skew_);
00181 break;
00182 default:
00183 vcl_cerr << "I/O ERROR: vpgl_calibration_matrix::b_read(vsl_b_istream&)\n"
00184 << " Unknown version number "<< ver << '\n';
00185 is.is().clear(vcl_ios::badbit);
00186 return;
00187 }
00188 }
00189
00190
00191
00192
00193 template <class T> void vpgl_calibration_matrix<T>::
00194 b_write(vsl_b_ostream &os) const
00195 {
00196 vsl_b_write(os, this->version());
00197 vsl_b_write(os, focal_length_);
00198 vsl_b_write(os, principal_point_);
00199 vsl_b_write(os, x_scale_);
00200 vsl_b_write(os, y_scale_);
00201 vsl_b_write(os, skew_);
00202 }
00203
00204
00205 template <class T> void
00206 vsl_b_write(vsl_b_ostream &os, const vpgl_calibration_matrix<T> * p)
00207 {
00208 if (p==0) {
00209 vsl_b_write(os, false);
00210 }
00211 else{
00212 vsl_b_write(os,true);
00213 p->b_write(os);
00214 }
00215 }
00216
00217
00218
00219 template <class T> void
00220 vsl_b_read(vsl_b_istream &is, vpgl_calibration_matrix<T>* &p)
00221 {
00222 delete p;
00223 bool not_null_ptr;
00224 vsl_b_read(is, not_null_ptr);
00225 if (not_null_ptr) {
00226 p = new vpgl_calibration_matrix<T>();
00227 p->b_read(is);
00228 }
00229 else
00230 p = 0;
00231 }
00232
00233
00234 #undef vpgl_CALIBRATION_MATRIX_INSTANTIATE
00235 #define vpgl_CALIBRATION_MATRIX_INSTANTIATE(T) \
00236 template class vpgl_calibration_matrix<T >
00237
00238 #endif // vpgl_calibration_matrix_txx_