Go to the documentation of this file.00001
00002 #ifndef vgl_line_2d_regression_txx_
00003 #define vgl_line_2d_regression_txx_
00004
00005
00006
00007 #include "vgl_line_2d_regression.h"
00008 #include <vcl_cmath.h>
00009 #include <vgl/vgl_distance.h>
00010 #include <vnl/vnl_matrix_fixed.h>
00011 #include <vnl/algo/vnl_symmetric_eigensystem.h>
00012 #include <vcl_iostream.h>
00013 #include <vcl_cassert.h>
00014
00015
00016 template <class T>
00017 vgl_line_2d_regression<T>::vgl_line_2d_regression()
00018 {
00019 this->clear();
00020 }
00021
00022
00023 template <class T>
00024 void vgl_line_2d_regression<T>::increment_partial_sums(const T x, const T y)
00025 {
00026 Sx_ += x;
00027 Sy_ += y;
00028 Sxx_ += x*x;
00029 Sxy_ += x*y;
00030 Syy_ += y*y;
00031 ++npts_;
00032 }
00033
00034
00035 template <class T>
00036 void vgl_line_2d_regression<T>::decrement_partial_sums(const T x, const T y)
00037 {
00038 assert(npts_!=0);
00039 Sx_ -= x;
00040 Sy_ -= y;
00041 Sxx_ -= x*x;
00042 Sxy_ -= x*y;
00043 Syy_ -= y*y;
00044 --npts_;
00045 }
00046
00047
00048 template <class T>
00049 void vgl_line_2d_regression<T>::clear()
00050 {
00051 Sx_ = 0;
00052 Sy_ = 0;
00053 Sxx_ = 0;
00054 Sxy_ = 0;
00055 Syy_ = 0;
00056 npts_=0;
00057 squared_error_=0;
00058 }
00059
00060
00061 template <class T>
00062 bool vgl_line_2d_regression<T>::fit()
00063 {
00064 if (npts_<2)
00065 return false;
00066
00067 vnl_matrix_fixed<T, 2, 2> M;
00068 M(0, 0) = Sxx_-Sx_*Sx_/npts_;
00069 M(0, 1) = M(1, 0) = Sxy_-Sx_*Sy_/npts_;
00070 M(1, 1) = Syy_-Sy_*Sy_/npts_;
00071
00072 vnl_symmetric_eigensystem<T> sym(M.as_ref());
00073 T a = sym.V(0,0);
00074 T b = sym.V(1,0);
00075 T c = -(a*Sx_/npts_ + b*Sy_/npts_);
00076 line_= vgl_line_2d<T>(a,b,c);
00077
00078 return true;
00079 }
00080
00081 template <class T>
00082 bool vgl_line_2d_regression<T>::fit_constrained(T x, T y)
00083 {
00084 if (npts_<1)
00085 {
00086 vcl_cout << "In vgl_line_2d_regression<T>::fit_constrained() - less than 1 point\n";
00087 return false;
00088 }
00089 vnl_matrix_fixed<T, 2, 2> M;
00090 M(0, 0) = Sxx_-2*Sx_*x +npts_*x*x;
00091 M(0, 1) = M(1, 0) = Sxy_-Sx_*y-x*Sy_+npts_*x*y;
00092 M(1, 1) = Syy_-2*Sy_*y+npts_*y*y;
00093 vnl_symmetric_eigensystem<T> sym(M.as_ref());
00094 T a = sym.V(0,0);
00095 T b = sym.V(1,0);
00096 T c = -(a*x + b*y);
00097 line_= vgl_line_2d<T>(a,b,c);
00098 return true;
00099 }
00100
00101 template <class T>
00102 double vgl_line_2d_regression<T>::get_rms_error(const T a, const T b, const T c)
00103 {
00104 if (npts_==0)
00105 return 0;
00106 double t0 = Sxx_*a*a + 2*Sxy_*a*b + Syy_*b*b;
00107 double t1 = 2*Sx_*a*c + 2*Sy_*b*c + npts_*c*c;
00108 double rms = vcl_sqrt(vcl_fabs(t0+t1)/((a*a+b*b)*npts_));
00109 return rms;
00110 }
00111
00112 template <class T>
00113 double vgl_line_2d_regression<T>::get_rms_error()
00114 {
00115 return this->get_rms_error(line_.a(), line_.b(), line_.c());
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 template <class T>
00131 void vgl_line_2d_regression<T>::init_rms_error_est()
00132 {
00133 squared_error_ = this->get_rms_error();
00134 squared_error_ *=squared_error_;
00135 squared_error_ *= npts_;
00136 }
00137
00138
00139
00140
00141 template <class T>
00142 double vgl_line_2d_regression<T>::get_rms_error_est(vgl_point_2d<T> const& p,
00143 bool increment)
00144 {
00145 if (npts_==0)
00146 return 0;
00147 double d = vgl_distance(p, line_);
00148 double ds = d*d;
00149 if (increment)
00150 squared_error_ = squared_error_ + ds;
00151 return vcl_sqrt(squared_error_/(npts_+1));
00152 }
00153
00154
00155 #undef VGL_LINE_2D_REGRESSION_INSTANTIATE
00156 #define VGL_LINE_2D_REGRESSION_INSTANTIATE(T) \
00157 template class vgl_line_2d_regression<T >
00158
00159 #endif // vgl_line_2d_regression_txx_