Go to the documentation of this file.00001
00002 #ifndef vgl_fit_plane_3d_txx_
00003 #define vgl_fit_plane_3d_txx_
00004
00005
00006
00007 #include "vgl_fit_plane_3d.h"
00008 #include <vgl/algo/vgl_norm_trans_3d.h>
00009 #include <vnl/algo/vnl_svd.h>
00010 #include <vnl/vnl_matrix.h>
00011 #include <vcl_iostream.h>
00012
00013 template <class T>
00014 vgl_fit_plane_3d<T>::vgl_fit_plane_3d(vcl_vector<vgl_homg_point_3d<T> > points)
00015 : points_(points)
00016 {
00017 }
00018
00019 template <class T>
00020 void vgl_fit_plane_3d<T>::add_point(vgl_homg_point_3d<T> const &p)
00021 {
00022 points_.push_back(p);
00023 }
00024
00025 template <class T>
00026 void vgl_fit_plane_3d<T>::add_point(const T x, const T y, const T z)
00027 {
00028 points_.push_back(vgl_homg_point_3d<T> (x, y, z));
00029 }
00030
00031 template <class T>
00032 void vgl_fit_plane_3d<T>::clear()
00033 {
00034 points_.clear();
00035 }
00036
00037 template <class T>
00038 bool vgl_fit_plane_3d<T>::fit(const T error_marg, vcl_ostream* errstream)
00039 {
00040
00041 vgl_norm_trans_3d<T> norm;
00042 if (!norm.compute_from_points(points_) && errstream) {
00043 *errstream << "there is a problem with norm transform\n";
00044 }
00045
00046
00047 for (unsigned i=0; i<points_.size(); i++) {
00048 vgl_homg_point_3d<T> p = points_[i];
00049 points_[i] = norm(p);
00050 }
00051
00052
00053 T A=0, B=0, C=0, D=0, E=0, F=0, G=0, H=0, I=0;
00054 unsigned n = points_.size();
00055 for (unsigned i=0; i<n; i++) {
00056 T x = points_[i].x()/points_[i].w();
00057 T y = points_[i].y()/points_[i].w();
00058 T z = points_[i].z()/points_[i].w();
00059 A += x;
00060 B += y;
00061 C += z;
00062 D += x*x;
00063 E += y*y;
00064 F += z*z;
00065 G += x*y;
00066 H += y*z;
00067 I += x*z;
00068 }
00069
00070 vnl_matrix<T> coeff_matrix(4, 4);
00071 coeff_matrix(0, 0) = D;
00072 coeff_matrix(0, 1) = G;
00073 coeff_matrix(0, 2) = I;
00074 coeff_matrix(0, 3) = A;
00075
00076 coeff_matrix(1, 0) = G;
00077 coeff_matrix(1, 1) = E;
00078 coeff_matrix(1, 2) = H;
00079 coeff_matrix(1, 3) = B;
00080
00081 coeff_matrix(2, 0) = I;
00082 coeff_matrix(2, 1) = H;
00083 coeff_matrix(2, 2) = F;
00084 coeff_matrix(2, 3) = C;
00085
00086 coeff_matrix(3, 0) = A;
00087 coeff_matrix(3, 1) = B;
00088 coeff_matrix(3, 2) = C;
00089 coeff_matrix(3, 3) = T(n);
00090
00091 vnl_svd<T> svd(coeff_matrix);
00092
00093 T min = svd.sigma_min();
00094 if (min > error_marg) {
00095 if (errstream) *errstream << "Error Margin " << error_marg << '<' << min << ". Could not fit the points to a plane\n";
00096 return false;
00097 }
00098
00099
00100 vnl_vector<T> s = svd.nullvector();
00101
00102
00103 vnl_matrix_fixed<T,4,4> N=norm.get_matrix();
00104 vnl_matrix_fixed<T,4,4> N_transp = N.transpose();
00105 s = N_transp * s;
00106
00107 T a, b, c, d;
00108 a = s.get(0);
00109 b = s.get(1);
00110 c = s.get(2);
00111 d = s.get(3);
00112 plane_ = vgl_homg_plane_3d<T> (a, b, c, d);
00113 return true;
00114 }
00115
00116
00117 #undef VGL_FIT_PLANE_3D_INSTANTIATE
00118 #define VGL_FIT_PLANE_3D_INSTANTIATE(T) \
00119 template class vgl_fit_plane_3d<T >
00120
00121 #endif // vgl_fit_plane_3d_txx_