vgl_h_matrix_1d_compute_optimize.cxx
Go to the documentation of this file.
1 #include <iomanip>
2 #include <iostream>
3 #include <utility>
6 
7 #include <cassert>
8 #ifdef _MSC_VER
9 # include <vcl_msvc_warnings.h>
10 #endif
11 
12 #include <vnl/vnl_least_squares_function.h>
13 #include <vnl/algo/vnl_levenberg_marquardt.h>
14 #include <vnl/vnl_double_2x2.h>
15 
16 //********************************************************************************
17 //
18 //
19 //
20 //********************************************************************************
21 
22 
23 #ifndef DOXYGEN_SHOULD_SKIP_THIS
24 class XXX : public vnl_least_squares_function
25 {
26  private:
27  unsigned N;
28  const std::vector<double> &z1,z2;
29  public:
30  XXX(const std::vector<double> &z1_,std::vector<double> z2_)
31  : vnl_least_squares_function(3, z1_.size(), no_gradient)
32  , N(z1_.size())
33  , z1(z1_) , z2(std::move(z2_))
34  {
35 #ifdef DEBUG
36  std::cerr << "N=" << N << '\n';
37 #endif
38  assert(N == z1.size());
39  assert(N == z2.size());
40  }
41  ~XXX() override { N=0; }
42 
43  void boo(const vnl_vector<double> &x) {
44  assert(x.size()==3);
45  std::cerr << std::showpos << std::fixed; // <iomanip>
46  double z,y;
47  for (unsigned i=0;i<N;i++) {
48  z=z1[i];
49  y=(z+x[0])/(x[1]*z+1+x[2]);
50  std::cerr << z << ' ' << y << '[' << z2[i] << ']' << std::endl;
51  }
52  }
53 
54  // the matrix is [ 1.0 x[0] ]
55  // [ x[1] 1+x[2] ]
56  void f(const vnl_vector<double>& x, vnl_vector<double>& fx) override {
57  assert(x.size()==3);
58  assert(fx.size()==N);
59  double z,y;
60  for (unsigned k=0;k<N;k++) {
61  z=z1[k];
62  y=(z+x[0])/(x[1]*z+1+x[2]);
63  fx[k]=z2[k]-y;
64  }
65  }
66 };
67 #endif // DOXYGEN_SHOULD_SKIP_THIS
68 
69 static
70 void do_compute(const std::vector<double> &z1,const std::vector<double> &z2,vgl_h_matrix_1d<double> &M)
71 {
72  //
73  // **** minimise over the set of 2x2 matrices of the form [ 1 x[0] ] ****
74  // **** [ x[1] 1+x[2] ] ****
75  //
76 
77  // Set up a compute object :
78  XXX f(z1,z2);
79 
80  // Set up the initial guess :
81  vnl_vector<double> x(3);
82  x.fill(0);
83 
84  // Make a Levenberg Marquardt minimizer and attach f to it :
85  vnl_levenberg_marquardt LM(f);
86 
87  // Run minimiser :
88  // f.boo(x);
89  LM.minimize(x);
90  // f.boo(x);
91 
92  // convert back to matrix format.
93  vnl_double_2x2 T;
94  T(0,0)=1; T(0,1)=x[0];
95  T(1,0)=x[1]; T(1,1)=1+x[2];
96  M.set(T);
97 }
98 
101  const std::vector<vgl_homg_point_1d<double> >&p2,
103 {
104  unsigned N=p1.size();
105  assert(N==p2.size());
106  if (N<3) return false;
107 
108  std::vector<double> z1(N,0.0),z2(N,0.0);
110  C.compute(p1,p2,M);
111 
112  // map the points in p1 under M so that we are
113  // looking for a correction near the identity :
114  for (unsigned i=0;i<N;i++) {
115  vgl_homg_point_1d<double> v = M(p1[i]);
116  if (v.w() == 0.0) return false;
117  z1[i] = v.x()/v.w(); // make nonhomogeneous
118  if (p2[i].w()) return false;
119  z2[i] = p2[i].x()/p2[i].w(); // make nonhomogeneous
120  }
121 
123  do_compute(z1,z2,K);
124  M= K * M; // refine M using the correction K.
125  return true;
126 }
bool compute_cool_homg(const std::vector< vgl_homg_point_1d< double > > &points1, const std::vector< vgl_homg_point_1d< double > > &points2, vgl_h_matrix_1d< double > &H) override
A class to hold a line-to-line projective transformation matrix and to perform common operations usin...
Definition: vgl_algo_fwd.h:10
#define v
Definition: vgl_vector_2d.h:74
compute the h_matrix using Levenberg-Marquardt.
vgl_h_matrix_1d & set(T const *M)
Set to 2x2 row-stored matrix.
find line-to-line projectivity from a set of matched points using SVD
bool compute(const std::vector< vgl_homg_point_1d< double > > &p1, const std::vector< vgl_homg_point_1d< double > > &p2, vgl_h_matrix_1d< double > &H)
principal interface: given point correspondences in p1,p2, returns H.
Represents a homogeneous 1-D point, i.e., a homogeneous pair (x,w).
Definition: vgl_fwd.h:7