Go to the documentation of this file.00001
00002 #include "HMatrix2DComputeLinear.h"
00003
00004
00005
00006 #include <vcl_vector.h>
00007 #include <vcl_iostream.h>
00008 #include <vcl_cassert.h>
00009 #include <vnl/algo/vnl_svd.h>
00010 #include <mvl/HMatrix2D.h>
00011 #include <mvl/HomgMetric.h>
00012 #include <mvl/HomgNorm2D.h>
00013
00014
00015
00016 HMatrix2DComputeLinear::HMatrix2DComputeLinear(bool allow_ideal_points):
00017 allow_ideal_points_(allow_ideal_points)
00018 {
00019 }
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 const int TM_UNKNOWNS_COUNT = 9;
00030 const double DEGENERACY_THRESHOLD = 0.00001;
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 bool
00051 HMatrix2DComputeLinear::compute_p(PointArray const& inpoints1,
00052 PointArray const& inpoints2,
00053 HMatrix2D *H)
00054 {
00055
00056 assert(inpoints1.size() == inpoints2.size());
00057 int n = inpoints1.size();
00058
00059 int equ_count = n * (allow_ideal_points_ ? 3 : 2);
00060 if (n * 2 < TM_UNKNOWNS_COUNT - 1) {
00061 vcl_cerr << "HMatrix2DComputeLinear: Need at least 4 matches.\n";
00062 if (n == 0) vcl_cerr << "Could be vcl_vector setlength idiosyncrasies!\n";
00063 return false;
00064 }
00065
00066 HomgNorm2D points1(inpoints1); if (points1.was_coincident()) return false;
00067 HomgNorm2D points2(inpoints2); if (points2.was_coincident()) return false;
00068
00069 vnl_matrix<double> D(equ_count, TM_UNKNOWNS_COUNT);
00070
00071 int row = 0;
00072 for (int i = 0; i < n; i++) {
00073 const HomgPoint2D& p1 = points1[i];
00074 const HomgPoint2D& p2 = points2[i];
00075
00076 D(row, 0) = p1.x() * p2.w();
00077 D(row, 1) = p1.y() * p2.w();
00078 D(row, 2) = p1.w() * p2.w();
00079 D(row, 3) = 0;
00080 D(row, 4) = 0;
00081 D(row, 5) = 0;
00082 D(row, 6) = -p1.x() * p2.x();
00083 D(row, 7) = -p1.y() * p2.x();
00084 D(row, 8) = -p1.w() * p2.x();
00085 ++row;
00086
00087 D(row, 0) = 0;
00088 D(row, 1) = 0;
00089 D(row, 2) = 0;
00090 D(row, 3) = p1.x() * p2.w();
00091 D(row, 4) = p1.y() * p2.w();
00092 D(row, 5) = p1.w() * p2.w();
00093 D(row, 6) = -p1.x() * p2.y();
00094 D(row, 7) = -p1.y() * p2.y();
00095 D(row, 8) = -p1.w() * p2.y();
00096 ++row;
00097
00098 if (allow_ideal_points_) {
00099 D(row, 0) = p1.x() * p2.y();
00100 D(row, 1) = p1.y() * p2.y();
00101 D(row, 2) = p1.w() * p2.y();
00102 D(row, 3) = -p1.x() * p2.x();
00103 D(row, 4) = -p1.y() * p2.x();
00104 D(row, 5) = -p1.w() * p2.x();
00105 D(row, 6) = 0;
00106 D(row, 7) = 0;
00107 D(row, 8) = 0;
00108 ++row;
00109 }
00110 }
00111
00112 D.normalize_rows();
00113 vnl_svd<double> svd(D);
00114
00115
00116
00117
00118 if (svd.W(7)<DEGENERACY_THRESHOLD*svd.W(8)) {
00119 vcl_cerr << "HMatrix2DComputeLinear : design matrix has rank < 8" << vcl_endl;
00120 vcl_cerr << "HMatrix2DComputeLinear : probably due to degenerate point configuration" << vcl_endl;
00121 return false;
00122 }
00123 H->set(svd.nullvector().data_block());
00124
00125 *H = HomgMetric::homg_to_image_H(*H, &points1, &points2);
00126
00127 return true;
00128 }