Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008 #include "ProjectiveBasis2D.h"
00009 #include <vcl_iostream.h>
00010 #include <vcl_vector.h>
00011 #include <vcl_cassert.h>
00012 #include <vnl/vnl_double_3.h>
00013 #include <vnl/vnl_double_3x3.h>
00014 #include <vnl/vnl_double_3x4.h>
00015 #include <vnl/vnl_inverse.h>
00016 #include <vnl/algo/vnl_svd.h>
00017
00018 static const int warn_ = false;
00019 static const int check_collinear = true;
00020
00021
00022 ProjectiveBasis2D::ProjectiveBasis2D(const HomgPoint2D& p1, const HomgPoint2D& p2, const HomgPoint2D& p3, const HomgPoint2D& p4)
00023 {
00024 compute(p1, p2, p3, p4);
00025 }
00026
00027
00028 ProjectiveBasis2D::ProjectiveBasis2D(const vcl_vector<HomgPoint2D>& points)
00029 {
00030 assert(points.size() >= 4);
00031 compute(points[0], points[1], points[2], points[3]);
00032 }
00033
00034
00035 ProjectiveBasis2D::ProjectiveBasis2D(const ProjectiveBasis2D& that)
00036 {
00037 operator=(that);
00038 }
00039
00040
00041 ProjectiveBasis2D& ProjectiveBasis2D::operator=(const ProjectiveBasis2D&)
00042 {
00043 assert(!"ProjectiveBasis2D::operator=");
00044 return *this;
00045 }
00046
00047
00048 ProjectiveBasis2D::~ProjectiveBasis2D()
00049 {
00050 }
00051
00052
00053
00054
00055
00056
00057 void ProjectiveBasis2D::compute(const HomgPoint2D& p1, const HomgPoint2D& p2, const HomgPoint2D& p3, const HomgPoint2D& p4)
00058 {
00059 if (check_collinear) {
00060 vnl_double_3x4 full_matrix;
00061 full_matrix.set_column(0, p1.get_vector());
00062 full_matrix.set_column(1, p2.get_vector());
00063 full_matrix.set_column(2, p3.get_vector());
00064 full_matrix.set_column(3, p4.get_vector());
00065
00066 if (! full_matrix.is_finite() || full_matrix.has_nans()) {
00067 vcl_cerr << "Error (ProjectiveBasis2D): given matrix has infinite or NaN values\n";
00068 T_.set_identity(); collinear_ = true; return;
00069 }
00070
00071 vnl_svd<double> s(full_matrix.as_ref(), 1e-8);
00072 collinear_ = (s.rank() < 3);
00073
00074 if (collinear_ && warn_)
00075 vcl_cerr << "Warning (ProjectiveBasis2D): Three out of the four points are nearly collinear\n";
00076 }
00077 else {
00078 collinear_ = false;
00079 }
00080
00081 vnl_double_3x3 back_matrix;
00082 back_matrix.set_column(0, p1.get_vector());
00083 back_matrix.set_column(1, p2.get_vector());
00084 back_matrix.set_column(2, p3.get_vector());
00085
00086 vnl_svd<double> svd(back_matrix.as_ref());
00087 vnl_double_3 scales_vector = svd.solve(p4.get_vector().as_ref());
00088
00089 back_matrix.set_column(0, scales_vector[0] * p1.get_vector());
00090 back_matrix.set_column(1, scales_vector[1] * p2.get_vector());
00091 back_matrix.set_column(2, scales_vector[2] * p3.get_vector());
00092
00093 if (! back_matrix.is_finite() || back_matrix.has_nans()) {
00094 vcl_cerr << "Error (ProjectiveBasis2D): back matrix has infinite or NaN values\n";
00095 T_.set_identity(); collinear_ = true; return;
00096 }
00097
00098 T_.set(vnl_inverse(back_matrix));
00099 }