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 this->t12_matrix_.set_identity();
00080 this->t12_matrix_.put(0,2, -cx); this->t12_matrix_.put(1,2, -cy);
00081 vcl_vector<vgl_homg_point_2d<T> > temp;
00082 for (typename vcl_vector<vgl_homg_point_2d<T> >::const_iterator
00083 pit = points.begin(); pit != points.end(); pit++)
00084 {
00085 vgl_homg_point_2d<T> p((*this)(*pit));
00086 temp.push_back(p);
00087 }
00088
00089 if (isotropic) {
00090 T radius = 1;
00091
00092 if (!this->scale_xyroot2(temp, radius))
00093 return false;
00094 T scale = 1/radius;
00095 this->t12_matrix_.put(0,0, scale);
00096 this->t12_matrix_.put(1,1, scale);
00097 this->t12_matrix_.put(0,2, -cx*scale);
00098 this->t12_matrix_.put(1,2, -cy*scale);
00099 return true;
00100 }
00101 T sdx = 1, sdy = 1, c = 1, s = 0;
00102 if (!this->scale_aniostropic(temp, sdx, sdy, c, s))
00103 return false;
00104 T scx = 1/sdx, scy = 1/sdy;
00105 this->t12_matrix_.put(0, 0, c*scx);
00106 this->t12_matrix_.put(0, 1, -s*scx);
00107 this->t12_matrix_.put(0, 2, (-c*scx*cx+s*scx*cy));
00108 this->t12_matrix_.put(1, 0, s*scy);
00109 this->t12_matrix_.put(1, 1, c*scy);
00110 this->t12_matrix_.put(1, 2, (-s*scy*cx-c*scy*cy));
00111 return true;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 template <class T>
00124 bool vgl_norm_trans_2d<T>::
00125 compute_from_lines(vcl_vector<vgl_homg_line_2d<T> > const& lines,
00126 bool isotropic)
00127 {
00128 vcl_vector<vgl_homg_point_2d<T> > points;
00129 for (typename vcl_vector<vgl_homg_line_2d<T> >::const_iterator lit=lines.begin();
00130 lit != lines.end(); lit++)
00131 {
00132 vgl_homg_line_2d<T> l = (*lit);
00133 vgl_homg_point_2d<T> p(-l.a()*l.c(), -l.b()*l.c(), l.a()*l.a()+l.b()*l.b());
00134 points.push_back(p);
00135 }
00136 return this->compute_from_points(points, isotropic);
00137 }
00138
00139
00140
00141
00142
00143
00144 template <class T>
00145 bool vgl_norm_trans_2d<T>::
00146 compute_from_points_and_lines(vcl_vector<vgl_homg_point_2d<T> > const& pts,
00147 vcl_vector<vgl_homg_line_2d< T> > const& lines,
00148 bool isotropic)
00149 {
00150 vcl_vector<vgl_homg_point_2d<T> > points = pts;
00151 for (typename vcl_vector<vgl_homg_line_2d<T> >::const_iterator lit=lines.begin();
00152 lit != lines.end(); lit++)
00153 {
00154 vgl_homg_line_2d<T> l = (*lit);
00155 vgl_homg_point_2d<T> p(-l.a()*l.c(), -l.b()*l.c(), l.a()*l.a()+l.b()*l.b());
00156 points.push_back(p);
00157 }
00158 return this->compute_from_points(points, isotropic);
00159 }
00160
00161
00162
00163
00164 template <class T>
00165 void vgl_norm_trans_2d<T>::
00166 center_of_mass(vcl_vector<vgl_homg_point_2d<T> > const& in, T& cx, T& cy)
00167 {
00168 T cog_x = 0;
00169 T cog_y = 0;
00170 T cog_count = 0.0;
00171 T tol = static_cast<T>(1e-06);
00172 unsigned n = in.size();
00173 for (unsigned i = 0; i < n; ++i)
00174 {
00175 if (in[i].ideal(tol))
00176 continue;
00177 vgl_point_2d<T> p(in[i]);
00178 T x = p.x();
00179 T y = p.y();
00180 cog_x += x;
00181 cog_y += y;
00182 ++cog_count;
00183 }
00184 if (cog_count > 0)
00185 {
00186 cog_x /= cog_count;
00187 cog_y /= cog_count;
00188 }
00189
00190 cx = cog_x;
00191 cy = cog_y;
00192 }
00193
00194
00195
00196
00197 template <class T>
00198 bool vgl_norm_trans_2d<T>::
00199 scale_xyroot2(vcl_vector<vgl_homg_point_2d<T> > const& in, T& radius)
00200 {
00201 T magnitude = T(0);
00202 int numfinite = 0;
00203 T tol = T(1e-06);
00204 radius = T(0);
00205 for (unsigned i = 0; i < in.size(); ++i)
00206 {
00207 if (in[i].ideal(tol))
00208 continue;
00209 vgl_point_2d<T> p(in[i]);
00210 magnitude += vnl_math_hypot(p.x(),p.y());
00211 ++numfinite;
00212 }
00213
00214 if (numfinite > 0)
00215 {
00216 radius = T(magnitude / (numfinite*vnl_math::sqrt2));
00217 return radius>=tol;
00218 }
00219 return false;
00220 }
00221
00222
00223
00224
00225
00226
00227 template <class T>
00228 bool vgl_norm_trans_2d<T>::
00229 scale_aniostropic(vcl_vector<vgl_homg_point_2d<T> > const& in,
00230 T& sdx, T& sdy, T& c, T& s)
00231 {
00232 T tol = T(1e-06);
00233 unsigned count = 0;
00234 unsigned n = in.size();
00235
00236 double Sx2=0, Sxy=0, Sy2=0;
00237 for (unsigned i = 0; i < n; ++i)
00238 {
00239 if (in[i].ideal(tol))
00240 continue;
00241 ++count;
00242 vgl_point_2d<T> p(in[i]);
00243 T x = p.x();
00244 T y = p.y();
00245 Sx2 += (double)x*x;
00246 Sxy += (double)x*y;
00247 Sy2 += (double)y*y;
00248 }
00249 if (!count)
00250 return false;
00251
00252 double t =0.0;
00253
00254 if ( Sx2 != Sy2 )
00255 t = 0.5*vcl_atan( -2.0*Sxy/(Sx2-Sy2) );
00256
00257 double dc = vcl_cos(t), ds = vcl_sin(t);
00258
00259
00260 double sddx = vcl_sqrt( (dc*dc*Sx2-2.0*dc*ds*Sxy+ds*ds*Sy2)/count );
00261 double sddy = vcl_sqrt( (ds*ds*Sx2+2.0*dc*ds*Sxy+dc*dc*Sy2)/count );
00262
00263
00264 sdx = static_cast<T>(sddx);
00265 sdy = static_cast<T>(sddy);
00266 c = static_cast<T>(dc);
00267 s = static_cast<T>(ds);
00268 return sdx>tol && sdy >tol;
00269 }
00270
00271
00272 #undef VGL_NORM_TRANS_2D_INSTANTIATE
00273 #define VGL_NORM_TRANS_2D_INSTANTIATE(T) \
00274 template class vgl_norm_trans_2d<T >
00275
00276 #endif // vgl_norm_trans_2d_txx_