9 # include <vcl_msvc_warnings.h> 12 #include <vnl/vnl_inverse.h> 13 #include <vnl/vnl_transpose.h> 14 #include <vnl/algo/vnl_svd.h> 37 for (
int i = 0; i < n; i++) {
38 D(row, 0) = p1[i].x();
39 D(row, 1) = -p1[i].y();
42 D(row, 4) = -p2[i].x();
45 D(row, 0) = p1[i].y();
46 D(row, 1) = p1[i].x();
49 D(row, 4) = -p2[i].y();
54 vnl_svd<double> svd(D);
55 vnl_vector<double> nullv = svd.nullvector();
58 std::cout <<
"vgl_h_matrix_2d_compute_rigid_body : inaccurate solution probably due to inconsistent point correspondences\n" 59 <<
"W\n" << svd.W() << std::endl;
65 double norm = nullv[4];
70 double angle = std::atan2(y,x);
71 double c = std::cos(
angle);
72 double s = std::sin(
angle);
73 vnl_matrix_fixed<double, 3,3> M;
74 M[0][0]=c; M[0][1]= -s; M[0][2] = nullv[2];
75 M[1][0]=s; M[1][1]= c; M[1][2] = nullv[3];
76 M[2][0]=0; M[2][1]= 0; M[2][2] = 1;
87 assert(points1.size() == points2.size());
88 int n = points1.size();
90 int equ_count = n * (2);
92 std::cerr <<
"vgl_h_matrix_2d_compute_rigid_body: Need at least 2 matches.\n";
93 if (n == 0) std::cerr <<
"Could be std::vector setlength idiosyncrasies!\n";
102 std::vector<vgl_homg_point_2d<double> > tpoints1, tpoints2;
103 for (
int i = 0; i<n; i++)
105 tpoints1.push_back(tr1(points1[i]));
106 tpoints2.push_back(tr2(points2[i]));
130 assert(lines1.size() == lines2.size());
131 int n = lines1.size();
140 std::vector<vgl_homg_point_2d<double> > tlines1, tlines2;
141 for (
const auto & lit : lines1)
147 tlines1.push_back(p);
149 for (
const auto & lit : lines2)
155 tlines2.push_back(p);
163 vnl_matrix_fixed<double, 3, 3>
const & Ml = hl.
get_matrix();
164 vnl_matrix_fixed<double, 3, 3> Mp = vnl_inverse_transpose(Ml);
187 assert(points1.size() == points2.size());
188 int np = points1.size();
190 assert(lines1.size() == lines2.size());
191 int nl = lines1.size();
193 int equ_count = np * 2 + 2*nl;
196 std::cerr <<
"vgl_h_matrix_2d_compute_rigid_body: Need at least 4 matches.\n";
197 if (np+nl == 0) std::cerr <<
"Could be std::vector setlength idiosyncrasies!\n";
206 std::vector<vgl_homg_point_2d<double> > tpoints1, tpoints2;
207 for (
int i = 0; i<np; i++)
209 tpoints1.push_back(tr1(points1[i]));
210 tpoints2.push_back(tr2(points2[i]));
212 for (
int i = 0; i<nl; i++)
214 double a=lines1[i].a(), b=lines1[i].b(), c=lines1[i].c(), d=std::sqrt(a*a+b*b);
216 a=lines2[i].a(), b=lines2[i].b(), c=lines2[i].c(), d = std::sqrt(a*a+b*b);
231 std::vector<double>
const& ,
255 bool vgl_h_matrix_2d_compute_rigid_body::
258 std::vector<double>
const& w,
264 vnl_vector<double> two_w(2*Nc);
266 for (
int i = 0; i<Nc; i++, j+=2)
271 vnl_diag_matrix<double> W(two_w);
278 for (
int i = 0; i < Nc; i++)
280 D(row, 0) = l1[i].a() * l2[i].c();
281 D(row, 1) = l1[i].b() * l2[i].c();
282 D(row, 2) = l1[i].c() * l2[i].c();
286 D(row, 6) = -l1[i].a() * l2[i].a();
287 D(row, 7) = -l1[i].b() * l2[i].a();
288 D(row, 8) = -l1[i].c() * l2[i].a();
294 D(row, 3) = l1[i].a() * l2[i].c();
295 D(row, 4) = l1[i].b() * l2[i].c();
296 D(row, 5) = l1[i].c() * l2[i].c();
297 D(row, 6) = -l1[i].a() * l2[i].b();
298 D(row, 7) = -l1[i].b() * l2[i].b();
299 D(row, 8) = -l1[i].c() * l2[i].b();
302 M = vnl_transpose(D)*W*D;
304 vnl_svd<double> svd(D);
310 std::cerr <<
"vgl_h_matrix_2d_compute_rigid_body : design matrix has rank < 8\n" 311 <<
"vgl_h_matrix_2d_compute_rigid_body : probably due to degenerate point configuration\n";
315 H.
set(svd.nullvector().data_block());
322 std::vector<double>
const & weights,
326 assert(lines1.size() == lines2.size());
331 if (!tr1.compute_from_lines(lines1))
333 if (!tr2.compute_from_lines(lines2))
335 std::vector<vgl_homg_line_2d<double> > tlines1, tlines2;
337 lit = lines1.begin(); lit != lines1.end(); lit++)
341 tlines1.push_back(
l);
344 lit = lines2.begin(); lit != lines2.end(); lit++)
348 tlines2.push_back(
l);
352 if (!solve_weighted_least_squares(tlines1, tlines2, weights, hl))
356 vnl_matrix_fixed<double, 3, 3>
const & Ml = hl.
get_matrix();
357 vnl_matrix_fixed<double, 3, 3> Mp = vnl_inverse_transpose(Ml);
constexpr int TM_UNKNOWNS_COUNT
vnl_matrix_fixed< T, 3, 3 > const & get_matrix() const
Return the 3x3 homography matrix.
constexpr double DEGENERACY_THRESHOLD
vgl_h_matrix_2d_compute_rigid_body()
Construct a vgl_h_matrix_2d_compute_rigid_body object.
Represents a homogeneous 2D line.
vgl_h_matrix_2d & set(unsigned int row_index, unsigned int col_index, T value)
Set an element of the 3x3 homography matrix.
The similarity transform that normalizes a point set.
contains class vgl_h_matrix_2d_compute_rigid_body
bool compute_pl(std::vector< vgl_homg_point_2d< double > > const &points1, std::vector< vgl_homg_point_2d< double > > const &points2, std::vector< vgl_homg_line_2d< double > > const &lines1, std::vector< vgl_homg_line_2d< double > > const &lines2, vgl_h_matrix_2d< double > &H) override
compute from matched points and lines.
bool compute_from_lines(std::vector< vgl_homg_line_2d< T > > const &lines, bool isotropic=true)
The normalizing transform for lines is computed from the set of points defined by the intersection of...
bool compute_l(std::vector< vgl_homg_line_2d< double > > const &lines1, std::vector< vgl_homg_line_2d< double > > const &lines2, vgl_h_matrix_2d< double > &H) override
compute from matched lines.
bool compute_from_points_and_lines(std::vector< vgl_homg_point_2d< T > > const &pts, std::vector< vgl_homg_line_2d< T > > const &lines, bool isotropic=true)
The normalizing transform for points and lines is computed from the set of points used by compute_fro...
bool compute_p(std::vector< vgl_homg_point_2d< double > > const &points1, std::vector< vgl_homg_point_2d< double > > const &points2, vgl_h_matrix_2d< double > &H) override
compute from matched points.
bool compute_from_points(std::vector< vgl_homg_point_2d< T > > const &points, bool isotropic=true)
compute the normalizing transform.
double angle(vgl_ray_3d< Type > const &r0, vgl_ray_3d< Type > const &r1)
public functions.
vgl_h_matrix_2d get_inverse() const
Return the inverse homography.
Represents a homogeneous 2D point.
bool solve_rigid_body_problem(int equ_count, std::vector< vgl_homg_point_2d< double > >const &p1, std::vector< vgl_homg_point_2d< double > >const &p2, vgl_h_matrix_2d< double > &H)
Assumes all corresponding points have equal weight.