Go to the documentation of this file.00001
00002 #ifndef vgl_norm_trans_2d_txx_
00003 #define vgl_norm_trans_2d_txx_
00004
00005
00006
00007 #include "vgl_norm_trans_2d.h"
00008 #include <vgl/vgl_point_2d.h>
00009 #include <vcl_iostream.h>
00010 #include <vnl/vnl_math.h>
00011
00012
00013
00014
00015
00016 template <class T>
00017 vgl_norm_trans_2d<T>::vgl_norm_trans_2d() : vgl_h_matrix_2d<T>()
00018 {
00019 }
00020
00021
00022 template <class T>
00023 vgl_norm_trans_2d<T>::vgl_norm_trans_2d(const vgl_norm_trans_2d<T>& M)
00024 : vgl_h_matrix_2d<T>(M)
00025 {
00026 }
00027
00028
00029
00030 template <class T>
00031 vgl_norm_trans_2d<T>::vgl_norm_trans_2d(vcl_istream& s)
00032 : vgl_h_matrix_2d<T>(s)
00033 {
00034 }
00035
00036
00037 template <class T>
00038 vgl_norm_trans_2d<T>::vgl_norm_trans_2d(char const* filename)
00039 : vgl_h_matrix_2d<T>(filename)
00040 {
00041 }
00042
00043
00044
00045 template <class T>
00046 vgl_norm_trans_2d<T>::vgl_norm_trans_2d(vnl_matrix_fixed<T,3,3> const& M)
00047 : vgl_h_matrix_2d<T>(M)
00048 {
00049 }
00050
00051
00052
00053 template <class T>
00054 vgl_norm_trans_2d<T>::vgl_norm_trans_2d(const T* H)
00055 : vgl_h_matrix_2d<T>(H)
00056 {
00057 }
00058
00059
00060 template <class T>
00061 vgl_norm_trans_2d<T>::~vgl_norm_trans_2d()
00062 {
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072 template <class T>
00073 bool vgl_norm_trans_2d<T>::
00074 compute_from_points(vcl_vector<vgl_homg_point_2d<T> > const& points,
00075 bool isotropic)
00076 {
00077 T cx, cy;
00078 this->center_of_mass(points, cx, cy);
00079 vgl_h_matrix_2d<T>::set_identity().set_translation(-cx,-cy);
00080 vcl_vector<vgl_homg_point_2d<T> > temp;
00081 for (typename vcl_vector<vgl_homg_point_2d<T> >::const_iterator
00082 pit = points.begin(); pit != points.end(); pit++)
00083 {
00084 vgl_homg_point_2d<T> p((*this)(*pit));
00085 temp.push_back(p);
00086 }
00087
00088 if (isotropic) {
00089 T radius = T(1);
00090
00091 if (!this->scale_xyroot2(temp, radius))
00092 return false;
00093 vgl_h_matrix_2d<T>::set_scale(T(1)/radius);
00094 return true;
00095 }
00096 T sdx = 1, sdy = 1, c = 1, s = 0;
00097 if (!this->scale_aniostropic(temp, sdx, sdy, c, s))
00098 return false;
00099 T scx = 1/sdx, scy = 1/sdy;
00100 T data[] = { c*scx, -s*scx, -c*scx*cx +s*scx*cy,
00101 s*scy, c*scy, -s*scy*cx -c*scy*cy };
00102 vgl_h_matrix_2d<T>::set_affine(vnl_matrix_fixed<T,2,3>(data));
00103 return true;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 template <class T>
00116 bool vgl_norm_trans_2d<T>::
00117 compute_from_lines(vcl_vector<vgl_homg_line_2d<T> > const& lines,
00118 bool isotropic)
00119 {
00120 vcl_vector<vgl_homg_point_2d<T> > points;
00121 for (typename vcl_vector<vgl_homg_line_2d<T> >::const_iterator lit=lines.begin();
00122 lit != lines.end(); lit++)
00123 {
00124 vgl_homg_line_2d<T> l = (*lit);
00125 vgl_homg_point_2d<T> p(-l.a()*l.c(), -l.b()*l.c(), l.a()*l.a()+l.b()*l.b());
00126 points.push_back(p);
00127 }
00128 return this->compute_from_points(points, isotropic);
00129 }
00130
00131
00132
00133
00134
00135
00136 template <class T>
00137 bool vgl_norm_trans_2d<T>::
00138 compute_from_points_and_lines(vcl_vector<vgl_homg_point_2d<T> > const& pts,
00139 vcl_vector<vgl_homg_line_2d< T> > const& lines,
00140 bool isotropic)
00141 {
00142 vcl_vector<vgl_homg_point_2d<T> > points = pts;
00143 for (typename vcl_vector<vgl_homg_line_2d<T> >::const_iterator lit=lines.begin();
00144 lit != lines.end(); lit++)
00145 {
00146 vgl_homg_line_2d<T> l = (*lit);
00147 vgl_homg_point_2d<T> p(-l.a()*l.c(), -l.b()*l.c(), l.a()*l.a()+l.b()*l.b());
00148 points.push_back(p);
00149 }
00150 return this->compute_from_points(points, isotropic);
00151 }
00152
00153
00154
00155
00156 template <class T>
00157 void vgl_norm_trans_2d<T>::
00158 center_of_mass(vcl_vector<vgl_homg_point_2d<T> > const& in, T& cx, T& cy)
00159 {
00160 T cog_x = 0;
00161 T cog_y = 0;
00162 T cog_count = 0.0;
00163 T tol = static_cast<T>(1e-06);
00164 unsigned n = in.size();
00165 for (unsigned i = 0; i < n; ++i)
00166 {
00167 if (in[i].ideal(tol))
00168 continue;
00169 vgl_point_2d<T> p(in[i]);
00170 T x = p.x();
00171 T y = p.y();
00172 cog_x += x;
00173 cog_y += y;
00174 ++cog_count;
00175 }
00176 if (cog_count > 0)
00177 {
00178 cog_x /= cog_count;
00179 cog_y /= cog_count;
00180 }
00181
00182 cx = cog_x;
00183 cy = cog_y;
00184 }
00185
00186
00187
00188
00189 template <class T>
00190 bool vgl_norm_trans_2d<T>::
00191 scale_xyroot2(vcl_vector<vgl_homg_point_2d<T> > const& in, T& radius)
00192 {
00193 T magnitude = T(0);
00194 int numfinite = 0;
00195 T tol = T(1e-06);
00196 radius = T(0);
00197 for (unsigned i = 0; i < in.size(); ++i)
00198 {
00199 if (in[i].ideal(tol))
00200 continue;
00201 vgl_point_2d<T> p(in[i]);
00202 magnitude += vnl_math_hypot(p.x(),p.y());
00203 ++numfinite;
00204 }
00205
00206 if (numfinite > 0)
00207 {
00208 radius = T(magnitude / (numfinite*vnl_math::sqrt2));
00209 return radius>=tol;
00210 }
00211 return false;
00212 }
00213
00214
00215
00216
00217
00218
00219 template <class T>
00220 bool vgl_norm_trans_2d<T>::
00221 scale_aniostropic(vcl_vector<vgl_homg_point_2d<T> > const& in,
00222 T& sdx, T& sdy, T& c, T& s)
00223 {
00224 T tol = T(1e-06);
00225 unsigned count = 0;
00226 unsigned n = in.size();
00227
00228 double Sx2=0, Sxy=0, Sy2=0;
00229 for (unsigned i = 0; i < n; ++i)
00230 {
00231 if (in[i].ideal(tol))
00232 continue;
00233 ++count;
00234 vgl_point_2d<T> p(in[i]);
00235 T x = p.x();
00236 T y = p.y();
00237 Sx2 += (double)x*x;
00238 Sxy += (double)x*y;
00239 Sy2 += (double)y*y;
00240 }
00241 if (!count)
00242 return false;
00243
00244 double t =0.0;
00245
00246 if ( Sx2 != Sy2 )
00247 t = 0.5*vcl_atan( -2.0*Sxy/(Sx2-Sy2) );
00248
00249 double dc = vcl_cos(t), ds = vcl_sin(t);
00250
00251
00252 double sddx = vcl_sqrt( (dc*dc*Sx2-2.0*dc*ds*Sxy+ds*ds*Sy2)/count );
00253 double sddy = vcl_sqrt( (ds*ds*Sx2+2.0*dc*ds*Sxy+dc*dc*Sy2)/count );
00254
00255
00256 sdx = static_cast<T>(sddx);
00257 sdy = static_cast<T>(sddy);
00258 c = static_cast<T>(dc);
00259 s = static_cast<T>(ds);
00260 return sdx>tol && sdy >tol;
00261 }
00262
00263
00264 #undef VGL_NORM_TRANS_2D_INSTANTIATE
00265 #define VGL_NORM_TRANS_2D_INSTANTIATE(T) \
00266 template class vgl_norm_trans_2d<T >
00267
00268 #endif // vgl_norm_trans_2d_txx_